@saasicat/ui-vue 0.24.2 → 0.26.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 +32 -8
- package/dist/{catalog-DJcfm5N2.d.cts → catalog-Dch1Ryw0.d.cts} +353 -69
- package/dist/{catalog-DJcfm5N2.d.ts → catalog-Dch1Ryw0.d.ts} +353 -69
- package/dist/{chunk-F7NRM6KI.js → chunk-BPF2BMCQ.js} +748 -24
- package/dist/{chunk-D74FFCCP.js → chunk-NEXTZZRQ.js} +95 -177
- package/dist/{chunk-TQQMKWN6.js → chunk-O3J3ITF2.js} +119 -7
- package/dist/client/index.cjs +758 -83
- package/dist/client/index.d.cts +414 -9
- package/dist/client/index.d.ts +414 -9
- package/dist/client/index.js +84 -12
- package/dist/index.cjs +1325 -294
- package/dist/index.d.cts +205 -15
- package/dist/index.d.ts +205 -15
- package/dist/index.js +566 -240
- package/dist/quasar/index.cjs +574 -62
- package/dist/quasar/index.d.cts +61 -6
- package/dist/quasar/index.d.ts +61 -6
- package/dist/quasar/index.js +83 -19
- package/dist/{use-sa-theme-OUBlaqgl.d.ts → resource-registry-D7Xjs-5f.d.cts} +157 -7
- package/dist/{use-sa-theme-B5t7oXph.d.cts → resource-registry-TaR7rtq0.d.ts} +157 -7
- package/package.json +4 -3
- package/src/client/admin-error.ts +552 -0
- package/src/client/admin-resource-client.ts +9 -12
- package/src/client/batch-column-fetcher.ts +2 -2
- package/src/client/boot-loader.ts +12 -1
- package/src/client/http/axios-http-client.ts +383 -0
- package/src/client/http/fetch-http-client.ts +89 -0
- package/src/client/http/index.ts +6 -0
- package/src/client/http-json.ts +82 -16
- package/src/client/i18n/messages/discovery.ts +0 -6
- package/src/client/i18n/messages/errors.ts +44 -0
- package/src/client/i18n/messages/marketing.ts +0 -6
- package/src/client/i18n/messages/promos.ts +0 -2
- package/src/client/i18n/messages/shell.ts +12 -0
- package/src/client/i18n/messages.ts +3 -0
- package/src/client/index.ts +6 -0
- package/src/client/manifest-loader.ts +65 -15
- package/src/client/resources/audit.resource.ts +25 -0
- package/src/client/resources/define-resource.ts +166 -0
- package/src/client/resources/index.ts +42 -0
- package/src/client/resources/list-resource.ts +176 -0
- package/src/client/resources/plans.resource.ts +169 -0
- package/src/client/resources/resource-request.ts +117 -0
- package/src/client/resources/tenants.resource.ts +27 -0
- package/src/client/types.ts +10 -3
- package/src/components/BundleVersionPublishDialog.vue +1 -1
- package/src/components/MarketingPromotionsTab.vue +263 -241
- package/src/components/ThemeSwitcher.vue +85 -0
- package/src/components/admin-page/AdminAccordion.vue +125 -0
- package/src/components/bundle-editor/BundleCreatePanel.vue +1 -1
- package/src/components/dialogs/PromoCodeDialogFields.vue +20 -20
- package/src/components/plan/PlanCycleToggle.vue +1 -1
- package/src/components/plan-detail/PlanVersionsPanel.vue +5 -2
- package/src/index.ts +5 -0
- package/src/pages-standard/AdminLayout.vue +57 -0
- package/src/pages-standard/AdminManifestErrorPage.vue +4 -3
- package/src/pages-standard/BundlesPage.vue +5 -35
- package/src/pages-standard/DiscoveryPage.vue +8 -1
- package/src/pages-standard/MarketingCatalogPage.vue +14 -3
- package/src/pages-standard/SuperAdminLoginPage.vue +23 -2
- package/src/pages-standard/SuperAdminSetupWizard.vue +37 -3
- package/src/pages-standard/bundles-page/BundleAccordionList.vue +30 -32
- package/src/pages-standard/discovery-page/DiscoveryFeatureCard.vue +80 -88
- package/src/pages-standard/discovery-page/DiscoveryQuotaCard.vue +73 -79
- package/src/pages-standard/marketing-catalog/MarketingCatalogAdmin.vue +44 -6
- package/src/pages-standard/marketing-catalog/MarketingCatalogPreview.vue +8 -2
- package/src/pages-tenant/PackageSnapshotPanel.vue +31 -2
- package/src/quasar/confirm.ts +83 -0
- package/src/quasar/create-super-admin-app.ts +84 -10
- package/src/quasar/dark-bridge.ts +47 -10
- package/src/quasar/index.ts +1 -0
- package/src/ui/theme/components/accordion.css +118 -0
- package/src/ui/theme/index.css +1 -0
- package/src/vue/create-admin-routes.ts +9 -1
- package/src/vue/platform-loaders.ts +12 -2
- package/src/vue/resource-registry.ts +211 -0
- package/src/vue/super-admin-context.ts +20 -5
- package/src/vue/ui-confirm.ts +76 -0
- package/src/vue/use-api-list.ts +50 -45
- package/src/vue/use-async-action.ts +170 -0
- package/src/vue/use-async-data.ts +83 -0
- package/src/vue/use-bundles.ts +34 -7
- package/src/vue/use-catalog-entries.ts +37 -12
- package/src/vue/use-discovery.ts +27 -6
- package/src/vue/use-marketing-projections.ts +29 -7
- package/src/vue/use-plans.ts +36 -8
- package/src/vue/use-promotions.ts +27 -7
- package/src/vue/use-resource-list.ts +272 -0
- package/src/vue/use-sa-theme.ts +34 -5
- package/src/vue/use-tenant-subscription-bundles.ts +22 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Component, App, InjectionKey, Ref, ComputedRef } from 'vue';
|
|
2
2
|
import { NavigationGuardWithThis } from 'vue-router';
|
|
3
3
|
import { ActionKey, ComponentKey, AdminManifest } from '@saasicat/types';
|
|
4
|
-
import { A as ActionHandler, H as HttpClient, S as SaLocale, a as SaMessages, b as SaLocaleOption, c as SaLocaleDefinition, d as SaMessagesOverrides, K as KvStore } from './catalog-
|
|
4
|
+
import { A as ActionHandler, H as HttpClient, S as SaLocale, a as SaMessages, b as SaLocaleOption, c as SaLocaleDefinition, d as SaMessagesOverrides, K as KvStore, R as ResourceDef, e as ResourceOps, f as ResourceContext, B as Bound, P as PlatformResources } from './catalog-Dch1Ryw0.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* App-specific branding data that the platform `AdminLayout` and other
|
|
@@ -26,6 +26,21 @@ interface SuperAdminEndpoints {
|
|
|
26
26
|
publicBootEndpoint?: string;
|
|
27
27
|
/** Post-login full-manifest endpoint, default `${apiBase}/manifest`. */
|
|
28
28
|
manifestEndpoint?: string;
|
|
29
|
+
/**
|
|
30
|
+
* The project whose catalogue this admin administers.
|
|
31
|
+
*
|
|
32
|
+
* App-wide and constant, which is why it belongs here. Today each page
|
|
33
|
+
* takes it as a prop and each consumer passes it again per route — the
|
|
34
|
+
* same value, written out once per page, with nothing keeping the copies
|
|
35
|
+
* in step.
|
|
36
|
+
*
|
|
37
|
+
* Optional in the type, but required in practice for an app that also
|
|
38
|
+
* passes `http`: that app gets the resource registry, the registry holds
|
|
39
|
+
* the plan catalogue, and binding a project-scoped resource without a
|
|
40
|
+
* project is refused at boot rather than sent as `?projectKey=`. An app
|
|
41
|
+
* that names no client gets no registry and needs no project.
|
|
42
|
+
*/
|
|
43
|
+
projectKey?: string;
|
|
29
44
|
}
|
|
30
45
|
type ExtensionLoader = () => Promise<Component | {
|
|
31
46
|
default: Component;
|
|
@@ -127,11 +142,11 @@ interface SuperAdminManifestGuardOptions {
|
|
|
127
142
|
* Discards the cached manifest, so the next `ensureLoaded()` fetches a
|
|
128
143
|
* fresh body instead of revalidating.
|
|
129
144
|
*
|
|
130
|
-
* Needed because the loader keeps an ETag in storage
|
|
131
|
-
*
|
|
132
|
-
* a
|
|
133
|
-
*
|
|
134
|
-
*
|
|
145
|
+
* Needed because the loader keeps an ETag in storage, which a full page
|
|
146
|
+
* reload does not touch. A plain retry therefore sends `If-None-Match`,
|
|
147
|
+
* and a 304 hands back the very manifest the app already had — so an
|
|
148
|
+
* operator retrying after a deployment would keep looking at the old one.
|
|
149
|
+
* Clearing first is what makes the retry ask an open question.
|
|
135
150
|
*
|
|
136
151
|
* `ManifestLoader.clearCache()` and the manifest store's reset both fit;
|
|
137
152
|
* pass whichever the app uses.
|
|
@@ -202,6 +217,53 @@ type UiNotify = (kind: UiNotifyKind, message: string, options?: UiNotifyOptions)
|
|
|
202
217
|
/** Vue inject key for the notify port (see `Symbol.for` note in super-admin-context.ts). */
|
|
203
218
|
declare const SUPER_ADMIN_NOTIFY_KEY: InjectionKey<UiNotify>;
|
|
204
219
|
|
|
220
|
+
/**
|
|
221
|
+
* How the confirming button is coloured. `negative` marks an action that
|
|
222
|
+
* destroys or revokes something; `primary` marks one that does not.
|
|
223
|
+
*/
|
|
224
|
+
type UiConfirmTone = 'primary' | 'negative';
|
|
225
|
+
/** Asks for a value along with the confirmation. */
|
|
226
|
+
interface UiConfirmPrompt {
|
|
227
|
+
/** Pre-filled value, e.g. the date a pilot currently ends on. */
|
|
228
|
+
initial?: string;
|
|
229
|
+
/** Input kind. Only the two the standard pages need. */
|
|
230
|
+
type?: 'text' | 'date';
|
|
231
|
+
}
|
|
232
|
+
interface UiConfirmRequest {
|
|
233
|
+
/** What is about to happen, naming the subject. */
|
|
234
|
+
title: string;
|
|
235
|
+
/**
|
|
236
|
+
* The consequence, in a sentence. For an action that cannot be reversed,
|
|
237
|
+
* say so here rather than asking "are you sure".
|
|
238
|
+
*/
|
|
239
|
+
message: string;
|
|
240
|
+
/** Label of the confirming button — a verb, not "OK". */
|
|
241
|
+
confirmLabel: string;
|
|
242
|
+
/** Label of the dismissing button. */
|
|
243
|
+
cancelLabel: string;
|
|
244
|
+
/** Default `primary`. Destructive actions pass `negative`. */
|
|
245
|
+
tone?: UiConfirmTone;
|
|
246
|
+
/** When set, the operator is asked for a value as well. */
|
|
247
|
+
prompt?: UiConfirmPrompt;
|
|
248
|
+
}
|
|
249
|
+
interface UiConfirmResult {
|
|
250
|
+
/** Whether the operator confirmed. Dismissing counts as `false`. */
|
|
251
|
+
ok: boolean;
|
|
252
|
+
/**
|
|
253
|
+
* What the operator entered, when the request carried a `prompt`.
|
|
254
|
+
* `undefined` otherwise, and whenever `ok` is `false`.
|
|
255
|
+
*/
|
|
256
|
+
value?: string;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Confirm port. Resolves once the operator has answered — an implementation
|
|
260
|
+
* that resolves `{ ok: true }` without asking would turn every guarded action
|
|
261
|
+
* into an unguarded one, so there is no such default.
|
|
262
|
+
*/
|
|
263
|
+
type UiConfirm = (request: UiConfirmRequest) => Promise<UiConfirmResult>;
|
|
264
|
+
/** Vue inject key for the confirm port (see `Symbol.for` note in super-admin-context.ts). */
|
|
265
|
+
declare const SUPER_ADMIN_CONFIRM_KEY: InjectionKey<UiConfirm>;
|
|
266
|
+
|
|
205
267
|
interface SuperAdminI18n {
|
|
206
268
|
/** Active UI locale — mutable; switching re-renders all catalog texts. */
|
|
207
269
|
locale: Ref<SaLocale>;
|
|
@@ -282,11 +344,21 @@ declare function useSaMessages<K extends keyof SaMessages>(namespace: K): Comput
|
|
|
282
344
|
|
|
283
345
|
type SaColorScheme = 'light' | 'dark' | 'system';
|
|
284
346
|
type SaResolvedScheme = 'light' | 'dark';
|
|
347
|
+
/** The schemes the switcher offers, in the order it lists them. */
|
|
348
|
+
declare const SA_COLOR_SCHEMES: readonly SaColorScheme[];
|
|
349
|
+
/** `KvStore` key holding the scheme the operator picked in the switcher. */
|
|
350
|
+
declare const SA_THEME_STORAGE_KEY = "saasicat.theme.scheme";
|
|
285
351
|
interface SaTheme {
|
|
286
352
|
/** What the operator picked. Writable — assigning switches the theme. */
|
|
287
353
|
scheme: Ref<SaColorScheme>;
|
|
288
354
|
/** What that means right now: `'system'` resolved against the OS. */
|
|
289
355
|
resolved: ComputedRef<SaResolvedScheme>;
|
|
356
|
+
/**
|
|
357
|
+
* Whether the shell renders its theme switcher. `false` when the app opted
|
|
358
|
+
* out or when `scheme` cannot be written to — a switcher that cannot change
|
|
359
|
+
* anything is worse than none.
|
|
360
|
+
*/
|
|
361
|
+
switcherEnabled: boolean;
|
|
290
362
|
/**
|
|
291
363
|
* Releases the `prefers-color-scheme` subscription and the persistence
|
|
292
364
|
* watcher. Idempotent.
|
|
@@ -312,6 +384,18 @@ interface SaThemeOptions {
|
|
|
312
384
|
persist?: boolean;
|
|
313
385
|
/** Injection seam for tests. */
|
|
314
386
|
storage?: KvStore;
|
|
387
|
+
/**
|
|
388
|
+
* Prefix for the persisted key, mirroring `createSuperAdminI18n`. Set it
|
|
389
|
+
* when several admin apps share one origin and must not inherit each
|
|
390
|
+
* other's colour scheme.
|
|
391
|
+
*/
|
|
392
|
+
storageKeyPrefix?: string;
|
|
393
|
+
/**
|
|
394
|
+
* Renders the theme switcher in the shell chrome, default `true`. Set
|
|
395
|
+
* `false` for a deployment that ships one appearance. A readonly `scheme`
|
|
396
|
+
* ref disables it on its own — no need to set this as well.
|
|
397
|
+
*/
|
|
398
|
+
switcher?: boolean;
|
|
315
399
|
}
|
|
316
400
|
/**
|
|
317
401
|
* Creates the theme context. `createSuperAdminApp()` makes one and the Quasar
|
|
@@ -330,4 +414,70 @@ declare const SA_THEME_KEY: InjectionKey<SaTheme>;
|
|
|
330
414
|
*/
|
|
331
415
|
declare function useSaTheme(): SaTheme;
|
|
332
416
|
|
|
333
|
-
|
|
417
|
+
/**
|
|
418
|
+
* An override receives the platform's own implementation as `next`, so it
|
|
419
|
+
* wraps rather than replaces. Recording an approval before a publish is three
|
|
420
|
+
* lines; rewriting the publish is not.
|
|
421
|
+
*/
|
|
422
|
+
type OpOverride<TOp> = TOp extends (http: HttpClient, ctx: ResourceContext, ...args: infer A) => Promise<infer R> ? (next: (...args: A) => Promise<R>, ...args: A) => Promise<R> : never;
|
|
423
|
+
interface ResourceOverride<TOps extends ResourceOps> {
|
|
424
|
+
/** Only the endpoint, project or locale this resource is read under. */
|
|
425
|
+
context?: Partial<ResourceContext>;
|
|
426
|
+
/** Only the transport, e.g. a client with a different auth. */
|
|
427
|
+
http?: HttpClient;
|
|
428
|
+
/** Individual operations, each wrapping the platform's. */
|
|
429
|
+
ops?: {
|
|
430
|
+
[K in keyof TOps]?: OpOverride<TOps[K]>;
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
/** Resources by key, in the shape a registry holds them. */
|
|
434
|
+
type ResourceMap = Record<string, ResourceDef<ResourceOps>>;
|
|
435
|
+
type ResourceOverrides<TMap extends ResourceMap> = {
|
|
436
|
+
[K in keyof TMap]?: ResourceOverride<TMap[K]['ops']>;
|
|
437
|
+
};
|
|
438
|
+
interface ResourceRegistry<TMap extends ResourceMap = ResourceMap> {
|
|
439
|
+
/** The bound operations of one resource. Throws for an unknown key. */
|
|
440
|
+
get<K extends keyof TMap>(key: K): Bound<TMap[K]['ops']>;
|
|
441
|
+
/** Every key the registry can answer for. */
|
|
442
|
+
keys(): string[];
|
|
443
|
+
}
|
|
444
|
+
interface CreateResourceRegistryOptions<TMap extends ResourceMap> {
|
|
445
|
+
/**
|
|
446
|
+
* Required — there is deliberately no fallback.
|
|
447
|
+
*
|
|
448
|
+
* A registry that quietly reached for `fetch` when nobody passed a client
|
|
449
|
+
* would send every request without the app's `Authorization` header, and
|
|
450
|
+
* the failure is silent: the call 401s, one card renders an em dash, and
|
|
451
|
+
* nothing is logged. Three such call sites existed in this package and had
|
|
452
|
+
* to be found by reading. Asking for the client makes them unwritable.
|
|
453
|
+
*/
|
|
454
|
+
http: HttpClient;
|
|
455
|
+
/** Read per call, so a switched locale or project applies to what follows. */
|
|
456
|
+
context: ResourceContext | (() => ResourceContext);
|
|
457
|
+
/** The resources on offer. */
|
|
458
|
+
resources: TMap;
|
|
459
|
+
/** Per-resource adjustments from the app. */
|
|
460
|
+
overrides?: ResourceOverrides<TMap>;
|
|
461
|
+
}
|
|
462
|
+
declare function createResourceRegistry<TMap extends ResourceMap>(options: CreateResourceRegistryOptions<TMap>): ResourceRegistry<TMap>;
|
|
463
|
+
/** Vue inject key for the registry (see `Symbol.for` note in super-admin-context.ts). */
|
|
464
|
+
declare const SUPER_ADMIN_RESOURCES_KEY: InjectionKey<ResourceRegistry>;
|
|
465
|
+
/**
|
|
466
|
+
* The operations of one resource, ready to call.
|
|
467
|
+
*
|
|
468
|
+
* Typed against the platform roster, so `useResource('plans').update(id, data)`
|
|
469
|
+
* carries the argument types the descriptor declares and an unknown key is a
|
|
470
|
+
* compile error. Without that mapping the key parameter erased the operations
|
|
471
|
+
* to `ResourceOps`, whose `never[]` constraint made *every* call with an
|
|
472
|
+
* argument a type error while accepting any misspelled resource name — the
|
|
473
|
+
* exact opposite of the guarantee the registry exists for.
|
|
474
|
+
*
|
|
475
|
+
* An app with its own resources passes its map as the second type argument.
|
|
476
|
+
*
|
|
477
|
+
* Throws when the shell has no registry rather than returning something
|
|
478
|
+
* inert — a page whose data silently never arrives is harder to diagnose than
|
|
479
|
+
* one that says what is missing.
|
|
480
|
+
*/
|
|
481
|
+
declare function useResource<K extends keyof TMap & string, TMap extends ResourceMap = PlatformResources>(key: K): Bound<TMap[K]['ops']>;
|
|
482
|
+
|
|
483
|
+
export { useSaTheme as $, type ActionsMap as A, SUPER_ADMIN_MANIFEST_KEY as B, type CreateResourceRegistryOptions as C, SUPER_ADMIN_NOTIFY_KEY as D, type ExtensionsMap as E, SUPER_ADMIN_RESOURCES_KEY as F, type SaColorScheme as G, type SaResolvedScheme as H, type InstallPlugin as I, type SuperAdminAuthGuardOptions as J, type SuperAdminLoginResult as K, type SuperAdminManifestGuardOptions as L, type UiConfirmPrompt as M, type UiConfirmResult as N, type OpOverride as O, type UiConfirmTone as P, type UiNotifyKind as Q, type ResourceOverrides as R, type SuperAdminGuardOptions as S, type UiNotifyOptions as T, type UiNotify as U, buildNavigationGuard as V, createResourceRegistry as W, createSaTheme as X, createSuperAdminI18n as Y, useResource as Z, useSaMessages as _, type SuperAdminBrand as a, useSuperAdminI18n as a0, type SuperAdminEndpoints as b, type SuperAdminLoginAdapter as c, type UiConfirm as d, type SuperAdminI18nOptions as e, type SaThemeOptions as f, type SuperAdminI18n as g, type SaTheme as h, type UiConfirmRequest as i, type ResourceMap as j, type ExtensionLoader as k, type ResourceOverride as l, type ResourceRegistry as m, SA_COLOR_SCHEMES as n, SA_LOCALE_STORAGE_KEY as o, SA_THEME_KEY as p, SA_THEME_STORAGE_KEY as q, SUPER_ADMIN_ACTIONS_KEY as r, SUPER_ADMIN_BRAND_KEY as s, SUPER_ADMIN_CONFIRM_KEY as t, SUPER_ADMIN_ENDPOINTS_KEY as u, SUPER_ADMIN_EXTENSIONS_KEY as v, SUPER_ADMIN_HTTP_KEY as w, SUPER_ADMIN_I18N_KEY as x, SUPER_ADMIN_LOGIN_ADAPTER_KEY as y, SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saasicat/ui-vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Vue 3 components, resource clients and composables for the SuperAdmin UI shell. Provides boot and manifest loaders, navigation, actions and standard pages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"src"
|
|
62
62
|
],
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@saasicat/types": "^0.
|
|
64
|
+
"@saasicat/types": "^0.26.0"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"pinia": "^2.0.0 || ^3.0.0",
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
"@types/node": "^25.6.0",
|
|
87
87
|
"@vitejs/plugin-vue": "^6.0.8",
|
|
88
88
|
"@vue/test-utils": "^2.4.11",
|
|
89
|
+
"axios": "^1.15.0",
|
|
89
90
|
"jsdom": "^30.0.1",
|
|
90
91
|
"pinia": "^3.0.0",
|
|
91
92
|
"quasar": "^2.24.0",
|
|
@@ -113,7 +114,7 @@
|
|
|
113
114
|
"access": "public"
|
|
114
115
|
},
|
|
115
116
|
"scripts": {
|
|
116
|
-
"build": "node -
|
|
117
|
+
"build": "node ../../scripts/build-and-prune.mjs tsup",
|
|
117
118
|
"typecheck": "vue-tsc --noEmit -p tsconfig.json && vue-tsc --noEmit -p tsconfig.tests.json",
|
|
118
119
|
"pretest": "pnpm run build",
|
|
119
120
|
"test": "node --test tests/**/*.test.js",
|