feat(studio): plain-language store, bottom-anchored ask bar (v0.33.0)
The store had three structural problems flagged in user feedback: 1. "Lernkurve zu hoch — alle bridge, debug, alpha, planned, keiner weiß was das heißt." Wire-level enum values bled through into the UI: `bridge`, `debug`, `published`, `alpha`, `planned`. Operators don't share the data model. 2. "Filter / Kategorien sollten oben in die Leiste neben Store zum ausklappen, der Body soll übersichtlicher werden." A chip-row plus category strip plus result-count line ate a full row of viewport on every screen. 3. "Suche passt besser an den unteren Bildschirmrand." The chat-style ask bar belongs at the bottom — Claude / ChatGPT / Slack pattern — not at the top where it competes with the Today hero. Plus: "Es gibt noch ganz viele overflows in den Beschreibungen." Changes: - Plain-language display names. New ARB keys for category labels (Connectors / Sample modules / AI models / Storage / Channels / Authentication / Orchestration / …) and updated status values (stable / experimental / coming soon). Wire ids stay in StoreEntry, RPCs, seed.yaml — only the rendered pills and dropdowns get translated. Helpers `_categoryDisplayName` and `_statusDisplayName` keep the mapping in one place. - Toolbar moves into the AppBar. The new `_CategoryDropdown` hosts the category picker as a popup-menu with localised labels; the existing `_FilterButton` lives next to it; the reload icon stays where it always was. The body no longer carries any chip strip or result-count line. - Bottom-anchored `_AskBar`. The Scaffold body becomes a Column of `Expanded(scrollable content)` plus a pinned composer row at the foot of the viewport, with a top divider matching the chat-input pattern of modern AI assistants. AI answers now render at the top of the scroll (above the Today-Hero) so the operator sees them right after submitting the question at the bottom. - Overflow sweep on descriptions. Today-Hero header row becomes a Wrap (badge + deck flow naturally on narrow windows), the title is bound to 3 lines, the body to 6. Card category text gets `maxLines: 1, ellipsis` in both StoreCard and FeaturedTile. Recommended-source card title gets the same treatment. - Better toast for the "added but zero capabilities" path. When MCP discovery succeeds but returns no tools (typical Streamable-HTTP servers without Mcp-Session-Id support, or servers that need `notifications/initialized`), the toast now explains the situation in plain language and points the operator at Settings → MCP Clients to retry. Old pluralised toast still fires when N > 0. Hub-side `notifications/initialized` for HTTP MCP and Mcp-Session-Id support are out of scope for this commit; tracked as a separate fai_hub follow-up. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
c7869870c4
commit
de22791e86
8 changed files with 434 additions and 143 deletions
|
|
@ -127,10 +127,22 @@
|
|||
"storeNoMatchesHint": "Filter anpassen oder Suche leeren, um alle Einträge zu sehen.",
|
||||
"storeClearFilters": "Filter zurücksetzen",
|
||||
"storeStatusAll": "Alle",
|
||||
"storeStatusPublished": "Veröffentlicht",
|
||||
"storeStatusAlpha": "Alpha",
|
||||
"storeStatusPlanned": "Geplant",
|
||||
"storeStatusPublished": "stabil",
|
||||
"storeStatusAlpha": "experimentell",
|
||||
"storeStatusPlanned": "geplant",
|
||||
"storeInstalledOnly": "Installiert",
|
||||
"storeCategoryLabel": "Kategorie",
|
||||
"storeCategoryAll": "Alle Kategorien",
|
||||
"storeCategoryBridge": "Verbindungen",
|
||||
"storeCategoryDebug": "Beispiele",
|
||||
"storeCategoryText": "Text",
|
||||
"storeCategoryLlm": "KI-Modelle",
|
||||
"storeCategorySystem": "System",
|
||||
"storeCategoryAuth": "Authentifizierung",
|
||||
"storeCategoryStorage": "Speicher",
|
||||
"storeCategoryChannel": "Kanäle",
|
||||
"storeCategoryWeb": "Web",
|
||||
"storeCategoryOrchestrator": "Orchestrierung",
|
||||
"storeNResults": "{n} Treffer",
|
||||
"@storeNResults": {
|
||||
"placeholders": { "n": { "type": "int" } }
|
||||
|
|
@ -221,6 +233,10 @@
|
|||
"n": { "type": "int" }
|
||||
}
|
||||
},
|
||||
"storeProviderAddedZeroToast": "{name} ist eingetragen, aber der Server hat noch keine Capabilities geliefert. Öffne Einstellungen → MCP-Clients, um Discovery erneut zu versuchen oder den Server zu prüfen.",
|
||||
"@storeProviderAddedZeroToast": {
|
||||
"placeholders": { "name": { "type": "String" } }
|
||||
},
|
||||
"storeProviderAddFailed": "{name} konnte nicht hinzugefügt werden: {error}",
|
||||
"@storeProviderAddFailed": {
|
||||
"placeholders": {
|
||||
|
|
|
|||
|
|
@ -128,10 +128,22 @@
|
|||
"storeNoMatchesHint": "Adjust the filters or clear the search to see all entries.",
|
||||
"storeClearFilters": "Clear filters",
|
||||
"storeStatusAll": "All",
|
||||
"storeStatusPublished": "Published",
|
||||
"storeStatusAlpha": "Alpha",
|
||||
"storeStatusPlanned": "Planned",
|
||||
"storeStatusPublished": "stable",
|
||||
"storeStatusAlpha": "experimental",
|
||||
"storeStatusPlanned": "coming soon",
|
||||
"storeInstalledOnly": "Installed",
|
||||
"storeCategoryLabel": "Category",
|
||||
"storeCategoryAll": "All categories",
|
||||
"storeCategoryBridge": "Connectors",
|
||||
"storeCategoryDebug": "Sample modules",
|
||||
"storeCategoryText": "Text",
|
||||
"storeCategoryLlm": "AI models",
|
||||
"storeCategorySystem": "System",
|
||||
"storeCategoryAuth": "Authentication",
|
||||
"storeCategoryStorage": "Storage",
|
||||
"storeCategoryChannel": "Channels",
|
||||
"storeCategoryWeb": "Web",
|
||||
"storeCategoryOrchestrator": "Orchestration",
|
||||
"storeNResults": "{n} result{n, plural, =1{} other{s}}",
|
||||
"@storeNResults": {
|
||||
"placeholders": { "n": { "type": "int" } }
|
||||
|
|
@ -222,6 +234,10 @@
|
|||
"n": { "type": "int" }
|
||||
}
|
||||
},
|
||||
"storeProviderAddedZeroToast": "{name} registered, but the server returned no capabilities yet. Open Settings → MCP Clients to retry discovery or check the server.",
|
||||
"@storeProviderAddedZeroToast": {
|
||||
"placeholders": { "name": { "type": "String" } }
|
||||
},
|
||||
"storeProviderAddFailed": "Could not add {name}: {error}",
|
||||
"@storeProviderAddFailed": {
|
||||
"placeholders": {
|
||||
|
|
|
|||
|
|
@ -761,19 +761,19 @@ abstract class AppLocalizations {
|
|||
/// No description provided for @storeStatusPublished.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Published'**
|
||||
/// **'stable'**
|
||||
String get storeStatusPublished;
|
||||
|
||||
/// No description provided for @storeStatusAlpha.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Alpha'**
|
||||
/// **'experimental'**
|
||||
String get storeStatusAlpha;
|
||||
|
||||
/// No description provided for @storeStatusPlanned.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Planned'**
|
||||
/// **'coming soon'**
|
||||
String get storeStatusPlanned;
|
||||
|
||||
/// No description provided for @storeInstalledOnly.
|
||||
|
|
@ -782,6 +782,78 @@ abstract class AppLocalizations {
|
|||
/// **'Installed'**
|
||||
String get storeInstalledOnly;
|
||||
|
||||
/// No description provided for @storeCategoryLabel.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Category'**
|
||||
String get storeCategoryLabel;
|
||||
|
||||
/// No description provided for @storeCategoryAll.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'All categories'**
|
||||
String get storeCategoryAll;
|
||||
|
||||
/// No description provided for @storeCategoryBridge.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Connectors'**
|
||||
String get storeCategoryBridge;
|
||||
|
||||
/// No description provided for @storeCategoryDebug.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Sample modules'**
|
||||
String get storeCategoryDebug;
|
||||
|
||||
/// No description provided for @storeCategoryText.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Text'**
|
||||
String get storeCategoryText;
|
||||
|
||||
/// No description provided for @storeCategoryLlm.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'AI models'**
|
||||
String get storeCategoryLlm;
|
||||
|
||||
/// No description provided for @storeCategorySystem.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'System'**
|
||||
String get storeCategorySystem;
|
||||
|
||||
/// No description provided for @storeCategoryAuth.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Authentication'**
|
||||
String get storeCategoryAuth;
|
||||
|
||||
/// No description provided for @storeCategoryStorage.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Storage'**
|
||||
String get storeCategoryStorage;
|
||||
|
||||
/// No description provided for @storeCategoryChannel.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Channels'**
|
||||
String get storeCategoryChannel;
|
||||
|
||||
/// No description provided for @storeCategoryWeb.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Web'**
|
||||
String get storeCategoryWeb;
|
||||
|
||||
/// No description provided for @storeCategoryOrchestrator.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Orchestration'**
|
||||
String get storeCategoryOrchestrator;
|
||||
|
||||
/// No description provided for @storeNResults.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
@ -1100,6 +1172,12 @@ abstract class AppLocalizations {
|
|||
/// **'Added {name} — {n} federated {n, plural, =1{capability} other{capabilities}}.'**
|
||||
String storeProviderAddedToast(String name, int n);
|
||||
|
||||
/// No description provided for @storeProviderAddedZeroToast.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{name} registered, but the server returned no capabilities yet. Open Settings → MCP Clients to retry discovery or check the server.'**
|
||||
String storeProviderAddedZeroToast(String name);
|
||||
|
||||
/// No description provided for @storeProviderAddFailed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
|
|||
|
|
@ -382,17 +382,53 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get storeStatusAll => 'Alle';
|
||||
|
||||
@override
|
||||
String get storeStatusPublished => 'Veröffentlicht';
|
||||
String get storeStatusPublished => 'stabil';
|
||||
|
||||
@override
|
||||
String get storeStatusAlpha => 'Alpha';
|
||||
String get storeStatusAlpha => 'experimentell';
|
||||
|
||||
@override
|
||||
String get storeStatusPlanned => 'Geplant';
|
||||
String get storeStatusPlanned => 'geplant';
|
||||
|
||||
@override
|
||||
String get storeInstalledOnly => 'Installiert';
|
||||
|
||||
@override
|
||||
String get storeCategoryLabel => 'Kategorie';
|
||||
|
||||
@override
|
||||
String get storeCategoryAll => 'Alle Kategorien';
|
||||
|
||||
@override
|
||||
String get storeCategoryBridge => 'Verbindungen';
|
||||
|
||||
@override
|
||||
String get storeCategoryDebug => 'Beispiele';
|
||||
|
||||
@override
|
||||
String get storeCategoryText => 'Text';
|
||||
|
||||
@override
|
||||
String get storeCategoryLlm => 'KI-Modelle';
|
||||
|
||||
@override
|
||||
String get storeCategorySystem => 'System';
|
||||
|
||||
@override
|
||||
String get storeCategoryAuth => 'Authentifizierung';
|
||||
|
||||
@override
|
||||
String get storeCategoryStorage => 'Speicher';
|
||||
|
||||
@override
|
||||
String get storeCategoryChannel => 'Kanäle';
|
||||
|
||||
@override
|
||||
String get storeCategoryWeb => 'Web';
|
||||
|
||||
@override
|
||||
String get storeCategoryOrchestrator => 'Orchestrierung';
|
||||
|
||||
@override
|
||||
String storeNResults(int n) {
|
||||
return '$n Treffer';
|
||||
|
|
@ -596,6 +632,11 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
return '$name hinzugefügt — $n $_temp0.';
|
||||
}
|
||||
|
||||
@override
|
||||
String storeProviderAddedZeroToast(String name) {
|
||||
return '$name ist eingetragen, aber der Server hat noch keine Capabilities geliefert. Öffne Einstellungen → MCP-Clients, um Discovery erneut zu versuchen oder den Server zu prüfen.';
|
||||
}
|
||||
|
||||
@override
|
||||
String storeProviderAddFailed(String name, String error) {
|
||||
return '$name konnte nicht hinzugefügt werden: $error';
|
||||
|
|
|
|||
|
|
@ -394,17 +394,53 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get storeStatusAll => 'All';
|
||||
|
||||
@override
|
||||
String get storeStatusPublished => 'Published';
|
||||
String get storeStatusPublished => 'stable';
|
||||
|
||||
@override
|
||||
String get storeStatusAlpha => 'Alpha';
|
||||
String get storeStatusAlpha => 'experimental';
|
||||
|
||||
@override
|
||||
String get storeStatusPlanned => 'Planned';
|
||||
String get storeStatusPlanned => 'coming soon';
|
||||
|
||||
@override
|
||||
String get storeInstalledOnly => 'Installed';
|
||||
|
||||
@override
|
||||
String get storeCategoryLabel => 'Category';
|
||||
|
||||
@override
|
||||
String get storeCategoryAll => 'All categories';
|
||||
|
||||
@override
|
||||
String get storeCategoryBridge => 'Connectors';
|
||||
|
||||
@override
|
||||
String get storeCategoryDebug => 'Sample modules';
|
||||
|
||||
@override
|
||||
String get storeCategoryText => 'Text';
|
||||
|
||||
@override
|
||||
String get storeCategoryLlm => 'AI models';
|
||||
|
||||
@override
|
||||
String get storeCategorySystem => 'System';
|
||||
|
||||
@override
|
||||
String get storeCategoryAuth => 'Authentication';
|
||||
|
||||
@override
|
||||
String get storeCategoryStorage => 'Storage';
|
||||
|
||||
@override
|
||||
String get storeCategoryChannel => 'Channels';
|
||||
|
||||
@override
|
||||
String get storeCategoryWeb => 'Web';
|
||||
|
||||
@override
|
||||
String get storeCategoryOrchestrator => 'Orchestration';
|
||||
|
||||
@override
|
||||
String storeNResults(int n) {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
|
|
@ -613,6 +649,11 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
return 'Added $name — $n federated $_temp0.';
|
||||
}
|
||||
|
||||
@override
|
||||
String storeProviderAddedZeroToast(String name) {
|
||||
return '$name registered, but the server returned no capabilities yet. Open Settings → MCP Clients to retry discovery or check the server.';
|
||||
}
|
||||
|
||||
@override
|
||||
String storeProviderAddFailed(String name, String error) {
|
||||
return 'Could not add $name: $error';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue