@saasicat/ui-vue 0.19.0 → 0.22.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 (145) hide show
  1. package/dist/{catalog-JXdKdIqG.d.cts → catalog-DJcfm5N2.d.cts} +21 -7
  2. package/dist/{catalog-JXdKdIqG.d.ts → catalog-DJcfm5N2.d.ts} +21 -7
  3. package/dist/{chunk-DPTIOQXX.js → chunk-F7NRM6KI.js} +56 -28
  4. package/dist/{chunk-RVG6LQHL.js → chunk-LY52T4N4.js} +21 -2
  5. package/dist/{chunk-ORX3ZG47.js → chunk-XMMFN2WJ.js} +74 -3
  6. package/dist/client/index.cjs +134 -29
  7. package/dist/client/index.d.cts +53 -3
  8. package/dist/client/index.d.ts +53 -3
  9. package/dist/client/index.js +14 -2
  10. package/dist/index.cjs +321 -162
  11. package/dist/index.d.cts +30 -8
  12. package/dist/index.d.ts +30 -8
  13. package/dist/index.js +176 -133
  14. package/dist/quasar/index.cjs +78 -29
  15. package/dist/quasar/index.d.cts +2 -2
  16. package/dist/quasar/index.d.ts +2 -2
  17. package/dist/quasar/index.js +6 -2
  18. package/dist/testing-e2e/admin-pages-suite.d.cts +37 -0
  19. package/dist/testing-e2e/admin-pages-suite.d.ts +37 -0
  20. package/dist/{use-super-admin-i18n-BlqcD0N7.d.ts → use-super-admin-i18n-CHNdsSlm.d.ts} +34 -7
  21. package/dist/{use-super-admin-i18n-1nCOkvgi.d.cts → use-super-admin-i18n-CgTuNi8h.d.cts} +34 -7
  22. package/package.json +18 -8
  23. package/src/client/i18n/messages/bundles.ts +0 -2
  24. package/src/client/i18n/messages/common.ts +24 -0
  25. package/src/client/i18n/messages/discovery.ts +2 -2
  26. package/src/client/i18n/messages/marketing.ts +2 -4
  27. package/src/client/i18n/messages/plan-detail.ts +0 -4
  28. package/src/client/i18n/messages/plans.ts +20 -8
  29. package/src/client/i18n/messages/tenants.ts +0 -2
  30. package/src/client/index.ts +1 -0
  31. package/src/client/manifest-loader.ts +1 -1
  32. package/src/client/resolve-plans.ts +144 -0
  33. package/src/components/BundleVersionPublishDialog.vue +6 -6
  34. package/src/components/KvBlock.vue +4 -4
  35. package/src/components/MarketingPromotionsTab.vue +34 -48
  36. package/src/components/MfaPromptDialog.vue +8 -2
  37. package/src/components/TenantActionConfirmDialog.vue +4 -4
  38. package/src/components/VersionDiffPreview.vue +7 -7
  39. package/src/components/admin-page/AdminBody.vue +40 -0
  40. package/src/components/admin-page/AdminFilters.vue +12 -0
  41. package/src/components/admin-page/AdminHero.vue +49 -0
  42. package/src/components/admin-page/AdminKpi.vue +84 -0
  43. package/src/components/admin-page/AdminPage.vue +16 -0
  44. package/src/components/admin-page/AdminPaginator.vue +195 -0
  45. package/src/components/admin-page/AdminRefreshBtn.vue +39 -0
  46. package/src/components/admin-page/AdminSection.vue +53 -0
  47. package/src/components/admin-page/AdminStatistics.vue +40 -0
  48. package/src/components/admin-page/AdminTable.vue +175 -0
  49. package/src/components/bundle-editor/BundleCreatePanel.vue +23 -23
  50. package/src/components/bundle-editor/BundleFeaturesEditor.vue +7 -7
  51. package/src/components/bundle-editor/BundlePlanCompatPicker.vue +9 -9
  52. package/src/components/bundle-editor/BundleQuotasEditor.vue +11 -11
  53. package/src/components/bundle-editor/BundleStatusBanner.vue +6 -6
  54. package/src/components/bundle-editor/BundleVersionInlineEditor.vue +18 -18
  55. package/src/components/bundle-editor/BundleVersionStrip.vue +12 -12
  56. package/src/components/dialogs/PilotCreateDialog.vue +12 -12
  57. package/src/components/dialogs/PilotEditDialog.vue +7 -7
  58. package/src/components/dialogs/PromoCodeCreateDialog.vue +8 -8
  59. package/src/components/dialogs/PromoCodeDialogFields.vue +33 -19
  60. package/src/components/dialogs/PromoCodeEditDialog.vue +10 -10
  61. package/src/components/plan/PlanGrid.vue +1 -1
  62. package/src/components/plan-create-dialog/PlanCreateDialog.vue +34 -46
  63. package/src/components/plan-detail/PlanAuditLog.vue +7 -8
  64. package/src/components/plan-detail/PlanDetail.vue +95 -292
  65. package/src/components/plan-detail/PlanDetailKpis.vue +22 -27
  66. package/src/components/plan-detail/PlanTitleEdit.vue +133 -0
  67. package/src/components/plan-detail/PlanVersionDiffPanel.vue +5 -8
  68. package/src/components/plan-detail/PlanVersionsPanel.vue +9 -11
  69. package/src/components/plan-list/PlanList.vue +206 -457
  70. package/src/components/plan-matrix/PlanMatrix.vue +66 -183
  71. package/src/components/plan-review/PlanReview.vue +191 -275
  72. package/src/components/plan-version-editor/PlanCatalogPreview.vue +7 -5
  73. package/src/components/plan-version-editor/PlanVersionEditor.vue +200 -295
  74. package/src/components/plan-version-editor/PlanVersionEditorHeader.vue +23 -55
  75. package/src/index.ts +1 -0
  76. package/src/pages-standard/AdminLayout.vue +38 -12
  77. package/src/pages-standard/AdminManifestErrorPage.vue +79 -9
  78. package/src/pages-standard/AuditPage.vue +65 -109
  79. package/src/pages-standard/BundlesPage.vue +146 -179
  80. package/src/pages-standard/DashboardPage.vue +59 -154
  81. package/src/pages-standard/DiscoveryPage.vue +172 -227
  82. package/src/pages-standard/EmailHistoryPage.vue +118 -159
  83. package/src/pages-standard/MarketingCatalogPage.vue +399 -440
  84. package/src/pages-standard/PilotsPage.vue +69 -117
  85. package/src/pages-standard/PlansPage.vue +240 -112
  86. package/src/pages-standard/PlatformEmailPage.vue +56 -91
  87. package/src/pages-standard/PromoCodeDetailPage.vue +49 -74
  88. package/src/pages-standard/PromoCodesPage.vue +95 -128
  89. package/src/pages-standard/SubscriptionsPage.vue +19 -52
  90. package/src/pages-standard/SuperAdminLoginPage.vue +12 -12
  91. package/src/pages-standard/SuperAdminSetupWizard.vue +22 -18
  92. package/src/pages-standard/TenantDetailPage.vue +100 -191
  93. package/src/pages-standard/TenantsPage.vue +190 -295
  94. package/src/pages-standard/UsersPage.vue +89 -157
  95. package/src/pages-standard/bundles-page/BundleAccordionList.vue +20 -17
  96. package/src/pages-standard/bundles-page/BundlesKpis.vue +13 -22
  97. package/src/pages-standard/bundles-page/BundlesToolbar.vue +63 -0
  98. package/src/pages-standard/discovery-page/CatalogEntryTransPanel.vue +10 -10
  99. package/src/pages-standard/discovery-page/DiscoveryCapList.vue +5 -5
  100. package/src/pages-standard/discovery-page/DiscoveryFeatureCard.vue +16 -16
  101. package/src/pages-standard/discovery-page/DiscoveryKpis.vue +31 -27
  102. package/src/pages-standard/discovery-page/DiscoveryQuotaCard.vue +7 -7
  103. package/src/pages-standard/marketing-catalog/MarketingCatalogAdmin.vue +111 -73
  104. package/src/pages-standard/marketing-catalog/MarketingCatalogHeader.vue +43 -62
  105. package/src/pages-standard/marketing-catalog/MarketingCatalogPreview.vue +53 -35
  106. package/src/pages-standard/marketing-catalog/MarketingCatalogToolbar.vue +7 -7
  107. package/src/pages-standard/plan-versions/PlanDiffCard.vue +6 -6
  108. package/src/pages-standard/plan-versions/PlanVersionsDiff.vue +6 -6
  109. package/src/pages-standard/plan-versions/PlanVersionsTimeline.vue +16 -16
  110. package/src/pages-standard/plans-page/PlanBundleOverview.vue +14 -29
  111. package/src/pages-standard/plans-page/PlanPublishDialog.vue +1 -1
  112. package/src/pages-standard/plans-page/PlansPageToast.vue +6 -6
  113. package/src/pages-standard/sa-theme.css +552 -86
  114. package/src/pages-standard/tenant-detail/TenantMasterData.vue +28 -0
  115. package/src/pages-standard/tenant-detail/TenantUsage.vue +31 -0
  116. package/src/pages-standard/tenant-detail/TenantUsers.vue +15 -0
  117. package/src/pages-standard/tenant-detail/types.ts +38 -0
  118. package/src/pages-standard/tenants/StatusPill.vue +2 -2
  119. package/src/pages-tenant/MySubscriptionBundlesPage.vue +25 -25
  120. package/src/pages-tenant/OnboardingConfigurator.vue +1 -5
  121. package/src/pages-tenant/PackageSnapshotPanel.vue +1 -1
  122. package/src/pages-tenant/TenantPlanSection.vue +12 -20
  123. package/src/quasar/create-super-admin-app.ts +4 -0
  124. package/src/vue/entitlement-provider.ts +0 -1
  125. package/src/vue/feature-router-guard.ts +0 -1
  126. package/src/vue/super-admin-context.ts +106 -1
  127. package/src/vue/use-api-list.ts +2 -1
  128. package/src/vue/use-mfa-prompt.ts +72 -0
  129. package/src/vue/use-pagination.ts +63 -0
  130. package/src/vue/use-plans.ts +1 -2
  131. package/src/vue/use-sign-out.ts +90 -0
  132. package/src/vue/use-tenant-billing.ts +1 -1
  133. package/src/vue/use-tenant-manifest.ts +0 -1
  134. package/src/components/KpiCard.vue +0 -53
  135. package/src/components/plan-cockpit/PlanCockpit.vue +0 -1012
  136. package/src/components/plan-cockpit/PlanCockpitAuditLog.vue +0 -72
  137. package/src/components/plan-cockpit/PlanCockpitDiffPanel.vue +0 -100
  138. package/src/components/plan-cockpit/PlanCockpitHeader.vue +0 -101
  139. package/src/components/plan-cockpit/PlanCockpitImpactPanel.vue +0 -112
  140. package/src/components/plan-cockpit/PlanCockpitKpis.vue +0 -68
  141. package/src/components/plan-cockpit/PlanCockpitVersions.vue +0 -251
  142. package/src/components/plan-cockpit/types.ts +0 -72
  143. package/src/components/plan-detail/PlanDetailHeader.vue +0 -194
  144. package/src/pages-standard/bundles-page/BundlesHeader.vue +0 -68
  145. package/src/pages-standard/discovery-page/DiscoveryHeader.vue +0 -34
@@ -195,7 +195,6 @@ declare const bundlesMessages: Record<SaBuiltinLocale, {
195
195
  subtitle: string;
196
196
  displayLocale: string;
197
197
  newBundle: string;
198
- reload: string;
199
198
  };
200
199
  filter: {
201
200
  all: string;
@@ -391,6 +390,9 @@ declare const commonMessages: Record<SaBuiltinLocale, {
391
390
  loading: string;
392
391
  saving: string;
393
392
  loadingData: string;
393
+ noData: string;
394
+ filters: string;
395
+ results: string;
394
396
  error: string;
395
397
  errorLoadFailed: string;
396
398
  errorSaveFailed: string;
@@ -437,6 +439,15 @@ declare const commonMessages: Record<SaBuiltinLocale, {
437
439
  both: string;
438
440
  createFailed: string;
439
441
  noChanges: string;
442
+ paginator: {
443
+ label: string;
444
+ rowsPerPage: string;
445
+ all: string;
446
+ page: string;
447
+ pageInput: string;
448
+ previous: string;
449
+ next: string;
450
+ };
440
451
  }>;
441
452
 
442
453
  declare const dashboardMessages: Record<SaBuiltinLocale, {
@@ -625,7 +636,6 @@ declare const marketingMessages: Record<SaBuiltinLocale, {
625
636
  defaultLocale: string;
626
637
  deactivateLocale: string;
627
638
  addLocale: string;
628
- refresh: string;
629
639
  };
630
640
  page: {
631
641
  loading: string;
@@ -859,10 +869,8 @@ declare const planDetailMessages: Record<SaBuiltinLocale, {
859
869
  versionsSummary: string;
860
870
  versionsSummaryWithDrafts: string;
861
871
  openDraft: string;
862
- noDraft: string;
863
872
  readyToEdit: string;
864
873
  noOpenDraft: string;
865
- createNewDraft: string;
866
874
  };
867
875
  versions: {
868
876
  title: string;
@@ -1102,6 +1110,7 @@ declare const planVersionsMessages: Record<SaBuiltinLocale, {
1102
1110
 
1103
1111
  declare const plansMessages: Record<SaBuiltinLocale, {
1104
1112
  page: {
1113
+ subtitle: string;
1105
1114
  loading: string;
1106
1115
  toastPlanCreated: string;
1107
1116
  toastDraftSaved: string;
@@ -1146,7 +1155,10 @@ declare const plansMessages: Record<SaBuiltinLocale, {
1146
1155
  };
1147
1156
  list: {
1148
1157
  title: string;
1149
- summary: string;
1158
+ statPlans: string;
1159
+ statLive: string;
1160
+ statDrafts: string;
1161
+ statTenants: string;
1150
1162
  matrixView: string;
1151
1163
  newPlan: string;
1152
1164
  searchPlaceholder: string;
@@ -1183,7 +1195,10 @@ declare const plansMessages: Record<SaBuiltinLocale, {
1183
1195
  };
1184
1196
  matrix: {
1185
1197
  title: string;
1186
- summary: string;
1198
+ statPlans: string;
1199
+ statFeatures: string;
1200
+ statQuotas: string;
1201
+ statBundles: string;
1187
1202
  catalogPreview: string;
1188
1203
  createPlan: string;
1189
1204
  createPlanSub: string;
@@ -1496,7 +1511,6 @@ declare const tenantsMessages: Record<SaBuiltinLocale, {
1496
1511
  columnCreatedAt: string;
1497
1512
  suspended: string;
1498
1513
  empty: string;
1499
- pagination: string;
1500
1514
  };
1501
1515
  detail: {
1502
1516
  backToList: string;
@@ -195,7 +195,6 @@ declare const bundlesMessages: Record<SaBuiltinLocale, {
195
195
  subtitle: string;
196
196
  displayLocale: string;
197
197
  newBundle: string;
198
- reload: string;
199
198
  };
200
199
  filter: {
201
200
  all: string;
@@ -391,6 +390,9 @@ declare const commonMessages: Record<SaBuiltinLocale, {
391
390
  loading: string;
392
391
  saving: string;
393
392
  loadingData: string;
393
+ noData: string;
394
+ filters: string;
395
+ results: string;
394
396
  error: string;
395
397
  errorLoadFailed: string;
396
398
  errorSaveFailed: string;
@@ -437,6 +439,15 @@ declare const commonMessages: Record<SaBuiltinLocale, {
437
439
  both: string;
438
440
  createFailed: string;
439
441
  noChanges: string;
442
+ paginator: {
443
+ label: string;
444
+ rowsPerPage: string;
445
+ all: string;
446
+ page: string;
447
+ pageInput: string;
448
+ previous: string;
449
+ next: string;
450
+ };
440
451
  }>;
441
452
 
442
453
  declare const dashboardMessages: Record<SaBuiltinLocale, {
@@ -625,7 +636,6 @@ declare const marketingMessages: Record<SaBuiltinLocale, {
625
636
  defaultLocale: string;
626
637
  deactivateLocale: string;
627
638
  addLocale: string;
628
- refresh: string;
629
639
  };
630
640
  page: {
631
641
  loading: string;
@@ -859,10 +869,8 @@ declare const planDetailMessages: Record<SaBuiltinLocale, {
859
869
  versionsSummary: string;
860
870
  versionsSummaryWithDrafts: string;
861
871
  openDraft: string;
862
- noDraft: string;
863
872
  readyToEdit: string;
864
873
  noOpenDraft: string;
865
- createNewDraft: string;
866
874
  };
867
875
  versions: {
868
876
  title: string;
@@ -1102,6 +1110,7 @@ declare const planVersionsMessages: Record<SaBuiltinLocale, {
1102
1110
 
1103
1111
  declare const plansMessages: Record<SaBuiltinLocale, {
1104
1112
  page: {
1113
+ subtitle: string;
1105
1114
  loading: string;
1106
1115
  toastPlanCreated: string;
1107
1116
  toastDraftSaved: string;
@@ -1146,7 +1155,10 @@ declare const plansMessages: Record<SaBuiltinLocale, {
1146
1155
  };
1147
1156
  list: {
1148
1157
  title: string;
1149
- summary: string;
1158
+ statPlans: string;
1159
+ statLive: string;
1160
+ statDrafts: string;
1161
+ statTenants: string;
1150
1162
  matrixView: string;
1151
1163
  newPlan: string;
1152
1164
  searchPlaceholder: string;
@@ -1183,7 +1195,10 @@ declare const plansMessages: Record<SaBuiltinLocale, {
1183
1195
  };
1184
1196
  matrix: {
1185
1197
  title: string;
1186
- summary: string;
1198
+ statPlans: string;
1199
+ statFeatures: string;
1200
+ statQuotas: string;
1201
+ statBundles: string;
1187
1202
  catalogPreview: string;
1188
1203
  createPlan: string;
1189
1204
  createPlanSub: string;
@@ -1496,7 +1511,6 @@ declare const tenantsMessages: Record<SaBuiltinLocale, {
1496
1511
  columnCreatedAt: string;
1497
1512
  suspended: string;
1498
1513
  empty: string;
1499
- pagination: string;
1500
1514
  };
1501
1515
  detail: {
1502
1516
  backToList: string;
@@ -186,8 +186,7 @@ var bundlesMessages = defineMessages(
186
186
  title: "Bundles",
187
187
  subtitle: "Produktgruppen aus Features & Quotas \u2014 verwendet in Pl\xE4nen. Bundles werden im SuperAdmin kuratiert.",
188
188
  displayLocale: "Anzeige-Sprache",
189
- newBundle: "Neues Bundle",
190
- reload: "Liste neu laden"
189
+ newBundle: "Neues Bundle"
191
190
  },
192
191
  filter: {
193
192
  all: "Alle Status",
@@ -401,8 +400,7 @@ var bundlesMessages = defineMessages(
401
400
  title: "Bundles",
402
401
  subtitle: "Product groups made of features & quotas \u2014 used in plans. Bundles are curated in the SuperAdmin.",
403
402
  displayLocale: "Display language",
404
- newBundle: "New bundle",
405
- reload: "Reload list"
403
+ newBundle: "New bundle"
406
404
  },
407
405
  filter: {
408
406
  all: "All statuses",
@@ -601,6 +599,9 @@ var commonMessages = defineMessages(
601
599
  loading: "Lade \u2026",
602
600
  saving: "Speichere \u2026",
603
601
  loadingData: "Daten werden geladen\u2026",
602
+ noData: "Keine Daten vorhanden",
603
+ filters: "Filter",
604
+ results: "Ergebnisse",
604
605
  error: "Fehler",
605
606
  errorLoadFailed: "Laden fehlgeschlagen",
606
607
  errorSaveFailed: "Speichern fehlgeschlagen",
@@ -646,7 +647,16 @@ var commonMessages = defineMessages(
646
647
  unlimited: "unbegrenzt",
647
648
  both: "Beide",
648
649
  createFailed: "Anlegen fehlgeschlagen",
649
- noChanges: "Keine \xC4nderungen"
650
+ noChanges: "Keine \xC4nderungen",
651
+ paginator: {
652
+ label: "Seitennavigation",
653
+ rowsPerPage: "Zeilen pro Seite",
654
+ all: "Alle",
655
+ page: "Seite {page}/{pages}",
656
+ pageInput: "Seite, 1 bis {pages}",
657
+ previous: "Vorherige Seite",
658
+ next: "N\xE4chste Seite"
659
+ }
650
660
  },
651
661
  {
652
662
  save: "Save",
@@ -671,6 +681,9 @@ var commonMessages = defineMessages(
671
681
  loading: "Loading \u2026",
672
682
  saving: "Saving \u2026",
673
683
  loadingData: "Loading data\u2026",
684
+ noData: "No data available",
685
+ filters: "Filters",
686
+ results: "Results",
674
687
  error: "Error",
675
688
  errorLoadFailed: "Failed to load",
676
689
  errorSaveFailed: "Failed to save",
@@ -716,7 +729,16 @@ var commonMessages = defineMessages(
716
729
  unlimited: "unlimited",
717
730
  both: "Both",
718
731
  createFailed: "Creation failed",
719
- noChanges: "No changes"
732
+ noChanges: "No changes",
733
+ paginator: {
734
+ label: "Pagination",
735
+ rowsPerPage: "Rows per page",
736
+ all: "All",
737
+ page: "Page {page}/{pages}",
738
+ pageInput: "Page, 1 to {pages}",
739
+ previous: "Previous page",
740
+ next: "Next page"
741
+ }
720
742
  }
721
743
  );
722
744
 
@@ -821,7 +843,7 @@ var discoveryMessages = defineMessages(
821
843
  quota: {
822
844
  usageProvider: "UsageProvider",
823
845
  usageProviderMissing: "fehlt",
824
- noUsageProviderWarning: "Eine harte Quota ohne UsageProvider ist nicht deploy-f\xE4hig (Preflight, SPEC_V2 \xA76.3).",
846
+ noUsageProviderWarning: "Eine harte Quota ohne UsageProvider ist nicht deploy-f\xE4hig (Preflight).",
825
847
  outdatedBanner: "Die code-abgeleiteten Quota-Fakten (Einheit/Enforcement/Provider) haben sich seit der letzten Freigabe ge\xE4ndert \u2014 bitte pr\xFCfen und"
826
848
  },
827
849
  caps: {
@@ -925,7 +947,7 @@ var discoveryMessages = defineMessages(
925
947
  quota: {
926
948
  usageProvider: "UsageProvider",
927
949
  usageProviderMissing: "missing",
928
- noUsageProviderWarning: "A hard quota without a UsageProvider is not deployable (preflight, SPEC_V2 \xA76.3).",
950
+ noUsageProviderWarning: "A hard quota without a UsageProvider is not deployable (preflight).",
929
951
  outdatedBanner: "The code-derived quota facts (unit/enforcement/provider) have changed since the last approval \u2014 please review and"
930
952
  },
931
953
  caps: {
@@ -1085,8 +1107,7 @@ var marketingMessages = defineMessages(
1085
1107
  localesLabel: "Sprachen:",
1086
1108
  defaultLocale: "Default-Sprache",
1087
1109
  deactivateLocale: "Sprache deaktivieren",
1088
- addLocale: "+ Sprache",
1089
- refresh: "Aktualisieren"
1110
+ addLocale: "+ Sprache"
1090
1111
  },
1091
1112
  page: {
1092
1113
  loading: "Lade Marketing-Catalog \u2026",
@@ -1154,7 +1175,7 @@ var marketingMessages = defineMessages(
1154
1175
  },
1155
1176
  promotionsTab: {
1156
1177
  title: "Aktionen & Rabatte",
1157
- subtitle: "Zeitlich begrenzte Preis-Aktionen \u2014 \xFCberschreiben den regul\xE4ren Preis auf der Pricing-Page (SPEC_V2 \xA79a).",
1178
+ subtitle: "Zeitlich begrenzte Preis-Aktionen \u2014 \xFCberschreiben den regul\xE4ren Preis auf der Pricing-Page.",
1158
1179
  add: "+ Aktion anlegen",
1159
1180
  timelineHead: "Aktions-Timeline \xB7 gestrichelt = heute",
1160
1181
  today: "heute",
@@ -1213,8 +1234,7 @@ var marketingMessages = defineMessages(
1213
1234
  localesLabel: "Languages:",
1214
1235
  defaultLocale: "Default language",
1215
1236
  deactivateLocale: "Deactivate language",
1216
- addLocale: "+ Language",
1217
- refresh: "Refresh"
1237
+ addLocale: "+ Language"
1218
1238
  },
1219
1239
  page: {
1220
1240
  loading: "Loading marketing catalog \u2026",
@@ -1282,7 +1302,7 @@ var marketingMessages = defineMessages(
1282
1302
  },
1283
1303
  promotionsTab: {
1284
1304
  title: "Promotions & discounts",
1285
- subtitle: "Time-limited price promotions \u2014 they override the regular price on the pricing page (SPEC_V2 \xA79a).",
1305
+ subtitle: "Time-limited price promotions \u2014 they override the regular price on the pricing page.",
1286
1306
  add: "+ Create promotion",
1287
1307
  timelineHead: "Promotion timeline \xB7 dashed = today",
1288
1308
  today: "today",
@@ -1597,10 +1617,8 @@ var planDetailMessages = defineMessages(
1597
1617
  versionsSummary: "{published} live/superseded",
1598
1618
  versionsSummaryWithDrafts: "{published} live/superseded \xB7 {drafts} Draft",
1599
1619
  openDraft: "Offener Draft",
1600
- noDraft: "Kein Draft",
1601
1620
  readyToEdit: "Bereit zum Bearbeiten",
1602
- noOpenDraft: "Keine Draft-Version offen",
1603
- createNewDraft: "Neue Draft anlegen"
1621
+ noOpenDraft: "Keine Draft-Version offen"
1604
1622
  },
1605
1623
  versions: {
1606
1624
  title: "Versionen",
@@ -1724,10 +1742,8 @@ var planDetailMessages = defineMessages(
1724
1742
  versionsSummary: "{published} live/superseded",
1725
1743
  versionsSummaryWithDrafts: "{published} live/superseded \xB7 {drafts} draft",
1726
1744
  openDraft: "Open draft",
1727
- noDraft: "No draft",
1728
1745
  readyToEdit: "Ready to edit",
1729
- noOpenDraft: "No draft version open",
1730
- createNewDraft: "Create a new draft"
1746
+ noOpenDraft: "No draft version open"
1731
1747
  },
1732
1748
  versions: {
1733
1749
  title: "Versions",
@@ -2114,6 +2130,7 @@ var plansMessages = defineMessages(
2114
2130
  // PlansPage — shell of the plan area: loading state, toasts and the
2115
2131
  // error texts of the draft/publish/archive/discard actions.
2116
2132
  page: {
2133
+ subtitle: "Pl\xE4ne b\xFCndeln Features & Quotas zu einem Angebot. Jede \xC4nderung wird als neue Version ver\xF6ffentlicht \u2014 Live-Versionen bleiben unangetastet.",
2117
2134
  loading: "Pl\xE4ne werden geladen\u2026",
2118
2135
  toastPlanCreated: "Plan {planKey} angelegt \u2014 jetzt die erste Version zusammenstellen.",
2119
2136
  toastDraftSaved: "Draft v{version} von {planKey} gespeichert.",
@@ -2160,7 +2177,10 @@ var plansMessages = defineMessages(
2160
2177
  // PlanList — default plan overview with one row per plan.
2161
2178
  list: {
2162
2179
  title: "Alle Pl\xE4ne",
2163
- summary: "{plans} Pl\xE4ne \xB7 {live} live \xB7 {drafts} offene Drafts \xB7 {tenants} Mandanten zugeordnet",
2180
+ statPlans: "Pl\xE4ne",
2181
+ statLive: "Live",
2182
+ statDrafts: "Offene Drafts",
2183
+ statTenants: "Mandanten",
2164
2184
  matrixView: "Matrix-Ansicht",
2165
2185
  newPlan: "Neuer Plan",
2166
2186
  searchPlaceholder: "Plan suchen\u2026",
@@ -2198,7 +2218,10 @@ var plansMessages = defineMessages(
2198
2218
  // PlanMatrix — all plans side by side, components as rows.
2199
2219
  matrix: {
2200
2220
  title: "Pl\xE4ne \xB7 Matrix-Vergleich",
2201
- summary: "Alle Pl\xE4ne nebeneinander \xB7 {plans} Pl\xE4ne \xB7 {features} Features \xB7 {quotas} Quotas \xB7 {bundles} Bundles",
2221
+ statPlans: "Pl\xE4ne",
2222
+ statFeatures: "Features",
2223
+ statQuotas: "Quotas",
2224
+ statBundles: "Bundles",
2202
2225
  catalogPreview: "Catalog-Vorschau",
2203
2226
  createPlan: "Plan anlegen",
2204
2227
  createPlanSub: "oder Klon erstellen",
@@ -2339,6 +2362,7 @@ var plansMessages = defineMessages(
2339
2362
  },
2340
2363
  {
2341
2364
  page: {
2365
+ subtitle: "Plans bundle features & quotas into an offering. Every change ships as a new version \u2014 live versions stay untouched.",
2342
2366
  loading: "Loading plans\u2026",
2343
2367
  toastPlanCreated: "Plan {planKey} created \u2014 now assemble the first version.",
2344
2368
  toastDraftSaved: "Draft v{version} of {planKey} saved.",
@@ -2383,7 +2407,10 @@ var plansMessages = defineMessages(
2383
2407
  },
2384
2408
  list: {
2385
2409
  title: "All plans",
2386
- summary: "{plans} plans \xB7 {live} live \xB7 {drafts} open drafts \xB7 {tenants} tenants assigned",
2410
+ statPlans: "Plans",
2411
+ statLive: "Live",
2412
+ statDrafts: "Open drafts",
2413
+ statTenants: "Tenants",
2387
2414
  matrixView: "Matrix view",
2388
2415
  newPlan: "New plan",
2389
2416
  searchPlaceholder: "Search plan\u2026",
@@ -2420,7 +2447,10 @@ var plansMessages = defineMessages(
2420
2447
  },
2421
2448
  matrix: {
2422
2449
  title: "Plans \xB7 matrix comparison",
2423
- summary: "All plans side by side \xB7 {plans} plans \xB7 {features} features \xB7 {quotas} quotas \xB7 {bundles} bundles",
2450
+ statPlans: "Plans",
2451
+ statFeatures: "Features",
2452
+ statQuotas: "Quotas",
2453
+ statBundles: "Bundles",
2424
2454
  catalogPreview: "Catalog preview",
2425
2455
  createPlan: "Create plan",
2426
2456
  createPlanSub: "or create a clone",
@@ -2909,8 +2939,7 @@ var tenantsMessages = defineMessages(
2909
2939
  columnUsage: "Verbrauch",
2910
2940
  columnCreatedAt: "Angelegt",
2911
2941
  suspended: "Suspendiert",
2912
- empty: "Keine Mandanten mit diesen Filtern.",
2913
- pagination: "{total} Mandanten \xB7 Seite {page} / {pages}"
2942
+ empty: "Keine Mandanten mit diesen Filtern."
2914
2943
  },
2915
2944
  detail: {
2916
2945
  backToList: "Mandanten-Liste",
@@ -2958,8 +2987,7 @@ var tenantsMessages = defineMessages(
2958
2987
  columnUsage: "Usage",
2959
2988
  columnCreatedAt: "Created",
2960
2989
  suspended: "Suspended",
2961
- empty: "No tenants match these filters.",
2962
- pagination: "{total} tenants \xB7 Page {page} / {pages}"
2990
+ empty: "No tenants match these filters."
2963
2991
  },
2964
2992
  detail: {
2965
2993
  backToList: "Tenant list",
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createSaCatalog,
3
3
  defaultKvStore
4
- } from "./chunk-DPTIOQXX.js";
4
+ } from "./chunk-F7NRM6KI.js";
5
5
 
6
6
  // src/vue/super-admin-context.ts
7
7
  var SUPER_ADMIN_BRAND_KEY = /* @__PURE__ */ Symbol.for(
@@ -19,17 +19,27 @@ var SUPER_ADMIN_ACTIONS_KEY = /* @__PURE__ */ Symbol.for(
19
19
  var SUPER_ADMIN_MANIFEST_KEY = /* @__PURE__ */ Symbol.for(
20
20
  "@saasicat/ui-vue/SUPER_ADMIN_MANIFEST"
21
21
  );
22
+ var SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY = /* @__PURE__ */ Symbol.for("@saasicat/ui-vue/SUPER_ADMIN_MANIFEST_CLEAR_CACHE");
22
23
  var SUPER_ADMIN_LOGIN_ADAPTER_KEY = /* @__PURE__ */ Symbol.for(
23
24
  "@saasicat/ui-vue/SUPER_ADMIN_LOGIN_ADAPTER"
24
25
  );
25
26
  var SUPER_ADMIN_HTTP_KEY = /* @__PURE__ */ Symbol.for(
26
27
  "@saasicat/ui-vue/SUPER_ADMIN_HTTP"
27
28
  );
29
+ function isUnauthorizedError(err) {
30
+ const status = err?.status;
31
+ return status === 401 || status === 403;
32
+ }
28
33
  function buildNavigationGuard(options) {
29
34
  const { authGuard, manifestGuard } = options;
30
35
  if (!authGuard && !manifestGuard) return null;
36
+ let redirectedForUnauthorized = false;
37
+ let reachedLoginAfterRedirect = false;
31
38
  return async (to) => {
32
- if (to.meta?.public === true) return true;
39
+ if (to.meta?.public === true) {
40
+ if (redirectedForUnauthorized) reachedLoginAfterRedirect = true;
41
+ return true;
42
+ }
33
43
  if (authGuard) {
34
44
  if (!authGuard.isAuthenticated()) return authGuard.onUnauthenticated();
35
45
  if (authGuard.isSuperAdmin && !authGuard.isSuperAdmin()) {
@@ -39,7 +49,15 @@ function buildNavigationGuard(options) {
39
49
  if (manifestGuard) {
40
50
  try {
41
51
  await manifestGuard.ensureLoaded();
52
+ redirectedForUnauthorized = false;
53
+ reachedLoginAfterRedirect = false;
42
54
  } catch (err) {
55
+ if (authGuard && isUnauthorizedError(err)) {
56
+ if (!redirectedForUnauthorized || !reachedLoginAfterRedirect) {
57
+ redirectedForUnauthorized = true;
58
+ return authGuard.onUnauthenticated();
59
+ }
60
+ }
43
61
  if (manifestGuard.errorRoute && to.path !== manifestGuard.errorRoute) {
44
62
  return manifestGuard.errorRoute;
45
63
  }
@@ -113,6 +131,7 @@ export {
113
131
  SUPER_ADMIN_EXTENSIONS_KEY,
114
132
  SUPER_ADMIN_ACTIONS_KEY,
115
133
  SUPER_ADMIN_MANIFEST_KEY,
134
+ SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY,
116
135
  SUPER_ADMIN_LOGIN_ADAPTER_KEY,
117
136
  SUPER_ADMIN_HTTP_KEY,
118
137
  buildNavigationGuard,
@@ -4,7 +4,7 @@ import {
4
4
  defaultKvStore,
5
5
  isSaBuiltinLocale,
6
6
  navMessages
7
- } from "./chunk-DPTIOQXX.js";
7
+ } from "./chunk-F7NRM6KI.js";
8
8
 
9
9
  // src/client/version.ts
10
10
  var ADMIN_UI_VERSION = "1.2.0";
@@ -136,7 +136,7 @@ var ManifestLoader = class {
136
136
  if (res.status !== 200) {
137
137
  throw new ManifestLoadError(
138
138
  res.status,
139
- `Manifest-Endpunkt antwortete HTTP ${res.status}`
139
+ `Manifest endpoint responded with HTTP ${res.status}`
140
140
  );
141
141
  }
142
142
  const body = await res.json();
@@ -565,6 +565,71 @@ function isProductionBoot(boot) {
565
565
  return boot?.project?.environment === "production";
566
566
  }
567
567
 
568
+ // src/client/resolve-plans.ts
569
+ function todayIsoDate() {
570
+ return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
571
+ }
572
+ function isCurrentlyValid(v, today) {
573
+ if (!v.publishedAt) return false;
574
+ if (v.validFrom && v.validFrom.slice(0, 10) > today) return false;
575
+ if (v.validUntil && v.validUntil.slice(0, 10) < today) return false;
576
+ return true;
577
+ }
578
+ function isFutureScheduled(v, today) {
579
+ if (!v.publishedAt) return false;
580
+ if (!v.validFrom) return false;
581
+ return v.validFrom.slice(0, 10) > today;
582
+ }
583
+ function isExpired(v, today) {
584
+ if (!v.publishedAt) return false;
585
+ if (!v.validUntil) return false;
586
+ return v.validUntil.slice(0, 10) < today;
587
+ }
588
+ function resolvePlans({
589
+ plans,
590
+ versionsByPlanId,
591
+ tenantCountsByPlanKey,
592
+ today = todayIsoDate()
593
+ }) {
594
+ return [...plans].sort((a, b) => a.sortOrder - b.sortOrder || a.planKey.localeCompare(b.planKey)).map((plan) => {
595
+ const versions = versionsByPlanId[plan.id] ?? [];
596
+ const drafts = versions.filter((v) => !v.publishedAt);
597
+ const published = versions.filter((v) => Boolean(v.publishedAt));
598
+ const currentLive = published.find((v) => isCurrentlyValid(v, today)) ?? null;
599
+ const futureScheduled = published.filter((v) => isFutureScheduled(v, today)).sort((a, b) => (a.validFrom ?? "").localeCompare(b.validFrom ?? ""));
600
+ const primary = currentLive ?? futureScheduled[0] ?? null;
601
+ const seen = /* @__PURE__ */ new Set();
602
+ if (primary) seen.add(primary.id);
603
+ const subRows = [];
604
+ for (const v of [...futureScheduled, ...drafts]) {
605
+ if (seen.has(v.id)) continue;
606
+ subRows.push(v);
607
+ seen.add(v.id);
608
+ }
609
+ return {
610
+ plan,
611
+ planKey: plan.planKey,
612
+ label: plan.label,
613
+ description: plan.description ?? null,
614
+ currentLive,
615
+ primary,
616
+ subRows,
617
+ hasAnyVersion: versions.length > 0,
618
+ allExpired: versions.length > 0 && drafts.length === 0 && futureScheduled.length === 0 && published.every((v) => isExpired(v, today)),
619
+ draft: drafts[0] ?? null,
620
+ tenantCount: tenantCountsByPlanKey[plan.planKey] ?? 0
621
+ };
622
+ });
623
+ }
624
+ function countPlans(resolved) {
625
+ return {
626
+ plans: resolved.length,
627
+ live: resolved.filter((p) => p.currentLive !== null).length,
628
+ drafts: resolved.filter((p) => p.draft !== null).length,
629
+ tenants: resolved.reduce((sum, p) => sum + p.tenantCount, 0)
630
+ };
631
+ }
632
+
568
633
  export {
569
634
  ADMIN_UI_VERSION,
570
635
  HttpJsonError,
@@ -587,5 +652,11 @@ export {
587
652
  BatchColumnFetcher,
588
653
  createAdminResourceClient,
589
654
  resolveLoginBranding,
590
- isProductionBoot
655
+ isProductionBoot,
656
+ todayIsoDate,
657
+ isCurrentlyValid,
658
+ isFutureScheduled,
659
+ isExpired,
660
+ resolvePlans,
661
+ countPlans
591
662
  };