@saasicat/ui-vue 0.8.0 → 0.10.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/dist/{chunk-7N3CJTOA.js → chunk-66BUSVC5.js} +72 -1
- package/dist/client/index.cjs +72 -0
- package/dist/client/index.d.cts +35 -2
- package/dist/client/index.d.ts +35 -2
- package/dist/client/index.js +3 -1
- package/dist/index.cjs +72 -0
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -1
- package/package.json +5 -5
- package/src/client/admin-resource-client.ts +112 -0
- package/src/client/index.ts +1 -0
|
@@ -471,6 +471,76 @@ var BatchColumnFetcher = class {
|
|
|
471
471
|
}
|
|
472
472
|
};
|
|
473
473
|
|
|
474
|
+
// src/client/admin-resource-client.ts
|
|
475
|
+
function createAdminResourceClient(options) {
|
|
476
|
+
const base = options.adminBase ?? "/api/v1/admin";
|
|
477
|
+
const tenantsEndpoint = `${base}/tenants`;
|
|
478
|
+
const getJson2 = async (url) => {
|
|
479
|
+
const response = await options.http(url, { method: "GET" });
|
|
480
|
+
assertSuccess(response.status, "GET", url);
|
|
481
|
+
return await response.json();
|
|
482
|
+
};
|
|
483
|
+
const sendJson = async (method, url, body) => {
|
|
484
|
+
const response = await options.http(url, {
|
|
485
|
+
method,
|
|
486
|
+
headers: { "content-type": "application/json" },
|
|
487
|
+
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
488
|
+
});
|
|
489
|
+
assertSuccess(response.status, method, url);
|
|
490
|
+
return await response.json();
|
|
491
|
+
};
|
|
492
|
+
return {
|
|
493
|
+
tenantsEndpoint,
|
|
494
|
+
loadTenantDetail: (slug) => getJson2(`${tenantsEndpoint}/${encodeURIComponent(slug)}`),
|
|
495
|
+
loadUsers: (filter) => getJson2(
|
|
496
|
+
`${base}/users${queryString({ q: filter.q, tenant: filter.tenant })}`
|
|
497
|
+
),
|
|
498
|
+
loadAudit: (filter) => getJson2(
|
|
499
|
+
`${base}/audit${queryString({
|
|
500
|
+
actor: filter.actor,
|
|
501
|
+
action: filter.action,
|
|
502
|
+
entity: filter.entity,
|
|
503
|
+
since: filter.since,
|
|
504
|
+
limit: filter.limit
|
|
505
|
+
})}`
|
|
506
|
+
),
|
|
507
|
+
loadSubscriptions: () => getJson2(`${base}/subscriptions`),
|
|
508
|
+
loadPromos: (filter) => getJson2(
|
|
509
|
+
`${base}/promo-codes${queryString({
|
|
510
|
+
search: filter.search,
|
|
511
|
+
status: filter.status
|
|
512
|
+
})}`
|
|
513
|
+
),
|
|
514
|
+
createPromo: async (payload) => {
|
|
515
|
+
await sendJson("POST", `${base}/promo-codes`, payload);
|
|
516
|
+
},
|
|
517
|
+
updatePromo: async (id, payload) => {
|
|
518
|
+
await sendJson("PATCH", `${base}/promo-codes/${encodeURIComponent(id)}`, payload);
|
|
519
|
+
},
|
|
520
|
+
deletePromo: async (id) => {
|
|
521
|
+
await sendJson("DELETE", `${base}/promo-codes/${encodeURIComponent(id)}`);
|
|
522
|
+
},
|
|
523
|
+
suspendTenant: (slug, reason) => sendJson("POST", `${tenantsEndpoint}/${encodeURIComponent(slug)}/suspend`, {
|
|
524
|
+
reason
|
|
525
|
+
}),
|
|
526
|
+
reactivateTenant: (slug) => sendJson("POST", `${tenantsEndpoint}/${encodeURIComponent(slug)}/reactivate`)
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
function assertSuccess(status, method, url) {
|
|
530
|
+
if (status < 200 || status >= 300) {
|
|
531
|
+
throw new Error(`${method} ${url} \u2192 HTTP ${status}`);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
function queryString(params) {
|
|
535
|
+
const search = new URLSearchParams();
|
|
536
|
+
for (const [key, value2] of Object.entries(params)) {
|
|
537
|
+
if (value2 === void 0 || value2 === null || value2 === "") continue;
|
|
538
|
+
search.set(key, String(value2));
|
|
539
|
+
}
|
|
540
|
+
const value = search.toString();
|
|
541
|
+
return value ? `?${value}` : "";
|
|
542
|
+
}
|
|
543
|
+
|
|
474
544
|
export {
|
|
475
545
|
ADMIN_UI_VERSION,
|
|
476
546
|
HttpJsonError,
|
|
@@ -490,5 +560,6 @@ export {
|
|
|
490
560
|
ActionDefNotInManifestError,
|
|
491
561
|
ActionRegistry,
|
|
492
562
|
BatchColumnDriftError,
|
|
493
|
-
BatchColumnFetcher
|
|
563
|
+
BatchColumnFetcher,
|
|
564
|
+
createAdminResourceClient
|
|
494
565
|
};
|
package/dist/client/index.cjs
CHANGED
|
@@ -38,6 +38,7 @@ __export(client_exports, {
|
|
|
38
38
|
SA_MESSAGES: () => SA_MESSAGES,
|
|
39
39
|
buildRoutes: () => buildRoutes,
|
|
40
40
|
buildSidebar: () => buildSidebar,
|
|
41
|
+
createAdminResourceClient: () => createAdminResourceClient,
|
|
41
42
|
defaultHttpClient: () => defaultHttpClient,
|
|
42
43
|
defaultKvStore: () => defaultKvStore,
|
|
43
44
|
defaultSectionOrder: () => defaultSectionOrder,
|
|
@@ -620,6 +621,76 @@ var BatchColumnFetcher = class {
|
|
|
620
621
|
}
|
|
621
622
|
};
|
|
622
623
|
|
|
624
|
+
// src/client/admin-resource-client.ts
|
|
625
|
+
function createAdminResourceClient(options) {
|
|
626
|
+
const base = options.adminBase ?? "/api/v1/admin";
|
|
627
|
+
const tenantsEndpoint = `${base}/tenants`;
|
|
628
|
+
const getJson2 = async (url) => {
|
|
629
|
+
const response = await options.http(url, { method: "GET" });
|
|
630
|
+
assertSuccess(response.status, "GET", url);
|
|
631
|
+
return await response.json();
|
|
632
|
+
};
|
|
633
|
+
const sendJson = async (method, url, body) => {
|
|
634
|
+
const response = await options.http(url, {
|
|
635
|
+
method,
|
|
636
|
+
headers: { "content-type": "application/json" },
|
|
637
|
+
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
638
|
+
});
|
|
639
|
+
assertSuccess(response.status, method, url);
|
|
640
|
+
return await response.json();
|
|
641
|
+
};
|
|
642
|
+
return {
|
|
643
|
+
tenantsEndpoint,
|
|
644
|
+
loadTenantDetail: (slug) => getJson2(`${tenantsEndpoint}/${encodeURIComponent(slug)}`),
|
|
645
|
+
loadUsers: (filter) => getJson2(
|
|
646
|
+
`${base}/users${queryString({ q: filter.q, tenant: filter.tenant })}`
|
|
647
|
+
),
|
|
648
|
+
loadAudit: (filter) => getJson2(
|
|
649
|
+
`${base}/audit${queryString({
|
|
650
|
+
actor: filter.actor,
|
|
651
|
+
action: filter.action,
|
|
652
|
+
entity: filter.entity,
|
|
653
|
+
since: filter.since,
|
|
654
|
+
limit: filter.limit
|
|
655
|
+
})}`
|
|
656
|
+
),
|
|
657
|
+
loadSubscriptions: () => getJson2(`${base}/subscriptions`),
|
|
658
|
+
loadPromos: (filter) => getJson2(
|
|
659
|
+
`${base}/promo-codes${queryString({
|
|
660
|
+
search: filter.search,
|
|
661
|
+
status: filter.status
|
|
662
|
+
})}`
|
|
663
|
+
),
|
|
664
|
+
createPromo: async (payload) => {
|
|
665
|
+
await sendJson("POST", `${base}/promo-codes`, payload);
|
|
666
|
+
},
|
|
667
|
+
updatePromo: async (id, payload) => {
|
|
668
|
+
await sendJson("PATCH", `${base}/promo-codes/${encodeURIComponent(id)}`, payload);
|
|
669
|
+
},
|
|
670
|
+
deletePromo: async (id) => {
|
|
671
|
+
await sendJson("DELETE", `${base}/promo-codes/${encodeURIComponent(id)}`);
|
|
672
|
+
},
|
|
673
|
+
suspendTenant: (slug, reason) => sendJson("POST", `${tenantsEndpoint}/${encodeURIComponent(slug)}/suspend`, {
|
|
674
|
+
reason
|
|
675
|
+
}),
|
|
676
|
+
reactivateTenant: (slug) => sendJson("POST", `${tenantsEndpoint}/${encodeURIComponent(slug)}/reactivate`)
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
function assertSuccess(status, method, url) {
|
|
680
|
+
if (status < 200 || status >= 300) {
|
|
681
|
+
throw new Error(`${method} ${url} \u2192 HTTP ${status}`);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
function queryString(params) {
|
|
685
|
+
const search = new URLSearchParams();
|
|
686
|
+
for (const [key, value2] of Object.entries(params)) {
|
|
687
|
+
if (value2 === void 0 || value2 === null || value2 === "") continue;
|
|
688
|
+
search.set(key, String(value2));
|
|
689
|
+
}
|
|
690
|
+
const value = search.toString();
|
|
691
|
+
return value ? `?${value}` : "";
|
|
692
|
+
}
|
|
693
|
+
|
|
623
694
|
// src/client/i18n/format.ts
|
|
624
695
|
function formatMessage(template, params) {
|
|
625
696
|
return template.replace(/\{(\w+)\}/g, (match, name) => {
|
|
@@ -3618,6 +3689,7 @@ function resolveMessages(locale, overrides) {
|
|
|
3618
3689
|
SA_MESSAGES,
|
|
3619
3690
|
buildRoutes,
|
|
3620
3691
|
buildSidebar,
|
|
3692
|
+
createAdminResourceClient,
|
|
3621
3693
|
defaultHttpClient,
|
|
3622
3694
|
defaultKvStore,
|
|
3623
3695
|
defaultSectionOrder,
|
package/dist/client/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { H as HttpClient, K as KvStore, S as SaLocale } from '../messages-BIYw32u1.cjs';
|
|
2
2
|
export { d as ActionDefNotInManifestError, A as ActionHandler, c as ActionRegistry, D as DEFAULT_SA_LOCALE, e as HttpResponse, M as MessageTree, f as MissingHandlerError, P as PartialMessages, R as ResolvedAction, g as SA_INTL_LOCALES, h as SA_LOCALES, i as SA_MESSAGES, a as SaMessages, b as SaMessagesOverrides, T as TranslationOf, j as defaultHttpClient, k as defaultKvStore, l as defineMessages, m as mergeMessages, r as resolveMessages } from '../messages-BIYw32u1.cjs';
|
|
3
|
-
import { PublicBootResponse, AdminManifest, StandardPageKey, TenantColumnDef } from '@saasicat/types';
|
|
3
|
+
import { PublicBootResponse, AdminManifest, StandardPageKey, TenantColumnDef, PromoCodeRecord, AdminTenantDetail, AdminUserListFilter, AdminUserListRow, AdminAuditListFilter, AuditEntry, AdminSubscriptionListRow } from '@saasicat/types';
|
|
4
4
|
|
|
5
5
|
declare const ADMIN_UI_VERSION = "1.2.0";
|
|
6
6
|
|
|
@@ -247,6 +247,39 @@ declare class BatchColumnFetcher {
|
|
|
247
247
|
private buildUrl;
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
+
interface AdminResourceClientOptions {
|
|
251
|
+
http: HttpClient;
|
|
252
|
+
/** Default `/api/v1/admin`. */
|
|
253
|
+
adminBase?: string;
|
|
254
|
+
}
|
|
255
|
+
/** Filters accepted by the standard PromoCodesPage, including its "all" state. */
|
|
256
|
+
interface AdminPromoListFilter {
|
|
257
|
+
search?: string;
|
|
258
|
+
status?: string | null;
|
|
259
|
+
}
|
|
260
|
+
/** Promo row shape used by the extensible standard Admin table. */
|
|
261
|
+
interface AdminPromoListRow extends PromoCodeRecord {
|
|
262
|
+
[extra: string]: unknown;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Ready-to-use client for the standard SaaSiCat AdminResources and promo
|
|
266
|
+
* controllers. App wrappers pass these functions straight to the standard
|
|
267
|
+
* pages; no repeated fetch/error/query-string plumbing is needed.
|
|
268
|
+
*/
|
|
269
|
+
declare function createAdminResourceClient(options: AdminResourceClientOptions): {
|
|
270
|
+
tenantsEndpoint: string;
|
|
271
|
+
loadTenantDetail: (slug: string) => Promise<AdminTenantDetail>;
|
|
272
|
+
loadUsers: (filter: AdminUserListFilter) => Promise<AdminUserListRow[]>;
|
|
273
|
+
loadAudit: (filter: AdminAuditListFilter) => Promise<AuditEntry[]>;
|
|
274
|
+
loadSubscriptions: () => Promise<AdminSubscriptionListRow[]>;
|
|
275
|
+
loadPromos: (filter: AdminPromoListFilter) => Promise<AdminPromoListRow[]>;
|
|
276
|
+
createPromo: (payload: unknown) => Promise<void>;
|
|
277
|
+
updatePromo: (id: string, payload: unknown) => Promise<void>;
|
|
278
|
+
deletePromo: (id: string) => Promise<void>;
|
|
279
|
+
suspendTenant: (slug: string, reason: string) => Promise<unknown>;
|
|
280
|
+
reactivateTenant: (slug: string) => Promise<unknown>;
|
|
281
|
+
};
|
|
282
|
+
|
|
250
283
|
type MessageParams = Record<string, string | number>;
|
|
251
284
|
declare function formatMessage(template: string, params: MessageParams): string;
|
|
252
285
|
|
|
@@ -260,4 +293,4 @@ declare function formatMessage(template: string, params: MessageParams): string;
|
|
|
260
293
|
*/
|
|
261
294
|
declare function formatCurrency(amount: number | string | null | undefined, locale?: SaLocale, currency?: string): string;
|
|
262
295
|
|
|
263
|
-
export { ADMIN_UI_VERSION, type BatchColumnData, BatchColumnDriftError, BatchColumnFetcher, type BatchColumnFetcherOptions, type BatchColumnRow, type BatchColumnValue, BootLoadError, BootLoader, type BootLoaderOptions, type BuildRouteEntry, type CachedManifestEntry, DEFAULT_STANDARD_PAGE_ROUTES, HttpClient, HttpJsonError, KvStore, ManifestLoadError, ManifestLoader, type ManifestLoaderOptions, type MessageParams, type NavBuilderOptions, type ParamStyle, SaLocale, type SidebarItem, type SidebarSection, buildRoutes, buildSidebar, defaultSectionOrder, formatCurrency, formatMessage, getJson, postJson, resolveExtension, trimTrailingSlashes };
|
|
296
|
+
export { ADMIN_UI_VERSION, type AdminPromoListFilter, type AdminPromoListRow, type AdminResourceClientOptions, type BatchColumnData, BatchColumnDriftError, BatchColumnFetcher, type BatchColumnFetcherOptions, type BatchColumnRow, type BatchColumnValue, BootLoadError, BootLoader, type BootLoaderOptions, type BuildRouteEntry, type CachedManifestEntry, DEFAULT_STANDARD_PAGE_ROUTES, HttpClient, HttpJsonError, KvStore, ManifestLoadError, ManifestLoader, type ManifestLoaderOptions, type MessageParams, type NavBuilderOptions, type ParamStyle, SaLocale, type SidebarItem, type SidebarSection, buildRoutes, buildSidebar, createAdminResourceClient, defaultSectionOrder, formatCurrency, formatMessage, getJson, postJson, resolveExtension, trimTrailingSlashes };
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { H as HttpClient, K as KvStore, S as SaLocale } from '../messages-BIYw32u1.js';
|
|
2
2
|
export { d as ActionDefNotInManifestError, A as ActionHandler, c as ActionRegistry, D as DEFAULT_SA_LOCALE, e as HttpResponse, M as MessageTree, f as MissingHandlerError, P as PartialMessages, R as ResolvedAction, g as SA_INTL_LOCALES, h as SA_LOCALES, i as SA_MESSAGES, a as SaMessages, b as SaMessagesOverrides, T as TranslationOf, j as defaultHttpClient, k as defaultKvStore, l as defineMessages, m as mergeMessages, r as resolveMessages } from '../messages-BIYw32u1.js';
|
|
3
|
-
import { PublicBootResponse, AdminManifest, StandardPageKey, TenantColumnDef } from '@saasicat/types';
|
|
3
|
+
import { PublicBootResponse, AdminManifest, StandardPageKey, TenantColumnDef, PromoCodeRecord, AdminTenantDetail, AdminUserListFilter, AdminUserListRow, AdminAuditListFilter, AuditEntry, AdminSubscriptionListRow } from '@saasicat/types';
|
|
4
4
|
|
|
5
5
|
declare const ADMIN_UI_VERSION = "1.2.0";
|
|
6
6
|
|
|
@@ -247,6 +247,39 @@ declare class BatchColumnFetcher {
|
|
|
247
247
|
private buildUrl;
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
+
interface AdminResourceClientOptions {
|
|
251
|
+
http: HttpClient;
|
|
252
|
+
/** Default `/api/v1/admin`. */
|
|
253
|
+
adminBase?: string;
|
|
254
|
+
}
|
|
255
|
+
/** Filters accepted by the standard PromoCodesPage, including its "all" state. */
|
|
256
|
+
interface AdminPromoListFilter {
|
|
257
|
+
search?: string;
|
|
258
|
+
status?: string | null;
|
|
259
|
+
}
|
|
260
|
+
/** Promo row shape used by the extensible standard Admin table. */
|
|
261
|
+
interface AdminPromoListRow extends PromoCodeRecord {
|
|
262
|
+
[extra: string]: unknown;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Ready-to-use client for the standard SaaSiCat AdminResources and promo
|
|
266
|
+
* controllers. App wrappers pass these functions straight to the standard
|
|
267
|
+
* pages; no repeated fetch/error/query-string plumbing is needed.
|
|
268
|
+
*/
|
|
269
|
+
declare function createAdminResourceClient(options: AdminResourceClientOptions): {
|
|
270
|
+
tenantsEndpoint: string;
|
|
271
|
+
loadTenantDetail: (slug: string) => Promise<AdminTenantDetail>;
|
|
272
|
+
loadUsers: (filter: AdminUserListFilter) => Promise<AdminUserListRow[]>;
|
|
273
|
+
loadAudit: (filter: AdminAuditListFilter) => Promise<AuditEntry[]>;
|
|
274
|
+
loadSubscriptions: () => Promise<AdminSubscriptionListRow[]>;
|
|
275
|
+
loadPromos: (filter: AdminPromoListFilter) => Promise<AdminPromoListRow[]>;
|
|
276
|
+
createPromo: (payload: unknown) => Promise<void>;
|
|
277
|
+
updatePromo: (id: string, payload: unknown) => Promise<void>;
|
|
278
|
+
deletePromo: (id: string) => Promise<void>;
|
|
279
|
+
suspendTenant: (slug: string, reason: string) => Promise<unknown>;
|
|
280
|
+
reactivateTenant: (slug: string) => Promise<unknown>;
|
|
281
|
+
};
|
|
282
|
+
|
|
250
283
|
type MessageParams = Record<string, string | number>;
|
|
251
284
|
declare function formatMessage(template: string, params: MessageParams): string;
|
|
252
285
|
|
|
@@ -260,4 +293,4 @@ declare function formatMessage(template: string, params: MessageParams): string;
|
|
|
260
293
|
*/
|
|
261
294
|
declare function formatCurrency(amount: number | string | null | undefined, locale?: SaLocale, currency?: string): string;
|
|
262
295
|
|
|
263
|
-
export { ADMIN_UI_VERSION, type BatchColumnData, BatchColumnDriftError, BatchColumnFetcher, type BatchColumnFetcherOptions, type BatchColumnRow, type BatchColumnValue, BootLoadError, BootLoader, type BootLoaderOptions, type BuildRouteEntry, type CachedManifestEntry, DEFAULT_STANDARD_PAGE_ROUTES, HttpClient, HttpJsonError, KvStore, ManifestLoadError, ManifestLoader, type ManifestLoaderOptions, type MessageParams, type NavBuilderOptions, type ParamStyle, SaLocale, type SidebarItem, type SidebarSection, buildRoutes, buildSidebar, defaultSectionOrder, formatCurrency, formatMessage, getJson, postJson, resolveExtension, trimTrailingSlashes };
|
|
296
|
+
export { ADMIN_UI_VERSION, type AdminPromoListFilter, type AdminPromoListRow, type AdminResourceClientOptions, type BatchColumnData, BatchColumnDriftError, BatchColumnFetcher, type BatchColumnFetcherOptions, type BatchColumnRow, type BatchColumnValue, BootLoadError, BootLoader, type BootLoaderOptions, type BuildRouteEntry, type CachedManifestEntry, DEFAULT_STANDARD_PAGE_ROUTES, HttpClient, HttpJsonError, KvStore, ManifestLoadError, ManifestLoader, type ManifestLoaderOptions, type MessageParams, type NavBuilderOptions, type ParamStyle, SaLocale, type SidebarItem, type SidebarSection, buildRoutes, buildSidebar, createAdminResourceClient, defaultSectionOrder, formatCurrency, formatMessage, getJson, postJson, resolveExtension, trimTrailingSlashes };
|
package/dist/client/index.js
CHANGED
|
@@ -13,12 +13,13 @@ import {
|
|
|
13
13
|
MissingHandlerError,
|
|
14
14
|
buildRoutes,
|
|
15
15
|
buildSidebar,
|
|
16
|
+
createAdminResourceClient,
|
|
16
17
|
defaultSectionOrder,
|
|
17
18
|
getJson,
|
|
18
19
|
postJson,
|
|
19
20
|
resolveExtension,
|
|
20
21
|
trimTrailingSlashes
|
|
21
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-66BUSVC5.js";
|
|
22
23
|
import {
|
|
23
24
|
DEFAULT_SA_LOCALE,
|
|
24
25
|
SA_INTL_LOCALES,
|
|
@@ -51,6 +52,7 @@ export {
|
|
|
51
52
|
SA_MESSAGES,
|
|
52
53
|
buildRoutes,
|
|
53
54
|
buildSidebar,
|
|
55
|
+
createAdminResourceClient,
|
|
54
56
|
defaultHttpClient,
|
|
55
57
|
defaultKvStore,
|
|
56
58
|
defaultSectionOrder,
|
package/dist/index.cjs
CHANGED
|
@@ -65,6 +65,7 @@ __export(src_exports, {
|
|
|
65
65
|
buildQuotaRegistry: () => buildQuotaRegistry,
|
|
66
66
|
buildRoutes: () => buildRoutes,
|
|
67
67
|
buildSidebar: () => buildSidebar,
|
|
68
|
+
createAdminResourceClient: () => createAdminResourceClient,
|
|
68
69
|
createAdminRoutes: () => createAdminRoutes,
|
|
69
70
|
createManifestStore: () => createManifestStore,
|
|
70
71
|
createPlatformLoaders: () => createPlatformLoaders,
|
|
@@ -694,6 +695,76 @@ var BatchColumnFetcher = class {
|
|
|
694
695
|
}
|
|
695
696
|
};
|
|
696
697
|
|
|
698
|
+
// src/client/admin-resource-client.ts
|
|
699
|
+
function createAdminResourceClient(options) {
|
|
700
|
+
const base = options.adminBase ?? "/api/v1/admin";
|
|
701
|
+
const tenantsEndpoint = `${base}/tenants`;
|
|
702
|
+
const getJson2 = async (url) => {
|
|
703
|
+
const response = await options.http(url, { method: "GET" });
|
|
704
|
+
assertSuccess(response.status, "GET", url);
|
|
705
|
+
return await response.json();
|
|
706
|
+
};
|
|
707
|
+
const sendJson = async (method, url, body) => {
|
|
708
|
+
const response = await options.http(url, {
|
|
709
|
+
method,
|
|
710
|
+
headers: { "content-type": "application/json" },
|
|
711
|
+
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
712
|
+
});
|
|
713
|
+
assertSuccess(response.status, method, url);
|
|
714
|
+
return await response.json();
|
|
715
|
+
};
|
|
716
|
+
return {
|
|
717
|
+
tenantsEndpoint,
|
|
718
|
+
loadTenantDetail: (slug) => getJson2(`${tenantsEndpoint}/${encodeURIComponent(slug)}`),
|
|
719
|
+
loadUsers: (filter) => getJson2(
|
|
720
|
+
`${base}/users${queryString({ q: filter.q, tenant: filter.tenant })}`
|
|
721
|
+
),
|
|
722
|
+
loadAudit: (filter) => getJson2(
|
|
723
|
+
`${base}/audit${queryString({
|
|
724
|
+
actor: filter.actor,
|
|
725
|
+
action: filter.action,
|
|
726
|
+
entity: filter.entity,
|
|
727
|
+
since: filter.since,
|
|
728
|
+
limit: filter.limit
|
|
729
|
+
})}`
|
|
730
|
+
),
|
|
731
|
+
loadSubscriptions: () => getJson2(`${base}/subscriptions`),
|
|
732
|
+
loadPromos: (filter) => getJson2(
|
|
733
|
+
`${base}/promo-codes${queryString({
|
|
734
|
+
search: filter.search,
|
|
735
|
+
status: filter.status
|
|
736
|
+
})}`
|
|
737
|
+
),
|
|
738
|
+
createPromo: async (payload) => {
|
|
739
|
+
await sendJson("POST", `${base}/promo-codes`, payload);
|
|
740
|
+
},
|
|
741
|
+
updatePromo: async (id, payload) => {
|
|
742
|
+
await sendJson("PATCH", `${base}/promo-codes/${encodeURIComponent(id)}`, payload);
|
|
743
|
+
},
|
|
744
|
+
deletePromo: async (id) => {
|
|
745
|
+
await sendJson("DELETE", `${base}/promo-codes/${encodeURIComponent(id)}`);
|
|
746
|
+
},
|
|
747
|
+
suspendTenant: (slug, reason) => sendJson("POST", `${tenantsEndpoint}/${encodeURIComponent(slug)}/suspend`, {
|
|
748
|
+
reason
|
|
749
|
+
}),
|
|
750
|
+
reactivateTenant: (slug) => sendJson("POST", `${tenantsEndpoint}/${encodeURIComponent(slug)}/reactivate`)
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
function assertSuccess(status, method, url) {
|
|
754
|
+
if (status < 200 || status >= 300) {
|
|
755
|
+
throw new Error(`${method} ${url} \u2192 HTTP ${status}`);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
function queryString(params) {
|
|
759
|
+
const search = new URLSearchParams();
|
|
760
|
+
for (const [key, value2] of Object.entries(params)) {
|
|
761
|
+
if (value2 === void 0 || value2 === null || value2 === "") continue;
|
|
762
|
+
search.set(key, String(value2));
|
|
763
|
+
}
|
|
764
|
+
const value = search.toString();
|
|
765
|
+
return value ? `?${value}` : "";
|
|
766
|
+
}
|
|
767
|
+
|
|
697
768
|
// src/client/i18n/format.ts
|
|
698
769
|
function formatMessage(template, params) {
|
|
699
770
|
return template.replace(/\{(\w+)\}/g, (match, name) => {
|
|
@@ -6532,6 +6603,7 @@ function defaultTenantPlanSectionI18n(locale) {
|
|
|
6532
6603
|
buildQuotaRegistry,
|
|
6533
6604
|
buildRoutes,
|
|
6534
6605
|
buildSidebar,
|
|
6606
|
+
createAdminResourceClient,
|
|
6535
6607
|
createAdminRoutes,
|
|
6536
6608
|
createManifestStore,
|
|
6537
6609
|
createPlatformLoaders,
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BootLoaderOptions, ManifestLoaderOptions, BuildRouteEntry, SidebarSection, NavBuilderOptions, BatchColumnData, BatchColumnFetcherOptions, BootLoader, ManifestLoader } from './client/index.cjs';
|
|
2
|
-
export { ADMIN_UI_VERSION, BatchColumnDriftError, BatchColumnFetcher, BatchColumnRow, BatchColumnValue, BootLoadError, CachedManifestEntry, DEFAULT_STANDARD_PAGE_ROUTES, HttpJsonError, ManifestLoadError, MessageParams, ParamStyle, SidebarItem, buildRoutes, buildSidebar, defaultSectionOrder, formatCurrency, formatMessage, getJson, postJson, resolveExtension, trimTrailingSlashes } from './client/index.cjs';
|
|
2
|
+
export { ADMIN_UI_VERSION, AdminPromoListFilter, AdminPromoListRow, AdminResourceClientOptions, BatchColumnDriftError, BatchColumnFetcher, BatchColumnRow, BatchColumnValue, BootLoadError, CachedManifestEntry, DEFAULT_STANDARD_PAGE_ROUTES, HttpJsonError, ManifestLoadError, MessageParams, ParamStyle, SidebarItem, buildRoutes, buildSidebar, createAdminResourceClient, defaultSectionOrder, formatCurrency, formatMessage, getJson, postJson, resolveExtension, trimTrailingSlashes } from './client/index.cjs';
|
|
3
3
|
import { H as HttpClient, c as ActionRegistry, A as ActionHandler, K as KvStore, S as SaLocale } from './messages-BIYw32u1.cjs';
|
|
4
4
|
export { d as ActionDefNotInManifestError, D as DEFAULT_SA_LOCALE, e as HttpResponse, M as MessageTree, f as MissingHandlerError, P as PartialMessages, R as ResolvedAction, g as SA_INTL_LOCALES, h as SA_LOCALES, i as SA_MESSAGES, a as SaMessages, b as SaMessagesOverrides, T as TranslationOf, j as defaultHttpClient, k as defaultKvStore, l as defineMessages, m as mergeMessages, r as resolveMessages } from './messages-BIYw32u1.cjs';
|
|
5
5
|
import { A as ActionsMap, a as SuperAdminBrand, b as SuperAdminEndpoints, E as ExtensionsMap, c as SuperAdminLoginAdapter } from './use-super-admin-i18n-DL_qI1BY.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BootLoaderOptions, ManifestLoaderOptions, BuildRouteEntry, SidebarSection, NavBuilderOptions, BatchColumnData, BatchColumnFetcherOptions, BootLoader, ManifestLoader } from './client/index.js';
|
|
2
|
-
export { ADMIN_UI_VERSION, BatchColumnDriftError, BatchColumnFetcher, BatchColumnRow, BatchColumnValue, BootLoadError, CachedManifestEntry, DEFAULT_STANDARD_PAGE_ROUTES, HttpJsonError, ManifestLoadError, MessageParams, ParamStyle, SidebarItem, buildRoutes, buildSidebar, defaultSectionOrder, formatCurrency, formatMessage, getJson, postJson, resolveExtension, trimTrailingSlashes } from './client/index.js';
|
|
2
|
+
export { ADMIN_UI_VERSION, AdminPromoListFilter, AdminPromoListRow, AdminResourceClientOptions, BatchColumnDriftError, BatchColumnFetcher, BatchColumnRow, BatchColumnValue, BootLoadError, CachedManifestEntry, DEFAULT_STANDARD_PAGE_ROUTES, HttpJsonError, ManifestLoadError, MessageParams, ParamStyle, SidebarItem, buildRoutes, buildSidebar, createAdminResourceClient, defaultSectionOrder, formatCurrency, formatMessage, getJson, postJson, resolveExtension, trimTrailingSlashes } from './client/index.js';
|
|
3
3
|
import { H as HttpClient, c as ActionRegistry, A as ActionHandler, K as KvStore, S as SaLocale } from './messages-BIYw32u1.js';
|
|
4
4
|
export { d as ActionDefNotInManifestError, D as DEFAULT_SA_LOCALE, e as HttpResponse, M as MessageTree, f as MissingHandlerError, P as PartialMessages, R as ResolvedAction, g as SA_INTL_LOCALES, h as SA_LOCALES, i as SA_MESSAGES, a as SaMessages, b as SaMessagesOverrides, T as TranslationOf, j as defaultHttpClient, k as defaultKvStore, l as defineMessages, m as mergeMessages, r as resolveMessages } from './messages-BIYw32u1.js';
|
|
5
5
|
import { A as ActionsMap, a as SuperAdminBrand, b as SuperAdminEndpoints, E as ExtensionsMap, c as SuperAdminLoginAdapter } from './use-super-admin-i18n-CWNu_W3u.js';
|
package/dist/index.js
CHANGED
|
@@ -13,12 +13,13 @@ import {
|
|
|
13
13
|
MissingHandlerError,
|
|
14
14
|
buildRoutes,
|
|
15
15
|
buildSidebar,
|
|
16
|
+
createAdminResourceClient,
|
|
16
17
|
defaultSectionOrder,
|
|
17
18
|
getJson,
|
|
18
19
|
postJson,
|
|
19
20
|
resolveExtension,
|
|
20
21
|
trimTrailingSlashes
|
|
21
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-66BUSVC5.js";
|
|
22
23
|
import {
|
|
23
24
|
SUPER_ADMIN_ACTIONS_KEY,
|
|
24
25
|
SUPER_ADMIN_BRAND_KEY,
|
|
@@ -2831,6 +2832,7 @@ export {
|
|
|
2831
2832
|
buildQuotaRegistry,
|
|
2832
2833
|
buildRoutes,
|
|
2833
2834
|
buildSidebar,
|
|
2835
|
+
createAdminResourceClient,
|
|
2834
2836
|
createAdminRoutes,
|
|
2835
2837
|
createManifestStore,
|
|
2836
2838
|
createPlatformLoaders,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saasicat/ui-vue",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Vue 3 components
|
|
3
|
+
"version": "0.10.0",
|
|
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",
|
|
7
7
|
"module": "./dist/index.js",
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"src"
|
|
54
54
|
],
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@saasicat/types": "^0.
|
|
56
|
+
"@saasicat/types": "^0.10.0"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"pinia": "^2.0.0 || ^3.0.0",
|
|
60
|
-
"quasar": "^2.
|
|
60
|
+
"quasar": "^2.22.0",
|
|
61
61
|
"vue": "^3.5.0",
|
|
62
62
|
"vue-router": "^4.5.0 || ^5.0.0"
|
|
63
63
|
},
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"@playwright/test": "^1.59.1",
|
|
77
77
|
"@types/node": "^25.6.0",
|
|
78
78
|
"pinia": "^3.0.0",
|
|
79
|
-
"quasar": "^2.
|
|
79
|
+
"quasar": "^2.22.0",
|
|
80
80
|
"tsup": "^8.0.0",
|
|
81
81
|
"typescript": "^6.0.0",
|
|
82
82
|
"vue": "^3.5.0",
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AdminAuditListFilter,
|
|
3
|
+
AdminSubscriptionListRow,
|
|
4
|
+
AdminTenantDetail,
|
|
5
|
+
AdminUserListFilter,
|
|
6
|
+
AdminUserListRow,
|
|
7
|
+
AuditEntry,
|
|
8
|
+
PromoCodeRecord,
|
|
9
|
+
} from '@saasicat/types';
|
|
10
|
+
import type { HttpClient } from './types.js';
|
|
11
|
+
|
|
12
|
+
export interface AdminResourceClientOptions {
|
|
13
|
+
http: HttpClient;
|
|
14
|
+
/** Default `/api/v1/admin`. */
|
|
15
|
+
adminBase?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Filters accepted by the standard PromoCodesPage, including its "all" state. */
|
|
19
|
+
export interface AdminPromoListFilter {
|
|
20
|
+
search?: string;
|
|
21
|
+
status?: string | null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Promo row shape used by the extensible standard Admin table. */
|
|
25
|
+
export interface AdminPromoListRow extends PromoCodeRecord {
|
|
26
|
+
[extra: string]: unknown;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Ready-to-use client for the standard SaaSiCat AdminResources and promo
|
|
31
|
+
* controllers. App wrappers pass these functions straight to the standard
|
|
32
|
+
* pages; no repeated fetch/error/query-string plumbing is needed.
|
|
33
|
+
*/
|
|
34
|
+
export function createAdminResourceClient(options: AdminResourceClientOptions) {
|
|
35
|
+
const base = options.adminBase ?? '/api/v1/admin';
|
|
36
|
+
const tenantsEndpoint = `${base}/tenants`;
|
|
37
|
+
|
|
38
|
+
const getJson = async <T>(url: string): Promise<T> => {
|
|
39
|
+
const response = await options.http(url, { method: 'GET' });
|
|
40
|
+
assertSuccess(response.status, 'GET', url);
|
|
41
|
+
return (await response.json()) as T;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const sendJson = async <T>(method: string, url: string, body?: unknown): Promise<T> => {
|
|
45
|
+
const response = await options.http(url, {
|
|
46
|
+
method,
|
|
47
|
+
headers: { 'content-type': 'application/json' },
|
|
48
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
49
|
+
});
|
|
50
|
+
assertSuccess(response.status, method, url);
|
|
51
|
+
return (await response.json()) as T;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
tenantsEndpoint,
|
|
56
|
+
loadTenantDetail: (slug: string) =>
|
|
57
|
+
getJson<AdminTenantDetail>(`${tenantsEndpoint}/${encodeURIComponent(slug)}`),
|
|
58
|
+
loadUsers: (filter: AdminUserListFilter) =>
|
|
59
|
+
getJson<AdminUserListRow[]>(
|
|
60
|
+
`${base}/users${queryString({ q: filter.q, tenant: filter.tenant })}`,
|
|
61
|
+
),
|
|
62
|
+
loadAudit: (filter: AdminAuditListFilter) =>
|
|
63
|
+
getJson<AuditEntry[]>(
|
|
64
|
+
`${base}/audit${queryString({
|
|
65
|
+
actor: filter.actor,
|
|
66
|
+
action: filter.action,
|
|
67
|
+
entity: filter.entity,
|
|
68
|
+
since: filter.since,
|
|
69
|
+
limit: filter.limit,
|
|
70
|
+
})}`,
|
|
71
|
+
),
|
|
72
|
+
loadSubscriptions: () => getJson<AdminSubscriptionListRow[]>(`${base}/subscriptions`),
|
|
73
|
+
loadPromos: (filter: AdminPromoListFilter) =>
|
|
74
|
+
getJson<AdminPromoListRow[]>(
|
|
75
|
+
`${base}/promo-codes${queryString({
|
|
76
|
+
search: filter.search,
|
|
77
|
+
status: filter.status,
|
|
78
|
+
})}`,
|
|
79
|
+
),
|
|
80
|
+
createPromo: async (payload: unknown): Promise<void> => {
|
|
81
|
+
await sendJson('POST', `${base}/promo-codes`, payload);
|
|
82
|
+
},
|
|
83
|
+
updatePromo: async (id: string, payload: unknown): Promise<void> => {
|
|
84
|
+
await sendJson('PATCH', `${base}/promo-codes/${encodeURIComponent(id)}`, payload);
|
|
85
|
+
},
|
|
86
|
+
deletePromo: async (id: string): Promise<void> => {
|
|
87
|
+
await sendJson('DELETE', `${base}/promo-codes/${encodeURIComponent(id)}`);
|
|
88
|
+
},
|
|
89
|
+
suspendTenant: (slug: string, reason: string): Promise<unknown> =>
|
|
90
|
+
sendJson('POST', `${tenantsEndpoint}/${encodeURIComponent(slug)}/suspend`, {
|
|
91
|
+
reason,
|
|
92
|
+
}),
|
|
93
|
+
reactivateTenant: (slug: string): Promise<unknown> =>
|
|
94
|
+
sendJson('POST', `${tenantsEndpoint}/${encodeURIComponent(slug)}/reactivate`),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function assertSuccess(status: number, method: string, url: string): void {
|
|
99
|
+
if (status < 200 || status >= 300) {
|
|
100
|
+
throw new Error(`${method} ${url} → HTTP ${status}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function queryString(params: Record<string, string | number | null | undefined>): string {
|
|
105
|
+
const search = new URLSearchParams();
|
|
106
|
+
for (const [key, value] of Object.entries(params)) {
|
|
107
|
+
if (value === undefined || value === null || value === '') continue;
|
|
108
|
+
search.set(key, String(value));
|
|
109
|
+
}
|
|
110
|
+
const value = search.toString();
|
|
111
|
+
return value ? `?${value}` : '';
|
|
112
|
+
}
|
package/src/client/index.ts
CHANGED