From 27cf7e83829b563bda9cddf5723fca39e8ed5551 Mon Sep 17 00:00:00 2001 From: flemming-it Date: Mon, 22 Jun 2026 00:59:51 +0200 Subject: [PATCH] feat(studio): show module origin store ('from ') StoreItem gains source (mapped from StoreEntry.source); the store grid shows a 'from ' label for operator-added stores (bundled seed unlabelled). Foundation for grouping by store. EN+DE l10n. Signed-off-by: flemming-it --- lib/data/hub.dart | 8 ++++++++ lib/l10n/app_de.arb | 1 + lib/l10n/app_en.arb | 6 ++++++ lib/l10n/app_localizations.dart | 6 ++++++ lib/l10n/app_localizations_de.dart | 5 +++++ lib/l10n/app_localizations_en.dart | 5 +++++ lib/pages/store.dart | 13 +++++++++++++ 7 files changed, 44 insertions(+) diff --git a/lib/data/hub.dart b/lib/data/hub.dart index 27eb86c..df4b7fc 100644 --- a/lib/data/hub.dart +++ b/lib/data/hub.dart @@ -786,6 +786,7 @@ class HubService { kind: e.kind, provider: e.provider, sourceKind: e.sourceKind, + source: e.source, ), ) .toList(); @@ -1793,6 +1794,12 @@ class StoreItem { /// from `kind` for pre-0.12 hubs. final String sourceKind; + /// Name of the store this entry came from ("bundled" for the built-in + /// seed, otherwise the operator-added store's name). Distinct from + /// `sourceKind` (the transport) — this is the ORIGIN store, used to + /// label and group modules by where they came from. + final String source; + bool get isFederated => kind == 'federated'; const StoreItem({ @@ -1817,5 +1824,6 @@ class StoreItem { required this.kind, required this.provider, this.sourceKind = '', + this.source = '', }); } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index bad06e9..655204b 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -2,6 +2,7 @@ "@@locale": "de", "errModuleDownload": "Modul-Download fehlgeschlagen", "errModuleDownloadHint": "Die Bundle-URL des Moduls ist nicht erreichbar (Statuscode unten). Der Hub läuft — URL/Host korrigieren oder anderen Store wählen.", + "storeFromSource": "aus {store}", "guidedSetupTitle": "Setup-Assistent", "guidedSetupIntro": "Beantworte drei Fragen — Ch∆In stellt passende Konfiguration, Modul-Set und Start-Flow zusammen.", "guidedSetupScenario": "Szenario", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 8ac4f2b..3b0aa3e 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -2,6 +2,12 @@ "@@locale": "en", "errModuleDownload": "Module download failed", "errModuleDownloadHint": "The module's bundle URL is unreachable (status code below). The hub is running fine — fix the URL/host or choose another store.", + "storeFromSource": "from {store}", + "@storeFromSource": { + "placeholders": { + "store": { "type": "String" } + } + }, "guidedSetupTitle": "Setup assistant", "guidedSetupIntro": "Answer three questions and Ch∆In assembles a tailored config, module set and starter flow.", "guidedSetupScenario": "Scenario", diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 61235dd..bc599f3 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -110,6 +110,12 @@ abstract class AppLocalizations { /// **'The module\'s bundle URL is unreachable (status code below). The hub is running fine — fix the URL/host or choose another store.'** String get errModuleDownloadHint; + /// No description provided for @storeFromSource. + /// + /// In en, this message translates to: + /// **'from {store}'** + String storeFromSource(String store); + /// No description provided for @guidedSetupTitle. /// /// In en, this message translates to: diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index acf8b10..ec388a1 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -15,6 +15,11 @@ class AppLocalizationsDe extends AppLocalizations { String get errModuleDownloadHint => 'Die Bundle-URL des Moduls ist nicht erreichbar (Statuscode unten). Der Hub läuft — URL/Host korrigieren oder anderen Store wählen.'; + @override + String storeFromSource(String store) { + return 'aus $store'; + } + @override String get guidedSetupTitle => 'Setup-Assistent'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 615cd53..f51f4ed 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -15,6 +15,11 @@ class AppLocalizationsEn extends AppLocalizations { String get errModuleDownloadHint => 'The module\'s bundle URL is unreachable (status code below). The hub is running fine — fix the URL/host or choose another store.'; + @override + String storeFromSource(String store) { + return 'from $store'; + } + @override String get guidedSetupTitle => 'Setup assistant'; diff --git a/lib/pages/store.dart b/lib/pages/store.dart index c812aba..d21a7bf 100644 --- a/lib/pages/store.dart +++ b/lib/pages/store.dart @@ -1930,6 +1930,19 @@ class _StoreCardState extends State<_StoreCard> { color: theme.colorScheme.onSurfaceVariant, ), ), + // Origin store ("from ") — only for + // operator-added stores; the built-in seed + // ("bundled") needs no label. + if (item.source.isNotEmpty && + item.source != 'bundled') + Text( + l.storeFromSource(item.source), + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: theme.textTheme.labelSmall?.copyWith( + color: theme.colorScheme.onSurfaceVariant, + ), + ), ], ), ),