@saasicat/ui-vue 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/README.md +17 -0
  2. package/dist/{chunk-EH7TOD4H.js → chunk-A3W2N26K.js} +73 -77
  3. package/dist/{chunk-3YP2ZAOD.js → chunk-QZOSDCNP.js} +36 -1
  4. package/dist/chunk-X5SQ5HMB.js +3231 -0
  5. package/dist/client/index.cjs +3279 -76
  6. package/dist/client/index.d.cts +31 -5
  7. package/dist/client/index.d.ts +31 -5
  8. package/dist/client/index.js +23 -5
  9. package/dist/index.cjs +3709 -465
  10. package/dist/index.d.cts +37 -54
  11. package/dist/index.d.ts +37 -54
  12. package/dist/index.js +347 -311
  13. package/dist/messages-7b0P8W75.d.cts +1652 -0
  14. package/dist/messages-7b0P8W75.d.ts +1652 -0
  15. package/dist/quasar/index.cjs +3185 -4
  16. package/dist/quasar/index.d.cts +11 -2
  17. package/dist/quasar/index.d.ts +11 -2
  18. package/dist/quasar/index.js +8 -3
  19. package/dist/testing-e2e/admin-pages-suite.cjs +14 -11
  20. package/dist/testing-e2e/admin-pages-suite.js +14 -11
  21. package/dist/{ui-notify-COUzXEQ4.d.ts → use-super-admin-i18n-B3v3-SWZ.d.ts} +35 -3
  22. package/dist/{ui-notify-D_eAAwRh.d.cts → use-super-admin-i18n-DMktRVEt.d.cts} +35 -3
  23. package/package.json +2 -2
  24. package/src/client/action-registry.ts +4 -4
  25. package/src/client/batch-column-fetcher.ts +4 -4
  26. package/src/client/boot-loader.ts +3 -3
  27. package/src/client/i18n/currency.ts +42 -0
  28. package/src/client/i18n/define.ts +59 -0
  29. package/src/client/i18n/format.ts +12 -0
  30. package/src/client/i18n/index.ts +14 -0
  31. package/src/client/i18n/locale.ts +15 -0
  32. package/src/client/i18n/messages/audit.ts +42 -0
  33. package/src/client/i18n/messages/bundles.ts +459 -0
  34. package/src/client/i18n/messages/common.ts +147 -0
  35. package/src/client/i18n/messages/dashboard.ts +16 -0
  36. package/src/client/i18n/messages/discovery.ts +229 -0
  37. package/src/client/i18n/messages/email.ts +125 -0
  38. package/src/client/i18n/messages/marketing.ts +270 -0
  39. package/src/client/i18n/messages/nav.ts +72 -0
  40. package/src/client/i18n/messages/pilots.ts +192 -0
  41. package/src/client/i18n/messages/plan-detail.ts +266 -0
  42. package/src/client/i18n/messages/plan-editor.ts +177 -0
  43. package/src/client/i18n/messages/plan-versions.ts +251 -0
  44. package/src/client/i18n/messages/plans.ts +503 -0
  45. package/src/client/i18n/messages/promos.ts +202 -0
  46. package/src/client/i18n/messages/shell.ts +145 -0
  47. package/src/client/i18n/messages/tenants.ts +104 -0
  48. package/src/client/i18n/messages/users.ts +78 -0
  49. package/src/client/i18n/messages.ts +84 -0
  50. package/src/client/index.ts +2 -0
  51. package/src/client/manifest-loader.ts +4 -4
  52. package/src/client/nav-builder.ts +44 -51
  53. package/src/client/plan-versions-catalog.ts +42 -30
  54. package/src/components/BundleVersionPublishDialog.vue +35 -24
  55. package/src/components/MarketingPromotionsTab.vue +112 -59
  56. package/src/components/MfaPromptDialog.vue +11 -11
  57. package/src/components/TenantActionConfirmDialog.vue +19 -17
  58. package/src/components/VersionDiffPreview.vue +72 -43
  59. package/src/components/bundle-editor/BundleCreatePanel.vue +76 -63
  60. package/src/components/bundle-editor/BundleFeaturesEditor.vue +13 -6
  61. package/src/components/bundle-editor/BundlePlanCompatPicker.vue +19 -14
  62. package/src/components/bundle-editor/BundleQuotasEditor.vue +7 -4
  63. package/src/components/bundle-editor/BundleStatusBanner.vue +36 -19
  64. package/src/components/bundle-editor/BundleVersionInlineEditor.vue +51 -35
  65. package/src/components/bundle-editor/BundleVersionStrip.vue +24 -12
  66. package/src/components/bundle-editor/bundle-version-status.ts +29 -29
  67. package/src/components/dialogs/PilotCreateDialog.vue +58 -63
  68. package/src/components/dialogs/PilotEditDialog.vue +40 -34
  69. package/src/components/dialogs/PromoCodeCreateDialog.vue +89 -63
  70. package/src/components/dialogs/PromoCodeEditDialog.vue +98 -66
  71. package/src/components/dialogs/types.ts +3 -13
  72. package/src/components/plan/PlanCycleToggle.vue +20 -9
  73. package/src/components/plan-cockpit/PlanCockpit.vue +34 -15
  74. package/src/components/plan-cockpit/PlanCockpitAuditLog.vue +13 -6
  75. package/src/components/plan-cockpit/PlanCockpitDiffPanel.vue +18 -9
  76. package/src/components/plan-cockpit/PlanCockpitHeader.vue +9 -6
  77. package/src/components/plan-cockpit/PlanCockpitImpactPanel.vue +24 -11
  78. package/src/components/plan-cockpit/PlanCockpitKpis.vue +28 -17
  79. package/src/components/plan-cockpit/PlanCockpitVersions.vue +50 -25
  80. package/src/components/plan-create-dialog/PlanCreateDialog.vue +45 -35
  81. package/src/components/plan-detail/PlanAuditLog.vue +11 -6
  82. package/src/components/plan-detail/PlanDetail.vue +21 -23
  83. package/src/components/plan-detail/PlanDetailHeader.vue +20 -11
  84. package/src/components/plan-detail/PlanDetailKpis.vue +30 -17
  85. package/src/components/plan-detail/PlanTerminateDialog.vue +22 -9
  86. package/src/components/plan-detail/PlanVersionDiffPanel.vue +61 -27
  87. package/src/components/plan-detail/PlanVersionsPanel.vue +71 -36
  88. package/src/components/plan-list/PlanList.vue +99 -57
  89. package/src/components/plan-matrix/PlanMatrix.vue +85 -38
  90. package/src/components/plan-review/PlanReview.vue +105 -80
  91. package/src/components/plan-version-editor/PlanCatalogPreview.vue +43 -20
  92. package/src/components/plan-version-editor/PlanComponentPool.vue +15 -7
  93. package/src/components/plan-version-editor/PlanVersionBasket.vue +45 -24
  94. package/src/components/plan-version-editor/PlanVersionDiffDialog.vue +8 -7
  95. package/src/components/plan-version-editor/PlanVersionEditor.vue +74 -40
  96. package/src/components/plan-version-editor/PlanVersionEditorHeader.vue +24 -12
  97. package/src/index.ts +1 -1
  98. package/src/pages-standard/AdminLayout.vue +42 -17
  99. package/src/pages-standard/AdminManifestErrorPage.vue +10 -10
  100. package/src/pages-standard/AuditPage.vue +58 -19
  101. package/src/pages-standard/BundlesPage.vue +29 -18
  102. package/src/pages-standard/DashboardPage.vue +29 -15
  103. package/src/pages-standard/DiscoveryPage.vue +40 -28
  104. package/src/pages-standard/EmailHistoryPage.vue +92 -59
  105. package/src/pages-standard/MarketingCatalogPage.vue +35 -16
  106. package/src/pages-standard/PilotsPage.vue +57 -41
  107. package/src/pages-standard/PlanVersionsPage.vue +7 -3
  108. package/src/pages-standard/PlansPage.vue +89 -57
  109. package/src/pages-standard/PlatformEmailPage.vue +115 -50
  110. package/src/pages-standard/PromoCodeDetailPage.vue +66 -63
  111. package/src/pages-standard/PromoCodesPage.vue +46 -35
  112. package/src/pages-standard/SubscriptionsPage.vue +14 -9
  113. package/src/pages-standard/SuperAdminLoginPage.vue +16 -13
  114. package/src/pages-standard/SuperAdminSetupWizard.vue +51 -47
  115. package/src/pages-standard/TenantDetailPage.vue +50 -36
  116. package/src/pages-standard/TenantsPage.vue +54 -41
  117. package/src/pages-standard/UsersPage.vue +66 -42
  118. package/src/pages-standard/bundles-page/BundleAccordionList.vue +20 -8
  119. package/src/pages-standard/bundles-page/BundleDetailPanel.vue +28 -18
  120. package/src/pages-standard/bundles-page/BundlesFilterBar.vue +4 -1
  121. package/src/pages-standard/bundles-page/BundlesHeader.vue +9 -8
  122. package/src/pages-standard/bundles-page/BundlesKpis.vue +29 -11
  123. package/src/pages-standard/discovery-page/CatalogEntryTransPanel.vue +20 -8
  124. package/src/pages-standard/discovery-page/DiscoveryCapList.vue +5 -3
  125. package/src/pages-standard/discovery-page/DiscoveryFeatureCard.vue +43 -24
  126. package/src/pages-standard/discovery-page/DiscoveryHeader.vue +7 -4
  127. package/src/pages-standard/discovery-page/DiscoveryKpis.vue +28 -15
  128. package/src/pages-standard/discovery-page/DiscoveryQuotaCard.vue +20 -10
  129. package/src/pages-standard/discovery-page/DiscoveryStatusControl.vue +9 -6
  130. package/src/pages-standard/discovery-page/discovery-ui.ts +40 -52
  131. package/src/pages-standard/marketing-catalog/MarketingCatalogAdmin.vue +81 -49
  132. package/src/pages-standard/marketing-catalog/MarketingCatalogHeader.vue +13 -10
  133. package/src/pages-standard/marketing-catalog/MarketingCatalogPreview.vue +24 -20
  134. package/src/pages-standard/marketing-catalog/MarketingCatalogToolbar.vue +6 -3
  135. package/src/pages-standard/plan-versions/PlanDiffCard.vue +16 -6
  136. package/src/pages-standard/plan-versions/PlanVersionHeader.vue +41 -25
  137. package/src/pages-standard/plan-versions/PlanVersionsAudit.vue +45 -26
  138. package/src/pages-standard/plan-versions/PlanVersionsDiff.vue +7 -5
  139. package/src/pages-standard/plan-versions/PlanVersionsList.vue +39 -16
  140. package/src/pages-standard/plan-versions/PlanVersionsTimeline.vue +24 -12
  141. package/src/pages-standard/plan-versions/format.ts +33 -17
  142. package/src/pages-standard/plans-page/PlanArchiveDialog.vue +12 -8
  143. package/src/pages-standard/plans-page/PlanBundleOverview.vue +15 -6
  144. package/src/pages-standard/plans-page/PlanDiscardDraftDialog.vue +18 -7
  145. package/src/pages-standard/plans-page/PlanPublishDialog.vue +23 -12
  146. package/src/pages-standard/tenants/format.ts +3 -2
  147. package/src/pages-tenant/MySubscriptionBundlesPage.vue +72 -37
  148. package/src/pages-tenant/PlanChangeWizard.vue +8 -4
  149. package/src/pages-tenant/TenantPlanSection.vue +17 -13
  150. package/src/pages-tenant/default-i18n.ts +217 -1
  151. package/src/pages-tenant/tenant-plan-section/BundlePreviewDialog.vue +8 -6
  152. package/src/pages-tenant/tenant-plan-section/TenantBundleStore.vue +9 -10
  153. package/src/pages-tenant/tenant-plan-section/TenantFeatureMatrix.vue +4 -1
  154. package/src/quasar/create-super-admin-app.ts +19 -0
  155. package/src/testing-e2e/admin-pages-suite.ts +14 -11
  156. package/src/vue/project-page-host.ts +5 -3
  157. package/src/vue/use-audit-entries.ts +3 -3
  158. package/src/vue/use-bulk-publish.ts +6 -4
  159. package/src/vue/use-bundle-versions-map.ts +6 -4
  160. package/src/vue/use-bundles.ts +13 -13
  161. package/src/vue/use-catalog-entries.ts +13 -10
  162. package/src/vue/use-discovery.ts +8 -5
  163. package/src/vue/use-entitlement.ts +3 -3
  164. package/src/vue/use-live-plan-versions.ts +4 -4
  165. package/src/vue/use-marketing-projections.ts +9 -6
  166. package/src/vue/use-nav.ts +8 -2
  167. package/src/vue/use-plan-editor.ts +2 -2
  168. package/src/vue/use-plan-versions.ts +3 -3
  169. package/src/vue/use-plans.ts +12 -12
  170. package/src/vue/use-platform-tenant-actions.ts +9 -6
  171. package/src/vue/use-promotions.ts +9 -10
  172. package/src/vue/use-subscription-draft.ts +2 -3
  173. package/src/vue/use-super-admin-context.ts +3 -3
  174. package/src/vue/use-super-admin-i18n.ts +82 -0
  175. package/src/vue/use-tenant-action-flow.ts +11 -6
  176. package/src/vue/use-tenant-manifest.ts +1 -3
  177. package/src/vue/use-tenant-subscription-bundles.ts +4 -4
  178. package/src/vue/use-tenants.ts +3 -3
  179. package/dist/action-registry-CQ2wL3R-.d.cts +0 -85
  180. package/dist/action-registry-CQ2wL3R-.d.ts +0 -85
  181. package/dist/chunk-LVGUSD3T.js +0 -26
  182. package/src/components/BusinessTypeVersionEditorDialog.vue +0 -417
  183. package/src/components/BusinessTypeVersionPublishDialog.vue +0 -258
  184. package/src/pages-standard/BusinessTypesPage.vue +0 -662
  185. package/src/pages-standard/plan-versions/VersionDiffPreview.vue +0 -167
  186. package/src/vue/use-business-types.ts +0 -269
package/README.md CHANGED
@@ -80,6 +80,23 @@ pnpm create saasicat-admin admin --project-key=myapp
80
80
  See the [quickstart](https://github.com/uelker70/saasicat/blob/main/docs/quickstart.md) (step 9) for the full setup
81
81
  and the [handbook](https://github.com/uelker70/saasicat/blob/main/docs/handbook.md) for the architecture.
82
82
 
83
+ ## Language
84
+
85
+ The UI ships German (reference) and English catalogs — plain typed objects, no
86
+ `vue-i18n` dependency. German is the default:
87
+
88
+ ```ts
89
+ createSuperAdminApp({
90
+ // …
91
+ i18n: { locale: 'en' },
92
+ });
93
+ ```
94
+
95
+ Pass a `Ref<SaLocale>` instead of a literal to switch at runtime, and
96
+ `i18n.overrides` to replace individual strings per locale. Components read the
97
+ catalog via `useSaMessages('<namespace>')` / `useSuperAdminI18n()`.
98
+ See [handbook §8.6](https://github.com/uelker70/saasicat/blob/main/docs/handbook.md#86-ui-language-i18n).
99
+
83
100
  ## Build
84
101
 
85
102
  ```bash
@@ -1,7 +1,12 @@
1
1
  import {
2
+ DEFAULT_SA_LOCALE,
3
+ SA_INTL_LOCALES,
2
4
  defaultHttpClient,
3
- defaultKvStore
4
- } from "./chunk-LVGUSD3T.js";
5
+ defaultKvStore,
6
+ formatMessage,
7
+ navMessages,
8
+ planVersionsMessages
9
+ } from "./chunk-X5SQ5HMB.js";
5
10
 
6
11
  // src/client/version.ts
7
12
  var ADMIN_UI_VERSION = "1.2.0";
@@ -64,7 +69,7 @@ var BootLoader = class {
64
69
  constructor(options) {
65
70
  if (!options?.endpoint) {
66
71
  throw new Error(
67
- 'BootLoader: `endpoint` ist Pflicht (z. B. "/api/admin/boot" oder "/api/v1/admin/boot"). Plattform hat keinen Default, weil Apps unterschiedliche globalPrefix-Konventionen haben.'
72
+ 'BootLoader: `endpoint` is required (e.g. "/api/admin/boot" or "/api/v1/admin/boot"). The platform has no default because apps use different globalPrefix conventions.'
68
73
  );
69
74
  }
70
75
  this.endpoint = options.endpoint;
@@ -98,7 +103,7 @@ var ManifestLoader = class {
98
103
  constructor(options) {
99
104
  if (!options?.endpoint) {
100
105
  throw new Error(
101
- 'ManifestLoader: `endpoint` ist Pflicht (z. B. "/api/admin/manifest" oder "/api/v1/admin/manifest"). Plattform hat keinen Default, weil Apps unterschiedliche globalPrefix-Konventionen haben.'
106
+ 'ManifestLoader: `endpoint` is required (e.g. "/api/admin/manifest" or "/api/v1/admin/manifest"). The platform has no default because apps use different globalPrefix conventions.'
102
107
  );
103
108
  }
104
109
  this.endpoint = options.endpoint;
@@ -125,7 +130,7 @@ var ManifestLoader = class {
125
130
  if (!cachedBody) {
126
131
  throw new ManifestLoadError(
127
132
  304,
128
- "Server lieferte 304, aber Cache-Body fehlt \u2014 bitte clearCache() + reload"
133
+ "Server returned 304 but the cache body is missing \u2014 call clearCache() and reload"
129
134
  );
130
135
  }
131
136
  return cachedBody.body;
@@ -175,28 +180,10 @@ var DEFAULT_STANDARD_PAGE_ROUTES = {
175
180
  pilots: "/admin/pilots",
176
181
  discovery: "/admin/discovery",
177
182
  bundles: "/admin/bundles",
178
- businessTypes: "/admin/business-types",
179
183
  marketingCatalog: "/admin/marketing-catalog",
180
184
  platformEmail: "/admin/platform-email",
181
185
  platformEmailHistory: "/admin/platform-email-history"
182
186
  };
183
- var DEFAULT_LABELS = {
184
- dashboard: "Dashboard",
185
- tenants: "Mandanten",
186
- subscriptions: "Abonnements",
187
- promoCodes: "Promo-Codes",
188
- plans: "Pl\xE4ne & Versionen",
189
- planVersions: "Plan-Versionen",
190
- audit: "Audit-Log",
191
- users: "Benutzer",
192
- pilots: "Piloten",
193
- discovery: "Discovery",
194
- bundles: "Bundles",
195
- businessTypes: "Gesch\xE4ftstypen",
196
- marketingCatalog: "Marketing-Catalog",
197
- platformEmail: "Plattform-E-Mail",
198
- platformEmailHistory: "E-Mail-Verlauf"
199
- };
200
187
  var DEFAULT_ICONS = {
201
188
  dashboard: "dashboard",
202
189
  tenants: "business",
@@ -209,42 +196,42 @@ var DEFAULT_ICONS = {
209
196
  pilots: "flight_takeoff",
210
197
  discovery: "travel_explore",
211
198
  bundles: "inventory_2",
212
- businessTypes: "category",
213
199
  marketingCatalog: "campaign",
214
200
  platformEmail: "mail",
215
201
  platformEmailHistory: "mark_email_read"
216
202
  };
217
- var DEFAULT_NAV_SECTIONS = {
218
- dashboard: "\xDCbersicht",
219
- discovery: "Produktkatalog",
220
- businessTypes: "Produktkatalog",
221
- bundles: "Produktkatalog",
222
- plans: "Produktkatalog",
223
- planVersions: "Produktkatalog",
224
- marketingCatalog: "Produktkatalog",
225
- promoCodes: "Produktkatalog",
226
- tenants: "Kunden",
227
- subscriptions: "Kunden",
228
- users: "Kunden",
229
- pilots: "Kunden",
230
- audit: "System",
231
- platformEmail: "System",
232
- platformEmailHistory: "System"
203
+ var PAGE_SECTIONS = {
204
+ dashboard: "overview",
205
+ discovery: "catalog",
206
+ bundles: "catalog",
207
+ plans: "catalog",
208
+ planVersions: "catalog",
209
+ marketingCatalog: "catalog",
210
+ promoCodes: "catalog",
211
+ tenants: "customers",
212
+ subscriptions: "customers",
213
+ users: "customers",
214
+ pilots: "customers",
215
+ audit: "system",
216
+ platformEmail: "system",
217
+ platformEmailHistory: "system"
233
218
  };
234
- var DEFAULT_SECTION_ORDER = [
235
- "\xDCbersicht",
236
- "Produktkatalog",
237
- "Kunden",
238
- "System"
239
- ];
219
+ function defaultSectionOrder(locale = DEFAULT_SA_LOCALE) {
220
+ const sections = navMessages[locale].sections;
221
+ return [sections.overview, sections.catalog, sections.customers, sections.system];
222
+ }
240
223
  function buildRoutes(manifest, options = {}) {
241
224
  const routes = [];
242
225
  const capabilities = manifest.capabilities ?? {};
243
226
  const standard = manifest.navigation?.standardPages ?? {};
227
+ const nav = navMessages[options.locale ?? DEFAULT_SA_LOCALE];
228
+ const defaultNavSections = Object.fromEntries(
229
+ Object.entries(PAGE_SECTIONS).map(([page, section]) => [page, nav.sections[section]])
230
+ );
244
231
  const overrideRoutes = { ...DEFAULT_STANDARD_PAGE_ROUTES, ...options.standardPageRoutes };
245
- const overrideLabels = { ...DEFAULT_LABELS, ...options.standardPageLabels };
232
+ const overrideLabels = { ...nav.pages, ...options.standardPageLabels };
246
233
  const overrideIcons = { ...DEFAULT_ICONS, ...options.standardPageIcons };
247
- const overrideNavSection = { ...DEFAULT_NAV_SECTIONS, ...options.standardPageNavSection };
234
+ const overrideNavSection = { ...defaultNavSections, ...options.standardPageNavSection };
248
235
  for (const key of Object.keys(standard)) {
249
236
  const def = standard[key];
250
237
  if (!def?.enabled) continue;
@@ -281,7 +268,7 @@ function buildRoutes(manifest, options = {}) {
281
268
  }
282
269
  return routes;
283
270
  }
284
- function buildSidebar(routes, sectionOrder = DEFAULT_SECTION_ORDER) {
271
+ function buildSidebar(routes, sectionOrder = defaultSectionOrder()) {
285
272
  const bySection = /* @__PURE__ */ new Map();
286
273
  for (const r of routes) {
287
274
  const section = r.navSection ?? null;
@@ -314,7 +301,7 @@ function resolveExtension(componentKey, extensions) {
314
301
  var MissingHandlerError = class extends Error {
315
302
  constructor(actionKey) {
316
303
  super(
317
- `Kein Handler f\xFCr actionKey "${actionKey}" registriert. Konsument-Shell muss \`actions["${actionKey}"]\` bereitstellen.`
304
+ `No handler registered for actionKey "${actionKey}". The consumer shell must provide \`actions["${actionKey}"]\`.`
318
305
  );
319
306
  this.name = "MissingHandlerError";
320
307
  }
@@ -322,7 +309,7 @@ var MissingHandlerError = class extends Error {
322
309
  var ActionDefNotInManifestError = class extends Error {
323
310
  constructor(actionKey) {
324
311
  super(
325
- `actionKey "${actionKey}" ist im Manifest nicht deklariert. Bitte als TenantAction in einer ManifestContribution registrieren.`
312
+ `actionKey "${actionKey}" is not declared in the manifest. Register it as a TenantAction in a ManifestContribution.`
326
313
  );
327
314
  this.name = "ActionDefNotInManifestError";
328
315
  }
@@ -466,12 +453,12 @@ var BatchColumnFetcher = class {
466
453
  }
467
454
  validateBatchEndpoint(col) {
468
455
  if (!col.endpoint || col.endpoint.trim().length === 0) {
469
- throw new BatchColumnDriftError(col, "endpoint ist leer");
456
+ throw new BatchColumnDriftError(col, "endpoint is empty");
470
457
  }
471
458
  if (col.endpoint.includes("{slug}") || col.endpoint.includes("{tenantId}")) {
472
459
  throw new BatchColumnDriftError(
473
460
  col,
474
- "endpoint enth\xE4lt per-Tenant-Placeholder ({slug}/{tenantId}). Spalten-Endpoints m\xFCssen batchf\xE4hig sein \u2014 bitte Backend auf `?tenantIds=...`-Parameter umstellen."
461
+ "endpoint contains per-tenant placeholders ({slug}/{tenantId}). Column endpoints must be batchable \u2014 switch the backend to a `?tenantIds=...` parameter."
475
462
  );
476
463
  }
477
464
  }
@@ -548,14 +535,20 @@ function resolvePlan(source, liveBase) {
548
535
  maxStorageGb: quotas.storageGb
549
536
  };
550
537
  }
551
- function dateLabelDe(iso) {
552
- return new Date(iso).toLocaleDateString("de-DE", {
538
+ function draftsTitle(draftCount, msg) {
539
+ if (draftCount === 0) return msg.draftsTitleEmpty;
540
+ const template = draftCount === 1 ? msg.draftsTitleOne : msg.draftsTitleMany;
541
+ return formatMessage(template, { count: draftCount });
542
+ }
543
+ function dateLabel(iso, locale) {
544
+ return new Date(iso).toLocaleDateString(SA_INTL_LOCALES[locale], {
553
545
  day: "2-digit",
554
546
  month: "short",
555
547
  year: "numeric"
556
548
  });
557
549
  }
558
- function buildDraftsSnapshot(data, sortPlansFn) {
550
+ function buildDraftsSnapshot(data, sortPlansFn, locale) {
551
+ const msg = planVersionsMessages[locale].catalog;
559
552
  const planByKey = groupBy(data.planVersions, (r) => r.planId);
560
553
  const plans = [];
561
554
  for (const [, rows] of planByKey) {
@@ -569,9 +562,9 @@ function buildDraftsSnapshot(data, sortPlansFn) {
569
562
  id: "drafts",
570
563
  kind: "drafts",
571
564
  status: "DRAFT",
572
- label: "Arbeitsstand",
573
- title: draftCount === 0 ? "Keine offenen Drafts" : `${draftCount} offene${draftCount === 1 ? "r" : ""} Draft${draftCount === 1 ? "" : "s"} bereit f\xFCr Publish`,
574
- description: draftCount === 0 ? "Lege einen Draft an, um Limits, Preise oder Features zu \xE4ndern. Drafts sind ohne MFA editierbar und werden erst beim Publish wirksam." : "Diese Tabelle zeigt, wie der Catalog nach Publish aller Drafts aussehen w\xFCrde. Bestehende Mandanten bleiben auf der vorherigen Version, bis sie aktiv migriert werden.",
565
+ label: msg.draftsLabel,
566
+ title: draftsTitle(draftCount, msg),
567
+ description: draftCount === 0 ? msg.draftsDescriptionEmpty : msg.draftsDescription,
575
568
  asOf: null,
576
569
  createdAt: null,
577
570
  publishedAt: null,
@@ -581,7 +574,8 @@ function buildDraftsSnapshot(data, sortPlansFn) {
581
574
  regressionCount: 0
582
575
  };
583
576
  }
584
- function buildActiveSnapshot(data, sortPlansFn) {
577
+ function buildActiveSnapshot(data, sortPlansFn, locale) {
578
+ const msg = planVersionsMessages[locale].catalog;
585
579
  const planByKey = groupBy(data.planVersions, (r) => r.planId);
586
580
  const plans = [];
587
581
  for (const [, rows] of planByKey) {
@@ -595,9 +589,9 @@ function buildActiveSnapshot(data, sortPlansFn) {
595
589
  id: "active",
596
590
  kind: "active",
597
591
  status: "ACTIVE",
598
- label: "Aktuell",
599
- title: "Live-Catalog",
600
- description: "Diese Plan-Versionen sind aktuell f\xFCr neue Onboardings und f\xFCr Renewals nach Stichtag aktiv.",
592
+ label: msg.activeLabel,
593
+ title: msg.activeTitle,
594
+ description: msg.activeDescription,
601
595
  asOf: latestPublished ?? null,
602
596
  createdAt: null,
603
597
  publishedAt: latestPublished ?? null,
@@ -607,7 +601,8 @@ function buildActiveSnapshot(data, sortPlansFn) {
607
601
  regressionCount: 0
608
602
  };
609
603
  }
610
- function buildHistoricalSnapshots(data, sortPlansFn) {
604
+ function buildHistoricalSnapshots(data, sortPlansFn, locale) {
605
+ const msg = planVersionsMessages[locale].catalog;
611
606
  const allPublishedAt = /* @__PURE__ */ new Set();
612
607
  for (const r of data.planVersions) if (r.publishedAt) allPublishedAt.add(r.publishedAt);
613
608
  if (allPublishedAt.size === 0) return [];
@@ -637,9 +632,9 @@ function buildHistoricalSnapshots(data, sortPlansFn) {
637
632
  id: `hist-${ts}`,
638
633
  kind: "historical",
639
634
  status: "ARCHIVED",
640
- label: dateLabelDe(ts),
641
- title: summarizeEvent(publishedAtThisEvent),
642
- description: detailEvent(publishedAtThisEvent),
635
+ label: dateLabel(ts, locale),
636
+ title: summarizeEvent(publishedAtThisEvent, msg),
637
+ description: detailEvent(publishedAtThisEvent, msg),
643
638
  asOf: ts,
644
639
  createdAt: ts,
645
640
  publishedAt: ts,
@@ -651,18 +646,18 @@ function buildHistoricalSnapshots(data, sortPlansFn) {
651
646
  }
652
647
  return out;
653
648
  }
654
- function summarizeEvent(rows) {
655
- if (rows.length === 0) return "Publish-Event";
649
+ function summarizeEvent(rows, msg) {
650
+ if (rows.length === 0) return msg.publishEvent;
656
651
  if (rows.length === 1) {
657
652
  const r = rows[0];
658
- return `${r.planId} v${r.version} publiziert`;
653
+ return formatMessage(msg.publishEventSingle, { planId: r.planId, version: r.version });
659
654
  }
660
- return `${rows.length} Versionen publiziert`;
655
+ return formatMessage(msg.publishEventMultiple, { count: rows.length });
661
656
  }
662
- function detailEvent(rows) {
657
+ function detailEvent(rows, msg) {
663
658
  if (rows.length === 0) return "";
664
659
  const note = rows[0]?.changeNote ?? "";
665
- return note.length > 0 ? note : "Snapshot rekonstruiert aus per-Entity-Versionen.";
660
+ return note.length > 0 ? note : msg.reconstructedSnapshot;
666
661
  }
667
662
  function sortPlansBy(order) {
668
663
  if (!order || order.length === 0) {
@@ -678,10 +673,11 @@ function sortPlansBy(order) {
678
673
  });
679
674
  }
680
675
  function buildSnapshots(data, options = {}) {
676
+ const locale = options.locale ?? DEFAULT_SA_LOCALE;
681
677
  const sortPlansFn = sortPlansBy(options.planSortOrder);
682
- const drafts = buildDraftsSnapshot(data, sortPlansFn);
683
- const active = buildActiveSnapshot(data, sortPlansFn);
684
- const historical = buildHistoricalSnapshots(data, sortPlansFn);
678
+ const drafts = buildDraftsSnapshot(data, sortPlansFn, locale);
679
+ const active = buildActiveSnapshot(data, sortPlansFn, locale);
680
+ const historical = buildHistoricalSnapshots(data, sortPlansFn, locale);
685
681
  const out = [drafts];
686
682
  if (active) out.push(active);
687
683
  out.push(...historical);
@@ -704,7 +700,7 @@ export {
704
700
  ManifestLoadError,
705
701
  ManifestLoader,
706
702
  DEFAULT_STANDARD_PAGE_ROUTES,
707
- DEFAULT_SECTION_ORDER,
703
+ defaultSectionOrder,
708
704
  buildRoutes,
709
705
  buildSidebar,
710
706
  resolveExtension,
@@ -1,3 +1,9 @@
1
+ import {
2
+ DEFAULT_SA_LOCALE,
3
+ SA_INTL_LOCALES,
4
+ resolveMessages
5
+ } from "./chunk-X5SQ5HMB.js";
6
+
1
7
  // src/vue/super-admin-context.ts
2
8
  var SUPER_ADMIN_BRAND_KEY = /* @__PURE__ */ Symbol.for(
3
9
  "@saasicat/ui-vue/SUPER_ADMIN_BRAND"
@@ -50,6 +56,31 @@ var SUPER_ADMIN_NOTIFY_KEY = /* @__PURE__ */ Symbol.for(
50
56
  "@saasicat/ui-vue/SUPER_ADMIN_NOTIFY"
51
57
  );
52
58
 
59
+ // src/vue/use-super-admin-i18n.ts
60
+ import { computed, inject, isRef, ref } from "vue";
61
+ var SUPER_ADMIN_I18N_KEY = /* @__PURE__ */ Symbol.for(
62
+ "@saasicat/ui-vue/SUPER_ADMIN_I18N"
63
+ );
64
+ function createSuperAdminI18n(options = {}) {
65
+ const locale = isRef(options.locale) ? options.locale : ref(options.locale ?? DEFAULT_SA_LOCALE);
66
+ const messages = computed(
67
+ () => resolveMessages(locale.value, options.overrides?.[locale.value])
68
+ );
69
+ const intlLocale = computed(() => SA_INTL_LOCALES[locale.value]);
70
+ return { locale, messages, intlLocale };
71
+ }
72
+ var fallbackI18n = null;
73
+ function useSuperAdminI18n() {
74
+ const injected = inject(SUPER_ADMIN_I18N_KEY, null);
75
+ if (injected) return injected;
76
+ fallbackI18n ??= createSuperAdminI18n();
77
+ return fallbackI18n;
78
+ }
79
+ function useSaMessages(namespace) {
80
+ const { messages } = useSuperAdminI18n();
81
+ return computed(() => messages.value[namespace]);
82
+ }
83
+
53
84
  export {
54
85
  SUPER_ADMIN_BRAND_KEY,
55
86
  SUPER_ADMIN_ENDPOINTS_KEY,
@@ -59,5 +90,9 @@ export {
59
90
  SUPER_ADMIN_LOGIN_ADAPTER_KEY,
60
91
  SUPER_ADMIN_HTTP_KEY,
61
92
  buildNavigationGuard,
62
- SUPER_ADMIN_NOTIFY_KEY
93
+ SUPER_ADMIN_NOTIFY_KEY,
94
+ SUPER_ADMIN_I18N_KEY,
95
+ createSuperAdminI18n,
96
+ useSuperAdminI18n,
97
+ useSaMessages
63
98
  };