@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,173 @@
|
|
|
1
|
+
// createSuperAdminApp — universal bootstrap helper for SuperAdmin Vue apps.
|
|
2
|
+
// Bundles the Quasar/Pinia/Router setup that every consumer app rebuilds itself
|
|
3
|
+
// today, and exposes the platform contract maps (`extensions:`, `actions:`)
|
|
4
|
+
// via `provide()`.
|
|
5
|
+
//
|
|
6
|
+
// This module is the Quasar layer entry (`@saasicat/ui-vue/quasar`) — the only
|
|
7
|
+
// non-page module in the package that imports `quasar`. The injection keys,
|
|
8
|
+
// option types and the navigation guard live in the Vue layer
|
|
9
|
+
// (`super-admin-context.ts`) so the main entry stays Quasar-free.
|
|
10
|
+
//
|
|
11
|
+
// What the helper does NOT do:
|
|
12
|
+
// - Auth stores, login flows, JWT refresh — app-specific.
|
|
13
|
+
// - CSS imports (Quasar CSS, Material Icons, app theme) — these stay in the
|
|
14
|
+
// app's own `main.ts`, because tsup does not bundle CSS.
|
|
15
|
+
|
|
16
|
+
import { createApp, type App, type Component } from 'vue';
|
|
17
|
+
import { Quasar, Notify, Dialog, Loading, type QuasarPluginOptions } from 'quasar';
|
|
18
|
+
import { createPinia, type Pinia } from 'pinia';
|
|
19
|
+
import {
|
|
20
|
+
createRouter,
|
|
21
|
+
createWebHistory,
|
|
22
|
+
type RouteRecordRaw,
|
|
23
|
+
type Router,
|
|
24
|
+
type RouterHistory,
|
|
25
|
+
} from 'vue-router';
|
|
26
|
+
|
|
27
|
+
import { defaultHttpClient, type HttpClient } from '../client/types.js';
|
|
28
|
+
import {
|
|
29
|
+
SUPER_ADMIN_ACTIONS_KEY,
|
|
30
|
+
SUPER_ADMIN_BRAND_KEY,
|
|
31
|
+
SUPER_ADMIN_ENDPOINTS_KEY,
|
|
32
|
+
SUPER_ADMIN_EXTENSIONS_KEY,
|
|
33
|
+
SUPER_ADMIN_HTTP_KEY,
|
|
34
|
+
SUPER_ADMIN_LOGIN_ADAPTER_KEY,
|
|
35
|
+
SUPER_ADMIN_MANIFEST_KEY,
|
|
36
|
+
buildNavigationGuard,
|
|
37
|
+
type ActionsMap,
|
|
38
|
+
type ExtensionsMap,
|
|
39
|
+
type InstallPlugin,
|
|
40
|
+
type SuperAdminBrand,
|
|
41
|
+
type SuperAdminEndpoints,
|
|
42
|
+
type SuperAdminGuardOptions,
|
|
43
|
+
type SuperAdminLoginAdapter,
|
|
44
|
+
} from '../vue/super-admin-context.js';
|
|
45
|
+
import { SUPER_ADMIN_NOTIFY_KEY, type UiNotify } from '../vue/ui-notify.js';
|
|
46
|
+
import { quasarNotify } from './notify.js';
|
|
47
|
+
|
|
48
|
+
export interface CreateSuperAdminAppOptions extends SuperAdminGuardOptions {
|
|
49
|
+
/** App root component (`App.vue`). */
|
|
50
|
+
rootComponent: Component;
|
|
51
|
+
/** App branding (logo, name). */
|
|
52
|
+
brand: SuperAdminBrand;
|
|
53
|
+
/** Endpoint configuration. */
|
|
54
|
+
endpoints: SuperAdminEndpoints;
|
|
55
|
+
/** App's own routes (login, standard pages, bundle pages, …). */
|
|
56
|
+
appRoutes: RouteRecordRaw[];
|
|
57
|
+
/**
|
|
58
|
+
* Static `extensions:` map. Manifest `projectPages[].componentKey` is
|
|
59
|
+
* looked up in it (see Spec §4.4).
|
|
60
|
+
*/
|
|
61
|
+
extensions?: ExtensionsMap;
|
|
62
|
+
/**
|
|
63
|
+
* Static `actions:` map. Manifest `tenants.actions[].actionKey` is looked
|
|
64
|
+
* up in it.
|
|
65
|
+
*/
|
|
66
|
+
actions?: ActionsMap;
|
|
67
|
+
/**
|
|
68
|
+
* Optional: login adapter. When set, it is exposed via `provide()` for the
|
|
69
|
+
* shared `<SuperAdminLoginPage>` (from `pages-standard/`) — the app no
|
|
70
|
+
* longer needs to hold its own LoginPage Vue component.
|
|
71
|
+
*/
|
|
72
|
+
loginAdapter?: SuperAdminLoginAdapter;
|
|
73
|
+
/**
|
|
74
|
+
* Optional: router history variant, default `createWebHistory()`.
|
|
75
|
+
* Apps with a subpath mount override this.
|
|
76
|
+
*/
|
|
77
|
+
routerHistory?: RouterHistory;
|
|
78
|
+
/**
|
|
79
|
+
* Optional: Quasar configuration. Default loads `Notify`/`Dialog`/`Loading`
|
|
80
|
+
* with the established consumer convention (`top-right`, 3 s).
|
|
81
|
+
*/
|
|
82
|
+
quasarOptions?: Partial<QuasarPluginOptions>;
|
|
83
|
+
/**
|
|
84
|
+
* Optional: notify port for the standard pages' toasts. Default is the
|
|
85
|
+
* Quasar `Notify` implementation — apps with their own notification
|
|
86
|
+
* center replace it here without touching the pages.
|
|
87
|
+
*/
|
|
88
|
+
notify?: UiNotify;
|
|
89
|
+
/**
|
|
90
|
+
* Optional: additional Vue plugins (e.g. an app's own NotificationCenter)
|
|
91
|
+
* that are installed after the platform setup, before the mount.
|
|
92
|
+
*/
|
|
93
|
+
installPlugins?: InstallPlugin[];
|
|
94
|
+
/**
|
|
95
|
+
* Optional: `HttpClient` for all pre-login calls (boot, first-run setup).
|
|
96
|
+
* Default `defaultHttpClient()` (= `fetch`). Consumers pass their own
|
|
97
|
+
* variant through (auth header, baseURL, retry) — it then applies uniformly,
|
|
98
|
+
* including for the setup wizard. Consumed via `useSuperAdminHttp()`.
|
|
99
|
+
*/
|
|
100
|
+
http?: HttpClient;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface SuperAdminAppHandle {
|
|
104
|
+
app: App;
|
|
105
|
+
router: Router;
|
|
106
|
+
pinia: Pinia;
|
|
107
|
+
/** Mounts the app on a selector. Returns the root component instance. */
|
|
108
|
+
mount: (selector: string | Element) => ReturnType<App['mount']>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const DEFAULT_QUASAR_OPTIONS: QuasarPluginOptions = {
|
|
112
|
+
plugins: { Notify, Dialog, Loading },
|
|
113
|
+
config: { notify: { position: 'top-right', timeout: 3000 } },
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Universal bootstrap function for SuperAdmin apps. Replaces the `main.ts`
|
|
118
|
+
* boilerplate duplicated per app today (Quasar + Pinia + Router + manifest
|
|
119
|
+
* guard) and exposes the platform maps via `provide()` for downstream
|
|
120
|
+
* components.
|
|
121
|
+
*/
|
|
122
|
+
export function createSuperAdminApp(options: CreateSuperAdminAppOptions): SuperAdminAppHandle {
|
|
123
|
+
const app = createApp(options.rootComponent);
|
|
124
|
+
|
|
125
|
+
app.use(Quasar, options.quasarOptions ?? DEFAULT_QUASAR_OPTIONS);
|
|
126
|
+
|
|
127
|
+
const pinia = createPinia();
|
|
128
|
+
app.use(pinia);
|
|
129
|
+
|
|
130
|
+
const router = createRouter({
|
|
131
|
+
history: options.routerHistory ?? createWebHistory(),
|
|
132
|
+
routes: options.appRoutes,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const navGuard = buildNavigationGuard(options);
|
|
136
|
+
if (navGuard) {
|
|
137
|
+
router.beforeEach(navGuard);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
app.use(router);
|
|
141
|
+
|
|
142
|
+
const endpoints: Required<SuperAdminEndpoints> = {
|
|
143
|
+
apiBase: options.endpoints.apiBase,
|
|
144
|
+
publicBootEndpoint:
|
|
145
|
+
options.endpoints.publicBootEndpoint ?? `${options.endpoints.apiBase}/boot`,
|
|
146
|
+
manifestEndpoint:
|
|
147
|
+
options.endpoints.manifestEndpoint ?? `${options.endpoints.apiBase}/manifest`,
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
app.provide(SUPER_ADMIN_BRAND_KEY, { tag: 'SuperAdmin', ...options.brand });
|
|
151
|
+
app.provide(SUPER_ADMIN_ENDPOINTS_KEY, endpoints);
|
|
152
|
+
app.provide(SUPER_ADMIN_EXTENSIONS_KEY, options.extensions ?? {});
|
|
153
|
+
app.provide(SUPER_ADMIN_ACTIONS_KEY, options.actions ?? {});
|
|
154
|
+
app.provide(SUPER_ADMIN_NOTIFY_KEY, options.notify ?? quasarNotify);
|
|
155
|
+
if (options.manifestGuard?.getManifest) {
|
|
156
|
+
app.provide(SUPER_ADMIN_MANIFEST_KEY, options.manifestGuard.getManifest);
|
|
157
|
+
}
|
|
158
|
+
if (options.loginAdapter) {
|
|
159
|
+
app.provide(SUPER_ADMIN_LOGIN_ADAPTER_KEY, options.loginAdapter);
|
|
160
|
+
}
|
|
161
|
+
app.provide(SUPER_ADMIN_HTTP_KEY, options.http ?? defaultHttpClient());
|
|
162
|
+
|
|
163
|
+
for (const plugin of options.installPlugins ?? []) {
|
|
164
|
+
plugin(app);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
app,
|
|
169
|
+
router,
|
|
170
|
+
pinia,
|
|
171
|
+
mount: (selector) => app.mount(selector),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// @saasicat/ui-vue/quasar — the Quasar layer entry: everything that installs
|
|
2
|
+
// or calls Quasar from TypeScript. Kept out of the main entry so that
|
|
3
|
+
// `import ... from '@saasicat/ui-vue'` never executes a `quasar` import
|
|
4
|
+
// (Quasar is an optional peer dependency).
|
|
5
|
+
//
|
|
6
|
+
// The Quasar standard pages themselves are consumed as raw SFCs via the
|
|
7
|
+
// `./pages-standard/*`, `./pages-tenant/*` and `./components/*` subpath
|
|
8
|
+
// exports, not through this bundle (tsup ignores `.vue`).
|
|
9
|
+
|
|
10
|
+
export * from './create-super-admin-app.js';
|
|
11
|
+
export * from './notify.js';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Quasar implementation of the UI notify port.
|
|
2
|
+
//
|
|
3
|
+
// Standard pages resolve the port via `useSuperAdminNotify()`: the app-provided
|
|
4
|
+
// port wins, otherwise the Quasar default below. The fallback keeps apps
|
|
5
|
+
// working that mount the standard pages without `createSuperAdminApp()`
|
|
6
|
+
// (their own `main.ts` installs the Quasar Notify plugin, as before).
|
|
7
|
+
|
|
8
|
+
import { inject } from 'vue';
|
|
9
|
+
import { Notify } from 'quasar';
|
|
10
|
+
|
|
11
|
+
import { SUPER_ADMIN_NOTIFY_KEY, type UiNotify } from '../vue/ui-notify.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Quasar-backed notify port: `position: 'top'` matches the convention the
|
|
15
|
+
* standard pages used with their previous direct `$q.notify` calls.
|
|
16
|
+
*/
|
|
17
|
+
export const quasarNotify: UiNotify = (kind, message, options) => {
|
|
18
|
+
Notify.create({
|
|
19
|
+
type: kind,
|
|
20
|
+
message,
|
|
21
|
+
position: 'top',
|
|
22
|
+
caption: options?.caption,
|
|
23
|
+
timeout: options?.timeoutMs,
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/** Returns the app-provided notify port, falling back to the Quasar default. */
|
|
28
|
+
export function useSuperAdminNotify(): UiNotify {
|
|
29
|
+
return inject(SUPER_ADMIN_NOTIFY_KEY, quasarNotify);
|
|
30
|
+
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import { defineStore, type StoreDefinition } from 'pinia';
|
|
14
14
|
import { ref, type Ref } from 'vue';
|
|
15
15
|
import type { AdminManifest } from '@saasicat/types';
|
|
16
|
-
import type { ManifestLoader } from '
|
|
16
|
+
import type { ManifestLoader } from '../client/manifest-loader.js';
|
|
17
17
|
|
|
18
18
|
export interface ManifestStoreState {
|
|
19
19
|
manifest: Ref<AdminManifest | null>;
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
// a single constant that `main.ts` passes to `createSuperAdminApp()` and that
|
|
6
6
|
// the loader wiring from this helper consumes.
|
|
7
7
|
|
|
8
|
-
import { BootLoader } from '
|
|
9
|
-
import { ManifestLoader } from '
|
|
10
|
-
import type { SuperAdminEndpoints } from './
|
|
11
|
-
import type { HttpClient, KvStore } from '
|
|
8
|
+
import { BootLoader } from '../client/boot-loader.js';
|
|
9
|
+
import { ManifestLoader } from '../client/manifest-loader.js';
|
|
10
|
+
import type { SuperAdminEndpoints } from './super-admin-context.js';
|
|
11
|
+
import type { HttpClient, KvStore } from '../client/types.js';
|
|
12
12
|
|
|
13
13
|
export interface CreatePlatformLoadersOptions {
|
|
14
14
|
/**
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
SUPER_ADMIN_EXTENSIONS_KEY,
|
|
15
15
|
SUPER_ADMIN_MANIFEST_KEY,
|
|
16
16
|
type ExtensionsMap,
|
|
17
|
-
} from './
|
|
17
|
+
} from './super-admin-context.js';
|
|
18
18
|
|
|
19
19
|
// `defineAsyncComponent` gets its own wrapper component per loader
|
|
20
20
|
// function — without a cache, re-renders would recreate the same component
|
|
@@ -1,29 +1,17 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
1
|
+
// SuperAdmin shell contract — injection keys, option types and the
|
|
2
|
+
// navigation guard shared between the Quasar bootstrap
|
|
3
|
+
// (`createSuperAdminApp()`, `@saasicat/ui-vue/quasar`) and the framework
|
|
4
|
+
// components/composables in this package.
|
|
5
5
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
// - CSS imports (Quasar CSS, Material Icons, app theme) — these stay in the
|
|
9
|
-
// app's own `main.ts`, because tsup does not bundle CSS.
|
|
6
|
+
// Lives in the Vue layer (no Quasar import) so that the main entry and all
|
|
7
|
+
// composables stay consumable without Quasar being installed.
|
|
10
8
|
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { createPinia, type Pinia } from 'pinia';
|
|
14
|
-
import {
|
|
15
|
-
createRouter,
|
|
16
|
-
createWebHistory,
|
|
17
|
-
type NavigationGuardWithThis,
|
|
18
|
-
type RouteLocationNormalized,
|
|
19
|
-
type RouteRecordRaw,
|
|
20
|
-
type Router,
|
|
21
|
-
type RouterHistory,
|
|
22
|
-
} from 'vue-router';
|
|
9
|
+
import type { App, Component, InjectionKey } from 'vue';
|
|
10
|
+
import type { NavigationGuardWithThis, RouteLocationNormalized } from 'vue-router';
|
|
23
11
|
|
|
24
12
|
import type { ActionKey, AdminManifest, ComponentKey } from '@saasicat/types';
|
|
25
|
-
import type { ActionHandler } from '
|
|
26
|
-
import {
|
|
13
|
+
import type { ActionHandler } from '../client/action-registry.js';
|
|
14
|
+
import type { HttpClient } from '../client/types.js';
|
|
27
15
|
|
|
28
16
|
/**
|
|
29
17
|
* App-specific branding data that the platform `AdminLayout` and other
|
|
@@ -133,25 +121,11 @@ export interface SuperAdminManifestGuardOptions {
|
|
|
133
121
|
errorRoute?: string;
|
|
134
122
|
}
|
|
135
123
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
/** Endpoint configuration. */
|
|
142
|
-
endpoints: SuperAdminEndpoints;
|
|
143
|
-
/** App's own routes (login, standard pages, bundle pages, …). */
|
|
144
|
-
appRoutes: RouteRecordRaw[];
|
|
145
|
-
/**
|
|
146
|
-
* Static `extensions:` map. Manifest `projectPages[].componentKey` is
|
|
147
|
-
* looked up in it (see Spec §4.4).
|
|
148
|
-
*/
|
|
149
|
-
extensions?: ExtensionsMap;
|
|
150
|
-
/**
|
|
151
|
-
* Static `actions:` map. Manifest `tenants.actions[].actionKey` is looked
|
|
152
|
-
* up in it.
|
|
153
|
-
*/
|
|
154
|
-
actions?: ActionsMap;
|
|
124
|
+
/**
|
|
125
|
+
* Guard configuration shared by `buildNavigationGuard()` and
|
|
126
|
+
* `createSuperAdminApp()` (which embeds both fields in its options).
|
|
127
|
+
*/
|
|
128
|
+
export interface SuperAdminGuardOptions {
|
|
155
129
|
/**
|
|
156
130
|
* Optional: auth guard. When set, `router.beforeEach` is wired up
|
|
157
131
|
* automatically — `to.meta.public === true` bypasses the guard.
|
|
@@ -162,47 +136,11 @@ export interface CreateSuperAdminAppOptions {
|
|
|
162
136
|
* render until the manifest is loaded (prevents sidebar flicker).
|
|
163
137
|
*/
|
|
164
138
|
manifestGuard?: SuperAdminManifestGuardOptions;
|
|
165
|
-
/**
|
|
166
|
-
* Optional: login adapter. When set, it is exposed via `provide()` for the
|
|
167
|
-
* shared `<SuperAdminLoginPage>` (from `pages-standard/`) — the app no
|
|
168
|
-
* longer needs to hold its own LoginPage Vue component.
|
|
169
|
-
*/
|
|
170
|
-
loginAdapter?: SuperAdminLoginAdapter;
|
|
171
|
-
/**
|
|
172
|
-
* Optional: router history variant, default `createWebHistory()`.
|
|
173
|
-
* Apps with a subpath mount override this.
|
|
174
|
-
*/
|
|
175
|
-
routerHistory?: RouterHistory;
|
|
176
|
-
/**
|
|
177
|
-
* Optional: Quasar configuration. Default loads `Notify`/`Dialog`/`Loading`
|
|
178
|
-
* with the established consumer convention (`top-right`, 3 s).
|
|
179
|
-
*/
|
|
180
|
-
quasarOptions?: Partial<QuasarPluginOptions>;
|
|
181
|
-
/**
|
|
182
|
-
* Optional: additional Vue plugins (e.g. an app's own NotificationCenter)
|
|
183
|
-
* that are installed after the platform setup, before the mount.
|
|
184
|
-
*/
|
|
185
|
-
installPlugins?: Array<(app: App) => void>;
|
|
186
|
-
/**
|
|
187
|
-
* Optional: `HttpClient` for all pre-login calls (boot, first-run setup).
|
|
188
|
-
* Default `defaultHttpClient()` (= `fetch`). Consumers pass their own
|
|
189
|
-
* variant through (auth header, baseURL, retry) — it then applies uniformly,
|
|
190
|
-
* including for the setup wizard. Consumed via `useSuperAdminHttp()`.
|
|
191
|
-
*/
|
|
192
|
-
http?: HttpClient;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export interface SuperAdminAppHandle {
|
|
196
|
-
app: App;
|
|
197
|
-
router: Router;
|
|
198
|
-
pinia: Pinia;
|
|
199
|
-
/** Mounts the app on a selector. Returns the root component instance. */
|
|
200
|
-
mount: (selector: string | Element) => ReturnType<App['mount']>;
|
|
201
139
|
}
|
|
202
140
|
|
|
203
141
|
// Vue inject keys are registered globally via `Symbol.for(...)`. Reason:
|
|
204
142
|
// apps import `createSuperAdminApp` (and thus `app.provide(KEY, ...)`) from
|
|
205
|
-
// the built `dist
|
|
143
|
+
// the built `dist/` bundles, but shared `.vue` pages in the
|
|
206
144
|
// `pages-standard/` directory directly from `src/`. Both paths produce two
|
|
207
145
|
// independent module instances — with local `Symbol(...)` the identity would
|
|
208
146
|
// differ, and `inject()` would always throw "not found". `Symbol.for(...)`
|
|
@@ -241,68 +179,11 @@ export const SUPER_ADMIN_HTTP_KEY: InjectionKey<HttpClient> = Symbol.for(
|
|
|
241
179
|
'@saasicat/ui-vue/SUPER_ADMIN_HTTP',
|
|
242
180
|
);
|
|
243
181
|
|
|
244
|
-
const DEFAULT_QUASAR_OPTIONS: QuasarPluginOptions = {
|
|
245
|
-
plugins: { Notify, Dialog, Loading },
|
|
246
|
-
config: { notify: { position: 'top-right', timeout: 3000 } },
|
|
247
|
-
};
|
|
248
|
-
|
|
249
182
|
/**
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
* guard) and exposes the platform maps via `provide()` for downstream
|
|
253
|
-
* components.
|
|
183
|
+
* Additional Vue plugins (e.g. an app's own NotificationCenter) that a
|
|
184
|
+
* bootstrap installs after the platform setup, before the mount.
|
|
254
185
|
*/
|
|
255
|
-
export
|
|
256
|
-
const app = createApp(options.rootComponent);
|
|
257
|
-
|
|
258
|
-
app.use(Quasar, options.quasarOptions ?? DEFAULT_QUASAR_OPTIONS);
|
|
259
|
-
|
|
260
|
-
const pinia = createPinia();
|
|
261
|
-
app.use(pinia);
|
|
262
|
-
|
|
263
|
-
const router = createRouter({
|
|
264
|
-
history: options.routerHistory ?? createWebHistory(),
|
|
265
|
-
routes: options.appRoutes,
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
const navGuard = buildNavigationGuard(options);
|
|
269
|
-
if (navGuard) {
|
|
270
|
-
router.beforeEach(navGuard);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
app.use(router);
|
|
274
|
-
|
|
275
|
-
const endpoints: Required<SuperAdminEndpoints> = {
|
|
276
|
-
apiBase: options.endpoints.apiBase,
|
|
277
|
-
publicBootEndpoint:
|
|
278
|
-
options.endpoints.publicBootEndpoint ?? `${options.endpoints.apiBase}/boot`,
|
|
279
|
-
manifestEndpoint:
|
|
280
|
-
options.endpoints.manifestEndpoint ?? `${options.endpoints.apiBase}/manifest`,
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
app.provide(SUPER_ADMIN_BRAND_KEY, { tag: 'SuperAdmin', ...options.brand });
|
|
284
|
-
app.provide(SUPER_ADMIN_ENDPOINTS_KEY, endpoints);
|
|
285
|
-
app.provide(SUPER_ADMIN_EXTENSIONS_KEY, options.extensions ?? {});
|
|
286
|
-
app.provide(SUPER_ADMIN_ACTIONS_KEY, options.actions ?? {});
|
|
287
|
-
if (options.manifestGuard?.getManifest) {
|
|
288
|
-
app.provide(SUPER_ADMIN_MANIFEST_KEY, options.manifestGuard.getManifest);
|
|
289
|
-
}
|
|
290
|
-
if (options.loginAdapter) {
|
|
291
|
-
app.provide(SUPER_ADMIN_LOGIN_ADAPTER_KEY, options.loginAdapter);
|
|
292
|
-
}
|
|
293
|
-
app.provide(SUPER_ADMIN_HTTP_KEY, options.http ?? defaultHttpClient());
|
|
294
|
-
|
|
295
|
-
for (const plugin of options.installPlugins ?? []) {
|
|
296
|
-
plugin(app);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
return {
|
|
300
|
-
app,
|
|
301
|
-
router,
|
|
302
|
-
pinia,
|
|
303
|
-
mount: (selector) => app.mount(selector),
|
|
304
|
-
};
|
|
305
|
-
}
|
|
186
|
+
export type InstallPlugin = (app: App) => void;
|
|
306
187
|
|
|
307
188
|
/**
|
|
308
189
|
* Internal helper, exported for isolated unit tests of the navigation
|
|
@@ -310,7 +191,7 @@ export function createSuperAdminApp(options: CreateSuperAdminAppOptions): SuperA
|
|
|
310
191
|
* `createSuperAdminApp()`, not this helper directly.
|
|
311
192
|
*/
|
|
312
193
|
export function buildNavigationGuard(
|
|
313
|
-
options:
|
|
194
|
+
options: SuperAdminGuardOptions,
|
|
314
195
|
): NavigationGuardWithThis<undefined> | null {
|
|
315
196
|
const { authGuard, manifestGuard } = options;
|
|
316
197
|
if (!authGuard && !manifestGuard) return null;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// UI notify port — the single toast/snackbar seam between platform pages and
|
|
2
|
+
// the host app. Standard pages emit user feedback exclusively through this
|
|
3
|
+
// port; which component library renders it is the app's choice.
|
|
4
|
+
//
|
|
5
|
+
// `createSuperAdminApp()` (`@saasicat/ui-vue/quasar`) provides a
|
|
6
|
+
// Quasar-backed default; apps override it via
|
|
7
|
+
// `createSuperAdminApp({ notify })` or by providing the key themselves.
|
|
8
|
+
|
|
9
|
+
import type { InjectionKey } from 'vue';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Feedback kind, aligned with the established page conventions
|
|
13
|
+
* (`positive` = success, `negative` = error).
|
|
14
|
+
*/
|
|
15
|
+
export type UiNotifyKind = 'positive' | 'negative' | 'warning' | 'info';
|
|
16
|
+
|
|
17
|
+
export interface UiNotifyOptions {
|
|
18
|
+
/** Secondary line below the message (e.g. changed fields, one-time password). */
|
|
19
|
+
caption?: string;
|
|
20
|
+
/** Display duration in ms; implementations fall back to their default when unset. */
|
|
21
|
+
timeoutMs?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Notify port. Compatible with the `(kind, message)` callbacks pages already accept. */
|
|
25
|
+
export type UiNotify = (kind: UiNotifyKind, message: string, options?: UiNotifyOptions) => void;
|
|
26
|
+
|
|
27
|
+
/** Vue inject key for the notify port (see `Symbol.for` note in super-admin-context.ts). */
|
|
28
|
+
export const SUPER_ADMIN_NOTIFY_KEY: InjectionKey<UiNotify> = Symbol.for(
|
|
29
|
+
'@saasicat/ui-vue/SUPER_ADMIN_NOTIFY',
|
|
30
|
+
);
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { computed, type ComputedRef, type Ref } from 'vue';
|
|
9
9
|
import type { AdminManifest } from '@saasicat/types';
|
|
10
|
-
import { ActionRegistry, type ActionHandler } from '
|
|
10
|
+
import { ActionRegistry, type ActionHandler } from '../client/action-registry.js';
|
|
11
11
|
|
|
12
12
|
export interface UseActionsResult {
|
|
13
13
|
registry: ComputedRef<ActionRegistry | null>;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// Direct use is also allowed for custom endpoints.
|
|
6
6
|
|
|
7
7
|
import { ref, watch, type Ref } from 'vue';
|
|
8
|
-
import { defaultHttpClient, type HttpClient } from '
|
|
8
|
+
import { defaultHttpClient, type HttpClient } from '../client/types.js';
|
|
9
9
|
|
|
10
10
|
export interface ApiListResponse<T> {
|
|
11
11
|
items: T[];
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
BatchColumnFetcher,
|
|
13
13
|
type BatchColumnData,
|
|
14
14
|
type BatchColumnFetcherOptions,
|
|
15
|
-
} from '
|
|
15
|
+
} from '../client/batch-column-fetcher.js';
|
|
16
16
|
|
|
17
17
|
export interface UseBatchColumnsResult {
|
|
18
18
|
/** Data per column key (`columnKey → tenantId → value`). */
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// `mfaCode` parameter through.
|
|
12
12
|
|
|
13
13
|
import { computed, ref, type ComputedRef, type Ref } from 'vue';
|
|
14
|
-
import { defaultHttpClient, type HttpClient } from '
|
|
14
|
+
import { defaultHttpClient, type HttpClient } from '../client/types.js';
|
|
15
15
|
|
|
16
16
|
export type BulkItemKind = 'plan';
|
|
17
17
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import { ref, watch, type Ref } from 'vue';
|
|
13
13
|
import type { BundleRow, BundleVersionRow } from '@saasicat/types';
|
|
14
|
-
import { defaultHttpClient, type HttpClient } from '
|
|
14
|
+
import { defaultHttpClient, type HttpClient } from '../client/types.js';
|
|
15
15
|
|
|
16
16
|
export interface UseBundleVersionsMapOptions {
|
|
17
17
|
adminEndpoint: string;
|
|
@@ -16,7 +16,7 @@ import type {
|
|
|
16
16
|
UpdateBundleData,
|
|
17
17
|
UpdateBundleVersionDraftData,
|
|
18
18
|
} from '@saasicat/types';
|
|
19
|
-
import { defaultHttpClient, type HttpClient } from '
|
|
19
|
+
import { defaultHttpClient, type HttpClient } from '../client/types.js';
|
|
20
20
|
|
|
21
21
|
export interface UseBundlesOptions {
|
|
22
22
|
/**
|
|
@@ -14,7 +14,7 @@ import type {
|
|
|
14
14
|
UpdateBusinessTypeData,
|
|
15
15
|
UpdateBusinessTypeVersionDraftData,
|
|
16
16
|
} from '@saasicat/types';
|
|
17
|
-
import { defaultHttpClient, type HttpClient } from '
|
|
17
|
+
import { defaultHttpClient, type HttpClient } from '../client/types.js';
|
|
18
18
|
|
|
19
19
|
export interface UseBusinessTypesOptions {
|
|
20
20
|
adminEndpoint: string;
|
|
@@ -19,7 +19,7 @@ import type {
|
|
|
19
19
|
SyncDiscoveryResult,
|
|
20
20
|
UpdateCatalogEntryBaseData,
|
|
21
21
|
} from '@saasicat/types';
|
|
22
|
-
import { defaultHttpClient, type HttpClient } from '
|
|
22
|
+
import { defaultHttpClient, type HttpClient } from '../client/types.js';
|
|
23
23
|
|
|
24
24
|
export interface UseCatalogEntriesOptions {
|
|
25
25
|
/** Admin endpoint prefix incl. globalPrefix (`/api/admin`, `/api/v1/admin`). */
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import { ref, type Ref } from 'vue';
|
|
14
14
|
import type { DiscoverySnapshot } from '@saasicat/types';
|
|
15
|
-
import { defaultHttpClient, type HttpClient } from '
|
|
15
|
+
import { defaultHttpClient, type HttpClient } from '../client/types.js';
|
|
16
16
|
|
|
17
17
|
export interface UseDiscoveryOptions {
|
|
18
18
|
/**
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// expose the snapshot (it lives in saas-platform-nest/entitlement).
|
|
13
13
|
|
|
14
14
|
import { ref, type Ref } from 'vue';
|
|
15
|
-
import { defaultHttpClient, type HttpClient } from '
|
|
15
|
+
import { defaultHttpClient, type HttpClient } from '../client/types.js';
|
|
16
16
|
|
|
17
17
|
export interface EntitlementSnapshotShape {
|
|
18
18
|
plan: string;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import { ref, watch, type Ref } from 'vue';
|
|
12
12
|
import type { PlanRow, PlanVersionRow } from '@saasicat/types';
|
|
13
|
-
import { defaultHttpClient, type HttpClient } from '
|
|
13
|
+
import { defaultHttpClient, type HttpClient } from '../client/types.js';
|
|
14
14
|
|
|
15
15
|
export interface UseLivePlanVersionsOptions {
|
|
16
16
|
adminEndpoint: string;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { ref, type Ref } from 'vue';
|
|
11
11
|
import type { AdminManifest } from '@saasicat/types';
|
|
12
|
-
import { ManifestLoader, type ManifestLoaderOptions } from '
|
|
12
|
+
import { ManifestLoader, type ManifestLoaderOptions } from '../client/manifest-loader.js';
|
|
13
13
|
|
|
14
14
|
export interface UseManifestResult {
|
|
15
15
|
manifest: Ref<AdminManifest | null>;
|
|
@@ -13,7 +13,7 @@ import type {
|
|
|
13
13
|
MarketingProjectionRow,
|
|
14
14
|
UpdateMarketingProjectionData,
|
|
15
15
|
} from '@saasicat/types';
|
|
16
|
-
import { defaultHttpClient, type HttpClient } from '
|
|
16
|
+
import { defaultHttpClient, type HttpClient } from '../client/types.js';
|
|
17
17
|
|
|
18
18
|
export interface UseMarketingProjectionsOptions {
|
|
19
19
|
adminEndpoint: string;
|
|
@@ -13,7 +13,7 @@ import type {
|
|
|
13
13
|
UpdatePlanData,
|
|
14
14
|
UpdatePlanVersionDraftData,
|
|
15
15
|
} from '@saasicat/types';
|
|
16
|
-
import { defaultHttpClient, type HttpClient } from '
|
|
16
|
+
import { defaultHttpClient, type HttpClient } from '../client/types.js';
|
|
17
17
|
|
|
18
18
|
export interface UsePlansOptions {
|
|
19
19
|
/**
|
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
PromotionRow,
|
|
11
11
|
UpdatePromotionData,
|
|
12
12
|
} from '@saasicat/types';
|
|
13
|
-
import { defaultHttpClient, type HttpClient } from '
|
|
13
|
+
import { defaultHttpClient, type HttpClient } from '../client/types.js';
|
|
14
14
|
|
|
15
15
|
export interface UsePromotionsOptions {
|
|
16
16
|
adminEndpoint: string;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import { ref, type Ref } from 'vue';
|
|
10
10
|
import type { PublicBootResponse } from '@saasicat/types';
|
|
11
|
-
import { BootLoader, type BootLoaderOptions } from '
|
|
11
|
+
import { BootLoader, type BootLoaderOptions } from '../client/boot-loader.js';
|
|
12
12
|
|
|
13
13
|
export interface UsePublicBootResult {
|
|
14
14
|
boot: Ref<PublicBootResponse | null>;
|