@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
@@ -92,17 +92,27 @@ var SUPER_ADMIN_ACTIONS_KEY = /* @__PURE__ */ Symbol.for(
92
92
  var SUPER_ADMIN_MANIFEST_KEY = /* @__PURE__ */ Symbol.for(
93
93
  "@saasicat/ui-vue/SUPER_ADMIN_MANIFEST"
94
94
  );
95
+ var SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY = /* @__PURE__ */ Symbol.for("@saasicat/ui-vue/SUPER_ADMIN_MANIFEST_CLEAR_CACHE");
95
96
  var SUPER_ADMIN_LOGIN_ADAPTER_KEY = /* @__PURE__ */ Symbol.for(
96
97
  "@saasicat/ui-vue/SUPER_ADMIN_LOGIN_ADAPTER"
97
98
  );
98
99
  var SUPER_ADMIN_HTTP_KEY = /* @__PURE__ */ Symbol.for(
99
100
  "@saasicat/ui-vue/SUPER_ADMIN_HTTP"
100
101
  );
102
+ function isUnauthorizedError(err) {
103
+ const status = err?.status;
104
+ return status === 401 || status === 403;
105
+ }
101
106
  function buildNavigationGuard(options) {
102
107
  const { authGuard, manifestGuard } = options;
103
108
  if (!authGuard && !manifestGuard) return null;
109
+ let redirectedForUnauthorized = false;
110
+ let reachedLoginAfterRedirect = false;
104
111
  return async (to) => {
105
- if (to.meta?.public === true) return true;
112
+ if (to.meta?.public === true) {
113
+ if (redirectedForUnauthorized) reachedLoginAfterRedirect = true;
114
+ return true;
115
+ }
106
116
  if (authGuard) {
107
117
  if (!authGuard.isAuthenticated()) return authGuard.onUnauthenticated();
108
118
  if (authGuard.isSuperAdmin && !authGuard.isSuperAdmin()) {
@@ -112,7 +122,15 @@ function buildNavigationGuard(options) {
112
122
  if (manifestGuard) {
113
123
  try {
114
124
  await manifestGuard.ensureLoaded();
125
+ redirectedForUnauthorized = false;
126
+ reachedLoginAfterRedirect = false;
115
127
  } catch (err) {
128
+ if (authGuard && isUnauthorizedError(err)) {
129
+ if (!redirectedForUnauthorized || !reachedLoginAfterRedirect) {
130
+ redirectedForUnauthorized = true;
131
+ return authGuard.onUnauthenticated();
132
+ }
133
+ }
116
134
  if (manifestGuard.errorRoute && to.path !== manifestGuard.errorRoute) {
117
135
  return manifestGuard.errorRoute;
118
136
  }
@@ -249,8 +267,7 @@ var bundlesMessages = defineMessages(
249
267
  title: "Bundles",
250
268
  subtitle: "Produktgruppen aus Features & Quotas \u2014 verwendet in Pl\xE4nen. Bundles werden im SuperAdmin kuratiert.",
251
269
  displayLocale: "Anzeige-Sprache",
252
- newBundle: "Neues Bundle",
253
- reload: "Liste neu laden"
270
+ newBundle: "Neues Bundle"
254
271
  },
255
272
  filter: {
256
273
  all: "Alle Status",
@@ -464,8 +481,7 @@ var bundlesMessages = defineMessages(
464
481
  title: "Bundles",
465
482
  subtitle: "Product groups made of features & quotas \u2014 used in plans. Bundles are curated in the SuperAdmin.",
466
483
  displayLocale: "Display language",
467
- newBundle: "New bundle",
468
- reload: "Reload list"
484
+ newBundle: "New bundle"
469
485
  },
470
486
  filter: {
471
487
  all: "All statuses",
@@ -664,6 +680,9 @@ var commonMessages = defineMessages(
664
680
  loading: "Lade \u2026",
665
681
  saving: "Speichere \u2026",
666
682
  loadingData: "Daten werden geladen\u2026",
683
+ noData: "Keine Daten vorhanden",
684
+ filters: "Filter",
685
+ results: "Ergebnisse",
667
686
  error: "Fehler",
668
687
  errorLoadFailed: "Laden fehlgeschlagen",
669
688
  errorSaveFailed: "Speichern fehlgeschlagen",
@@ -709,7 +728,16 @@ var commonMessages = defineMessages(
709
728
  unlimited: "unbegrenzt",
710
729
  both: "Beide",
711
730
  createFailed: "Anlegen fehlgeschlagen",
712
- noChanges: "Keine \xC4nderungen"
731
+ noChanges: "Keine \xC4nderungen",
732
+ paginator: {
733
+ label: "Seitennavigation",
734
+ rowsPerPage: "Zeilen pro Seite",
735
+ all: "Alle",
736
+ page: "Seite {page}/{pages}",
737
+ pageInput: "Seite, 1 bis {pages}",
738
+ previous: "Vorherige Seite",
739
+ next: "N\xE4chste Seite"
740
+ }
713
741
  },
714
742
  {
715
743
  save: "Save",
@@ -734,6 +762,9 @@ var commonMessages = defineMessages(
734
762
  loading: "Loading \u2026",
735
763
  saving: "Saving \u2026",
736
764
  loadingData: "Loading data\u2026",
765
+ noData: "No data available",
766
+ filters: "Filters",
767
+ results: "Results",
737
768
  error: "Error",
738
769
  errorLoadFailed: "Failed to load",
739
770
  errorSaveFailed: "Failed to save",
@@ -779,7 +810,16 @@ var commonMessages = defineMessages(
779
810
  unlimited: "unlimited",
780
811
  both: "Both",
781
812
  createFailed: "Creation failed",
782
- noChanges: "No changes"
813
+ noChanges: "No changes",
814
+ paginator: {
815
+ label: "Pagination",
816
+ rowsPerPage: "Rows per page",
817
+ all: "All",
818
+ page: "Page {page}/{pages}",
819
+ pageInput: "Page, 1 to {pages}",
820
+ previous: "Previous page",
821
+ next: "Next page"
822
+ }
783
823
  }
784
824
  );
785
825
 
@@ -884,7 +924,7 @@ var discoveryMessages = defineMessages(
884
924
  quota: {
885
925
  usageProvider: "UsageProvider",
886
926
  usageProviderMissing: "fehlt",
887
- noUsageProviderWarning: "Eine harte Quota ohne UsageProvider ist nicht deploy-f\xE4hig (Preflight, SPEC_V2 \xA76.3).",
927
+ noUsageProviderWarning: "Eine harte Quota ohne UsageProvider ist nicht deploy-f\xE4hig (Preflight).",
888
928
  outdatedBanner: "Die code-abgeleiteten Quota-Fakten (Einheit/Enforcement/Provider) haben sich seit der letzten Freigabe ge\xE4ndert \u2014 bitte pr\xFCfen und"
889
929
  },
890
930
  caps: {
@@ -988,7 +1028,7 @@ var discoveryMessages = defineMessages(
988
1028
  quota: {
989
1029
  usageProvider: "UsageProvider",
990
1030
  usageProviderMissing: "missing",
991
- noUsageProviderWarning: "A hard quota without a UsageProvider is not deployable (preflight, SPEC_V2 \xA76.3).",
1031
+ noUsageProviderWarning: "A hard quota without a UsageProvider is not deployable (preflight).",
992
1032
  outdatedBanner: "The code-derived quota facts (unit/enforcement/provider) have changed since the last approval \u2014 please review and"
993
1033
  },
994
1034
  caps: {
@@ -1148,8 +1188,7 @@ var marketingMessages = defineMessages(
1148
1188
  localesLabel: "Sprachen:",
1149
1189
  defaultLocale: "Default-Sprache",
1150
1190
  deactivateLocale: "Sprache deaktivieren",
1151
- addLocale: "+ Sprache",
1152
- refresh: "Aktualisieren"
1191
+ addLocale: "+ Sprache"
1153
1192
  },
1154
1193
  page: {
1155
1194
  loading: "Lade Marketing-Catalog \u2026",
@@ -1217,7 +1256,7 @@ var marketingMessages = defineMessages(
1217
1256
  },
1218
1257
  promotionsTab: {
1219
1258
  title: "Aktionen & Rabatte",
1220
- subtitle: "Zeitlich begrenzte Preis-Aktionen \u2014 \xFCberschreiben den regul\xE4ren Preis auf der Pricing-Page (SPEC_V2 \xA79a).",
1259
+ subtitle: "Zeitlich begrenzte Preis-Aktionen \u2014 \xFCberschreiben den regul\xE4ren Preis auf der Pricing-Page.",
1221
1260
  add: "+ Aktion anlegen",
1222
1261
  timelineHead: "Aktions-Timeline \xB7 gestrichelt = heute",
1223
1262
  today: "heute",
@@ -1276,8 +1315,7 @@ var marketingMessages = defineMessages(
1276
1315
  localesLabel: "Languages:",
1277
1316
  defaultLocale: "Default language",
1278
1317
  deactivateLocale: "Deactivate language",
1279
- addLocale: "+ Language",
1280
- refresh: "Refresh"
1318
+ addLocale: "+ Language"
1281
1319
  },
1282
1320
  page: {
1283
1321
  loading: "Loading marketing catalog \u2026",
@@ -1345,7 +1383,7 @@ var marketingMessages = defineMessages(
1345
1383
  },
1346
1384
  promotionsTab: {
1347
1385
  title: "Promotions & discounts",
1348
- subtitle: "Time-limited price promotions \u2014 they override the regular price on the pricing page (SPEC_V2 \xA79a).",
1386
+ subtitle: "Time-limited price promotions \u2014 they override the regular price on the pricing page.",
1349
1387
  add: "+ Create promotion",
1350
1388
  timelineHead: "Promotion timeline \xB7 dashed = today",
1351
1389
  today: "today",
@@ -1660,10 +1698,8 @@ var planDetailMessages = defineMessages(
1660
1698
  versionsSummary: "{published} live/superseded",
1661
1699
  versionsSummaryWithDrafts: "{published} live/superseded \xB7 {drafts} Draft",
1662
1700
  openDraft: "Offener Draft",
1663
- noDraft: "Kein Draft",
1664
1701
  readyToEdit: "Bereit zum Bearbeiten",
1665
- noOpenDraft: "Keine Draft-Version offen",
1666
- createNewDraft: "Neue Draft anlegen"
1702
+ noOpenDraft: "Keine Draft-Version offen"
1667
1703
  },
1668
1704
  versions: {
1669
1705
  title: "Versionen",
@@ -1787,10 +1823,8 @@ var planDetailMessages = defineMessages(
1787
1823
  versionsSummary: "{published} live/superseded",
1788
1824
  versionsSummaryWithDrafts: "{published} live/superseded \xB7 {drafts} draft",
1789
1825
  openDraft: "Open draft",
1790
- noDraft: "No draft",
1791
1826
  readyToEdit: "Ready to edit",
1792
- noOpenDraft: "No draft version open",
1793
- createNewDraft: "Create a new draft"
1827
+ noOpenDraft: "No draft version open"
1794
1828
  },
1795
1829
  versions: {
1796
1830
  title: "Versions",
@@ -2177,6 +2211,7 @@ var plansMessages = defineMessages(
2177
2211
  // PlansPage — shell of the plan area: loading state, toasts and the
2178
2212
  // error texts of the draft/publish/archive/discard actions.
2179
2213
  page: {
2214
+ subtitle: "Pl\xE4ne b\xFCndeln Features & Quotas zu einem Angebot. Jede \xC4nderung wird als neue Version ver\xF6ffentlicht \u2014 Live-Versionen bleiben unangetastet.",
2180
2215
  loading: "Pl\xE4ne werden geladen\u2026",
2181
2216
  toastPlanCreated: "Plan {planKey} angelegt \u2014 jetzt die erste Version zusammenstellen.",
2182
2217
  toastDraftSaved: "Draft v{version} von {planKey} gespeichert.",
@@ -2223,7 +2258,10 @@ var plansMessages = defineMessages(
2223
2258
  // PlanList — default plan overview with one row per plan.
2224
2259
  list: {
2225
2260
  title: "Alle Pl\xE4ne",
2226
- summary: "{plans} Pl\xE4ne \xB7 {live} live \xB7 {drafts} offene Drafts \xB7 {tenants} Mandanten zugeordnet",
2261
+ statPlans: "Pl\xE4ne",
2262
+ statLive: "Live",
2263
+ statDrafts: "Offene Drafts",
2264
+ statTenants: "Mandanten",
2227
2265
  matrixView: "Matrix-Ansicht",
2228
2266
  newPlan: "Neuer Plan",
2229
2267
  searchPlaceholder: "Plan suchen\u2026",
@@ -2261,7 +2299,10 @@ var plansMessages = defineMessages(
2261
2299
  // PlanMatrix — all plans side by side, components as rows.
2262
2300
  matrix: {
2263
2301
  title: "Pl\xE4ne \xB7 Matrix-Vergleich",
2264
- summary: "Alle Pl\xE4ne nebeneinander \xB7 {plans} Pl\xE4ne \xB7 {features} Features \xB7 {quotas} Quotas \xB7 {bundles} Bundles",
2302
+ statPlans: "Pl\xE4ne",
2303
+ statFeatures: "Features",
2304
+ statQuotas: "Quotas",
2305
+ statBundles: "Bundles",
2265
2306
  catalogPreview: "Catalog-Vorschau",
2266
2307
  createPlan: "Plan anlegen",
2267
2308
  createPlanSub: "oder Klon erstellen",
@@ -2402,6 +2443,7 @@ var plansMessages = defineMessages(
2402
2443
  },
2403
2444
  {
2404
2445
  page: {
2446
+ subtitle: "Plans bundle features & quotas into an offering. Every change ships as a new version \u2014 live versions stay untouched.",
2405
2447
  loading: "Loading plans\u2026",
2406
2448
  toastPlanCreated: "Plan {planKey} created \u2014 now assemble the first version.",
2407
2449
  toastDraftSaved: "Draft v{version} of {planKey} saved.",
@@ -2446,7 +2488,10 @@ var plansMessages = defineMessages(
2446
2488
  },
2447
2489
  list: {
2448
2490
  title: "All plans",
2449
- summary: "{plans} plans \xB7 {live} live \xB7 {drafts} open drafts \xB7 {tenants} tenants assigned",
2491
+ statPlans: "Plans",
2492
+ statLive: "Live",
2493
+ statDrafts: "Open drafts",
2494
+ statTenants: "Tenants",
2450
2495
  matrixView: "Matrix view",
2451
2496
  newPlan: "New plan",
2452
2497
  searchPlaceholder: "Search plan\u2026",
@@ -2483,7 +2528,10 @@ var plansMessages = defineMessages(
2483
2528
  },
2484
2529
  matrix: {
2485
2530
  title: "Plans \xB7 matrix comparison",
2486
- summary: "All plans side by side \xB7 {plans} plans \xB7 {features} features \xB7 {quotas} quotas \xB7 {bundles} bundles",
2531
+ statPlans: "Plans",
2532
+ statFeatures: "Features",
2533
+ statQuotas: "Quotas",
2534
+ statBundles: "Bundles",
2487
2535
  catalogPreview: "Catalog preview",
2488
2536
  createPlan: "Create plan",
2489
2537
  createPlanSub: "or create a clone",
@@ -2972,8 +3020,7 @@ var tenantsMessages = defineMessages(
2972
3020
  columnUsage: "Verbrauch",
2973
3021
  columnCreatedAt: "Angelegt",
2974
3022
  suspended: "Suspendiert",
2975
- empty: "Keine Mandanten mit diesen Filtern.",
2976
- pagination: "{total} Mandanten \xB7 Seite {page} / {pages}"
3023
+ empty: "Keine Mandanten mit diesen Filtern."
2977
3024
  },
2978
3025
  detail: {
2979
3026
  backToList: "Mandanten-Liste",
@@ -3021,8 +3068,7 @@ var tenantsMessages = defineMessages(
3021
3068
  columnUsage: "Usage",
3022
3069
  columnCreatedAt: "Created",
3023
3070
  suspended: "Suspended",
3024
- empty: "No tenants match these filters.",
3025
- pagination: "{total} tenants \xB7 Page {page} / {pages}"
3071
+ empty: "No tenants match these filters."
3026
3072
  },
3027
3073
  detail: {
3028
3074
  backToList: "Tenant list",
@@ -3280,6 +3326,9 @@ function createSuperAdminApp(options) {
3280
3326
  if (options.manifestGuard?.getManifest) {
3281
3327
  app.provide(SUPER_ADMIN_MANIFEST_KEY, options.manifestGuard.getManifest);
3282
3328
  }
3329
+ if (options.manifestGuard?.clearCache) {
3330
+ app.provide(SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY, options.manifestGuard.clearCache);
3331
+ }
3283
3332
  if (options.loginAdapter) {
3284
3333
  app.provide(SUPER_ADMIN_LOGIN_ADAPTER_KEY, options.loginAdapter);
3285
3334
  }
@@ -2,8 +2,8 @@ import { Component, App } from 'vue';
2
2
  import { QuasarPluginOptions } from 'quasar';
3
3
  import { Pinia } from 'pinia';
4
4
  import { RouteRecordRaw, RouterHistory, Router } from 'vue-router';
5
- import { H as HttpClient } from '../catalog-JXdKdIqG.cjs';
6
- import { S as SuperAdminGuardOptions, a as SuperAdminBrand, b as SuperAdminEndpoints, E as ExtensionsMap, A as ActionsMap, c as SuperAdminLoginAdapter, U as UiNotify, I as InstallPlugin, d as SuperAdminI18nOptions, e as SuperAdminI18n } from '../use-super-admin-i18n-1nCOkvgi.cjs';
5
+ import { H as HttpClient } from '../catalog-DJcfm5N2.cjs';
6
+ import { S as SuperAdminGuardOptions, a as SuperAdminBrand, b as SuperAdminEndpoints, E as ExtensionsMap, A as ActionsMap, c as SuperAdminLoginAdapter, U as UiNotify, I as InstallPlugin, d as SuperAdminI18nOptions, e as SuperAdminI18n } from '../use-super-admin-i18n-CgTuNi8h.cjs';
7
7
  import '@saasicat/types';
8
8
 
9
9
  interface CreateSuperAdminAppOptions extends SuperAdminGuardOptions {
@@ -2,8 +2,8 @@ import { Component, App } from 'vue';
2
2
  import { QuasarPluginOptions } from 'quasar';
3
3
  import { Pinia } from 'pinia';
4
4
  import { RouteRecordRaw, RouterHistory, Router } from 'vue-router';
5
- import { H as HttpClient } from '../catalog-JXdKdIqG.js';
6
- import { S as SuperAdminGuardOptions, a as SuperAdminBrand, b as SuperAdminEndpoints, E as ExtensionsMap, A as ActionsMap, c as SuperAdminLoginAdapter, U as UiNotify, I as InstallPlugin, d as SuperAdminI18nOptions, e as SuperAdminI18n } from '../use-super-admin-i18n-BlqcD0N7.js';
5
+ import { H as HttpClient } from '../catalog-DJcfm5N2.js';
6
+ import { S as SuperAdminGuardOptions, a as SuperAdminBrand, b as SuperAdminEndpoints, E as ExtensionsMap, A as ActionsMap, c as SuperAdminLoginAdapter, U as UiNotify, I as InstallPlugin, d as SuperAdminI18nOptions, e as SuperAdminI18n } from '../use-super-admin-i18n-CHNdsSlm.js';
7
7
  import '@saasicat/types';
8
8
 
9
9
  interface CreateSuperAdminAppOptions extends SuperAdminGuardOptions {
@@ -6,14 +6,15 @@ import {
6
6
  SUPER_ADMIN_HTTP_KEY,
7
7
  SUPER_ADMIN_I18N_KEY,
8
8
  SUPER_ADMIN_LOGIN_ADAPTER_KEY,
9
+ SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY,
9
10
  SUPER_ADMIN_MANIFEST_KEY,
10
11
  SUPER_ADMIN_NOTIFY_KEY,
11
12
  buildNavigationGuard,
12
13
  createSuperAdminI18n
13
- } from "../chunk-RVG6LQHL.js";
14
+ } from "../chunk-LY52T4N4.js";
14
15
  import {
15
16
  defaultHttpClient
16
- } from "../chunk-DPTIOQXX.js";
17
+ } from "../chunk-F7NRM6KI.js";
17
18
 
18
19
  // src/quasar/create-super-admin-app.ts
19
20
  import { createApp } from "vue";
@@ -74,6 +75,9 @@ function createSuperAdminApp(options) {
74
75
  if (options.manifestGuard?.getManifest) {
75
76
  app.provide(SUPER_ADMIN_MANIFEST_KEY, options.manifestGuard.getManifest);
76
77
  }
78
+ if (options.manifestGuard?.clearCache) {
79
+ app.provide(SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY, options.manifestGuard.clearCache);
80
+ }
77
81
  if (options.loginAdapter) {
78
82
  app.provide(SUPER_ADMIN_LOGIN_ADAPTER_KEY, options.loginAdapter);
79
83
  }
@@ -0,0 +1,37 @@
1
+ import { test, expect } from '@playwright/test';
2
+
3
+ interface AdminPagesSuiteConfig {
4
+ /** Display name, e.g. 'demoapp' / 'clubapp'. */
5
+ appName: string;
6
+ /** URL of the login page (full). */
7
+ loginUrl: string;
8
+ /** Test account. */
9
+ email: string;
10
+ password: string;
11
+ /** Paths the smoke test should click through. */
12
+ pages: ReadonlyArray<{
13
+ /** Display name in the test description. */
14
+ name: string;
15
+ /** Path relative to the origin (e.g. '/admin/tenants'). */
16
+ path: string;
17
+ /** Optional: if set, check that this selector exists. */
18
+ expectVisible?: string;
19
+ /** Optional: HTTP patterns that are OK as 4xx/5xx (e.g. missing backend endpoints). */
20
+ allowedFailures?: readonly RegExp[];
21
+ }>;
22
+ /** Expected KPI card labels on the dashboard page. */
23
+ expectedKpiLabels: readonly string[];
24
+ /** Expected distribution section titles. */
25
+ expectedDistributionTitles?: readonly string[];
26
+ /** Expected shortcut titles on the dashboard. */
27
+ expectedShortcutTitles: readonly string[];
28
+ /** Shortcuts that must NOT appear (e.g. "Dashboard"). */
29
+ forbiddenShortcutTitles?: readonly string[];
30
+ /** Console error patterns that should be ignored. */
31
+ consoleErrorAllowlist?: readonly RegExp[];
32
+ /** Path to the dashboard page (default `/admin/`). */
33
+ dashboardPath?: string;
34
+ }
35
+ declare function runAdminPagesSuite(test: typeof test, expect: typeof expect, config: AdminPagesSuiteConfig): void;
36
+
37
+ export { type AdminPagesSuiteConfig, runAdminPagesSuite };
@@ -0,0 +1,37 @@
1
+ import { test, expect } from '@playwright/test';
2
+
3
+ interface AdminPagesSuiteConfig {
4
+ /** Display name, e.g. 'demoapp' / 'clubapp'. */
5
+ appName: string;
6
+ /** URL of the login page (full). */
7
+ loginUrl: string;
8
+ /** Test account. */
9
+ email: string;
10
+ password: string;
11
+ /** Paths the smoke test should click through. */
12
+ pages: ReadonlyArray<{
13
+ /** Display name in the test description. */
14
+ name: string;
15
+ /** Path relative to the origin (e.g. '/admin/tenants'). */
16
+ path: string;
17
+ /** Optional: if set, check that this selector exists. */
18
+ expectVisible?: string;
19
+ /** Optional: HTTP patterns that are OK as 4xx/5xx (e.g. missing backend endpoints). */
20
+ allowedFailures?: readonly RegExp[];
21
+ }>;
22
+ /** Expected KPI card labels on the dashboard page. */
23
+ expectedKpiLabels: readonly string[];
24
+ /** Expected distribution section titles. */
25
+ expectedDistributionTitles?: readonly string[];
26
+ /** Expected shortcut titles on the dashboard. */
27
+ expectedShortcutTitles: readonly string[];
28
+ /** Shortcuts that must NOT appear (e.g. "Dashboard"). */
29
+ forbiddenShortcutTitles?: readonly string[];
30
+ /** Console error patterns that should be ignored. */
31
+ consoleErrorAllowlist?: readonly RegExp[];
32
+ /** Path to the dashboard page (default `/admin/`). */
33
+ dashboardPath?: string;
34
+ }
35
+ declare function runAdminPagesSuite(test: typeof test, expect: typeof expect, config: AdminPagesSuiteConfig): void;
36
+
37
+ export { type AdminPagesSuiteConfig, runAdminPagesSuite };
@@ -1,7 +1,7 @@
1
1
  import { Component, App, InjectionKey, Ref, ComputedRef } from 'vue';
2
2
  import { NavigationGuardWithThis } from 'vue-router';
3
3
  import { ActionKey, ComponentKey, AdminManifest } from '@saasicat/types';
4
- import { A as ActionHandler, H as HttpClient, S as SaLocale, a as SaMessages, b as SaLocaleOption, c as SaLocaleDefinition, d as SaMessagesOverrides, K as KvStore } from './catalog-JXdKdIqG.js';
4
+ import { A as ActionHandler, H as HttpClient, S as SaLocale, a as SaMessages, b as SaLocaleOption, c as SaLocaleDefinition, d as SaMessagesOverrides, K as KvStore } from './catalog-DJcfm5N2.js';
5
5
 
6
6
  /**
7
7
  * App-specific branding data that the platform `AdminLayout` and other
@@ -70,6 +70,17 @@ interface SuperAdminLoginAdapter {
70
70
  * storage, MFA hops etc.
71
71
  */
72
72
  login(email: string, password: string): Promise<SuperAdminLoginResult>;
73
+ /**
74
+ * Undoes what `login` established — token, session storage, app store.
75
+ *
76
+ * Whoever knows how to start a session is the only one who knows how to
77
+ * end it, so it belongs next to `login` rather than in a second seam. The
78
+ * platform's own sign-out affordances call it; without it they can only
79
+ * navigate to `/login`, and an app whose `isAuthenticated()` reads a
80
+ * surviving token lets the operator straight back in — a sign-out button
81
+ * that does not sign out.
82
+ */
83
+ logout?(): void | Promise<void>;
73
84
  /**
74
85
  * Target route after a successful login. Default: `/admin/dashboard`
75
86
  * (platform convention for the standard pages — apps with a different
@@ -112,6 +123,20 @@ interface SuperAdminManifestGuardOptions {
112
123
  * manifest guard again and produces a redirect loop.
113
124
  */
114
125
  errorRoute?: string;
126
+ /**
127
+ * Discards the cached manifest, so the next `ensureLoaded()` fetches a
128
+ * fresh body instead of revalidating.
129
+ *
130
+ * Needed because the loader keeps an ETag in storage. Its own documented
131
+ * failure — "server returned 304 but the cache body is missing" — survives
132
+ * a full page reload: the next request sends the same `If-None-Match`,
133
+ * gets another 304, and lands back on the error page. Retry is a dead end
134
+ * for that case unless something clears the ETag first.
135
+ *
136
+ * `ManifestLoader.clearCache()` and the manifest store's reset both fit;
137
+ * pass whichever the app uses.
138
+ */
139
+ clearCache?: () => void | Promise<void>;
115
140
  }
116
141
  /**
117
142
  * Guard configuration shared by `buildNavigationGuard()` and
@@ -143,6 +168,13 @@ declare const SUPER_ADMIN_ACTIONS_KEY: InjectionKey<ActionsMap>;
143
168
  * `<ProjectPageHost>` needs it to resolve project pages.
144
169
  */
145
170
  declare const SUPER_ADMIN_MANIFEST_KEY: InjectionKey<() => AdminManifest | null>;
171
+ /**
172
+ * Vue inject key for `manifestGuard.clearCache`.
173
+ *
174
+ * The fail-closed error page is route-mounted and gets no props, so the only
175
+ * way it can reach the app's cache is through the shell.
176
+ */
177
+ declare const SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY: InjectionKey<() => void | Promise<void>>;
146
178
  /** Vue inject key for `useSuperAdminLoginAdapter()`. */
147
179
  declare const SUPER_ADMIN_LOGIN_ADAPTER_KEY: InjectionKey<SuperAdminLoginAdapter>;
148
180
  /** Vue inject key for `useSuperAdminHttp()` (pre-login HttpClient). */
@@ -152,11 +184,6 @@ declare const SUPER_ADMIN_HTTP_KEY: InjectionKey<HttpClient>;
152
184
  * bootstrap installs after the platform setup, before the mount.
153
185
  */
154
186
  type InstallPlugin = (app: App) => void;
155
- /**
156
- * Internal helper, exported for isolated unit tests of the navigation
157
- * behavior (auth redirect, manifest fail-closed path). Consumers should call
158
- * `createSuperAdminApp()`, not this helper directly.
159
- */
160
187
  declare function buildNavigationGuard(options: SuperAdminGuardOptions): NavigationGuardWithThis<undefined> | null;
161
188
 
162
189
  /**
@@ -253,4 +280,4 @@ declare function useSuperAdminI18n(): SuperAdminI18n;
253
280
  */
254
281
  declare function useSaMessages<K extends keyof SaMessages>(namespace: K): ComputedRef<SaMessages[K]>;
255
282
 
256
- export { type ActionsMap as A, type ExtensionsMap as E, type InstallPlugin as I, type SuperAdminGuardOptions as S, type UiNotify as U, type SuperAdminBrand as a, type SuperAdminEndpoints as b, type SuperAdminLoginAdapter as c, type SuperAdminI18nOptions as d, type SuperAdminI18n as e, type ExtensionLoader as f, SA_LOCALE_STORAGE_KEY as g, SUPER_ADMIN_ACTIONS_KEY as h, SUPER_ADMIN_BRAND_KEY as i, SUPER_ADMIN_ENDPOINTS_KEY as j, SUPER_ADMIN_EXTENSIONS_KEY as k, SUPER_ADMIN_HTTP_KEY as l, SUPER_ADMIN_I18N_KEY as m, SUPER_ADMIN_LOGIN_ADAPTER_KEY as n, SUPER_ADMIN_MANIFEST_KEY as o, SUPER_ADMIN_NOTIFY_KEY as p, type SuperAdminAuthGuardOptions as q, type SuperAdminLoginResult as r, type SuperAdminManifestGuardOptions as s, type UiNotifyKind as t, type UiNotifyOptions as u, buildNavigationGuard as v, createSuperAdminI18n as w, useSaMessages as x, useSuperAdminI18n as y };
283
+ export { type ActionsMap as A, type ExtensionsMap as E, type InstallPlugin as I, type SuperAdminGuardOptions as S, type UiNotify as U, type SuperAdminBrand as a, type SuperAdminEndpoints as b, type SuperAdminLoginAdapter as c, type SuperAdminI18nOptions as d, type SuperAdminI18n as e, type ExtensionLoader as f, SA_LOCALE_STORAGE_KEY as g, SUPER_ADMIN_ACTIONS_KEY as h, SUPER_ADMIN_BRAND_KEY as i, SUPER_ADMIN_ENDPOINTS_KEY as j, SUPER_ADMIN_EXTENSIONS_KEY as k, SUPER_ADMIN_HTTP_KEY as l, SUPER_ADMIN_I18N_KEY as m, SUPER_ADMIN_LOGIN_ADAPTER_KEY as n, SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY as o, SUPER_ADMIN_MANIFEST_KEY as p, SUPER_ADMIN_NOTIFY_KEY as q, type SuperAdminAuthGuardOptions as r, type SuperAdminLoginResult as s, type SuperAdminManifestGuardOptions as t, type UiNotifyKind as u, type UiNotifyOptions as v, buildNavigationGuard as w, createSuperAdminI18n as x, useSaMessages as y, useSuperAdminI18n as z };
@@ -1,7 +1,7 @@
1
1
  import { Component, App, InjectionKey, Ref, ComputedRef } from 'vue';
2
2
  import { NavigationGuardWithThis } from 'vue-router';
3
3
  import { ActionKey, ComponentKey, AdminManifest } from '@saasicat/types';
4
- import { A as ActionHandler, H as HttpClient, S as SaLocale, a as SaMessages, b as SaLocaleOption, c as SaLocaleDefinition, d as SaMessagesOverrides, K as KvStore } from './catalog-JXdKdIqG.cjs';
4
+ import { A as ActionHandler, H as HttpClient, S as SaLocale, a as SaMessages, b as SaLocaleOption, c as SaLocaleDefinition, d as SaMessagesOverrides, K as KvStore } from './catalog-DJcfm5N2.cjs';
5
5
 
6
6
  /**
7
7
  * App-specific branding data that the platform `AdminLayout` and other
@@ -70,6 +70,17 @@ interface SuperAdminLoginAdapter {
70
70
  * storage, MFA hops etc.
71
71
  */
72
72
  login(email: string, password: string): Promise<SuperAdminLoginResult>;
73
+ /**
74
+ * Undoes what `login` established — token, session storage, app store.
75
+ *
76
+ * Whoever knows how to start a session is the only one who knows how to
77
+ * end it, so it belongs next to `login` rather than in a second seam. The
78
+ * platform's own sign-out affordances call it; without it they can only
79
+ * navigate to `/login`, and an app whose `isAuthenticated()` reads a
80
+ * surviving token lets the operator straight back in — a sign-out button
81
+ * that does not sign out.
82
+ */
83
+ logout?(): void | Promise<void>;
73
84
  /**
74
85
  * Target route after a successful login. Default: `/admin/dashboard`
75
86
  * (platform convention for the standard pages — apps with a different
@@ -112,6 +123,20 @@ interface SuperAdminManifestGuardOptions {
112
123
  * manifest guard again and produces a redirect loop.
113
124
  */
114
125
  errorRoute?: string;
126
+ /**
127
+ * Discards the cached manifest, so the next `ensureLoaded()` fetches a
128
+ * fresh body instead of revalidating.
129
+ *
130
+ * Needed because the loader keeps an ETag in storage. Its own documented
131
+ * failure — "server returned 304 but the cache body is missing" — survives
132
+ * a full page reload: the next request sends the same `If-None-Match`,
133
+ * gets another 304, and lands back on the error page. Retry is a dead end
134
+ * for that case unless something clears the ETag first.
135
+ *
136
+ * `ManifestLoader.clearCache()` and the manifest store's reset both fit;
137
+ * pass whichever the app uses.
138
+ */
139
+ clearCache?: () => void | Promise<void>;
115
140
  }
116
141
  /**
117
142
  * Guard configuration shared by `buildNavigationGuard()` and
@@ -143,6 +168,13 @@ declare const SUPER_ADMIN_ACTIONS_KEY: InjectionKey<ActionsMap>;
143
168
  * `<ProjectPageHost>` needs it to resolve project pages.
144
169
  */
145
170
  declare const SUPER_ADMIN_MANIFEST_KEY: InjectionKey<() => AdminManifest | null>;
171
+ /**
172
+ * Vue inject key for `manifestGuard.clearCache`.
173
+ *
174
+ * The fail-closed error page is route-mounted and gets no props, so the only
175
+ * way it can reach the app's cache is through the shell.
176
+ */
177
+ declare const SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY: InjectionKey<() => void | Promise<void>>;
146
178
  /** Vue inject key for `useSuperAdminLoginAdapter()`. */
147
179
  declare const SUPER_ADMIN_LOGIN_ADAPTER_KEY: InjectionKey<SuperAdminLoginAdapter>;
148
180
  /** Vue inject key for `useSuperAdminHttp()` (pre-login HttpClient). */
@@ -152,11 +184,6 @@ declare const SUPER_ADMIN_HTTP_KEY: InjectionKey<HttpClient>;
152
184
  * bootstrap installs after the platform setup, before the mount.
153
185
  */
154
186
  type InstallPlugin = (app: App) => void;
155
- /**
156
- * Internal helper, exported for isolated unit tests of the navigation
157
- * behavior (auth redirect, manifest fail-closed path). Consumers should call
158
- * `createSuperAdminApp()`, not this helper directly.
159
- */
160
187
  declare function buildNavigationGuard(options: SuperAdminGuardOptions): NavigationGuardWithThis<undefined> | null;
161
188
 
162
189
  /**
@@ -253,4 +280,4 @@ declare function useSuperAdminI18n(): SuperAdminI18n;
253
280
  */
254
281
  declare function useSaMessages<K extends keyof SaMessages>(namespace: K): ComputedRef<SaMessages[K]>;
255
282
 
256
- export { type ActionsMap as A, type ExtensionsMap as E, type InstallPlugin as I, type SuperAdminGuardOptions as S, type UiNotify as U, type SuperAdminBrand as a, type SuperAdminEndpoints as b, type SuperAdminLoginAdapter as c, type SuperAdminI18nOptions as d, type SuperAdminI18n as e, type ExtensionLoader as f, SA_LOCALE_STORAGE_KEY as g, SUPER_ADMIN_ACTIONS_KEY as h, SUPER_ADMIN_BRAND_KEY as i, SUPER_ADMIN_ENDPOINTS_KEY as j, SUPER_ADMIN_EXTENSIONS_KEY as k, SUPER_ADMIN_HTTP_KEY as l, SUPER_ADMIN_I18N_KEY as m, SUPER_ADMIN_LOGIN_ADAPTER_KEY as n, SUPER_ADMIN_MANIFEST_KEY as o, SUPER_ADMIN_NOTIFY_KEY as p, type SuperAdminAuthGuardOptions as q, type SuperAdminLoginResult as r, type SuperAdminManifestGuardOptions as s, type UiNotifyKind as t, type UiNotifyOptions as u, buildNavigationGuard as v, createSuperAdminI18n as w, useSaMessages as x, useSuperAdminI18n as y };
283
+ export { type ActionsMap as A, type ExtensionsMap as E, type InstallPlugin as I, type SuperAdminGuardOptions as S, type UiNotify as U, type SuperAdminBrand as a, type SuperAdminEndpoints as b, type SuperAdminLoginAdapter as c, type SuperAdminI18nOptions as d, type SuperAdminI18n as e, type ExtensionLoader as f, SA_LOCALE_STORAGE_KEY as g, SUPER_ADMIN_ACTIONS_KEY as h, SUPER_ADMIN_BRAND_KEY as i, SUPER_ADMIN_ENDPOINTS_KEY as j, SUPER_ADMIN_EXTENSIONS_KEY as k, SUPER_ADMIN_HTTP_KEY as l, SUPER_ADMIN_I18N_KEY as m, SUPER_ADMIN_LOGIN_ADAPTER_KEY as n, SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY as o, SUPER_ADMIN_MANIFEST_KEY as p, SUPER_ADMIN_NOTIFY_KEY as q, type SuperAdminAuthGuardOptions as r, type SuperAdminLoginResult as s, type SuperAdminManifestGuardOptions as t, type UiNotifyKind as u, type UiNotifyOptions as v, buildNavigationGuard as w, createSuperAdminI18n as x, useSaMessages as y, useSuperAdminI18n as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saasicat/ui-vue",
3
- "version": "0.19.0",
3
+ "version": "0.22.0",
4
4
  "description": "Vue 3 components, resource clients and composables for the SuperAdmin UI shell. Provides boot and manifest loaders, navigation, actions and standard pages.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -43,9 +43,14 @@
43
43
  "./components/*": "./src/components/*",
44
44
  "./sa-theme.css": "./src/pages-standard/sa-theme.css",
45
45
  "./testing-e2e/*": {
46
- "types": "./dist/testing-e2e/*.d.ts",
47
- "import": "./dist/testing-e2e/*.js",
48
- "require": "./dist/testing-e2e/*.cjs"
46
+ "import": {
47
+ "types": "./dist/testing-e2e/*.d.ts",
48
+ "default": "./dist/testing-e2e/*.js"
49
+ },
50
+ "require": {
51
+ "types": "./dist/testing-e2e/*.d.cts",
52
+ "default": "./dist/testing-e2e/*.cjs"
53
+ }
49
54
  }
50
55
  },
51
56
  "files": [
@@ -53,7 +58,7 @@
53
58
  "src"
54
59
  ],
55
60
  "dependencies": {
56
- "@saasicat/types": "^0.19.0"
61
+ "@saasicat/types": "^0.22.0"
57
62
  },
58
63
  "peerDependencies": {
59
64
  "pinia": "^2.0.0 || ^3.0.0",
@@ -74,14 +79,17 @@
74
79
  },
75
80
  "devDependencies": {
76
81
  "@playwright/test": "^1.59.1",
82
+ "@quasar/vite-plugin": "^1.12.0",
77
83
  "@types/node": "^25.6.0",
78
84
  "@vitejs/plugin-vue": "^6.0.8",
79
85
  "@vue/test-utils": "^2.4.11",
80
86
  "jsdom": "^30.0.1",
81
87
  "pinia": "^3.0.0",
82
88
  "quasar": "^2.24.0",
89
+ "sass": "^1.101.3",
83
90
  "tsup": "^8.0.0",
84
91
  "typescript": "^6.0.0",
92
+ "vite": "^7.3.6",
85
93
  "vitest": "^4.1.10",
86
94
  "vue": "^3.5.0",
87
95
  "vue-router": "^5.0.0",
@@ -102,11 +110,13 @@
102
110
  "access": "public"
103
111
  },
104
112
  "scripts": {
105
- "build": "tsup",
106
- "typecheck": "vue-tsc --noEmit -p tsconfig.json",
113
+ "build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsup",
114
+ "typecheck": "vue-tsc --noEmit -p tsconfig.json && vue-tsc --noEmit -p tsconfig.tests.json",
107
115
  "pretest": "pnpm run build",
108
116
  "test": "node --test tests/**/*.test.js",
109
117
  "test:component": "vitest run --config vitest.config.ts",
110
- "test:e2e": "playwright test"
118
+ "test:e2e": "playwright test",
119
+ "test:visual": "playwright test --project=visual",
120
+ "test:visual:update": "playwright test --project=visual --update-snapshots"
111
121
  }
112
122
  }
@@ -40,7 +40,6 @@ export const bundlesMessages = defineMessages(
40
40
  'Produktgruppen aus Features & Quotas — verwendet in Plänen. Bundles werden im SuperAdmin kuratiert.',
41
41
  displayLocale: 'Anzeige-Sprache',
42
42
  newBundle: 'Neues Bundle',
43
- reload: 'Liste neu laden',
44
43
  },
45
44
  filter: {
46
45
  all: 'Alle Status',
@@ -271,7 +270,6 @@ export const bundlesMessages = defineMessages(
271
270
  'Product groups made of features & quotas — used in plans. Bundles are curated in the SuperAdmin.',
272
271
  displayLocale: 'Display language',
273
272
  newBundle: 'New bundle',
274
- reload: 'Reload list',
275
273
  },
276
274
  filter: {
277
275
  all: 'All statuses',