@saasicat/ui-vue 0.22.2 → 0.24.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 (119) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-LY52T4N4.js → chunk-TQQMKWN6.js} +58 -1
  3. package/dist/{chunk-XMMFN2WJ.js → chunk-VYMTWCTT.js} +51 -1
  4. package/dist/client/index.cjs +57 -0
  5. package/dist/client/index.d.cts +58 -1
  6. package/dist/client/index.d.ts +58 -1
  7. package/dist/client/index.js +15 -1
  8. package/dist/index.cjs +321 -159
  9. package/dist/index.d.cts +67 -4
  10. package/dist/index.d.ts +67 -4
  11. package/dist/index.js +72 -2
  12. package/dist/quasar/index.cjs +116 -20
  13. package/dist/quasar/index.d.cts +48 -3
  14. package/dist/quasar/index.d.ts +48 -3
  15. package/dist/quasar/index.js +58 -3
  16. package/dist/{use-super-admin-i18n-CgTuNi8h.d.cts → use-sa-theme-B5t7oXph.d.cts} +51 -1
  17. package/dist/{use-super-admin-i18n-CHNdsSlm.d.ts → use-sa-theme-OUBlaqgl.d.ts} +51 -1
  18. package/package.json +5 -2
  19. package/src/client/identity-accents.ts +129 -0
  20. package/src/client/index.ts +1 -0
  21. package/src/components/BundleVersionPublishDialog.vue +17 -17
  22. package/src/components/KvBlock.vue +6 -6
  23. package/src/components/MarketingPromotionsTab.vue +84 -80
  24. package/src/components/MfaPromptDialog.vue +2 -2
  25. package/src/components/TenantActionConfirmDialog.vue +5 -5
  26. package/src/components/VersionDiffPreview.vue +18 -18
  27. package/src/components/bundle-editor/BundleCreatePanel.vue +52 -52
  28. package/src/components/bundle-editor/BundleFeaturesEditor.vue +20 -20
  29. package/src/components/bundle-editor/BundlePlanCompatPicker.vue +33 -33
  30. package/src/components/bundle-editor/BundleQuotasEditor.vue +26 -26
  31. package/src/components/bundle-editor/BundleStatusBanner.vue +21 -21
  32. package/src/components/bundle-editor/BundleVersionInlineEditor.vue +49 -49
  33. package/src/components/bundle-editor/BundleVersionStrip.vue +30 -30
  34. package/src/components/dialogs/PilotCreateDialog.vue +20 -20
  35. package/src/components/dialogs/PilotEditDialog.vue +6 -6
  36. package/src/components/dialogs/PromoCodeCreateDialog.vue +9 -9
  37. package/src/components/dialogs/PromoCodeDialogFields.vue +64 -63
  38. package/src/components/dialogs/PromoCodeEditDialog.vue +11 -11
  39. package/src/components/dialogs/pilot-dialog.css +48 -48
  40. package/src/components/plan/PlanCycleToggle.vue +9 -16
  41. package/src/components/plan/PlanGrid.vue +30 -34
  42. package/src/components/plan/PriceSummary.vue +35 -35
  43. package/src/components/plan/PromoCodeInput.vue +26 -26
  44. package/src/components/plan/PublicBundleGrid.vue +32 -28
  45. package/src/components/plan-create-dialog/PlanCreateDialog.vue +50 -50
  46. package/src/components/plan-detail/PlanDetail.vue +178 -157
  47. package/src/components/plan-detail/PlanTitleEdit.vue +11 -11
  48. package/src/components/plan-list/PlanList.vue +116 -100
  49. package/src/components/plan-matrix/PlanMatrix.vue +97 -114
  50. package/src/components/plan-review/PlanReview.vue +61 -57
  51. package/src/components/plan-version-editor/PlanVersionEditor.vue +246 -203
  52. package/src/components/wizard-stepper/WizardStepper.vue +17 -17
  53. package/src/index.ts +1 -0
  54. package/src/pages-standard/AdminLayout.vue +58 -37
  55. package/src/pages-standard/AdminManifestErrorPage.vue +6 -6
  56. package/src/pages-standard/AuditPage.vue +3 -3
  57. package/src/pages-standard/BundlesPage.vue +37 -37
  58. package/src/pages-standard/DashboardPage.vue +22 -19
  59. package/src/pages-standard/DiscoveryPage.vue +55 -49
  60. package/src/pages-standard/EmailHistoryPage.vue +53 -71
  61. package/src/pages-standard/MarketingCatalogPage.vue +245 -221
  62. package/src/pages-standard/PilotsPage.vue +7 -6
  63. package/src/pages-standard/PlatformEmailPage.vue +18 -18
  64. package/src/pages-standard/PromoCodeDetailPage.vue +3 -3
  65. package/src/pages-standard/PromoCodesPage.vue +10 -7
  66. package/src/pages-standard/SuperAdminLoginPage.vue +39 -25
  67. package/src/pages-standard/SuperAdminSetupWizard.vue +44 -33
  68. package/src/pages-standard/TenantDetailPage.vue +7 -7
  69. package/src/pages-standard/TenantsPage.vue +16 -50
  70. package/src/pages-standard/bundles-page/BundleAccordionList.vue +13 -13
  71. package/src/pages-standard/discovery-page/CatalogEntryTransPanel.vue +24 -24
  72. package/src/pages-standard/discovery-page/DiscoveryCapList.vue +22 -22
  73. package/src/pages-standard/discovery-page/DiscoveryFeatureCard.vue +39 -39
  74. package/src/pages-standard/discovery-page/DiscoveryQuotaCard.vue +26 -26
  75. package/src/pages-standard/discovery-page/DiscoveryStatusControl.vue +1 -1
  76. package/src/pages-standard/discovery-page/discovery-ui.ts +10 -7
  77. package/src/pages-standard/marketing-catalog/MarketingCatalogAdmin.vue +2 -5
  78. package/src/pages-standard/plan-versions/PlanDiffCard.vue +27 -20
  79. package/src/pages-standard/plan-versions/PlanVersionsDiff.vue +24 -16
  80. package/src/pages-standard/plan-versions/PlanVersionsTimeline.vue +45 -45
  81. package/src/pages-standard/plans-page/PlanBundleOverview.vue +21 -15
  82. package/src/pages-standard/plans-page/PlanPublishDialog.vue +4 -4
  83. package/src/pages-standard/plans-page/PlansPageToast.vue +6 -6
  84. package/src/pages-standard/sa-theme.css +9 -687
  85. package/src/pages-standard/tenants/StatusPill.vue +13 -13
  86. package/src/pages-standard/tenants/format.ts +11 -12
  87. package/src/pages-tenant/LimitsRow.vue +4 -4
  88. package/src/pages-tenant/MySubscriptionBundlesPage.vue +70 -61
  89. package/src/pages-tenant/OnboardingConfigurator.vue +25 -25
  90. package/src/pages-tenant/PackageSnapshotPanel.vue +10 -16
  91. package/src/pages-tenant/PendingVersionBanner.vue +12 -12
  92. package/src/pages-tenant/PlanChangeWizard.vue +22 -76
  93. package/src/pages-tenant/TenantPlanSection.vue +19 -69
  94. package/src/pages-tenant/UsageBar.vue +7 -7
  95. package/src/pages-tenant/default-i18n.ts +113 -0
  96. package/src/pages-tenant/tenant-plan-section/BundlePreviewDialog.vue +14 -14
  97. package/src/pages-tenant/tenant-plan-section/TenantBundleStore.vue +10 -10
  98. package/src/pages-tenant/tenant-plan-section/TenantFeatureMatrix.vue +2 -2
  99. package/src/quasar/create-super-admin-app.ts +96 -1
  100. package/src/quasar/dark-bridge.ts +66 -0
  101. package/src/quasar/index.ts +1 -0
  102. package/src/ui/theme/_breakpoints.scss +34 -0
  103. package/src/ui/theme/base.css +50 -0
  104. package/src/ui/theme/components/body.css +23 -0
  105. package/src/ui/theme/components/button.css +158 -0
  106. package/src/ui/theme/components/card.css +74 -0
  107. package/src/ui/theme/components/field.css +38 -0
  108. package/src/ui/theme/components/hero.css +46 -0
  109. package/src/ui/theme/components/paginator.css +63 -0
  110. package/src/ui/theme/components/section.css +67 -0
  111. package/src/ui/theme/components/statistics.css +189 -0
  112. package/src/ui/theme/components/table.css +60 -0
  113. package/src/ui/theme/index.css +42 -0
  114. package/src/ui/theme/tokens.legacy.css +147 -0
  115. package/src/ui/theme/tokens.primitive.css +112 -0
  116. package/src/ui/theme/tokens.scale.css +103 -0
  117. package/src/ui/theme/tokens.semantic.dark.css +185 -0
  118. package/src/ui/theme/tokens.semantic.light.css +242 -0
  119. package/src/vue/use-sa-theme.ts +154 -0
package/dist/index.cjs CHANGED
@@ -40,6 +40,10 @@ __export(src_exports, {
40
40
  DiscoveryLoadError: () => DiscoveryLoadError,
41
41
  ENTITLEMENT_INJECTION_KEY: () => ENTITLEMENT_INJECTION_KEY,
42
42
  HttpJsonError: () => HttpJsonError,
43
+ IDENTITY_ACCENTS: () => IDENTITY_ACCENTS,
44
+ IDENTITY_ACCENT_VALUES: () => IDENTITY_ACCENT_VALUES,
45
+ IDENTITY_NEUTRAL: () => IDENTITY_NEUTRAL,
46
+ IDENTITY_NEUTRAL_VALUE: () => IDENTITY_NEUTRAL_VALUE,
43
47
  ManifestLoadError: () => ManifestLoadError,
44
48
  ManifestLoader: () => ManifestLoader,
45
49
  MarketingProjectionsApiError: () => MarketingProjectionsApiError,
@@ -54,6 +58,7 @@ __export(src_exports, {
54
58
  SA_LOCALE_LABELS: () => SA_LOCALE_LABELS,
55
59
  SA_LOCALE_STORAGE_KEY: () => SA_LOCALE_STORAGE_KEY,
56
60
  SA_MESSAGES: () => SA_MESSAGES,
61
+ SA_THEME_KEY: () => SA_THEME_KEY,
57
62
  SERVER_PAGE_SIZE_OPTIONS: () => SERVER_PAGE_SIZE_OPTIONS,
58
63
  SUPER_ADMIN_ACTIONS_KEY: () => SUPER_ADMIN_ACTIONS_KEY,
59
64
  SUPER_ADMIN_BRAND_KEY: () => SUPER_ADMIN_BRAND_KEY,
@@ -79,6 +84,7 @@ __export(src_exports, {
79
84
  createPlatformLoaders: () => createPlatformLoaders,
80
85
  createProjectPageHostRoute: () => createProjectPageHostRoute,
81
86
  createSaCatalog: () => createSaCatalog,
87
+ createSaTheme: () => createSaTheme,
82
88
  createSuperAdminI18n: () => createSuperAdminI18n,
83
89
  defaultHttpClient: () => defaultHttpClient,
84
90
  defaultIconForActionKey: () => defaultIconForActionKey,
@@ -90,12 +96,16 @@ __export(src_exports, {
90
96
  formatCurrency: () => formatCurrency,
91
97
  formatMessage: () => formatMessage,
92
98
  getJson: () => getJson,
99
+ identityAccentAt: () => identityAccentAt,
100
+ identityAccentFor: () => identityAccentFor,
101
+ identityChipStyle: () => identityChipStyle,
93
102
  isCurrentlyValid: () => isCurrentlyValid,
94
103
  isExpired: () => isExpired,
95
104
  isFutureScheduled: () => isFutureScheduled,
96
105
  isProductionBoot: () => isProductionBoot,
97
106
  isSaBuiltinLocale: () => isSaBuiltinLocale,
98
107
  mergeMessages: () => mergeMessages,
108
+ planChangeWizardI18n: () => planChangeWizardI18n,
99
109
  postJson: () => postJson,
100
110
  provideEntitlement: () => provideEntitlement,
101
111
  resolveExtension: () => resolveExtension,
@@ -128,6 +138,7 @@ __export(src_exports, {
128
138
  usePromotions: () => usePromotions,
129
139
  usePublicBoot: () => usePublicBoot,
130
140
  useSaMessages: () => useSaMessages,
141
+ useSaTheme: () => useSaTheme,
131
142
  useSubscriptionDraft: () => useSubscriptionDraft,
132
143
  useSuperAdminActions: () => useSuperAdminActions,
133
144
  useSuperAdminBrand: () => useSuperAdminBrand,
@@ -3938,6 +3949,49 @@ function countPlans(resolved) {
3938
3949
  };
3939
3950
  }
3940
3951
 
3952
+ // src/client/identity-accents.ts
3953
+ var IDENTITY_ACCENTS = [
3954
+ "var(--sa-color-identity-1)",
3955
+ "var(--sa-color-identity-2)",
3956
+ "var(--sa-color-identity-3)",
3957
+ "var(--sa-color-identity-4)",
3958
+ "var(--sa-color-identity-5)",
3959
+ "var(--sa-color-identity-6)"
3960
+ ];
3961
+ var IDENTITY_ACCENT_VALUES = [
3962
+ "#1d4ed8",
3963
+ "#6d28d9",
3964
+ "#047857",
3965
+ "#b45309",
3966
+ "#0369a1",
3967
+ "#b91c1c"
3968
+ ];
3969
+ var IDENTITY_NEUTRAL_VALUE = "#64748b";
3970
+ var IDENTITY_NEUTRAL = "var(--sa-color-identity-neutral)";
3971
+ function identityAccentAt(index) {
3972
+ if (!Number.isFinite(index) || index < 0) return IDENTITY_NEUTRAL;
3973
+ return IDENTITY_ACCENTS[Math.floor(index) % IDENTITY_ACCENTS.length];
3974
+ }
3975
+ var WELL_KNOWN = {
3976
+ STARTER: IDENTITY_NEUTRAL,
3977
+ BASIC: IDENTITY_NEUTRAL,
3978
+ STANDARD: "var(--sa-color-identity-1)",
3979
+ PRO: "var(--sa-color-identity-2)",
3980
+ PROFESSIONAL: "var(--sa-color-identity-2)",
3981
+ BUSINESS: "var(--sa-color-identity-5)",
3982
+ ENTERPRISE: "var(--sa-color-identity-3)"
3983
+ };
3984
+ function identityAccentFor(key, overrides = {}, index = -1) {
3985
+ return overrides[key] ?? WELL_KNOWN[key] ?? identityAccentAt(index);
3986
+ }
3987
+ function identityChipStyle(accent) {
3988
+ return {
3989
+ background: `color-mix(in srgb, ${accent} 8%, transparent)`,
3990
+ color: accent,
3991
+ borderColor: `color-mix(in srgb, ${accent} 20%, transparent)`
3992
+ };
3993
+ }
3994
+
3941
3995
  // src/vue/super-admin-context.ts
3942
3996
  var SUPER_ADMIN_BRAND_KEY = /* @__PURE__ */ Symbol.for(
3943
3997
  "@saasicat/ui-vue/SUPER_ADMIN_BRAND"
@@ -4096,8 +4150,56 @@ function useSaMessages(namespace) {
4096
4150
  return (0, import_vue2.computed)(() => messages.value[namespace]);
4097
4151
  }
4098
4152
 
4099
- // src/vue/project-page-host.ts
4153
+ // src/vue/use-sa-theme.ts
4100
4154
  var import_vue3 = require("vue");
4155
+ var SCHEMES = ["light", "dark", "system"];
4156
+ var STORAGE_KEY = "saasicat.theme.scheme";
4157
+ function isScheme(value) {
4158
+ return typeof value === "string" && SCHEMES.includes(value);
4159
+ }
4160
+ function systemScheme() {
4161
+ const value = (0, import_vue3.ref)("light");
4162
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
4163
+ return { value, unsubscribe: () => {
4164
+ } };
4165
+ }
4166
+ const query = window.matchMedia("(prefers-color-scheme: dark)");
4167
+ value.value = query.matches ? "dark" : "light";
4168
+ const onChange = (event) => {
4169
+ value.value = event.matches ? "dark" : "light";
4170
+ };
4171
+ query.addEventListener("change", onChange);
4172
+ return { value, unsubscribe: () => query.removeEventListener("change", onChange) };
4173
+ }
4174
+ function createSaTheme(options = {}) {
4175
+ const storage = options.storage ?? defaultKvStore();
4176
+ const persist = options.persist !== false;
4177
+ const provided = options.scheme;
4178
+ const appOwnsIt = (0, import_vue3.isRef)(provided);
4179
+ const stored = persist && !appOwnsIt ? storage.get(STORAGE_KEY) : null;
4180
+ const scheme = (0, import_vue3.isRef)(provided) ? provided : (0, import_vue3.ref)(isScheme(stored) ? stored : provided ?? "system");
4181
+ const { value: system, unsubscribe } = systemScheme();
4182
+ const stopPersisting = persist && !appOwnsIt ? (0, import_vue3.watch)(scheme, (next) => storage.set(STORAGE_KEY, next)) : null;
4183
+ return {
4184
+ scheme,
4185
+ resolved: (0, import_vue3.computed)(() => scheme.value === "system" ? system.value : scheme.value),
4186
+ dispose: () => {
4187
+ unsubscribe();
4188
+ stopPersisting?.();
4189
+ }
4190
+ };
4191
+ }
4192
+ var SA_THEME_KEY = /* @__PURE__ */ Symbol.for("@saasicat/ui-vue/SA_THEME");
4193
+ var fallbackTheme = null;
4194
+ function useSaTheme() {
4195
+ const injected = (0, import_vue3.inject)(SA_THEME_KEY, null);
4196
+ if (injected) return injected;
4197
+ fallbackTheme ??= createSaTheme({ persist: false });
4198
+ return fallbackTheme;
4199
+ }
4200
+
4201
+ // src/vue/project-page-host.ts
4202
+ var import_vue4 = require("vue");
4101
4203
  var import_vue_router = require("vue-router");
4102
4204
  var asyncComponentCache = /* @__PURE__ */ new WeakMap();
4103
4205
  function resolveAsync(extensions, key) {
@@ -4110,23 +4212,23 @@ function resolveAsync(extensions, key) {
4110
4212
  if (cached) return cached;
4111
4213
  const loader = extensions[key];
4112
4214
  if (!loader) return null;
4113
- const cmp = (0, import_vue3.defineAsyncComponent)(loader);
4215
+ const cmp = (0, import_vue4.defineAsyncComponent)(loader);
4114
4216
  bucket.set(key, cmp);
4115
4217
  return cmp;
4116
4218
  }
4117
- var ProjectPageHost = (0, import_vue3.defineComponent)({
4219
+ var ProjectPageHost = (0, import_vue4.defineComponent)({
4118
4220
  name: "ProjectPageHost",
4119
4221
  setup() {
4120
4222
  const route = (0, import_vue_router.useRoute)();
4121
- const extensions = (0, import_vue3.inject)(SUPER_ADMIN_EXTENSIONS_KEY, {});
4122
- const manifestAccessor = (0, import_vue3.inject)(SUPER_ADMIN_MANIFEST_KEY, null);
4123
- const matchingPage = (0, import_vue3.computed)(() => {
4223
+ const extensions = (0, import_vue4.inject)(SUPER_ADMIN_EXTENSIONS_KEY, {});
4224
+ const manifestAccessor = (0, import_vue4.inject)(SUPER_ADMIN_MANIFEST_KEY, null);
4225
+ const matchingPage = (0, import_vue4.computed)(() => {
4124
4226
  const manifest = manifestAccessor ? manifestAccessor() : null;
4125
4227
  if (!manifest) return null;
4126
4228
  const pages = manifest.navigation?.projectPages ?? [];
4127
4229
  return pages.find((p) => p.route === route.path) ?? null;
4128
4230
  });
4129
- const resolvedComponent = (0, import_vue3.computed)(() => {
4231
+ const resolvedComponent = (0, import_vue4.computed)(() => {
4130
4232
  const page = matchingPage.value;
4131
4233
  if (!page) return null;
4132
4234
  return resolveAsync(extensions, page.componentKey);
@@ -4134,10 +4236,10 @@ var ProjectPageHost = (0, import_vue3.defineComponent)({
4134
4236
  return () => {
4135
4237
  const page = matchingPage.value;
4136
4238
  const cmp = resolvedComponent.value;
4137
- if (page && cmp) return (0, import_vue3.h)(cmp);
4138
- return (0, import_vue3.h)("div", { class: "sa-project-page-host__missing", role: "alert" }, [
4139
- (0, import_vue3.h)("h2", "Page not available"),
4140
- (0, import_vue3.h)(
4239
+ if (page && cmp) return (0, import_vue4.h)(cmp);
4240
+ return (0, import_vue4.h)("div", { class: "sa-project-page-host__missing", role: "alert" }, [
4241
+ (0, import_vue4.h)("h2", "Page not available"),
4242
+ (0, import_vue4.h)(
4141
4243
  "p",
4142
4244
  page ? `componentKey "${page.componentKey}" is not registered in the extensions: map. Apps must register the component in createSuperAdminApp({ extensions }).` : `No manifest definition for ${route.path}. Either the ProjectPage is missing from the manifest, or the capability is not active.`
4143
4245
  )
@@ -4188,15 +4290,15 @@ function createAdminRoutes(options) {
4188
4290
  }
4189
4291
 
4190
4292
  // src/vue/use-api-list.ts
4191
- var import_vue4 = require("vue");
4293
+ var import_vue5 = require("vue");
4192
4294
  function useApiList(options) {
4193
4295
  const http = options.http ?? defaultHttpClient();
4194
- const items = (0, import_vue4.ref)([]);
4195
- const page = (0, import_vue4.ref)(1);
4196
- const pageSize = (0, import_vue4.ref)(50);
4197
- const total = (0, import_vue4.ref)(0);
4198
- const loading = (0, import_vue4.ref)(false);
4199
- const error = (0, import_vue4.ref)(null);
4296
+ const items = (0, import_vue5.ref)([]);
4297
+ const page = (0, import_vue5.ref)(1);
4298
+ const pageSize = (0, import_vue5.ref)(50);
4299
+ const total = (0, import_vue5.ref)(0);
4300
+ const loading = (0, import_vue5.ref)(false);
4301
+ const error = (0, import_vue5.ref)(null);
4200
4302
  function buildUrl() {
4201
4303
  const params = new URLSearchParams();
4202
4304
  params.set("page", String(page.value));
@@ -4252,7 +4354,7 @@ function useApiList(options) {
4252
4354
  await load();
4253
4355
  }
4254
4356
  if (options.filter) {
4255
- (0, import_vue4.watch)(
4357
+ (0, import_vue5.watch)(
4256
4358
  options.filter,
4257
4359
  () => {
4258
4360
  page.value = 1;
@@ -4278,22 +4380,22 @@ function useApiList(options) {
4278
4380
  }
4279
4381
 
4280
4382
  // src/vue/use-pagination.ts
4281
- var import_vue5 = require("vue");
4383
+ var import_vue6 = require("vue");
4282
4384
  var ALL_ROWS = 0;
4283
4385
  var DEFAULT_ROWS_PER_PAGE = 10;
4284
4386
  var PAGE_SIZE_OPTIONS = [10, 25, 50, 100, ALL_ROWS];
4285
4387
  var SERVER_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];
4286
4388
  function usePagination(rows, initialRowsPerPage = DEFAULT_ROWS_PER_PAGE) {
4287
- const page = (0, import_vue5.ref)(1);
4288
- const rowsPerPage = (0, import_vue5.ref)(initialRowsPerPage);
4289
- const total = (0, import_vue5.computed)(() => rows.value.length);
4290
- const pageCount = (0, import_vue5.computed)(
4389
+ const page = (0, import_vue6.ref)(1);
4390
+ const rowsPerPage = (0, import_vue6.ref)(initialRowsPerPage);
4391
+ const total = (0, import_vue6.computed)(() => rows.value.length);
4392
+ const pageCount = (0, import_vue6.computed)(
4291
4393
  () => rowsPerPage.value === ALL_ROWS ? 1 : Math.max(1, Math.ceil(total.value / rowsPerPage.value))
4292
4394
  );
4293
- (0, import_vue5.watch)(pageCount, (count) => {
4395
+ (0, import_vue6.watch)(pageCount, (count) => {
4294
4396
  if (page.value > count) page.value = count;
4295
4397
  });
4296
- const pagedRows = (0, import_vue5.computed)(() => {
4398
+ const pagedRows = (0, import_vue6.computed)(() => {
4297
4399
  if (rowsPerPage.value === ALL_ROWS) return [...rows.value];
4298
4400
  const start = (page.value - 1) * rowsPerPage.value;
4299
4401
  return rows.value.slice(start, start + rowsPerPage.value);
@@ -4302,14 +4404,14 @@ function usePagination(rows, initialRowsPerPage = DEFAULT_ROWS_PER_PAGE) {
4302
4404
  }
4303
4405
 
4304
4406
  // src/vue/use-tenants.ts
4305
- var import_vue6 = require("vue");
4407
+ var import_vue7 = require("vue");
4306
4408
  function useTenants(options) {
4307
4409
  if (!options?.endpoint) {
4308
4410
  throw new Error(
4309
4411
  'useTenants: `endpoint` is required (e.g. "/api/v1/admin/tenants" or "/api/admin/tenants"). The platform has no default because apps use different globalPrefix conventions.'
4310
4412
  );
4311
4413
  }
4312
- const filter = options.filter ?? (0, import_vue6.ref)({});
4414
+ const filter = options.filter ?? (0, import_vue7.ref)({});
4313
4415
  const list = useApiList({
4314
4416
  endpoint: options.endpoint,
4315
4417
  filter,
@@ -4321,14 +4423,14 @@ function useTenants(options) {
4321
4423
  }
4322
4424
 
4323
4425
  // src/vue/use-audit-entries.ts
4324
- var import_vue7 = require("vue");
4426
+ var import_vue8 = require("vue");
4325
4427
  function useAuditEntries(options) {
4326
4428
  if (!options?.endpoint) {
4327
4429
  throw new Error(
4328
4430
  'useAuditEntries: `endpoint` is required (e.g. "/api/admin/audit" or "/api/v1/admin/audit"). The platform has no default because apps use different globalPrefix conventions.'
4329
4431
  );
4330
4432
  }
4331
- const filter = options.filter ?? (0, import_vue7.ref)({});
4433
+ const filter = options.filter ?? (0, import_vue8.ref)({});
4332
4434
  const list = useApiList({
4333
4435
  endpoint: options.endpoint,
4334
4436
  filter,
@@ -4340,7 +4442,7 @@ function useAuditEntries(options) {
4340
4442
  }
4341
4443
 
4342
4444
  // src/vue/use-entitlement.ts
4343
- var import_vue8 = require("vue");
4445
+ var import_vue9 = require("vue");
4344
4446
  function useEntitlement(options) {
4345
4447
  if (!options?.endpoint) {
4346
4448
  throw new Error(
@@ -4349,9 +4451,9 @@ function useEntitlement(options) {
4349
4451
  }
4350
4452
  const endpoint = options.endpoint;
4351
4453
  const http = options.http ?? defaultHttpClient();
4352
- const entitlement = (0, import_vue8.ref)(null);
4353
- const loading = (0, import_vue8.ref)(false);
4354
- const error = (0, import_vue8.ref)(null);
4454
+ const entitlement = (0, import_vue9.ref)(null);
4455
+ const loading = (0, import_vue9.ref)(false);
4456
+ const error = (0, import_vue9.ref)(null);
4355
4457
  async function load() {
4356
4458
  loading.value = true;
4357
4459
  error.value = null;
@@ -4381,15 +4483,15 @@ function useEntitlement(options) {
4381
4483
  }
4382
4484
 
4383
4485
  // src/vue/use-tenant-manifest.ts
4384
- var import_vue9 = require("vue");
4486
+ var import_vue10 = require("vue");
4385
4487
  function useTenantManifest(options) {
4386
4488
  if (!options?.endpoint) {
4387
4489
  throw new Error('useTenantManifest: `endpoint` is required (e.g. "/api/tenant/manifest").');
4388
4490
  }
4389
4491
  const http = options.http ?? defaultHttpClient();
4390
- const manifest = (0, import_vue9.ref)(null);
4391
- const loading = (0, import_vue9.ref)(false);
4392
- const error = (0, import_vue9.ref)(null);
4492
+ const manifest = (0, import_vue10.ref)(null);
4493
+ const loading = (0, import_vue10.ref)(false);
4494
+ const error = (0, import_vue10.ref)(null);
4393
4495
  async function load() {
4394
4496
  loading.value = true;
4395
4497
  error.value = null;
@@ -4423,7 +4525,7 @@ function useTenantManifest(options) {
4423
4525
  }
4424
4526
 
4425
4527
  // src/vue/entitlement-provider.ts
4426
- var import_vue10 = require("vue");
4528
+ var import_vue11 = require("vue");
4427
4529
  var ENTITLEMENT_INJECTION_KEY = /* @__PURE__ */ Symbol.for(
4428
4530
  "@saasicat/ui-vue/ENTITLEMENT"
4429
4531
  );
@@ -4431,7 +4533,7 @@ function provideEntitlement(app, entitlement) {
4431
4533
  app.provide(ENTITLEMENT_INJECTION_KEY, entitlement);
4432
4534
  }
4433
4535
  function useInjectedEntitlement() {
4434
- return (0, import_vue10.inject)(ENTITLEMENT_INJECTION_KEY, null);
4536
+ return (0, import_vue11.inject)(ENTITLEMENT_INJECTION_KEY, null);
4435
4537
  }
4436
4538
 
4437
4539
  // src/vue/feature-router-guard.ts
@@ -4460,15 +4562,15 @@ function buildFeatureRouterGuard(options) {
4460
4562
  }
4461
4563
 
4462
4564
  // src/vue/use-tenant-billing-catalog.ts
4463
- var import_vue11 = require("vue");
4565
+ var import_vue12 = require("vue");
4464
4566
  function useTenantBillingCatalog(options = {}) {
4465
4567
  const apiPrefix = trimTrailingSlashes(options.apiPrefix ?? "/billing");
4466
4568
  const http = options.http ?? defaultHttpClient();
4467
- const plans = (0, import_vue11.ref)(null);
4468
- const featureRegistry = (0, import_vue11.ref)(null);
4469
- const bundles = (0, import_vue11.ref)(null);
4470
- const loading = (0, import_vue11.ref)(false);
4471
- const error = (0, import_vue11.ref)(null);
4569
+ const plans = (0, import_vue12.ref)(null);
4570
+ const featureRegistry = (0, import_vue12.ref)(null);
4571
+ const bundles = (0, import_vue12.ref)(null);
4572
+ const loading = (0, import_vue12.ref)(false);
4573
+ const error = (0, import_vue12.ref)(null);
4472
4574
  async function fetchJson(path) {
4473
4575
  const res = await http(`${apiPrefix}${path}`, { method: "GET" });
4474
4576
  if (res.status !== 200) {
@@ -4518,14 +4620,14 @@ function useTenantBillingCatalog(options = {}) {
4518
4620
  }
4519
4621
 
4520
4622
  // src/vue/use-tenant-billing.ts
4521
- var import_vue12 = require("vue");
4623
+ var import_vue13 = require("vue");
4522
4624
  function useTenantBilling(options = {}) {
4523
4625
  const apiPrefix = trimTrailingSlashes(options.apiPrefix ?? "/billing");
4524
4626
  const http = options.http ?? defaultHttpClient();
4525
- const usage = (0, import_vue12.ref)(null);
4526
- const loading = (0, import_vue12.ref)(false);
4527
- const error = (0, import_vue12.ref)(null);
4528
- const subscriptionBundles = (0, import_vue12.ref)([]);
4627
+ const usage = (0, import_vue13.ref)(null);
4628
+ const loading = (0, import_vue13.ref)(false);
4629
+ const error = (0, import_vue13.ref)(null);
4630
+ const subscriptionBundles = (0, import_vue13.ref)([]);
4529
4631
  function authHeaders() {
4530
4632
  const headers = {};
4531
4633
  const token = options.getAuthToken?.();
@@ -4659,8 +4761,8 @@ function useTenantBilling(options = {}) {
4659
4761
  }
4660
4762
 
4661
4763
  // src/vue/use-subscription-draft.ts
4662
- var import_vue13 = require("vue");
4663
- var import_types12 = require("@saasicat/types");
4764
+ var import_vue14 = require("vue");
4765
+ var import_types13 = require("@saasicat/types");
4664
4766
  var DEFAULT_YEARLY_FACTOR = 10;
4665
4767
  function unwrap(source) {
4666
4768
  if (source && typeof source === "object" && "value" in source) {
@@ -4676,35 +4778,35 @@ function priceForCycle(monthlyNet, yearlyNet, cycle, yearlyFactor) {
4676
4778
  }
4677
4779
  function useSubscriptionDraft(options) {
4678
4780
  const yearlyFactor = options.yearlyFactor ?? DEFAULT_YEARLY_FACTOR;
4679
- const plansRef = (0, import_vue13.computed)(() => unwrap(options.plans) ?? []);
4680
- const subscriptionBundlesRef = (0, import_vue13.computed)(
4781
+ const plansRef = (0, import_vue14.computed)(() => unwrap(options.plans) ?? []);
4782
+ const subscriptionBundlesRef = (0, import_vue14.computed)(
4681
4783
  () => unwrap(options.subscriptionBundles ?? null) ?? []
4682
4784
  );
4683
- const plan = (0, import_vue13.ref)(options.initialPlan ?? null);
4684
- const cycle = (0, import_vue13.ref)(options.initialCycle ?? "MONTHLY");
4685
- const selectedBundleVersionIds = (0, import_vue13.ref)(
4785
+ const plan = (0, import_vue14.ref)(options.initialPlan ?? null);
4786
+ const cycle = (0, import_vue14.ref)(options.initialCycle ?? "MONTHLY");
4787
+ const selectedBundleVersionIds = (0, import_vue14.ref)(
4686
4788
  new Set(options.initialBundleVersionIds ?? [])
4687
4789
  );
4688
- const promoCode = (0, import_vue13.ref)("");
4689
- const promoState = (0, import_vue13.ref)({ status: "idle", preview: null, message: "" });
4690
- const selectedPlan = (0, import_vue13.computed)(() => {
4790
+ const promoCode = (0, import_vue14.ref)("");
4791
+ const promoState = (0, import_vue14.ref)({ status: "idle", preview: null, message: "" });
4792
+ const selectedPlan = (0, import_vue14.computed)(() => {
4691
4793
  if (!plan.value) return null;
4692
4794
  return plansRef.value.find((p) => p.id === plan.value) ?? null;
4693
4795
  });
4694
- const selectedBundles = (0, import_vue13.computed)(
4796
+ const selectedBundles = (0, import_vue14.computed)(
4695
4797
  () => subscriptionBundlesRef.value.filter(
4696
4798
  (b) => selectedBundleVersionIds.value.has(b.bundleVersionId)
4697
4799
  )
4698
4800
  );
4699
- const chargeableBundles = (0, import_vue13.computed)(() => {
4801
+ const chargeableBundles = (0, import_vue14.computed)(() => {
4700
4802
  const planFeatures = selectedPlan.value?.features ?? [];
4701
4803
  const selected = selectedBundles.value;
4702
4804
  const keptIds = new Set(
4703
- (0, import_types12.selectChargeableBundles)(planFeatures, selected).map((b) => b.bundleVersionId)
4805
+ (0, import_types13.selectChargeableBundles)(planFeatures, selected).map((b) => b.bundleVersionId)
4704
4806
  );
4705
4807
  return selected.filter((b) => keptIds.has(b.bundleVersionId));
4706
4808
  });
4707
- const activeFeatures = (0, import_vue13.computed)(() => {
4809
+ const activeFeatures = (0, import_vue14.computed)(() => {
4708
4810
  const result = /* @__PURE__ */ new Set();
4709
4811
  const planObj = selectedPlan.value;
4710
4812
  if (planObj) {
@@ -4715,7 +4817,7 @@ function useSubscriptionDraft(options) {
4715
4817
  }
4716
4818
  return result;
4717
4819
  });
4718
- const pricing = (0, import_vue13.computed)(() => {
4820
+ const pricing = (0, import_vue14.computed)(() => {
4719
4821
  const cyc = cycle.value;
4720
4822
  const planObj = selectedPlan.value;
4721
4823
  const planNet = planObj ? priceForCycle(planObj.monthlyNet ?? 0, planObj.yearlyNet, cyc, yearlyFactor) : 0;
@@ -4775,7 +4877,7 @@ function useSubscriptionDraft(options) {
4775
4877
  }
4776
4878
  };
4777
4879
  });
4778
- const isDirty = (0, import_vue13.computed)(() => {
4880
+ const isDirty = (0, import_vue14.computed)(() => {
4779
4881
  return selectedBundleVersionIds.value.size > 0 || promoState.value.status === "valid";
4780
4882
  });
4781
4883
  function setPlan(planId) {
@@ -4851,7 +4953,7 @@ function useSubscriptionDraft(options) {
4851
4953
  }
4852
4954
 
4853
4955
  // src/vue/use-bulk-publish.ts
4854
- var import_vue14 = require("vue");
4956
+ var import_vue15 = require("vue");
4855
4957
  function useBulkPublish(options) {
4856
4958
  const msg = useSaMessages("planVersions");
4857
4959
  if (!options?.endpoints) {
@@ -4861,15 +4963,15 @@ function useBulkPublish(options) {
4861
4963
  }
4862
4964
  const http = options.http ?? defaultHttpClient();
4863
4965
  const endpoints = options.endpoints;
4864
- const items = (0, import_vue14.ref)([]);
4865
- const successCount = (0, import_vue14.computed)(() => items.value.filter((i) => i.status === "published").length);
4866
- const failureCount = (0, import_vue14.computed)(() => items.value.filter((i) => i.status === "failed").length);
4867
- const progress = (0, import_vue14.computed)(() => {
4966
+ const items = (0, import_vue15.ref)([]);
4967
+ const successCount = (0, import_vue15.computed)(() => items.value.filter((i) => i.status === "published").length);
4968
+ const failureCount = (0, import_vue15.computed)(() => items.value.filter((i) => i.status === "failed").length);
4969
+ const progress = (0, import_vue15.computed)(() => {
4868
4970
  if (items.value.length === 0) return 0;
4869
4971
  const done2 = successCount.value + failureCount.value;
4870
4972
  return done2 / items.value.length;
4871
4973
  });
4872
- const done = (0, import_vue14.computed)(
4974
+ const done = (0, import_vue15.computed)(
4873
4975
  () => items.value.length > 0 && items.value.every((i) => i.status === "published" || i.status === "failed")
4874
4976
  );
4875
4977
  function setItems(next) {
@@ -4927,7 +5029,7 @@ function useBulkPublish(options) {
4927
5029
  }
4928
5030
 
4929
5031
  // src/vue/use-plan-editor.ts
4930
- var import_vue15 = require("vue");
5032
+ var import_vue16 = require("vue");
4931
5033
  var PlannedOnlyFeatureError = class extends Error {
4932
5034
  constructor(violations) {
4933
5035
  super(
@@ -4947,10 +5049,10 @@ function tierWeight(tier) {
4947
5049
  function usePlanEditor(manifest, options = {}) {
4948
5050
  const baseSet = new Set(options.baseFeatures ?? []);
4949
5051
  const nonRegressive = options.nonRegressive ?? true;
4950
- const selectedFeatures = (0, import_vue15.ref)(new Set(options.initialFeatures ?? []));
5052
+ const selectedFeatures = (0, import_vue16.ref)(new Set(options.initialFeatures ?? []));
4951
5053
  const catalogFeatures = manifest.planCatalogSnapshot.features ?? [];
4952
5054
  const plannedOnlySet = new Set(catalogFeatures.filter((f) => f.plannedOnly).map((f) => f.key));
4953
- const availableFeatures = (0, import_vue15.computed)(() => {
5055
+ const availableFeatures = (0, import_vue16.computed)(() => {
4954
5056
  return catalogFeatures.map((def) => {
4955
5057
  const isSelected = selectedFeatures.value.has(def.key);
4956
5058
  const isPlannedOnly = !!def.plannedOnly;
@@ -4959,7 +5061,7 @@ function usePlanEditor(manifest, options = {}) {
4959
5061
  return { def, isSelected, isPlannedOnly, isInherited, canToggle };
4960
5062
  });
4961
5063
  });
4962
- const featuresByTier = (0, import_vue15.computed)(() => {
5064
+ const featuresByTier = (0, import_vue16.computed)(() => {
4963
5065
  const groups = /* @__PURE__ */ new Map();
4964
5066
  for (const row of availableFeatures.value) {
4965
5067
  const tier = row.def.tier ?? "OTHER";
@@ -5004,12 +5106,12 @@ function usePlanEditor(manifest, options = {}) {
5004
5106
  }
5005
5107
 
5006
5108
  // src/vue/use-public-boot.ts
5007
- var import_vue16 = require("vue");
5109
+ var import_vue17 = require("vue");
5008
5110
  function usePublicBoot(options) {
5009
5111
  const loader = new BootLoader(options);
5010
- const boot = (0, import_vue16.ref)(null);
5011
- const loading = (0, import_vue16.ref)(false);
5012
- const error = (0, import_vue16.ref)(null);
5112
+ const boot = (0, import_vue17.ref)(null);
5113
+ const loading = (0, import_vue17.ref)(false);
5114
+ const error = (0, import_vue17.ref)(null);
5013
5115
  async function load() {
5014
5116
  loading.value = true;
5015
5117
  error.value = null;
@@ -5026,7 +5128,7 @@ function usePublicBoot(options) {
5026
5128
  }
5027
5129
 
5028
5130
  // src/vue/use-discovery.ts
5029
- var import_vue17 = require("vue");
5131
+ var import_vue18 = require("vue");
5030
5132
  var DiscoveryLoadError = class extends Error {
5031
5133
  constructor(status, message) {
5032
5134
  super(message);
@@ -5043,10 +5145,10 @@ function useDiscovery(options) {
5043
5145
  );
5044
5146
  }
5045
5147
  const http = options.http ?? defaultHttpClient();
5046
- const snapshot = (0, import_vue17.ref)(null);
5047
- const etag = (0, import_vue17.ref)(null);
5048
- const loading = (0, import_vue17.ref)(false);
5049
- const error = (0, import_vue17.ref)(null);
5148
+ const snapshot = (0, import_vue18.ref)(null);
5149
+ const etag = (0, import_vue18.ref)(null);
5150
+ const loading = (0, import_vue18.ref)(false);
5151
+ const error = (0, import_vue18.ref)(null);
5050
5152
  async function fetchSnapshot(includeEtag) {
5051
5153
  loading.value = true;
5052
5154
  error.value = null;
@@ -5113,7 +5215,7 @@ function useDiscovery(options) {
5113
5215
  }
5114
5216
 
5115
5217
  // src/vue/use-catalog-entries.ts
5116
- var import_vue18 = require("vue");
5218
+ var import_vue19 = require("vue");
5117
5219
  var CatalogEntriesApiError = class extends Error {
5118
5220
  constructor(status, body, message) {
5119
5221
  super(message);
@@ -5133,11 +5235,11 @@ function useCatalogEntries(options) {
5133
5235
  }
5134
5236
  const msg = useSaMessages("discovery");
5135
5237
  const http = options.http ?? defaultHttpClient();
5136
- const capabilities = (0, import_vue18.ref)([]);
5137
- const features = (0, import_vue18.ref)([]);
5138
- const quotas = (0, import_vue18.ref)([]);
5139
- const loading = (0, import_vue18.ref)(false);
5140
- const error = (0, import_vue18.ref)(null);
5238
+ const capabilities = (0, import_vue19.ref)([]);
5239
+ const features = (0, import_vue19.ref)([]);
5240
+ const quotas = (0, import_vue19.ref)([]);
5241
+ const loading = (0, import_vue19.ref)(false);
5242
+ const error = (0, import_vue19.ref)(null);
5141
5243
  const base = `${options.adminEndpoint}/catalog`;
5142
5244
  const pk = encodeURIComponent(options.projectKey);
5143
5245
  function authHeaders() {
@@ -5263,7 +5365,7 @@ function useCatalogEntries(options) {
5263
5365
  }
5264
5366
 
5265
5367
  // src/vue/use-bundles.ts
5266
- var import_vue19 = require("vue");
5368
+ var import_vue20 = require("vue");
5267
5369
  var BundlesApiError = class extends Error {
5268
5370
  constructor(status, body, message) {
5269
5371
  super(message);
@@ -5284,9 +5386,9 @@ function useBundles(options) {
5284
5386
  throw new Error("useBundles: `projectKey` is required.");
5285
5387
  }
5286
5388
  const http = options.http ?? defaultHttpClient();
5287
- const bundles = (0, import_vue19.ref)([]);
5288
- const loading = (0, import_vue19.ref)(false);
5289
- const error = (0, import_vue19.ref)(null);
5389
+ const bundles = (0, import_vue20.ref)([]);
5390
+ const loading = (0, import_vue20.ref)(false);
5391
+ const error = (0, import_vue20.ref)(null);
5290
5392
  const baseUrl = `${options.adminEndpoint}/catalog/bundles`;
5291
5393
  function authHeaders() {
5292
5394
  const token = options.getAuthToken?.();
@@ -5358,9 +5460,9 @@ function useBundleVersions(options) {
5358
5460
  throw new Error("useBundleVersions: `bundleId` is required.");
5359
5461
  }
5360
5462
  const http = options.http ?? defaultHttpClient();
5361
- const versions = (0, import_vue19.ref)([]);
5362
- const loading = (0, import_vue19.ref)(false);
5363
- const error = (0, import_vue19.ref)(null);
5463
+ const versions = (0, import_vue20.ref)([]);
5464
+ const loading = (0, import_vue20.ref)(false);
5465
+ const error = (0, import_vue20.ref)(null);
5364
5466
  const bundleVersionsUrl = `${options.adminEndpoint}/catalog/bundles/${options.bundleId}/versions`;
5365
5467
  const versionUrlBase = `${options.adminEndpoint}/catalog/bundle-versions`;
5366
5468
  function authHeaders() {
@@ -5434,7 +5536,7 @@ function useBundleVersions(options) {
5434
5536
  }
5435
5537
 
5436
5538
  // src/vue/use-bundle-versions-map.ts
5437
- var import_vue20 = require("vue");
5539
+ var import_vue21 = require("vue");
5438
5540
  function useBundleVersionsMap(options) {
5439
5541
  if (!options?.adminEndpoint) {
5440
5542
  throw new Error("useBundleVersionsMap: `adminEndpoint` is required.");
@@ -5443,9 +5545,9 @@ function useBundleVersionsMap(options) {
5443
5545
  throw new Error("useBundleVersionsMap: `bundles` is required.");
5444
5546
  }
5445
5547
  const http = options.http ?? defaultHttpClient();
5446
- const versionsByBundle = (0, import_vue20.ref)({});
5447
- const loading = (0, import_vue20.ref)(false);
5448
- const error = (0, import_vue20.ref)(null);
5548
+ const versionsByBundle = (0, import_vue21.ref)({});
5549
+ const loading = (0, import_vue21.ref)(false);
5550
+ const error = (0, import_vue21.ref)(null);
5449
5551
  function authHeaders() {
5450
5552
  const token = options.getAuthToken?.();
5451
5553
  return token ? { Authorization: `Bearer ${token}` } : {};
@@ -5495,7 +5597,7 @@ function useBundleVersionsMap(options) {
5495
5597
  console.warn(`useBundleVersionsMap: refreshOne('${bundleId}') failed`, err);
5496
5598
  }
5497
5599
  }
5498
- (0, import_vue20.watch)(
5600
+ (0, import_vue21.watch)(
5499
5601
  () => options.bundles.value.map((b) => b.id).join(","),
5500
5602
  () => {
5501
5603
  if (options.bundles.value.length > 0) void refresh();
@@ -5507,7 +5609,7 @@ function useBundleVersionsMap(options) {
5507
5609
  }
5508
5610
 
5509
5611
  // src/vue/use-tenant-subscription-bundles.ts
5510
- var import_vue21 = require("vue");
5612
+ var import_vue22 = require("vue");
5511
5613
  var TenantSubscriptionBundlesApiError = class extends Error {
5512
5614
  constructor(status, body, message) {
5513
5615
  super(message);
@@ -5526,9 +5628,9 @@ function useTenantSubscriptionBundles(options) {
5526
5628
  }
5527
5629
  const http = options.http ?? defaultHttpClient();
5528
5630
  const baseUrl = `${options.billingEndpoint}/billing/subscription-bundles`;
5529
- const bundles = (0, import_vue21.ref)([]);
5530
- const loading = (0, import_vue21.ref)(false);
5531
- const error = (0, import_vue21.ref)(null);
5631
+ const bundles = (0, import_vue22.ref)([]);
5632
+ const loading = (0, import_vue22.ref)(false);
5633
+ const error = (0, import_vue22.ref)(null);
5532
5634
  function authHeaders() {
5533
5635
  const token = options.getAuthToken?.();
5534
5636
  return token ? { Authorization: `Bearer ${token}` } : {};
@@ -5602,7 +5704,7 @@ function rehydrateDates(raw) {
5602
5704
  }
5603
5705
 
5604
5706
  // src/vue/use-marketing-projections.ts
5605
- var import_vue22 = require("vue");
5707
+ var import_vue23 = require("vue");
5606
5708
  var MarketingProjectionsApiError = class extends Error {
5607
5709
  constructor(status, body, message) {
5608
5710
  super(message);
@@ -5622,10 +5724,10 @@ function useMarketingProjections(options) {
5622
5724
  }
5623
5725
  const msg = useSaMessages("marketing");
5624
5726
  const http = options.http ?? defaultHttpClient();
5625
- const projections = (0, import_vue22.ref)([]);
5626
- const filter = (0, import_vue22.ref)({ ...options.filter });
5627
- const loading = (0, import_vue22.ref)(false);
5628
- const error = (0, import_vue22.ref)(null);
5727
+ const projections = (0, import_vue23.ref)([]);
5728
+ const filter = (0, import_vue23.ref)({ ...options.filter });
5729
+ const loading = (0, import_vue23.ref)(false);
5730
+ const error = (0, import_vue23.ref)(null);
5629
5731
  const baseUrl = `${options.adminEndpoint}/catalog/marketing-projections`;
5630
5732
  function authHeaders() {
5631
5733
  const token = options.getAuthToken?.();
@@ -5706,7 +5808,7 @@ function useMarketingProjections(options) {
5706
5808
  }
5707
5809
 
5708
5810
  // src/vue/use-promotions.ts
5709
- var import_vue23 = require("vue");
5811
+ var import_vue24 = require("vue");
5710
5812
  var PromotionsApiError = class extends Error {
5711
5813
  constructor(status, body, message) {
5712
5814
  super(message);
@@ -5726,9 +5828,9 @@ function usePromotions(options) {
5726
5828
  }
5727
5829
  const msg = useSaMessages("promos");
5728
5830
  const http = options.http ?? defaultHttpClient();
5729
- const promotions = (0, import_vue23.ref)([]);
5730
- const loading = (0, import_vue23.ref)(false);
5731
- const error = (0, import_vue23.ref)(null);
5831
+ const promotions = (0, import_vue24.ref)([]);
5832
+ const loading = (0, import_vue24.ref)(false);
5833
+ const error = (0, import_vue24.ref)(null);
5732
5834
  const baseUrl = `${options.adminEndpoint}/catalog/promotions`;
5733
5835
  const pk = encodeURIComponent(options.projectKey);
5734
5836
  function authHeaders() {
@@ -5793,7 +5895,7 @@ function usePromotions(options) {
5793
5895
  }
5794
5896
 
5795
5897
  // src/vue/use-plans.ts
5796
- var import_vue24 = require("vue");
5898
+ var import_vue25 = require("vue");
5797
5899
  var PlansApiError = class extends Error {
5798
5900
  constructor(status, body, message) {
5799
5901
  super(message);
@@ -5814,10 +5916,10 @@ function usePlans(options) {
5814
5916
  throw new Error("usePlans: `projectKey` is required.");
5815
5917
  }
5816
5918
  const http = options.http ?? defaultHttpClient();
5817
- const plans = (0, import_vue24.ref)([]);
5818
- const loading = (0, import_vue24.ref)(false);
5819
- const error = (0, import_vue24.ref)(null);
5820
- const tenantCountsByPlanKey = (0, import_vue24.ref)({});
5919
+ const plans = (0, import_vue25.ref)([]);
5920
+ const loading = (0, import_vue25.ref)(false);
5921
+ const error = (0, import_vue25.ref)(null);
5922
+ const tenantCountsByPlanKey = (0, import_vue25.ref)({});
5821
5923
  const baseUrl = `${options.adminEndpoint}/catalog/plans`;
5822
5924
  function authHeaders() {
5823
5925
  const token = options.getAuthToken?.();
@@ -5918,9 +6020,9 @@ function usePlanVersions(options) {
5918
6020
  throw new Error("usePlanVersions: `planId` is required.");
5919
6021
  }
5920
6022
  const http = options.http ?? defaultHttpClient();
5921
- const versions = (0, import_vue24.ref)([]);
5922
- const loading = (0, import_vue24.ref)(false);
5923
- const error = (0, import_vue24.ref)(null);
6023
+ const versions = (0, import_vue25.ref)([]);
6024
+ const loading = (0, import_vue25.ref)(false);
6025
+ const error = (0, import_vue25.ref)(null);
5924
6026
  const planVersionsUrl = `${options.adminEndpoint}/catalog/plans/${options.planId}/versions`;
5925
6027
  const versionUrlBase = `${options.adminEndpoint}/catalog/plan-versions`;
5926
6028
  function authHeaders() {
@@ -6017,7 +6119,7 @@ function usePlanVersions(options) {
6017
6119
  }
6018
6120
 
6019
6121
  // src/vue/use-live-plan-versions.ts
6020
- var import_vue25 = require("vue");
6122
+ var import_vue26 = require("vue");
6021
6123
  function useLivePlanVersions(options) {
6022
6124
  if (!options?.adminEndpoint) {
6023
6125
  throw new Error("useLivePlanVersions: `adminEndpoint` is required.");
@@ -6026,9 +6128,9 @@ function useLivePlanVersions(options) {
6026
6128
  throw new Error("useLivePlanVersions: `plans` is required.");
6027
6129
  }
6028
6130
  const http = options.http ?? defaultHttpClient();
6029
- const livePlanVersions = (0, import_vue25.ref)({});
6030
- const loading = (0, import_vue25.ref)(false);
6031
- const error = (0, import_vue25.ref)(null);
6131
+ const livePlanVersions = (0, import_vue26.ref)({});
6132
+ const loading = (0, import_vue26.ref)(false);
6133
+ const error = (0, import_vue26.ref)(null);
6032
6134
  function authHeaders() {
6033
6135
  const token = options.getAuthToken?.();
6034
6136
  return token ? { Authorization: `Bearer ${token}` } : {};
@@ -6070,7 +6172,7 @@ function useLivePlanVersions(options) {
6070
6172
  loading.value = false;
6071
6173
  }
6072
6174
  }
6073
- (0, import_vue25.watch)(
6175
+ (0, import_vue26.watch)(
6074
6176
  () => options.plans.value.map((p) => p.id).join(","),
6075
6177
  () => {
6076
6178
  if (options.plans.value.length > 0) void refresh();
@@ -6092,12 +6194,12 @@ function findLatestLive(versions) {
6092
6194
  }
6093
6195
 
6094
6196
  // src/vue/use-manifest.ts
6095
- var import_vue26 = require("vue");
6197
+ var import_vue27 = require("vue");
6096
6198
  function useManifest(options) {
6097
6199
  const loader = new ManifestLoader(options);
6098
- const manifest = (0, import_vue26.ref)(null);
6099
- const loading = (0, import_vue26.ref)(false);
6100
- const error = (0, import_vue26.ref)(null);
6200
+ const manifest = (0, import_vue27.ref)(null);
6201
+ const loading = (0, import_vue27.ref)(false);
6202
+ const error = (0, import_vue27.ref)(null);
6101
6203
  async function load() {
6102
6204
  loading.value = true;
6103
6205
  error.value = null;
@@ -6123,24 +6225,24 @@ function useManifest(options) {
6123
6225
  }
6124
6226
 
6125
6227
  // src/vue/use-nav.ts
6126
- var import_vue27 = require("vue");
6228
+ var import_vue28 = require("vue");
6127
6229
  function useNav(manifest, options = {}) {
6128
6230
  const { locale } = useSuperAdminI18n();
6129
- const activeLocale = (0, import_vue27.computed)(() => options.locale ?? locale.value);
6130
- const routes = (0, import_vue27.computed)(() => {
6231
+ const activeLocale = (0, import_vue28.computed)(() => options.locale ?? locale.value);
6232
+ const routes = (0, import_vue28.computed)(() => {
6131
6233
  if (!manifest.value) return [];
6132
6234
  return buildRoutes(manifest.value, { ...options, locale: activeLocale.value });
6133
6235
  });
6134
- const sidebar = (0, import_vue27.computed)(
6236
+ const sidebar = (0, import_vue28.computed)(
6135
6237
  () => buildSidebar(routes.value, defaultSectionOrder(activeLocale.value))
6136
6238
  );
6137
6239
  return { routes, sidebar };
6138
6240
  }
6139
6241
 
6140
6242
  // src/vue/use-actions.ts
6141
- var import_vue28 = require("vue");
6243
+ var import_vue29 = require("vue");
6142
6244
  function useActions(manifest, actions) {
6143
- const registry = (0, import_vue28.computed)(() => {
6245
+ const registry = (0, import_vue29.computed)(() => {
6144
6246
  if (!manifest.value) return null;
6145
6247
  return new ActionRegistry(manifest.value, actions);
6146
6248
  });
@@ -6148,18 +6250,18 @@ function useActions(manifest, actions) {
6148
6250
  }
6149
6251
 
6150
6252
  // src/vue/use-tenant-action-flow.ts
6151
- var import_vue29 = require("vue");
6253
+ var import_vue30 = require("vue");
6152
6254
  function useTenantActionFlow(manifest, providers = {}) {
6153
6255
  const handlers = useSuperAdminActions();
6154
6256
  const msg = useSaMessages("tenants");
6155
- const registry = (0, import_vue29.computed)(() => {
6257
+ const registry = (0, import_vue30.computed)(() => {
6156
6258
  if (!manifest.value) return null;
6157
6259
  return new ActionRegistry(manifest.value, handlers);
6158
6260
  });
6159
- const orphanedDefs = (0, import_vue29.computed)(
6261
+ const orphanedDefs = (0, import_vue30.computed)(
6160
6262
  () => registry.value ? registry.value.listOrphanedDefs() : []
6161
6263
  );
6162
- const availableActions = (0, import_vue29.computed)(() => {
6264
+ const availableActions = (0, import_vue30.computed)(() => {
6163
6265
  const m = manifest.value;
6164
6266
  const reg = registry.value;
6165
6267
  if (!m || !reg) return [];
@@ -6232,7 +6334,7 @@ async function runFlow(def, row, registry, providers, successTemplate) {
6232
6334
  }
6233
6335
 
6234
6336
  // src/vue/use-platform-tenant-actions.ts
6235
- var import_vue30 = require("vue");
6337
+ var import_vue31 = require("vue");
6236
6338
  var DEFAULT_VISIBLE_FOR_ROW = (def, row) => {
6237
6339
  if (def.actionKey === "tenants.suspend") return row.isActive;
6238
6340
  if (def.actionKey === "tenants.reactivate") return !row.isActive;
@@ -6268,7 +6370,7 @@ function usePlatformTenantActions(options) {
6268
6370
  const iconForActionKey = options.iconForActionKey ?? DEFAULT_ICON_FOR_ACTION_KEY;
6269
6371
  const toneForActionKey = options.toneForActionKey ?? DEFAULT_TONE_FOR_ACTION_KEY;
6270
6372
  const visibleForRow = options.visibleForRow ?? DEFAULT_VISIBLE_FOR_ROW;
6271
- const mfa = (0, import_vue30.ref)({ show: false, description: "", error: "" });
6373
+ const mfa = (0, import_vue31.ref)({ show: false, description: "", error: "" });
6272
6374
  let pendingMfaResolve = null;
6273
6375
  function showMfaDialog(def, ctx) {
6274
6376
  return new Promise((resolve) => {
@@ -6293,7 +6395,7 @@ function usePlatformTenantActions(options) {
6293
6395
  pendingMfaResolve(null);
6294
6396
  }
6295
6397
  }
6296
- const confirmDialog = (0, import_vue30.ref)({
6398
+ const confirmDialog = (0, import_vue31.ref)({
6297
6399
  show: false,
6298
6400
  def: null,
6299
6401
  row: null
@@ -6335,7 +6437,7 @@ function usePlatformTenantActions(options) {
6335
6437
  },
6336
6438
  visibleForRow
6337
6439
  });
6338
- const manifestActions = (0, import_vue30.computed)(
6440
+ const manifestActions = (0, import_vue31.computed)(
6339
6441
  () => flow.availableActions.value.map((def) => ({
6340
6442
  id: def.id,
6341
6443
  label: def.label,
@@ -6349,7 +6451,7 @@ function usePlatformTenantActions(options) {
6349
6451
  }
6350
6452
  }))
6351
6453
  );
6352
- const realOrphans = (0, import_vue30.computed)(() => {
6454
+ const realOrphans = (0, import_vue31.computed)(() => {
6353
6455
  const caps = options.manifest.value?.capabilities ?? {};
6354
6456
  const defs = options.manifest.value?.tenants?.actions ?? [];
6355
6457
  const defByActionKey = new Map(defs.map((d) => [d.actionKey, d]));
@@ -6374,12 +6476,12 @@ function usePlatformTenantActions(options) {
6374
6476
  }
6375
6477
 
6376
6478
  // src/vue/use-batch-columns.ts
6377
- var import_vue31 = require("vue");
6479
+ var import_vue32 = require("vue");
6378
6480
  function useBatchColumns(manifest, tenantIds, options = {}) {
6379
6481
  const fetcher = new BatchColumnFetcher(options);
6380
- const data = (0, import_vue31.ref)({});
6381
- const loading = (0, import_vue31.ref)(false);
6382
- const error = (0, import_vue31.ref)(null);
6482
+ const data = (0, import_vue32.ref)({});
6483
+ const loading = (0, import_vue32.ref)(false);
6484
+ const error = (0, import_vue32.ref)(null);
6383
6485
  async function load() {
6384
6486
  if (!manifest.value || tenantIds.value.length === 0) {
6385
6487
  data.value = {};
@@ -6396,7 +6498,7 @@ function useBatchColumns(manifest, tenantIds, options = {}) {
6396
6498
  loading.value = false;
6397
6499
  }
6398
6500
  }
6399
- (0, import_vue31.watch)([manifest, tenantIds], () => {
6501
+ (0, import_vue32.watch)([manifest, tenantIds], () => {
6400
6502
  void load();
6401
6503
  });
6402
6504
  return { data, loading, error, reload: load };
@@ -6428,13 +6530,13 @@ function createPlatformLoaders(options) {
6428
6530
 
6429
6531
  // src/vue/manifest-store-factory.ts
6430
6532
  var import_pinia = require("pinia");
6431
- var import_vue32 = require("vue");
6533
+ var import_vue33 = require("vue");
6432
6534
  function createManifestStore(options) {
6433
6535
  return (0, import_pinia.defineStore)(options.id ?? "admin-manifest", () => {
6434
- const manifest = (0, import_vue32.ref)(null);
6435
- const loading = (0, import_vue32.ref)(false);
6436
- const error = (0, import_vue32.ref)(null);
6437
- const loaded = (0, import_vue32.ref)(false);
6536
+ const manifest = (0, import_vue33.ref)(null);
6537
+ const loading = (0, import_vue33.ref)(false);
6538
+ const error = (0, import_vue33.ref)(null);
6539
+ const loaded = (0, import_vue33.ref)(false);
6438
6540
  let inflight = null;
6439
6541
  async function load() {
6440
6542
  loading.value = true;
@@ -6812,6 +6914,55 @@ var DEFAULT_I18N_EN = {
6812
6914
  function defaultTenantPlanSectionI18n(locale) {
6813
6915
  return locale === "en" ? DEFAULT_I18N_EN : DEFAULT_I18N_DE;
6814
6916
  }
6917
+ function planChangeWizardI18n(i18n) {
6918
+ return {
6919
+ title: i18n.wizardTitle,
6920
+ close: i18n.wizardClose,
6921
+ currentLabel: i18n.wizardCurrent,
6922
+ cycleMonthly: i18n.cycleMonthly,
6923
+ cycleYearly: i18n.cycleYearly,
6924
+ badgeCurrent: i18n.wizardBadgeCurrent,
6925
+ badgePopular: i18n.wizardBadgePopular,
6926
+ priceUnitMonthly: i18n.wizardPriceUnitMonthly,
6927
+ priceUnitYearly: i18n.wizardPriceUnitYearly,
6928
+ priceOnRequest: i18n.wizardPriceOnRequest,
6929
+ stepChoose: i18n.wizardStepChoose,
6930
+ stepChooseIntro: i18n.wizardStepChooseIntro,
6931
+ stepPreview: i18n.wizardStepPreview,
6932
+ stepConfirm: i18n.wizardStepConfirm,
6933
+ next: i18n.wizardNext,
6934
+ back: i18n.wizardBack,
6935
+ previewLoading: i18n.wizardPreviewLoading,
6936
+ effectiveAtLabel: i18n.wizardEffectiveAtLabel,
6937
+ effectiveImmediate: i18n.wizardEffectiveImmediate,
6938
+ prorationTitle: i18n.wizardProrationTitle,
6939
+ prorationLine: i18n.wizardProrationLine,
6940
+ prorationDays: i18n.wizardProrationDays,
6941
+ limitsTitle: i18n.wizardLimitsTitle,
6942
+ limitsUsed: i18n.wizardLimitsUsed,
6943
+ limitsCurrent: i18n.wizardLimitsCurrent,
6944
+ limitsTarget: i18n.wizardLimitsTarget,
6945
+ featuresGained: i18n.wizardFeaturesGained,
6946
+ featuresLost: i18n.wizardFeaturesLost,
6947
+ blockersTitle: i18n.wizardBlockersTitle,
6948
+ confirmImmediate: i18n.wizardConfirmImmediate,
6949
+ confirmScheduled: i18n.wizardConfirmScheduled,
6950
+ confirmAction: i18n.wizardConfirmAction,
6951
+ confirmInProgress: i18n.wizardConfirmInProgress,
6952
+ confirmPriceTitle: i18n.wizardConfirmPriceTitle,
6953
+ confirmProratedNow: i18n.wizardConfirmProratedNow,
6954
+ confirmRecurringNext: i18n.wizardConfirmRecurringNext,
6955
+ confirmRecurringFrom: i18n.wizardConfirmRecurringFrom,
6956
+ perCycleMonthly: i18n.wizardConfirmPerCycleMonthly,
6957
+ perCycleYearly: i18n.wizardConfirmPerCycleYearly,
6958
+ confirmTrialNote: i18n.wizardConfirmTrialNote,
6959
+ confirmRecurringTrialEnd: i18n.wizardConfirmRecurringTrialEnd,
6960
+ changeTypeUpgrade: i18n.wizardChangeTypeUpgrade,
6961
+ changeTypeDowngrade: i18n.wizardChangeTypeDowngrade,
6962
+ changeTypeCycle: i18n.wizardChangeTypeCycle,
6963
+ changeTypeNoop: i18n.wizardChangeTypeNoop
6964
+ };
6965
+ }
6815
6966
  // Annotate the CommonJS export names for ESM import in node:
6816
6967
  0 && (module.exports = {
6817
6968
  ADMIN_UI_VERSION,
@@ -6834,6 +6985,10 @@ function defaultTenantPlanSectionI18n(locale) {
6834
6985
  DiscoveryLoadError,
6835
6986
  ENTITLEMENT_INJECTION_KEY,
6836
6987
  HttpJsonError,
6988
+ IDENTITY_ACCENTS,
6989
+ IDENTITY_ACCENT_VALUES,
6990
+ IDENTITY_NEUTRAL,
6991
+ IDENTITY_NEUTRAL_VALUE,
6837
6992
  ManifestLoadError,
6838
6993
  ManifestLoader,
6839
6994
  MarketingProjectionsApiError,
@@ -6848,6 +7003,7 @@ function defaultTenantPlanSectionI18n(locale) {
6848
7003
  SA_LOCALE_LABELS,
6849
7004
  SA_LOCALE_STORAGE_KEY,
6850
7005
  SA_MESSAGES,
7006
+ SA_THEME_KEY,
6851
7007
  SERVER_PAGE_SIZE_OPTIONS,
6852
7008
  SUPER_ADMIN_ACTIONS_KEY,
6853
7009
  SUPER_ADMIN_BRAND_KEY,
@@ -6873,6 +7029,7 @@ function defaultTenantPlanSectionI18n(locale) {
6873
7029
  createPlatformLoaders,
6874
7030
  createProjectPageHostRoute,
6875
7031
  createSaCatalog,
7032
+ createSaTheme,
6876
7033
  createSuperAdminI18n,
6877
7034
  defaultHttpClient,
6878
7035
  defaultIconForActionKey,
@@ -6884,12 +7041,16 @@ function defaultTenantPlanSectionI18n(locale) {
6884
7041
  formatCurrency,
6885
7042
  formatMessage,
6886
7043
  getJson,
7044
+ identityAccentAt,
7045
+ identityAccentFor,
7046
+ identityChipStyle,
6887
7047
  isCurrentlyValid,
6888
7048
  isExpired,
6889
7049
  isFutureScheduled,
6890
7050
  isProductionBoot,
6891
7051
  isSaBuiltinLocale,
6892
7052
  mergeMessages,
7053
+ planChangeWizardI18n,
6893
7054
  postJson,
6894
7055
  provideEntitlement,
6895
7056
  resolveExtension,
@@ -6922,6 +7083,7 @@ function defaultTenantPlanSectionI18n(locale) {
6922
7083
  usePromotions,
6923
7084
  usePublicBoot,
6924
7085
  useSaMessages,
7086
+ useSaTheme,
6925
7087
  useSubscriptionDraft,
6926
7088
  useSuperAdminActions,
6927
7089
  useSuperAdminBrand,