@saasicat/ui-vue 0.4.0 → 0.6.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 (214) hide show
  1. package/README.md +64 -4
  2. package/dist/chunk-A3W2N26K.js +714 -0
  3. package/dist/chunk-QZOSDCNP.js +98 -0
  4. package/dist/chunk-X5SQ5HMB.js +3231 -0
  5. package/dist/client/index.cjs +3988 -0
  6. package/dist/client/index.d.cts +321 -0
  7. package/dist/client/index.d.ts +321 -0
  8. package/dist/client/index.js +70 -0
  9. package/dist/index.cjs +4446 -1249
  10. package/dist/index.d.cts +297 -888
  11. package/dist/index.d.ts +297 -888
  12. package/dist/index.js +609 -1348
  13. package/dist/messages-7b0P8W75.d.cts +1652 -0
  14. package/dist/messages-7b0P8W75.d.ts +1652 -0
  15. package/dist/quasar/index.cjs +3340 -0
  16. package/dist/quasar/index.d.cts +95 -0
  17. package/dist/quasar/index.d.ts +95 -0
  18. package/dist/quasar/index.js +96 -0
  19. package/dist/testing-e2e/admin-pages-suite.cjs +14 -11
  20. package/dist/testing-e2e/admin-pages-suite.js +14 -11
  21. package/dist/use-super-admin-i18n-B3v3-SWZ.d.ts +210 -0
  22. package/dist/use-super-admin-i18n-DMktRVEt.d.cts +210 -0
  23. package/package.json +23 -3
  24. package/src/{action-registry.ts → client/action-registry.ts} +4 -4
  25. package/src/{batch-column-fetcher.ts → client/batch-column-fetcher.ts} +4 -4
  26. package/src/{boot-loader.ts → client/boot-loader.ts} +3 -3
  27. package/src/client/i18n/currency.ts +42 -0
  28. package/src/client/i18n/define.ts +59 -0
  29. package/src/client/i18n/format.ts +12 -0
  30. package/src/client/i18n/index.ts +14 -0
  31. package/src/client/i18n/locale.ts +15 -0
  32. package/src/client/i18n/messages/audit.ts +42 -0
  33. package/src/client/i18n/messages/bundles.ts +459 -0
  34. package/src/client/i18n/messages/common.ts +147 -0
  35. package/src/client/i18n/messages/dashboard.ts +16 -0
  36. package/src/client/i18n/messages/discovery.ts +229 -0
  37. package/src/client/i18n/messages/email.ts +125 -0
  38. package/src/client/i18n/messages/marketing.ts +270 -0
  39. package/src/client/i18n/messages/nav.ts +72 -0
  40. package/src/client/i18n/messages/pilots.ts +192 -0
  41. package/src/client/i18n/messages/plan-detail.ts +266 -0
  42. package/src/client/i18n/messages/plan-editor.ts +177 -0
  43. package/src/client/i18n/messages/plan-versions.ts +251 -0
  44. package/src/client/i18n/messages/plans.ts +503 -0
  45. package/src/client/i18n/messages/promos.ts +202 -0
  46. package/src/client/i18n/messages/shell.ts +145 -0
  47. package/src/client/i18n/messages/tenants.ts +104 -0
  48. package/src/client/i18n/messages/users.ts +78 -0
  49. package/src/client/i18n/messages.ts +84 -0
  50. package/src/client/index.ts +27 -0
  51. package/src/{manifest-loader.ts → client/manifest-loader.ts} +4 -4
  52. package/src/{nav-builder.ts → client/nav-builder.ts} +44 -51
  53. package/src/{plan-versions-catalog.ts → client/plan-versions-catalog.ts} +42 -30
  54. package/src/components/BundleVersionPublishDialog.vue +35 -24
  55. package/src/components/FeatureGate.vue +1 -1
  56. package/src/components/MarketingPromotionsTab.vue +112 -59
  57. package/src/components/MfaPromptDialog.vue +11 -11
  58. package/src/components/TenantActionConfirmDialog.vue +19 -17
  59. package/src/components/VersionDiffPreview.vue +72 -43
  60. package/src/components/bundle-editor/BundleCreatePanel.vue +76 -63
  61. package/src/components/bundle-editor/BundleFeaturesEditor.vue +13 -6
  62. package/src/components/bundle-editor/BundlePlanCompatPicker.vue +19 -14
  63. package/src/components/bundle-editor/BundleQuotasEditor.vue +7 -4
  64. package/src/components/bundle-editor/BundleStatusBanner.vue +36 -19
  65. package/src/components/bundle-editor/BundleVersionInlineEditor.vue +51 -35
  66. package/src/components/bundle-editor/BundleVersionStrip.vue +24 -12
  67. package/src/components/bundle-editor/bundle-version-status.ts +29 -29
  68. package/src/components/dialogs/PilotCreateDialog.vue +58 -63
  69. package/src/components/dialogs/PilotEditDialog.vue +40 -34
  70. package/src/components/dialogs/PromoCodeCreateDialog.vue +89 -63
  71. package/src/components/dialogs/PromoCodeEditDialog.vue +98 -66
  72. package/src/components/dialogs/types.ts +3 -13
  73. package/src/components/plan/PlanCycleToggle.vue +21 -10
  74. package/src/components/plan/PlanGrid.vue +2 -2
  75. package/src/components/plan/PriceSummary.vue +1 -1
  76. package/src/components/plan/PromoCodeInput.vue +1 -1
  77. package/src/components/plan/PublicBundleGrid.vue +1 -1
  78. package/src/components/plan-cockpit/PlanCockpit.vue +34 -15
  79. package/src/components/plan-cockpit/PlanCockpitAuditLog.vue +13 -6
  80. package/src/components/plan-cockpit/PlanCockpitDiffPanel.vue +18 -9
  81. package/src/components/plan-cockpit/PlanCockpitHeader.vue +9 -6
  82. package/src/components/plan-cockpit/PlanCockpitImpactPanel.vue +24 -11
  83. package/src/components/plan-cockpit/PlanCockpitKpis.vue +28 -17
  84. package/src/components/plan-cockpit/PlanCockpitVersions.vue +50 -25
  85. package/src/components/plan-create-dialog/PlanCreateDialog.vue +45 -35
  86. package/src/components/plan-detail/PlanAuditLog.vue +11 -6
  87. package/src/components/plan-detail/PlanDetail.vue +21 -23
  88. package/src/components/plan-detail/PlanDetailHeader.vue +20 -11
  89. package/src/components/plan-detail/PlanDetailKpis.vue +30 -17
  90. package/src/components/plan-detail/PlanTerminateDialog.vue +22 -9
  91. package/src/components/plan-detail/PlanVersionDiffPanel.vue +61 -27
  92. package/src/components/plan-detail/PlanVersionsPanel.vue +71 -36
  93. package/src/components/plan-list/PlanList.vue +99 -57
  94. package/src/components/plan-matrix/PlanMatrix.vue +85 -38
  95. package/src/components/plan-review/PlanReview.vue +105 -80
  96. package/src/components/plan-version-editor/PlanCatalogPreview.vue +43 -20
  97. package/src/components/plan-version-editor/PlanComponentPool.vue +15 -7
  98. package/src/components/plan-version-editor/PlanVersionBasket.vue +45 -24
  99. package/src/components/plan-version-editor/PlanVersionDiffDialog.vue +8 -7
  100. package/src/components/plan-version-editor/PlanVersionEditor.vue +74 -40
  101. package/src/components/plan-version-editor/PlanVersionEditorHeader.vue +24 -12
  102. package/src/index.ts +82 -79
  103. package/src/pages-standard/AdminLayout.vue +43 -18
  104. package/src/pages-standard/AdminManifestErrorPage.vue +10 -10
  105. package/src/pages-standard/AuditPage.vue +58 -19
  106. package/src/pages-standard/BundlesPage.vue +29 -18
  107. package/src/pages-standard/DashboardPage.vue +31 -17
  108. package/src/pages-standard/DiscoveryPage.vue +40 -28
  109. package/src/pages-standard/EmailHistoryPage.vue +98 -69
  110. package/src/pages-standard/MarketingCatalogPage.vue +40 -21
  111. package/src/pages-standard/PilotsPage.vue +64 -52
  112. package/src/pages-standard/PlanVersionsPage.vue +9 -5
  113. package/src/pages-standard/PlansPage.vue +91 -59
  114. package/src/pages-standard/PlatformEmailPage.vue +120 -53
  115. package/src/pages-standard/PromoCodeDetailPage.vue +66 -63
  116. package/src/pages-standard/PromoCodesPage.vue +51 -54
  117. package/src/pages-standard/SubscriptionsPage.vue +14 -9
  118. package/src/pages-standard/SuperAdminLoginPage.vue +19 -16
  119. package/src/pages-standard/SuperAdminSetupWizard.vue +53 -49
  120. package/src/pages-standard/TenantDetailPage.vue +54 -40
  121. package/src/pages-standard/TenantsPage.vue +57 -44
  122. package/src/pages-standard/UsersPage.vue +70 -52
  123. package/src/pages-standard/bundles-page/BundleAccordionList.vue +20 -8
  124. package/src/pages-standard/bundles-page/BundleDetailPanel.vue +28 -18
  125. package/src/pages-standard/bundles-page/BundlesFilterBar.vue +4 -1
  126. package/src/pages-standard/bundles-page/BundlesHeader.vue +9 -8
  127. package/src/pages-standard/bundles-page/BundlesKpis.vue +29 -11
  128. package/src/pages-standard/discovery-page/CatalogEntryTransPanel.vue +20 -8
  129. package/src/pages-standard/discovery-page/DiscoveryCapList.vue +5 -3
  130. package/src/pages-standard/discovery-page/DiscoveryFeatureCard.vue +43 -24
  131. package/src/pages-standard/discovery-page/DiscoveryHeader.vue +7 -4
  132. package/src/pages-standard/discovery-page/DiscoveryKpis.vue +28 -15
  133. package/src/pages-standard/discovery-page/DiscoveryQuotaCard.vue +20 -10
  134. package/src/pages-standard/discovery-page/DiscoveryStatusControl.vue +9 -6
  135. package/src/pages-standard/discovery-page/discovery-ui.ts +40 -52
  136. package/src/pages-standard/marketing-catalog/MarketingCatalogAdmin.vue +81 -49
  137. package/src/pages-standard/marketing-catalog/MarketingCatalogHeader.vue +13 -10
  138. package/src/pages-standard/marketing-catalog/MarketingCatalogPreview.vue +24 -20
  139. package/src/pages-standard/marketing-catalog/MarketingCatalogToolbar.vue +6 -3
  140. package/src/pages-standard/plan-versions/PlanDiffCard.vue +16 -6
  141. package/src/pages-standard/plan-versions/PlanVersionHeader.vue +42 -26
  142. package/src/pages-standard/plan-versions/PlanVersionsAudit.vue +46 -27
  143. package/src/pages-standard/plan-versions/PlanVersionsDiff.vue +8 -6
  144. package/src/pages-standard/plan-versions/PlanVersionsList.vue +40 -17
  145. package/src/pages-standard/plan-versions/PlanVersionsMatrix.vue +1 -1
  146. package/src/pages-standard/plan-versions/PlanVersionsTimeline.vue +25 -13
  147. package/src/pages-standard/plan-versions/format.ts +33 -17
  148. package/src/pages-standard/plans-page/PlanArchiveDialog.vue +12 -8
  149. package/src/pages-standard/plans-page/PlanBundleOverview.vue +15 -6
  150. package/src/pages-standard/plans-page/PlanDiscardDraftDialog.vue +18 -7
  151. package/src/pages-standard/plans-page/PlanPublishDialog.vue +23 -12
  152. package/src/pages-standard/tenants/format.ts +3 -2
  153. package/src/pages-tenant/MySubscriptionBundlesPage.vue +73 -38
  154. package/src/pages-tenant/OnboardingConfigurator.vue +3 -3
  155. package/src/pages-tenant/PackageSnapshotPanel.vue +1 -1
  156. package/src/pages-tenant/PlanChangeWizard.vue +10 -6
  157. package/src/pages-tenant/TenantPlanSection.vue +20 -16
  158. package/src/pages-tenant/default-i18n.ts +217 -1
  159. package/src/pages-tenant/tenant-plan-section/BundlePreviewDialog.vue +9 -7
  160. package/src/pages-tenant/tenant-plan-section/TenantBundleStore.vue +11 -12
  161. package/src/pages-tenant/tenant-plan-section/TenantFeatureMatrix.vue +4 -1
  162. package/src/pages-tenant/tenant-plan-section/TenantPlanCardHeader.vue +1 -1
  163. package/src/pages-tenant/tenant-plan-section/TenantUsageGrid.vue +1 -1
  164. package/src/quasar/create-super-admin-app.ts +192 -0
  165. package/src/quasar/index.ts +11 -0
  166. package/src/quasar/notify.ts +30 -0
  167. package/src/testing-e2e/admin-pages-suite.ts +14 -11
  168. package/src/{manifest-store-factory.ts → vue/manifest-store-factory.ts} +1 -1
  169. package/src/{platform-loaders.ts → vue/platform-loaders.ts} +4 -4
  170. package/src/{project-page-host.ts → vue/project-page-host.ts} +6 -4
  171. package/src/{create-super-admin-app.ts → vue/super-admin-context.ts} +20 -139
  172. package/src/vue/ui-notify.ts +30 -0
  173. package/src/{use-actions.ts → vue/use-actions.ts} +1 -1
  174. package/src/{use-api-list.ts → vue/use-api-list.ts} +1 -1
  175. package/src/{use-audit-entries.ts → vue/use-audit-entries.ts} +3 -3
  176. package/src/{use-batch-columns.ts → vue/use-batch-columns.ts} +1 -1
  177. package/src/{use-bulk-publish.ts → vue/use-bulk-publish.ts} +7 -5
  178. package/src/{use-bundle-versions-map.ts → vue/use-bundle-versions-map.ts} +7 -5
  179. package/src/{use-bundles.ts → vue/use-bundles.ts} +14 -14
  180. package/src/{use-catalog-entries.ts → vue/use-catalog-entries.ts} +14 -11
  181. package/src/{use-discovery.ts → vue/use-discovery.ts} +9 -6
  182. package/src/{use-entitlement.ts → vue/use-entitlement.ts} +4 -4
  183. package/src/{use-live-plan-versions.ts → vue/use-live-plan-versions.ts} +5 -5
  184. package/src/{use-manifest.ts → vue/use-manifest.ts} +1 -1
  185. package/src/{use-marketing-projections.ts → vue/use-marketing-projections.ts} +10 -7
  186. package/src/{use-nav.ts → vue/use-nav.ts} +9 -3
  187. package/src/{use-plan-editor.ts → vue/use-plan-editor.ts} +2 -2
  188. package/src/{use-plan-versions.ts → vue/use-plan-versions.ts} +3 -3
  189. package/src/{use-plans.ts → vue/use-plans.ts} +13 -13
  190. package/src/{use-platform-tenant-actions.ts → vue/use-platform-tenant-actions.ts} +9 -6
  191. package/src/{use-promotions.ts → vue/use-promotions.ts} +10 -11
  192. package/src/{use-public-boot.ts → vue/use-public-boot.ts} +1 -1
  193. package/src/{use-subscription-draft.ts → vue/use-subscription-draft.ts} +2 -3
  194. package/src/{use-super-admin-context.ts → vue/use-super-admin-context.ts} +5 -5
  195. package/src/vue/use-super-admin-i18n.ts +82 -0
  196. package/src/{use-tenant-action-flow.ts → vue/use-tenant-action-flow.ts} +12 -7
  197. package/src/{use-tenant-billing-catalog.ts → vue/use-tenant-billing-catalog.ts} +2 -2
  198. package/src/{use-tenant-billing.ts → vue/use-tenant-billing.ts} +2 -2
  199. package/src/{use-tenant-manifest.ts → vue/use-tenant-manifest.ts} +2 -4
  200. package/src/{use-tenant-subscription-bundles.ts → vue/use-tenant-subscription-bundles.ts} +5 -5
  201. package/src/{use-tenants.ts → vue/use-tenants.ts} +3 -3
  202. package/dist/testing-e2e/admin-pages-suite.d.cts +0 -37
  203. package/dist/testing-e2e/admin-pages-suite.d.ts +0 -37
  204. package/src/components/BusinessTypeVersionEditorDialog.vue +0 -417
  205. package/src/components/BusinessTypeVersionPublishDialog.vue +0 -258
  206. package/src/pages-standard/BusinessTypesPage.vue +0 -662
  207. package/src/pages-standard/plan-versions/VersionDiffPreview.vue +0 -167
  208. package/src/use-business-types.ts +0 -269
  209. /package/src/{http-json.ts → client/http-json.ts} +0 -0
  210. /package/src/{types.ts → client/types.ts} +0 -0
  211. /package/src/{version.ts → client/version.ts} +0 -0
  212. /package/src/{create-admin-routes.ts → vue/create-admin-routes.ts} +0 -0
  213. /package/src/{entitlement-provider.ts → vue/entitlement-provider.ts} +0 -0
  214. /package/src/{feature-router-guard.ts → vue/feature-router-guard.ts} +0 -0
@@ -0,0 +1,82 @@
1
+ // Reactive i18n context for the SuperAdmin shell. `createSuperAdminApp()`
2
+ // provides one instance; pages, components and composables read it via
3
+ // `useSuperAdminI18n()` or the namespace-focused `useSaMessages()`.
4
+ //
5
+ // Design: no vue-i18n dependency. The platform ships complete typed catalogs
6
+ // (`SA_MESSAGES`, German reference + English translation) and consumers switch
7
+ // the locale or override individual strings through the bootstrap option.
8
+ // Without a provider the composables fall back to a shared German instance, so
9
+ // isolated mounts and unit tests need no setup.
10
+
11
+ import { computed, inject, isRef, ref, type ComputedRef, type InjectionKey, type Ref } from 'vue';
12
+
13
+ import {
14
+ DEFAULT_SA_LOCALE,
15
+ SA_INTL_LOCALES,
16
+ resolveMessages,
17
+ type SaLocale,
18
+ type SaMessages,
19
+ type SaMessagesOverrides,
20
+ } from '../client/i18n/index.js';
21
+
22
+ export interface SuperAdminI18n {
23
+ /** Active UI locale — mutable; switching re-renders all catalog texts. */
24
+ locale: Ref<SaLocale>;
25
+ /** Resolved catalog for the active locale (platform + app overrides). */
26
+ messages: ComputedRef<SaMessages>;
27
+ /** BCP-47 tag for `Intl`/`toLocaleString` formatting in the active locale. */
28
+ intlLocale: ComputedRef<string>;
29
+ }
30
+
31
+ export interface SuperAdminI18nOptions {
32
+ /**
33
+ * Initial UI locale, default `'de'`. Pass a `Ref` when the app wants to
34
+ * keep control (e.g. a user-profile setting or a header switcher).
35
+ */
36
+ locale?: SaLocale | Ref<SaLocale>;
37
+ /** Per-locale string overrides layered over the platform catalog. */
38
+ overrides?: Partial<Record<SaLocale, SaMessagesOverrides>>;
39
+ }
40
+
41
+ // `Symbol.for` — see super-admin-context.ts: dist- and src-imported module
42
+ // instances must resolve to the same injection key.
43
+ export const SUPER_ADMIN_I18N_KEY: InjectionKey<SuperAdminI18n> = Symbol.for(
44
+ '@saasicat/ui-vue/SUPER_ADMIN_I18N',
45
+ );
46
+
47
+ export function createSuperAdminI18n(options: SuperAdminI18nOptions = {}): SuperAdminI18n {
48
+ const locale = isRef(options.locale)
49
+ ? options.locale
50
+ : ref(options.locale ?? DEFAULT_SA_LOCALE);
51
+ const messages = computed(() =>
52
+ resolveMessages(locale.value, options.overrides?.[locale.value]),
53
+ );
54
+ const intlLocale = computed(() => SA_INTL_LOCALES[locale.value]);
55
+ return { locale, messages, intlLocale };
56
+ }
57
+
58
+ let fallbackI18n: SuperAdminI18n | null = null;
59
+
60
+ /**
61
+ * Returns the i18n context provided by `createSuperAdminApp()`. Outside a
62
+ * shell (isolated mounts, tests) a shared German default instance is returned
63
+ * so callers never have to guard for a missing context.
64
+ */
65
+ export function useSuperAdminI18n(): SuperAdminI18n {
66
+ const injected = inject(SUPER_ADMIN_I18N_KEY, null);
67
+ if (injected) return injected;
68
+ fallbackI18n ??= createSuperAdminI18n();
69
+ return fallbackI18n;
70
+ }
71
+
72
+ /**
73
+ * Focused accessor for one catalog namespace:
74
+ * `const msg = useSaMessages('plans')` → `msg.value.title` /
75
+ * template `msg.title`.
76
+ */
77
+ export function useSaMessages<K extends keyof SaMessages>(
78
+ namespace: K,
79
+ ): ComputedRef<SaMessages[K]> {
80
+ const { messages } = useSuperAdminI18n();
81
+ return computed(() => messages.value[namespace]);
82
+ }
@@ -13,8 +13,10 @@
13
13
 
14
14
  import { computed, type ComputedRef, type Ref } from 'vue';
15
15
  import type { AdminManifest, TenantActionDef, TenantDto } from '@saasicat/types';
16
- import { ActionRegistry } from './action-registry.js';
16
+ import { ActionRegistry } from '../client/action-registry.js';
17
+ import { formatMessage } from '../client/i18n/format.js';
17
18
  import { useSuperAdminActions } from './use-super-admin-context.js';
19
+ import { useSaMessages } from './use-super-admin-i18n.js';
18
20
 
19
21
  /**
20
22
  * Input the app-side handler receives. `mfaCode` is populated when
@@ -125,6 +127,7 @@ export function useTenantActionFlow<TRow extends TenantDto = TenantDto>(
125
127
  providers: TenantActionFlowProviders<TRow> = {},
126
128
  ): UseTenantActionFlowResult<TRow> {
127
129
  const handlers = useSuperAdminActions();
130
+ const msg = useSaMessages('tenants');
128
131
  const registry = computed<ActionRegistry | null>(() => {
129
132
  if (!manifest.value) return null;
130
133
  return new ActionRegistry(manifest.value, handlers);
@@ -151,7 +154,8 @@ export function useTenantActionFlow<TRow extends TenantDto = TenantDto>(
151
154
  .filter((def) => !providers.visibleForRow || providers.visibleForRow(def, row))
152
155
  .map((def) => ({
153
156
  def,
154
- invoke: (r: TRow) => runFlow(def, r ?? row, reg, providers),
157
+ invoke: (r: TRow) =>
158
+ runFlow(def, r ?? row, reg, providers, msg.value.actions.successNotify),
155
159
  }));
156
160
  }
157
161
 
@@ -184,6 +188,7 @@ async function runFlow<TRow extends TenantDto>(
184
188
  row: TRow,
185
189
  registry: ActionRegistry,
186
190
  providers: TenantActionFlowProviders<TRow>,
191
+ successTemplate: string,
187
192
  ): Promise<unknown> {
188
193
  let reason: string | null = null;
189
194
  let extras: Record<string, unknown> = {};
@@ -191,8 +196,8 @@ async function runFlow<TRow extends TenantDto>(
191
196
  if (def.confirmType && def.confirmType !== 'none') {
192
197
  if (!providers.confirm) {
193
198
  throw new Error(
194
- `useTenantActionFlow: Action "${def.id}" verlangt confirmType="${def.confirmType}", ` +
195
- `aber kein \`confirm\`-Provider übergeben.`,
199
+ `useTenantActionFlow: action "${def.id}" requires confirmType="${def.confirmType}", ` +
200
+ `but no \`confirm\` provider was supplied.`,
196
201
  );
197
202
  }
198
203
  const c = await providers.confirm(def, { row });
@@ -205,8 +210,8 @@ async function runFlow<TRow extends TenantDto>(
205
210
  if (def.requiresMfa) {
206
211
  if (!providers.mfa) {
207
212
  throw new Error(
208
- `useTenantActionFlow: Action "${def.id}" verlangt MFA, aber kein ` +
209
- `\`mfa\`-Provider übergeben.`,
213
+ `useTenantActionFlow: action "${def.id}" requires MFA, but no ` +
214
+ `\`mfa\` provider was supplied.`,
210
215
  );
211
216
  }
212
217
  mfaCode = await providers.mfa(def, { row });
@@ -225,7 +230,7 @@ async function runFlow<TRow extends TenantDto>(
225
230
  try {
226
231
  const input: TenantActionInput<TRow> = { row, mfaCode, reason, extras };
227
232
  const result = await resolved.handler(input);
228
- providers.notify?.('positive', `${def.label}: erfolgreich.`);
233
+ providers.notify?.('positive', formatMessage(successTemplate, { action: def.label }));
229
234
  providers.onSuccess?.(def, { row });
230
235
  return result;
231
236
  } catch (err) {
@@ -8,8 +8,8 @@
8
8
 
9
9
  import { ref, type Ref } from 'vue';
10
10
  import type { FeatureUiRegistry } from '@saasicat/types';
11
- import { defaultHttpClient, type HttpClient } from './types.js';
12
- import { trimTrailingSlashes } from './http-json.js';
11
+ import { defaultHttpClient, type HttpClient } from '../client/types.js';
12
+ import { trimTrailingSlashes } from '../client/http-json.js';
13
13
 
14
14
  export interface CatalogPlan {
15
15
  id: string;
@@ -11,8 +11,8 @@
11
11
  // has `/api` as its baseURL — the result would be `/api/api/billing/...` (404).
12
12
 
13
13
  import { ref, type Ref } from 'vue';
14
- import { defaultHttpClient, type HttpClient } from './types.js';
15
- import { trimTrailingSlashes } from './http-json.js';
14
+ import { defaultHttpClient, type HttpClient } from '../client/types.js';
15
+ import { trimTrailingSlashes } from '../client/http-json.js';
16
16
 
17
17
  export type BillingCycleStr = 'MONTHLY' | 'YEARLY';
18
18
 
@@ -8,7 +8,7 @@
8
8
  // Spec: handoff/superadmin/QUICKSTART_SIMPLIFICATIONS.md §P14.
9
9
 
10
10
  import { ref, type Ref } from 'vue';
11
- import { defaultHttpClient, type HttpClient } from './types.js';
11
+ import { defaultHttpClient, type HttpClient } from '../client/types.js';
12
12
 
13
13
  export interface TenantManifestNavItem {
14
14
  id: string;
@@ -48,9 +48,7 @@ export interface UseTenantManifestResult {
48
48
 
49
49
  export function useTenantManifest(options: UseTenantManifestOptions): UseTenantManifestResult {
50
50
  if (!options?.endpoint) {
51
- throw new Error(
52
- 'useTenantManifest: `endpoint` ist Pflicht (z. B. "/api/tenant/manifest").',
53
- );
51
+ throw new Error('useTenantManifest: `endpoint` is required (e.g. "/api/tenant/manifest").');
54
52
  }
55
53
  const http = options.http ?? defaultHttpClient();
56
54
  const manifest = ref<TenantManifestShape | null>(null);
@@ -5,7 +5,7 @@
5
5
 
6
6
  import { ref, type Ref } from 'vue';
7
7
  import type { SubscriptionBundleRecord } from '@saasicat/types';
8
- import { defaultHttpClient, type HttpClient } from './types.js';
8
+ import { defaultHttpClient, type HttpClient } from '../client/types.js';
9
9
 
10
10
  export interface UseTenantSubscriptionBundlesOptions {
11
11
  /** App-global API prefix incl. `/billing` (e.g. `/api/v1`). */
@@ -48,7 +48,7 @@ export function useTenantSubscriptionBundles(
48
48
  ): UseTenantSubscriptionBundlesResult {
49
49
  if (!options?.billingEndpoint) {
50
50
  throw new Error(
51
- 'useTenantSubscriptionBundles: `billingEndpoint` ist Pflicht (z. B. "/api/v1").',
51
+ 'useTenantSubscriptionBundles: `billingEndpoint` is required (e.g. "/api/v1").',
52
52
  );
53
53
  }
54
54
  const http = options.http ?? defaultHttpClient();
@@ -75,7 +75,7 @@ export function useTenantSubscriptionBundles(
75
75
  throw new TenantSubscriptionBundlesApiError(
76
76
  res.status,
77
77
  body,
78
- `SubscriptionBundle-API antwortete mit HTTP ${res.status}`,
78
+ `SubscriptionBundle API responded with HTTP ${res.status}`,
79
79
  );
80
80
  }
81
81
  return body as T;
@@ -103,7 +103,7 @@ export function useTenantSubscriptionBundles(
103
103
  body: JSON.stringify(data),
104
104
  });
105
105
  if (!result) {
106
- throw new TenantSubscriptionBundlesApiError(0, null, 'add gab keinen Body zurück');
106
+ throw new TenantSubscriptionBundlesApiError(0, null, 'add returned no body');
107
107
  }
108
108
  const hydrated = rehydrateDates(result);
109
109
  bundles.value = [hydrated, ...bundles.value];
@@ -119,7 +119,7 @@ export function useTenantSubscriptionBundles(
119
119
  { method: 'DELETE', body: JSON.stringify(opts) },
120
120
  );
121
121
  if (!result) {
122
- throw new TenantSubscriptionBundlesApiError(0, null, 'cancel gab keinen Body zurück');
122
+ throw new TenantSubscriptionBundlesApiError(0, null, 'cancel returned no body');
123
123
  }
124
124
  const hydrated = rehydrateDates(result);
125
125
  bundles.value = bundles.value.map((b) => (b.id === subscriptionBundleId ? hydrated : b));
@@ -44,9 +44,9 @@ export function useTenants<T extends TenantDto = TenantDto>(
44
44
  ): UseTenantsResult<T> {
45
45
  if (!options?.endpoint) {
46
46
  throw new Error(
47
- 'useTenants: `endpoint` ist Pflicht (z. B. "/api/v1/admin/tenants" oder ' +
48
- '"/api/admin/tenants"). Plattform hat keinen Default, weil Apps ' +
49
- 'unterschiedliche globalPrefix-Konventionen haben.',
47
+ 'useTenants: `endpoint` is required (e.g. "/api/v1/admin/tenants" or ' +
48
+ '"/api/admin/tenants"). The platform has no default because apps ' +
49
+ 'use different globalPrefix conventions.',
50
50
  );
51
51
  }
52
52
  const filter = options.filter ?? ref<TenantListFilter>({});
@@ -1,37 +0,0 @@
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,37 +0,0 @@
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 };