@saasicat/ui-vue 0.3.0 → 0.5.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.
- package/README.md +47 -4
- package/dist/action-registry-CQ2wL3R-.d.cts +85 -0
- package/dist/action-registry-CQ2wL3R-.d.ts +85 -0
- package/dist/chunk-3YP2ZAOD.js +63 -0
- package/dist/chunk-EH7TOD4H.js +718 -0
- package/dist/chunk-LVGUSD3T.js +26 -0
- package/dist/client/index.cjs +785 -0
- package/dist/client/index.d.cts +295 -0
- package/dist/client/index.d.ts +295 -0
- package/dist/client/index.js +52 -0
- package/dist/index.cjs +787 -834
- package/dist/index.d.cts +267 -841
- package/dist/index.d.ts +267 -841
- package/dist/index.js +284 -1059
- package/dist/quasar/index.cjs +159 -0
- package/dist/quasar/index.d.cts +86 -0
- package/dist/quasar/index.d.ts +86 -0
- package/dist/quasar/index.js +91 -0
- package/dist/ui-notify-COUzXEQ4.d.ts +178 -0
- package/dist/ui-notify-D_eAAwRh.d.cts +178 -0
- package/package.json +23 -3
- package/src/client/index.ts +25 -0
- package/src/components/FeatureGate.vue +1 -1
- package/src/components/plan/PlanCycleToggle.vue +1 -1
- package/src/components/plan/PlanGrid.vue +2 -2
- package/src/components/plan/PriceSummary.vue +1 -1
- package/src/components/plan/PromoCodeInput.vue +1 -1
- package/src/components/plan/PublicBundleGrid.vue +1 -1
- package/src/index.ts +82 -79
- package/src/pages-standard/AdminLayout.vue +2 -2
- package/src/pages-standard/DashboardPage.vue +2 -2
- package/src/pages-standard/EmailHistoryPage.vue +9 -13
- package/src/pages-standard/MarketingCatalogPage.vue +5 -5
- package/src/pages-standard/PilotsPage.vue +9 -13
- package/src/pages-standard/PlanVersionsPage.vue +2 -2
- package/src/pages-standard/PlansPage.vue +2 -2
- package/src/pages-standard/PlatformEmailPage.vue +7 -5
- package/src/pages-standard/PromoCodesPage.vue +8 -22
- package/src/pages-standard/SuperAdminLoginPage.vue +3 -3
- package/src/pages-standard/SuperAdminSetupWizard.vue +2 -2
- package/src/pages-standard/TenantDetailPage.vue +4 -4
- package/src/pages-standard/TenantsPage.vue +3 -3
- package/src/pages-standard/UsersPage.vue +6 -12
- package/src/pages-standard/plan-versions/PlanVersionHeader.vue +1 -1
- package/src/pages-standard/plan-versions/PlanVersionsAudit.vue +1 -1
- package/src/pages-standard/plan-versions/PlanVersionsDiff.vue +1 -1
- package/src/pages-standard/plan-versions/PlanVersionsList.vue +1 -1
- package/src/pages-standard/plan-versions/PlanVersionsMatrix.vue +1 -1
- package/src/pages-standard/plan-versions/PlanVersionsTimeline.vue +1 -1
- package/src/pages-tenant/MySubscriptionBundlesPage.vue +1 -1
- package/src/pages-tenant/OnboardingConfigurator.vue +3 -3
- package/src/pages-tenant/PackageSnapshotPanel.vue +1 -1
- package/src/pages-tenant/PlanChangeWizard.vue +2 -2
- package/src/pages-tenant/TenantPlanSection.vue +3 -3
- package/src/pages-tenant/tenant-plan-section/BundlePreviewDialog.vue +1 -1
- package/src/pages-tenant/tenant-plan-section/TenantBundleStore.vue +2 -2
- package/src/pages-tenant/tenant-plan-section/TenantPlanCardHeader.vue +1 -1
- package/src/pages-tenant/tenant-plan-section/TenantUsageGrid.vue +1 -1
- package/src/quasar/create-super-admin-app.ts +173 -0
- package/src/quasar/index.ts +11 -0
- package/src/quasar/notify.ts +30 -0
- package/src/{manifest-store-factory.ts → vue/manifest-store-factory.ts} +1 -1
- package/src/{platform-loaders.ts → vue/platform-loaders.ts} +4 -4
- package/src/{project-page-host.ts → vue/project-page-host.ts} +1 -1
- package/src/{create-super-admin-app.ts → vue/super-admin-context.ts} +20 -139
- package/src/vue/ui-notify.ts +30 -0
- package/src/{use-actions.ts → vue/use-actions.ts} +1 -1
- package/src/{use-api-list.ts → vue/use-api-list.ts} +1 -1
- package/src/{use-batch-columns.ts → vue/use-batch-columns.ts} +1 -1
- package/src/{use-bulk-publish.ts → vue/use-bulk-publish.ts} +1 -1
- package/src/{use-bundle-versions-map.ts → vue/use-bundle-versions-map.ts} +1 -1
- package/src/{use-bundles.ts → vue/use-bundles.ts} +1 -1
- package/src/{use-business-types.ts → vue/use-business-types.ts} +1 -1
- package/src/{use-catalog-entries.ts → vue/use-catalog-entries.ts} +1 -1
- package/src/{use-discovery.ts → vue/use-discovery.ts} +1 -1
- package/src/{use-entitlement.ts → vue/use-entitlement.ts} +1 -1
- package/src/{use-live-plan-versions.ts → vue/use-live-plan-versions.ts} +1 -1
- package/src/{use-manifest.ts → vue/use-manifest.ts} +1 -1
- package/src/{use-marketing-projections.ts → vue/use-marketing-projections.ts} +1 -1
- package/src/{use-nav.ts → vue/use-nav.ts} +1 -1
- package/src/{use-plans.ts → vue/use-plans.ts} +1 -1
- package/src/{use-promotions.ts → vue/use-promotions.ts} +1 -1
- package/src/{use-public-boot.ts → vue/use-public-boot.ts} +1 -1
- package/src/{use-super-admin-context.ts → vue/use-super-admin-context.ts} +2 -2
- package/src/{use-tenant-action-flow.ts → vue/use-tenant-action-flow.ts} +1 -1
- package/src/{use-tenant-billing-catalog.ts → vue/use-tenant-billing-catalog.ts} +2 -2
- package/src/{use-tenant-billing.ts → vue/use-tenant-billing.ts} +2 -2
- package/src/{use-tenant-manifest.ts → vue/use-tenant-manifest.ts} +1 -1
- package/src/{use-tenant-subscription-bundles.ts → vue/use-tenant-subscription-bundles.ts} +1 -1
- package/dist/testing-e2e/admin-pages-suite.d.cts +0 -37
- package/dist/testing-e2e/admin-pages-suite.d.ts +0 -37
- /package/src/{action-registry.ts → client/action-registry.ts} +0 -0
- /package/src/{batch-column-fetcher.ts → client/batch-column-fetcher.ts} +0 -0
- /package/src/{boot-loader.ts → client/boot-loader.ts} +0 -0
- /package/src/{http-json.ts → client/http-json.ts} +0 -0
- /package/src/{manifest-loader.ts → client/manifest-loader.ts} +0 -0
- /package/src/{nav-builder.ts → client/nav-builder.ts} +0 -0
- /package/src/{plan-versions-catalog.ts → client/plan-versions-catalog.ts} +0 -0
- /package/src/{types.ts → client/types.ts} +0 -0
- /package/src/{version.ts → client/version.ts} +0 -0
- /package/src/{create-admin-routes.ts → vue/create-admin-routes.ts} +0 -0
- /package/src/{entitlement-provider.ts → vue/entitlement-provider.ts} +0 -0
- /package/src/{feature-router-guard.ts → vue/feature-router-guard.ts} +0 -0
- /package/src/{use-audit-entries.ts → vue/use-audit-entries.ts} +0 -0
- /package/src/{use-plan-editor.ts → vue/use-plan-editor.ts} +0 -0
- /package/src/{use-plan-versions.ts → vue/use-plan-versions.ts} +0 -0
- /package/src/{use-platform-tenant-actions.ts → vue/use-platform-tenant-actions.ts} +0 -0
- /package/src/{use-subscription-draft.ts → vue/use-subscription-draft.ts} +0 -0
- /package/src/{use-tenants.ts → vue/use-tenants.ts} +0 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { Component, App, InjectionKey } from 'vue';
|
|
2
|
+
import { NavigationGuardWithThis } from 'vue-router';
|
|
3
|
+
import { ActionKey, ComponentKey, AdminManifest } from '@saasicat/types';
|
|
4
|
+
import { A as ActionHandler, H as HttpClient } from './action-registry-CQ2wL3R-.cjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* App-specific branding data that the platform `AdminLayout` and other
|
|
8
|
+
* consumers read via `useSuperAdminBrand()`.
|
|
9
|
+
*/
|
|
10
|
+
interface SuperAdminBrand {
|
|
11
|
+
/** 2-letter abbreviation in the logo badge (`'ma'`, `'da'`, …). */
|
|
12
|
+
logoText: string;
|
|
13
|
+
/** Full display name (`'DemoApp'`, `'ClubApp'`, …). */
|
|
14
|
+
name: string;
|
|
15
|
+
/** Optional: tag to the right of the name, default `'SuperAdmin'`. */
|
|
16
|
+
tag?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Endpoint configuration. `apiBase` is the shared prefix under which
|
|
20
|
+
* `/manifest`, `/boot` and extra routes live.
|
|
21
|
+
*/
|
|
22
|
+
interface SuperAdminEndpoints {
|
|
23
|
+
/** Shared prefix, e.g. `'/api/admin'` or `'/api/v1/admin'`. */
|
|
24
|
+
apiBase: string;
|
|
25
|
+
/** Pre-login branding endpoint, default `${apiBase}/boot`. */
|
|
26
|
+
publicBootEndpoint?: string;
|
|
27
|
+
/** Post-login full-manifest endpoint, default `${apiBase}/manifest`. */
|
|
28
|
+
manifestEndpoint?: string;
|
|
29
|
+
}
|
|
30
|
+
type ExtensionLoader = () => Promise<Component | {
|
|
31
|
+
default: Component;
|
|
32
|
+
}>;
|
|
33
|
+
type ExtensionsMap = Record<ComponentKey, ExtensionLoader>;
|
|
34
|
+
type ActionsMap = Record<ActionKey, ActionHandler>;
|
|
35
|
+
interface SuperAdminAuthGuardOptions {
|
|
36
|
+
/** App provides: is the user currently logged in? */
|
|
37
|
+
isAuthenticated: () => boolean;
|
|
38
|
+
/** App provides: does the user have the SuperAdmin role? Default: only check `isAuthenticated`. */
|
|
39
|
+
isSuperAdmin?: () => boolean;
|
|
40
|
+
/** App provides: redirect path for unauthenticated calls (e.g. `'/login'`). */
|
|
41
|
+
onUnauthenticated: () => string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Result of a login attempt. Apps pass this back from their auth store to the
|
|
45
|
+
* platform LoginPage; the page renders an appropriate error message.
|
|
46
|
+
*
|
|
47
|
+
* `ok: true` → login succeeded, page redirects to `redirectAfterLogin`.
|
|
48
|
+
* `ok: false` → page shows `message` or a translation derived from `code`.
|
|
49
|
+
*
|
|
50
|
+
* Known codes:
|
|
51
|
+
* - `BAD_CREDENTIALS` — wrong email/password combination.
|
|
52
|
+
* - `NOT_SUPER_ADMIN` — account does not have the SuperAdmin role.
|
|
53
|
+
* - otherwise — app-specific; `message` is displayed directly.
|
|
54
|
+
*/
|
|
55
|
+
type SuperAdminLoginResult = {
|
|
56
|
+
ok: true;
|
|
57
|
+
} | {
|
|
58
|
+
ok: false;
|
|
59
|
+
code?: 'BAD_CREDENTIALS' | 'NOT_SUPER_ADMIN' | string;
|
|
60
|
+
message?: string;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Login adapter. The app passes its auth-store call through here. The platform
|
|
64
|
+
* LoginPage consumes it via `useSuperAdminLoginAdapter()`, without knowledge
|
|
65
|
+
* of app-specific stores (Pinia, auth API routes, MFA hooks).
|
|
66
|
+
*/
|
|
67
|
+
interface SuperAdminLoginAdapter {
|
|
68
|
+
/**
|
|
69
|
+
* Performs the login. The app store encapsulates the API call, token
|
|
70
|
+
* storage, MFA hops etc.
|
|
71
|
+
*/
|
|
72
|
+
login(email: string, password: string): Promise<SuperAdminLoginResult>;
|
|
73
|
+
/**
|
|
74
|
+
* Target route after a successful login. Default: `/admin/dashboard`
|
|
75
|
+
* (platform convention for the standard pages — apps with a different
|
|
76
|
+
* default mount override this here).
|
|
77
|
+
*/
|
|
78
|
+
redirectAfterLogin?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Optional: dev hint (test account), shown below the form. Deliberately
|
|
81
|
+
* rendered only when `environment !== 'production'`.
|
|
82
|
+
*/
|
|
83
|
+
devHint?: {
|
|
84
|
+
email: string;
|
|
85
|
+
password: string;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
interface SuperAdminManifestGuardOptions {
|
|
89
|
+
/**
|
|
90
|
+
* App provides: loads the manifest into the app store. The router guard
|
|
91
|
+
* `await`s the promise before the route is resolved.
|
|
92
|
+
*
|
|
93
|
+
* **On loader error:** the promise REJECTS. The router guard catches the
|
|
94
|
+
* rejection and decides depending on `errorRoute`:
|
|
95
|
+
* - `errorRoute` set → redirect to this route (fail-closed).
|
|
96
|
+
* - `errorRoute` not set → `console.error` + render allowed
|
|
97
|
+
* (defensive default behavior; the app must render the manifest gap
|
|
98
|
+
* itself).
|
|
99
|
+
*/
|
|
100
|
+
ensureLoaded: () => Promise<void>;
|
|
101
|
+
/**
|
|
102
|
+
* Optional: read accessor on the loaded manifest. When set, it is exposed
|
|
103
|
+
* via `provide(SUPER_ADMIN_MANIFEST_KEY)` — the `<ProjectPageHost>`
|
|
104
|
+
* resolves manifest `projectPages` through it against the
|
|
105
|
+
* `extensions:` map.
|
|
106
|
+
*/
|
|
107
|
+
getManifest?: () => AdminManifest | null;
|
|
108
|
+
/**
|
|
109
|
+
* Optional: path that the router guard redirects to on a manifest load
|
|
110
|
+
* error (fail-closed mode). The app must register the route in `appRoutes`
|
|
111
|
+
* and mark it as `meta.public = true`, otherwise it runs through the
|
|
112
|
+
* manifest guard again and produces a redirect loop.
|
|
113
|
+
*/
|
|
114
|
+
errorRoute?: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Guard configuration shared by `buildNavigationGuard()` and
|
|
118
|
+
* `createSuperAdminApp()` (which embeds both fields in its options).
|
|
119
|
+
*/
|
|
120
|
+
interface SuperAdminGuardOptions {
|
|
121
|
+
/**
|
|
122
|
+
* Optional: auth guard. When set, `router.beforeEach` is wired up
|
|
123
|
+
* automatically — `to.meta.public === true` bypasses the guard.
|
|
124
|
+
*/
|
|
125
|
+
authGuard?: SuperAdminAuthGuardOptions;
|
|
126
|
+
/**
|
|
127
|
+
* Optional: manifest guard. Runs after a successful auth guard, blocks the
|
|
128
|
+
* render until the manifest is loaded (prevents sidebar flicker).
|
|
129
|
+
*/
|
|
130
|
+
manifestGuard?: SuperAdminManifestGuardOptions;
|
|
131
|
+
}
|
|
132
|
+
/** Vue inject key for `useSuperAdminBrand()`. */
|
|
133
|
+
declare const SUPER_ADMIN_BRAND_KEY: InjectionKey<SuperAdminBrand>;
|
|
134
|
+
/** Vue inject key for `useSuperAdminEndpoints()`. */
|
|
135
|
+
declare const SUPER_ADMIN_ENDPOINTS_KEY: InjectionKey<Required<SuperAdminEndpoints>>;
|
|
136
|
+
/** Vue inject key for `useSuperAdminExtensions()`. */
|
|
137
|
+
declare const SUPER_ADMIN_EXTENSIONS_KEY: InjectionKey<ExtensionsMap>;
|
|
138
|
+
/** Vue inject key for `useSuperAdminActions()`. */
|
|
139
|
+
declare const SUPER_ADMIN_ACTIONS_KEY: InjectionKey<ActionsMap>;
|
|
140
|
+
/**
|
|
141
|
+
* Vue inject key for the manifest accessor. Only provided when
|
|
142
|
+
* `manifestGuard.getManifest` was passed to `createSuperAdminApp()` — the
|
|
143
|
+
* `<ProjectPageHost>` needs it to resolve project pages.
|
|
144
|
+
*/
|
|
145
|
+
declare const SUPER_ADMIN_MANIFEST_KEY: InjectionKey<() => AdminManifest | null>;
|
|
146
|
+
/** Vue inject key for `useSuperAdminLoginAdapter()`. */
|
|
147
|
+
declare const SUPER_ADMIN_LOGIN_ADAPTER_KEY: InjectionKey<SuperAdminLoginAdapter>;
|
|
148
|
+
/** Vue inject key for `useSuperAdminHttp()` (pre-login HttpClient). */
|
|
149
|
+
declare const SUPER_ADMIN_HTTP_KEY: InjectionKey<HttpClient>;
|
|
150
|
+
/**
|
|
151
|
+
* Additional Vue plugins (e.g. an app's own NotificationCenter) that a
|
|
152
|
+
* bootstrap installs after the platform setup, before the mount.
|
|
153
|
+
*/
|
|
154
|
+
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
|
+
declare function buildNavigationGuard(options: SuperAdminGuardOptions): NavigationGuardWithThis<undefined> | null;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Feedback kind, aligned with the established page conventions
|
|
164
|
+
* (`positive` = success, `negative` = error).
|
|
165
|
+
*/
|
|
166
|
+
type UiNotifyKind = 'positive' | 'negative' | 'warning' | 'info';
|
|
167
|
+
interface UiNotifyOptions {
|
|
168
|
+
/** Secondary line below the message (e.g. changed fields, one-time password). */
|
|
169
|
+
caption?: string;
|
|
170
|
+
/** Display duration in ms; implementations fall back to their default when unset. */
|
|
171
|
+
timeoutMs?: number;
|
|
172
|
+
}
|
|
173
|
+
/** Notify port. Compatible with the `(kind, message)` callbacks pages already accept. */
|
|
174
|
+
type UiNotify = (kind: UiNotifyKind, message: string, options?: UiNotifyOptions) => void;
|
|
175
|
+
/** Vue inject key for the notify port (see `Symbol.for` note in super-admin-context.ts). */
|
|
176
|
+
declare const SUPER_ADMIN_NOTIFY_KEY: InjectionKey<UiNotify>;
|
|
177
|
+
|
|
178
|
+
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 ExtensionLoader as d, SUPER_ADMIN_ACTIONS_KEY as e, SUPER_ADMIN_BRAND_KEY as f, SUPER_ADMIN_ENDPOINTS_KEY as g, SUPER_ADMIN_EXTENSIONS_KEY as h, SUPER_ADMIN_HTTP_KEY as i, SUPER_ADMIN_LOGIN_ADAPTER_KEY as j, SUPER_ADMIN_MANIFEST_KEY as k, SUPER_ADMIN_NOTIFY_KEY as l, type SuperAdminAuthGuardOptions as m, type SuperAdminLoginResult as n, type SuperAdminManifestGuardOptions as o, type UiNotifyKind as p, type UiNotifyOptions as q, buildNavigationGuard as r };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saasicat/ui-vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Vue 3 components + composables for the SuperAdmin UI shell. Provides boot loader, manifest loader (ETag cache), nav builder, action registry and standard pages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -17,6 +17,26 @@
|
|
|
17
17
|
"default": "./dist/index.cjs"
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
|
+
"./client": {
|
|
21
|
+
"import": {
|
|
22
|
+
"types": "./dist/client/index.d.ts",
|
|
23
|
+
"default": "./dist/client/index.js"
|
|
24
|
+
},
|
|
25
|
+
"require": {
|
|
26
|
+
"types": "./dist/client/index.d.cts",
|
|
27
|
+
"default": "./dist/client/index.cjs"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"./quasar": {
|
|
31
|
+
"import": {
|
|
32
|
+
"types": "./dist/quasar/index.d.ts",
|
|
33
|
+
"default": "./dist/quasar/index.js"
|
|
34
|
+
},
|
|
35
|
+
"require": {
|
|
36
|
+
"types": "./dist/quasar/index.d.cts",
|
|
37
|
+
"default": "./dist/quasar/index.cjs"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
20
40
|
"./pages/*": "./src/pages-standard/*",
|
|
21
41
|
"./pages-standard/*": "./src/pages-standard/*",
|
|
22
42
|
"./pages-tenant/*": "./src/pages-tenant/*",
|
|
@@ -33,7 +53,7 @@
|
|
|
33
53
|
"src"
|
|
34
54
|
],
|
|
35
55
|
"dependencies": {
|
|
36
|
-
"@saasicat/types": "^0.
|
|
56
|
+
"@saasicat/types": "^0.5.0"
|
|
37
57
|
},
|
|
38
58
|
"peerDependencies": {
|
|
39
59
|
"pinia": "^2.0.0 || ^3.0.0",
|
|
@@ -78,7 +98,7 @@
|
|
|
78
98
|
"access": "public"
|
|
79
99
|
},
|
|
80
100
|
"scripts": {
|
|
81
|
-
"build": "tsup
|
|
101
|
+
"build": "tsup",
|
|
82
102
|
"typecheck": "vue-tsc --noEmit -p tsconfig.json",
|
|
83
103
|
"pretest": "pnpm run build",
|
|
84
104
|
"test": "node --test tests/**/*.test.js",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// @saasicat/ui-vue/client — the framework-free core of the SuperAdmin UI
|
|
2
|
+
// package. No Vue, no Pinia, no Quasar: only `@saasicat/types` and the
|
|
3
|
+
// platform HTTP contract. Usable from any framework binding or plain
|
|
4
|
+
// TypeScript (Node scripts, other UI stacks).
|
|
5
|
+
//
|
|
6
|
+
// Contents:
|
|
7
|
+
// - types: HttpClient, KvStore, defaultHttpClient, defaultKvStore
|
|
8
|
+
// - http-json: JSON fetch helper over HttpClient
|
|
9
|
+
// - boot-loader: BootLoader + BootLoadError
|
|
10
|
+
// - manifest-loader: ManifestLoader with ETag cache + ManifestLoadError
|
|
11
|
+
// - nav-builder: buildRoutes, buildSidebar, resolveExtension
|
|
12
|
+
// - action-registry: ActionRegistry, MissingHandlerError, ActionDefNotInManifestError
|
|
13
|
+
// - batch-column-fetcher: BatchColumnFetcher + BatchColumnDriftError
|
|
14
|
+
// - plan-versions-catalog: plan-version list/diff helpers
|
|
15
|
+
// - version: ADMIN_UI_VERSION
|
|
16
|
+
|
|
17
|
+
export * from './version.js';
|
|
18
|
+
export * from './types.js';
|
|
19
|
+
export * from './http-json.js';
|
|
20
|
+
export * from './boot-loader.js';
|
|
21
|
+
export * from './manifest-loader.js';
|
|
22
|
+
export * from './nav-builder.js';
|
|
23
|
+
export * from './action-registry.js';
|
|
24
|
+
export * from './batch-column-fetcher.js';
|
|
25
|
+
export * from './plan-versions-catalog.js';
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
// instead of returning `null`. (Strict mode comes later; currently default = lenient.)
|
|
36
36
|
|
|
37
37
|
import { computed } from 'vue';
|
|
38
|
-
import { useInjectedEntitlement } from '../entitlement-provider.js';
|
|
38
|
+
import { useInjectedEntitlement } from '../vue/entitlement-provider.js';
|
|
39
39
|
|
|
40
40
|
interface Props {
|
|
41
41
|
/** A single FeatureKey or several as a logical OR. */
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
</template>
|
|
49
49
|
|
|
50
50
|
<script setup lang="ts">
|
|
51
|
-
import type { CatalogPlan } from '../../use-tenant-billing-catalog.js';
|
|
52
|
-
import type { BillingCycleStr } from '../../use-tenant-billing.js';
|
|
51
|
+
import type { CatalogPlan } from '../../vue/use-tenant-billing-catalog.js';
|
|
52
|
+
import type { BillingCycleStr } from '../../vue/use-tenant-billing.js';
|
|
53
53
|
|
|
54
54
|
interface I18n {
|
|
55
55
|
popular: string;
|
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
type BundleAvailabilityState,
|
|
77
77
|
type PublicMarketingBundle,
|
|
78
78
|
} from '@saasicat/types';
|
|
79
|
-
import type { BillingCycleStr } from '../../use-tenant-billing.js';
|
|
79
|
+
import type { BillingCycleStr } from '../../vue/use-tenant-billing.js';
|
|
80
80
|
|
|
81
81
|
interface I18n {
|
|
82
82
|
perMonth: string;
|
package/src/index.ts
CHANGED
|
@@ -1,75 +1,88 @@
|
|
|
1
|
-
// @saasicat/ui-vue — Vue 3
|
|
2
|
-
// SuperAdmin UI shell.
|
|
1
|
+
// @saasicat/ui-vue — Vue 3 composables + loaders for the SuperAdmin UI shell.
|
|
3
2
|
//
|
|
4
|
-
//
|
|
5
|
-
// P4.2 (Phase 31): nav builder + extension host + action registry.
|
|
6
|
-
// P4.3 (Phase 32): batch column fetcher.
|
|
7
|
-
// P4.4 (Phase 33): composables for standard pages (Tenants, Audit, Entitlement).
|
|
8
|
-
// P4.5 (Phase 34): plan-versions list composables + bulk-publish orchestration.
|
|
3
|
+
// The package is layered; each layer has its own entry:
|
|
9
4
|
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
// -
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
// -
|
|
17
|
-
//
|
|
18
|
-
// -
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
//
|
|
28
|
-
//
|
|
5
|
+
// - `@saasicat/ui-vue/client` (`src/client/`) — framework-free core:
|
|
6
|
+
// loaders, nav builder, action registry, HTTP contract. No Vue, no
|
|
7
|
+
// Pinia, no Quasar.
|
|
8
|
+
// - `@saasicat/ui-vue` (this entry, `src/vue/`) — Vue bindings: composables,
|
|
9
|
+
// router guards, injection keys, optional Pinia store factory. Re-exports
|
|
10
|
+
// the client layer. No Quasar.
|
|
11
|
+
// - `@saasicat/ui-vue/quasar` (`src/quasar/`) — Quasar bootstrap:
|
|
12
|
+
// `createSuperAdminApp()` and the Quasar notify port implementation.
|
|
13
|
+
// - Quasar standard pages/components — raw SFCs via the
|
|
14
|
+
// `./pages-standard/*`, `./pages-tenant/*` and `./components/*` subpath
|
|
15
|
+
// exports (tsup ignores `.vue`).
|
|
16
|
+
//
|
|
17
|
+
// Layer rule (enforced via ESLint `no-restricted-imports`): client imports
|
|
18
|
+
// nothing framework-specific; vue never imports quasar; this entry never
|
|
19
|
+
// reaches the quasar layer or the SFC directories (except the whitelisted
|
|
20
|
+
// framework-free type/i18n modules below).
|
|
21
|
+
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Client layer (framework-free core).
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
export * from './client/index.js';
|
|
26
|
+
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Vue layer: shell contract (injection keys, option types, navigation guard)
|
|
29
|
+
// and the UI notify port. `createSuperAdminApp()` itself lives in
|
|
30
|
+
// `@saasicat/ui-vue/quasar`.
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
export * from './vue/super-admin-context.js';
|
|
33
|
+
export * from './vue/ui-notify.js';
|
|
34
|
+
export * from './vue/use-super-admin-context.js';
|
|
29
35
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
export * from './create-admin-routes.js';
|
|
34
|
-
export * from './
|
|
35
|
-
export * from './
|
|
36
|
-
export * from './
|
|
37
|
-
export * from './
|
|
38
|
-
export * from './
|
|
39
|
-
export * from './
|
|
40
|
-
export * from './
|
|
41
|
-
export * from './use-audit-entries.js';
|
|
42
|
-
export * from './use-entitlement.js';
|
|
43
|
-
export * from './use-tenant-manifest.js';
|
|
44
|
-
export * from './entitlement-provider.js';
|
|
45
|
-
export * from './feature-router-guard.js';
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// Vue layer: composables, guards, hosts, store factory.
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
export * from './vue/create-admin-routes.js';
|
|
40
|
+
export * from './vue/use-api-list.js';
|
|
41
|
+
export * from './vue/use-tenants.js';
|
|
42
|
+
export * from './vue/use-audit-entries.js';
|
|
43
|
+
export * from './vue/use-entitlement.js';
|
|
44
|
+
export * from './vue/use-tenant-manifest.js';
|
|
45
|
+
export * from './vue/entitlement-provider.js';
|
|
46
|
+
export * from './vue/feature-router-guard.js';
|
|
46
47
|
// FeatureGate.vue is not bundled — consumers import it directly:
|
|
47
48
|
// import FeatureGate from '@saasicat/ui-vue/components/FeatureGate.vue';
|
|
48
|
-
export * from './use-tenant-billing-catalog.js';
|
|
49
|
-
export * from './use-tenant-billing.js';
|
|
50
|
-
export * from './use-subscription-draft.js';
|
|
51
|
-
export * from './
|
|
52
|
-
export * from './use-
|
|
53
|
-
export * from './use-
|
|
54
|
-
export * from './use-
|
|
55
|
-
export * from './use-
|
|
56
|
-
export * from './use-
|
|
57
|
-
export * from './use-
|
|
58
|
-
export * from './use-
|
|
59
|
-
export * from './use-
|
|
60
|
-
export * from './use-
|
|
61
|
-
export * from './use-
|
|
62
|
-
export * from './use-
|
|
63
|
-
export * from './use-
|
|
64
|
-
export * from './use-
|
|
65
|
-
export * from './use-
|
|
66
|
-
export * from './use-
|
|
67
|
-
export * from './use-
|
|
68
|
-
export * from './use-
|
|
69
|
-
export * from './use-tenant-
|
|
70
|
-
export * from './use-
|
|
71
|
-
|
|
72
|
-
|
|
49
|
+
export * from './vue/use-tenant-billing-catalog.js';
|
|
50
|
+
export * from './vue/use-tenant-billing.js';
|
|
51
|
+
export * from './vue/use-subscription-draft.js';
|
|
52
|
+
export * from './vue/use-plan-versions.js';
|
|
53
|
+
export * from './vue/use-bulk-publish.js';
|
|
54
|
+
export * from './vue/use-plan-editor.js';
|
|
55
|
+
export * from './vue/use-public-boot.js';
|
|
56
|
+
export * from './vue/use-discovery.js';
|
|
57
|
+
export * from './vue/use-catalog-entries.js';
|
|
58
|
+
export * from './vue/use-bundles.js';
|
|
59
|
+
export * from './vue/use-bundle-versions-map.js';
|
|
60
|
+
export * from './vue/use-tenant-subscription-bundles.js';
|
|
61
|
+
export * from './vue/use-business-types.js';
|
|
62
|
+
export * from './vue/use-marketing-projections.js';
|
|
63
|
+
export * from './vue/use-promotions.js';
|
|
64
|
+
export * from './vue/use-plans.js';
|
|
65
|
+
export * from './vue/use-live-plan-versions.js';
|
|
66
|
+
export * from './vue/use-manifest.js';
|
|
67
|
+
export * from './vue/use-nav.js';
|
|
68
|
+
export * from './vue/use-actions.js';
|
|
69
|
+
export * from './vue/use-tenant-action-flow.js';
|
|
70
|
+
export * from './vue/use-platform-tenant-actions.js';
|
|
71
|
+
export * from './vue/use-batch-columns.js';
|
|
72
|
+
// Loader factory that builds BootLoader + ManifestLoader from the same
|
|
73
|
+
// endpoint configuration as createSuperAdminApp() — so that endpoints live
|
|
74
|
+
// in a single place per app.
|
|
75
|
+
export * from './vue/platform-loaders.js';
|
|
76
|
+
// ProjectPageHost: resolves manifest projectPages dynamically against the
|
|
77
|
+
// extensions: map — replaces static route duplication in the apps.
|
|
78
|
+
export * from './vue/project-page-host.js';
|
|
79
|
+
// Manifest Pinia store factory — standardizes ensureLoaded/reload/clearCache.
|
|
80
|
+
export * from './vue/manifest-store-factory.js';
|
|
81
|
+
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Framework-free type/i18n modules that deliberately stay co-located with
|
|
84
|
+
// their SFCs (whitelisted in the ESLint layer rules).
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
73
86
|
// Platform dialog types for app wrappers that type submit handlers.
|
|
74
87
|
export * from './components/dialogs/types.js';
|
|
75
88
|
// Pure resolvers for translated feature/quota labels in the bundle editors.
|
|
@@ -78,18 +91,8 @@ export * from './components/bundle-editor/catalog-i18n.js';
|
|
|
78
91
|
export * from './pages-standard/platform-email.types.js';
|
|
79
92
|
// Types of the shared EmailHistoryPage (platform email history).
|
|
80
93
|
export * from './pages-standard/email-history.types.js';
|
|
81
|
-
//
|
|
82
|
-
export * from './
|
|
83
|
-
export * from './use-super-admin-context.js';
|
|
84
|
-
// Loader factory that builds BootLoader + ManifestLoader from the same
|
|
85
|
-
// endpoint configuration as createSuperAdminApp() — so that endpoints live
|
|
86
|
-
// in a single place per app.
|
|
87
|
-
export * from './platform-loaders.js';
|
|
88
|
-
// ProjectPageHost: resolves manifest projectPages dynamically against the
|
|
89
|
-
// extensions: map — replaces static route duplication in the apps.
|
|
90
|
-
export * from './project-page-host.js';
|
|
91
|
-
// Manifest Pinia store factory — standardizes ensureLoaded/reload/clearCache.
|
|
92
|
-
export * from './manifest-store-factory.js';
|
|
94
|
+
// Default German labels for the tenant-facing pages.
|
|
95
|
+
export * from './pages-tenant/default-i18n.js';
|
|
93
96
|
|
|
94
97
|
// The shared SuperAdmin LoginPage lives at
|
|
95
98
|
// `@saasicat/ui-vue/pages-standard/SuperAdminLoginPage.vue` —
|
|
@@ -94,8 +94,8 @@
|
|
|
94
94
|
import { computed, ref } from 'vue';
|
|
95
95
|
import { useRoute } from 'vue-router';
|
|
96
96
|
import type { AdminManifest, StandardPageKey } from '@saasicat/types';
|
|
97
|
-
import { buildRoutes, buildSidebar, DEFAULT_SECTION_ORDER } from '../nav-builder.js';
|
|
98
|
-
import { ADMIN_UI_VERSION } from '../version.js';
|
|
97
|
+
import { buildRoutes, buildSidebar, DEFAULT_SECTION_ORDER } from '../client/nav-builder.js';
|
|
98
|
+
import { ADMIN_UI_VERSION } from '../client/version.js';
|
|
99
99
|
|
|
100
100
|
// SuperAdmin layout — universal platform shell for all consumer apps.
|
|
101
101
|
// CSS classes `sa-admin-*` with BEM convention; apps can override any class
|
|
@@ -108,8 +108,8 @@
|
|
|
108
108
|
<script setup lang="ts">
|
|
109
109
|
import { computed, onMounted, reactive, ref, watch } from 'vue';
|
|
110
110
|
import type { AdminManifest, KpiCardDef } from '@saasicat/types';
|
|
111
|
-
import type { HttpClient } from '../types.js';
|
|
112
|
-
import { buildRoutes } from '../nav-builder.js';
|
|
111
|
+
import type { HttpClient } from '../client/types.js';
|
|
112
|
+
import { buildRoutes } from '../client/nav-builder.js';
|
|
113
113
|
|
|
114
114
|
// Platform standard page: Dashboard.
|
|
115
115
|
//
|
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
|
|
198
198
|
<script setup lang="ts">
|
|
199
199
|
import { reactive, ref } from 'vue';
|
|
200
|
-
import {
|
|
200
|
+
import { useSuperAdminNotify } from '../quasar/notify.js';
|
|
201
201
|
import MfaPromptDialog from '../components/MfaPromptDialog.vue';
|
|
202
202
|
import type {
|
|
203
203
|
EmailHistoryRow,
|
|
@@ -231,7 +231,7 @@ const props = withDefaults(
|
|
|
231
231
|
},
|
|
232
232
|
);
|
|
233
233
|
|
|
234
|
-
const
|
|
234
|
+
const notify = useSuperAdminNotify();
|
|
235
235
|
|
|
236
236
|
const rows = ref<EmailHistoryRow[]>([]);
|
|
237
237
|
const loading = ref(false);
|
|
@@ -312,7 +312,7 @@ async function reload(): Promise<void> {
|
|
|
312
312
|
if (seq !== reloadSeq) return;
|
|
313
313
|
rows.value = [];
|
|
314
314
|
pagination.value.rowsNumber = 0;
|
|
315
|
-
|
|
315
|
+
notify('negative', errMsg(err));
|
|
316
316
|
} finally {
|
|
317
317
|
if (seq === reloadSeq) loading.value = false;
|
|
318
318
|
}
|
|
@@ -342,7 +342,7 @@ async function openDetail(row: EmailHistoryRow): Promise<void> {
|
|
|
342
342
|
detail.value = await props.loadEmailDetail(row.id);
|
|
343
343
|
} catch (err) {
|
|
344
344
|
detailOpen.value = false;
|
|
345
|
-
|
|
345
|
+
notify('negative', errMsg(err));
|
|
346
346
|
} finally {
|
|
347
347
|
detailLoading.value = false;
|
|
348
348
|
}
|
|
@@ -354,13 +354,9 @@ async function onResend(id: string): Promise<void> {
|
|
|
354
354
|
);
|
|
355
355
|
if (!ok) return;
|
|
356
356
|
if (result && result.success === false) {
|
|
357
|
-
|
|
358
|
-
type: 'negative',
|
|
359
|
-
message: result.message ?? 'Versand fehlgeschlagen',
|
|
360
|
-
position: 'top',
|
|
361
|
-
});
|
|
357
|
+
notify('negative', result.message ?? 'Versand fehlgeschlagen');
|
|
362
358
|
} else {
|
|
363
|
-
|
|
359
|
+
notify('positive', 'E-Mail erneut versendet');
|
|
364
360
|
}
|
|
365
361
|
await reload();
|
|
366
362
|
}
|
|
@@ -378,7 +374,7 @@ async function confirmDelete(): Promise<void> {
|
|
|
378
374
|
props.deleteEmail(id, code || undefined),
|
|
379
375
|
);
|
|
380
376
|
if (!ok) return;
|
|
381
|
-
|
|
377
|
+
notify('positive', 'Aus Verlauf entfernt');
|
|
382
378
|
if (detail.value?.id === id) detailOpen.value = false;
|
|
383
379
|
await reload();
|
|
384
380
|
}
|
|
@@ -394,7 +390,7 @@ async function runWrite<T>(
|
|
|
394
390
|
const result = await invoke('');
|
|
395
391
|
return { ok: true, result };
|
|
396
392
|
} catch (err) {
|
|
397
|
-
|
|
393
|
+
notify('negative', errMsg(err));
|
|
398
394
|
return { ok: false };
|
|
399
395
|
}
|
|
400
396
|
}
|
|
@@ -412,7 +408,7 @@ async function runWrite<T>(
|
|
|
412
408
|
continue;
|
|
413
409
|
}
|
|
414
410
|
showMfa.value = false;
|
|
415
|
-
|
|
411
|
+
notify('negative', errMsg(err));
|
|
416
412
|
return { ok: false };
|
|
417
413
|
}
|
|
418
414
|
}
|
|
@@ -122,11 +122,11 @@ import {
|
|
|
122
122
|
type PromotionResult,
|
|
123
123
|
type PromotionRow,
|
|
124
124
|
} from '@saasicat/types';
|
|
125
|
-
import { usePlans } from '../use-plans.js';
|
|
126
|
-
import { useMarketingProjections } from '../use-marketing-projections.js';
|
|
127
|
-
import { usePromotions } from '../use-promotions.js';
|
|
128
|
-
import { useCatalogEntries } from '../use-catalog-entries.js';
|
|
129
|
-
import { defaultHttpClient, type HttpClient } from '../types.js';
|
|
125
|
+
import { usePlans } from '../vue/use-plans.js';
|
|
126
|
+
import { useMarketingProjections } from '../vue/use-marketing-projections.js';
|
|
127
|
+
import { usePromotions } from '../vue/use-promotions.js';
|
|
128
|
+
import { useCatalogEntries } from '../vue/use-catalog-entries.js';
|
|
129
|
+
import { defaultHttpClient, type HttpClient } from '../client/types.js';
|
|
130
130
|
import MarketingPromotionsTab from '../components/MarketingPromotionsTab.vue';
|
|
131
131
|
import MarketingCatalogAdmin from './marketing-catalog/MarketingCatalogAdmin.vue';
|
|
132
132
|
import MarketingCatalogHeader from './marketing-catalog/MarketingCatalogHeader.vue';
|