@saasicat/ui-vue 0.19.0 → 0.22.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/{catalog-JXdKdIqG.d.cts → catalog-DJcfm5N2.d.cts} +21 -7
- package/dist/{catalog-JXdKdIqG.d.ts → catalog-DJcfm5N2.d.ts} +21 -7
- package/dist/{chunk-DPTIOQXX.js → chunk-F7NRM6KI.js} +56 -28
- package/dist/{chunk-RVG6LQHL.js → chunk-LY52T4N4.js} +21 -2
- package/dist/{chunk-ORX3ZG47.js → chunk-XMMFN2WJ.js} +74 -3
- package/dist/client/index.cjs +134 -29
- package/dist/client/index.d.cts +53 -3
- package/dist/client/index.d.ts +53 -3
- package/dist/client/index.js +14 -2
- package/dist/index.cjs +321 -162
- package/dist/index.d.cts +30 -8
- package/dist/index.d.ts +30 -8
- package/dist/index.js +176 -133
- package/dist/quasar/index.cjs +78 -29
- package/dist/quasar/index.d.cts +2 -2
- package/dist/quasar/index.d.ts +2 -2
- package/dist/quasar/index.js +6 -2
- package/dist/testing-e2e/admin-pages-suite.d.cts +37 -0
- package/dist/testing-e2e/admin-pages-suite.d.ts +37 -0
- package/dist/{use-super-admin-i18n-BlqcD0N7.d.ts → use-super-admin-i18n-CHNdsSlm.d.ts} +34 -7
- package/dist/{use-super-admin-i18n-1nCOkvgi.d.cts → use-super-admin-i18n-CgTuNi8h.d.cts} +34 -7
- package/package.json +18 -8
- package/src/client/i18n/messages/bundles.ts +0 -2
- package/src/client/i18n/messages/common.ts +24 -0
- package/src/client/i18n/messages/discovery.ts +2 -2
- package/src/client/i18n/messages/marketing.ts +2 -4
- package/src/client/i18n/messages/plan-detail.ts +0 -4
- package/src/client/i18n/messages/plans.ts +20 -8
- package/src/client/i18n/messages/tenants.ts +0 -2
- package/src/client/index.ts +1 -0
- package/src/client/manifest-loader.ts +1 -1
- package/src/client/resolve-plans.ts +144 -0
- package/src/components/BundleVersionPublishDialog.vue +6 -6
- package/src/components/KvBlock.vue +4 -4
- package/src/components/MarketingPromotionsTab.vue +34 -48
- package/src/components/MfaPromptDialog.vue +8 -2
- package/src/components/TenantActionConfirmDialog.vue +4 -4
- package/src/components/VersionDiffPreview.vue +7 -7
- package/src/components/admin-page/AdminBody.vue +40 -0
- package/src/components/admin-page/AdminFilters.vue +12 -0
- package/src/components/admin-page/AdminHero.vue +49 -0
- package/src/components/admin-page/AdminKpi.vue +84 -0
- package/src/components/admin-page/AdminPage.vue +16 -0
- package/src/components/admin-page/AdminPaginator.vue +195 -0
- package/src/components/admin-page/AdminRefreshBtn.vue +39 -0
- package/src/components/admin-page/AdminSection.vue +53 -0
- package/src/components/admin-page/AdminStatistics.vue +40 -0
- package/src/components/admin-page/AdminTable.vue +175 -0
- package/src/components/bundle-editor/BundleCreatePanel.vue +23 -23
- package/src/components/bundle-editor/BundleFeaturesEditor.vue +7 -7
- package/src/components/bundle-editor/BundlePlanCompatPicker.vue +9 -9
- package/src/components/bundle-editor/BundleQuotasEditor.vue +11 -11
- package/src/components/bundle-editor/BundleStatusBanner.vue +6 -6
- package/src/components/bundle-editor/BundleVersionInlineEditor.vue +18 -18
- package/src/components/bundle-editor/BundleVersionStrip.vue +12 -12
- package/src/components/dialogs/PilotCreateDialog.vue +12 -12
- package/src/components/dialogs/PilotEditDialog.vue +7 -7
- package/src/components/dialogs/PromoCodeCreateDialog.vue +8 -8
- package/src/components/dialogs/PromoCodeDialogFields.vue +33 -19
- package/src/components/dialogs/PromoCodeEditDialog.vue +10 -10
- package/src/components/plan/PlanGrid.vue +1 -1
- package/src/components/plan-create-dialog/PlanCreateDialog.vue +34 -46
- package/src/components/plan-detail/PlanAuditLog.vue +7 -8
- package/src/components/plan-detail/PlanDetail.vue +95 -292
- package/src/components/plan-detail/PlanDetailKpis.vue +22 -27
- package/src/components/plan-detail/PlanTitleEdit.vue +133 -0
- package/src/components/plan-detail/PlanVersionDiffPanel.vue +5 -8
- package/src/components/plan-detail/PlanVersionsPanel.vue +9 -11
- package/src/components/plan-list/PlanList.vue +206 -457
- package/src/components/plan-matrix/PlanMatrix.vue +66 -183
- package/src/components/plan-review/PlanReview.vue +191 -275
- package/src/components/plan-version-editor/PlanCatalogPreview.vue +7 -5
- package/src/components/plan-version-editor/PlanVersionEditor.vue +200 -295
- package/src/components/plan-version-editor/PlanVersionEditorHeader.vue +23 -55
- package/src/index.ts +1 -0
- package/src/pages-standard/AdminLayout.vue +38 -12
- package/src/pages-standard/AdminManifestErrorPage.vue +79 -9
- package/src/pages-standard/AuditPage.vue +65 -109
- package/src/pages-standard/BundlesPage.vue +146 -179
- package/src/pages-standard/DashboardPage.vue +59 -154
- package/src/pages-standard/DiscoveryPage.vue +172 -227
- package/src/pages-standard/EmailHistoryPage.vue +118 -159
- package/src/pages-standard/MarketingCatalogPage.vue +399 -440
- package/src/pages-standard/PilotsPage.vue +69 -117
- package/src/pages-standard/PlansPage.vue +240 -112
- package/src/pages-standard/PlatformEmailPage.vue +56 -91
- package/src/pages-standard/PromoCodeDetailPage.vue +49 -74
- package/src/pages-standard/PromoCodesPage.vue +95 -128
- package/src/pages-standard/SubscriptionsPage.vue +19 -52
- package/src/pages-standard/SuperAdminLoginPage.vue +12 -12
- package/src/pages-standard/SuperAdminSetupWizard.vue +22 -18
- package/src/pages-standard/TenantDetailPage.vue +100 -191
- package/src/pages-standard/TenantsPage.vue +190 -295
- package/src/pages-standard/UsersPage.vue +89 -157
- package/src/pages-standard/bundles-page/BundleAccordionList.vue +20 -17
- package/src/pages-standard/bundles-page/BundlesKpis.vue +13 -22
- package/src/pages-standard/bundles-page/BundlesToolbar.vue +63 -0
- package/src/pages-standard/discovery-page/CatalogEntryTransPanel.vue +10 -10
- package/src/pages-standard/discovery-page/DiscoveryCapList.vue +5 -5
- package/src/pages-standard/discovery-page/DiscoveryFeatureCard.vue +16 -16
- package/src/pages-standard/discovery-page/DiscoveryKpis.vue +31 -27
- package/src/pages-standard/discovery-page/DiscoveryQuotaCard.vue +7 -7
- package/src/pages-standard/marketing-catalog/MarketingCatalogAdmin.vue +111 -73
- package/src/pages-standard/marketing-catalog/MarketingCatalogHeader.vue +43 -62
- package/src/pages-standard/marketing-catalog/MarketingCatalogPreview.vue +53 -35
- package/src/pages-standard/marketing-catalog/MarketingCatalogToolbar.vue +7 -7
- package/src/pages-standard/plan-versions/PlanDiffCard.vue +6 -6
- package/src/pages-standard/plan-versions/PlanVersionsDiff.vue +6 -6
- package/src/pages-standard/plan-versions/PlanVersionsTimeline.vue +16 -16
- package/src/pages-standard/plans-page/PlanBundleOverview.vue +14 -29
- package/src/pages-standard/plans-page/PlanPublishDialog.vue +1 -1
- package/src/pages-standard/plans-page/PlansPageToast.vue +6 -6
- package/src/pages-standard/sa-theme.css +552 -86
- package/src/pages-standard/tenant-detail/TenantMasterData.vue +28 -0
- package/src/pages-standard/tenant-detail/TenantUsage.vue +31 -0
- package/src/pages-standard/tenant-detail/TenantUsers.vue +15 -0
- package/src/pages-standard/tenant-detail/types.ts +38 -0
- package/src/pages-standard/tenants/StatusPill.vue +2 -2
- package/src/pages-tenant/MySubscriptionBundlesPage.vue +25 -25
- package/src/pages-tenant/OnboardingConfigurator.vue +1 -5
- package/src/pages-tenant/PackageSnapshotPanel.vue +1 -1
- package/src/pages-tenant/TenantPlanSection.vue +12 -20
- package/src/quasar/create-super-admin-app.ts +4 -0
- package/src/vue/entitlement-provider.ts +0 -1
- package/src/vue/feature-router-guard.ts +0 -1
- package/src/vue/super-admin-context.ts +106 -1
- package/src/vue/use-api-list.ts +2 -1
- package/src/vue/use-mfa-prompt.ts +72 -0
- package/src/vue/use-pagination.ts +63 -0
- package/src/vue/use-plans.ts +1 -2
- package/src/vue/use-sign-out.ts +90 -0
- package/src/vue/use-tenant-billing.ts +1 -1
- package/src/vue/use-tenant-manifest.ts +0 -1
- package/src/components/KpiCard.vue +0 -53
- package/src/components/plan-cockpit/PlanCockpit.vue +0 -1012
- package/src/components/plan-cockpit/PlanCockpitAuditLog.vue +0 -72
- package/src/components/plan-cockpit/PlanCockpitDiffPanel.vue +0 -100
- package/src/components/plan-cockpit/PlanCockpitHeader.vue +0 -101
- package/src/components/plan-cockpit/PlanCockpitImpactPanel.vue +0 -112
- package/src/components/plan-cockpit/PlanCockpitKpis.vue +0 -68
- package/src/components/plan-cockpit/PlanCockpitVersions.vue +0 -251
- package/src/components/plan-cockpit/types.ts +0 -72
- package/src/components/plan-detail/PlanDetailHeader.vue +0 -194
- package/src/pages-standard/bundles-page/BundlesHeader.vue +0 -68
- package/src/pages-standard/discovery-page/DiscoveryHeader.vue +0 -34
|
@@ -1,60 +1,51 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
</p>
|
|
9
|
-
</div>
|
|
10
|
-
<div class="sa-page-head__actions">
|
|
2
|
+
<AdminPage class="sa-pilots">
|
|
3
|
+
<AdminHero
|
|
4
|
+
:title="msg.title"
|
|
5
|
+
:subtitle="formatMessage(msg.subtitleCount, { count: rows.length })"
|
|
6
|
+
>
|
|
7
|
+
<template #actions>
|
|
11
8
|
<slot name="head-actions">
|
|
12
|
-
<
|
|
9
|
+
<button
|
|
13
10
|
v-if="enableCreate"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
icon="add"
|
|
17
|
-
:label="resolvedCreateLabel"
|
|
11
|
+
class="sa-btn sa-btn--primary"
|
|
12
|
+
type="button"
|
|
18
13
|
@click="showCreate = true"
|
|
19
|
-
|
|
14
|
+
>
|
|
15
|
+
<q-icon name="add" size="16px" />
|
|
16
|
+
<span>{{ resolvedCreateLabel }}</span>
|
|
17
|
+
</button>
|
|
20
18
|
</slot>
|
|
21
|
-
</
|
|
22
|
-
</
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
tile.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
row-key="id"
|
|
52
|
-
:pagination="{ rowsPerPage: 0 }"
|
|
53
|
-
:loading="loading"
|
|
54
|
-
hide-pagination
|
|
55
|
-
>
|
|
56
|
-
<template #body-cell-actions="{ row }">
|
|
57
|
-
<q-td>
|
|
19
|
+
</template>
|
|
20
|
+
</AdminHero>
|
|
21
|
+
|
|
22
|
+
<AdminBody>
|
|
23
|
+
<AdminStatistics :label="msg.title">
|
|
24
|
+
<AdminKpi
|
|
25
|
+
v-for="tile in statTiles"
|
|
26
|
+
:key="tile.id"
|
|
27
|
+
:label="tile.label"
|
|
28
|
+
:value="tile.count"
|
|
29
|
+
:sub="tile.hint"
|
|
30
|
+
:tone="tile.tone"
|
|
31
|
+
:selected="filter === tile.id"
|
|
32
|
+
:action="() => (filter = tile.id)"
|
|
33
|
+
/>
|
|
34
|
+
</AdminStatistics>
|
|
35
|
+
|
|
36
|
+
<q-banner v-if="reviewSoon.length" class="bg-amber-2 text-grey-9 q-mb-md" rounded>
|
|
37
|
+
<template #avatar><q-icon name="event" color="amber-9" /></template>
|
|
38
|
+
{{ formatMessage(msg.list.reviewSoonBanner, { count: reviewSoon.length }) }}
|
|
39
|
+
</q-banner>
|
|
40
|
+
|
|
41
|
+
<AdminSection class="sa-pilots__card">
|
|
42
|
+
<AdminTable
|
|
43
|
+
:rows="filteredRows"
|
|
44
|
+
:columns="effectiveColumns"
|
|
45
|
+
:loading="loading"
|
|
46
|
+
storage-key="pilots"
|
|
47
|
+
>
|
|
48
|
+
<template #row-actions="{ row }">
|
|
58
49
|
<slot name="row-actions" :row="row">
|
|
59
50
|
<q-btn
|
|
60
51
|
v-for="action in visibleActions(row)"
|
|
@@ -67,10 +58,10 @@
|
|
|
67
58
|
@click="action.handler(row)"
|
|
68
59
|
/>
|
|
69
60
|
</slot>
|
|
70
|
-
</
|
|
71
|
-
</
|
|
72
|
-
</
|
|
73
|
-
</
|
|
61
|
+
</template>
|
|
62
|
+
</AdminTable>
|
|
63
|
+
</AdminSection>
|
|
64
|
+
</AdminBody>
|
|
74
65
|
|
|
75
66
|
<PilotCreateDialog
|
|
76
67
|
v-if="enableCreate && submitCreate"
|
|
@@ -98,22 +89,30 @@
|
|
|
98
89
|
|
|
99
90
|
<MfaPromptDialog
|
|
100
91
|
v-if="needsMfaDialog"
|
|
101
|
-
:model-value="
|
|
102
|
-
:description="
|
|
103
|
-
:error="
|
|
92
|
+
:model-value="mfa.show.value"
|
|
93
|
+
:description="mfa.description.value"
|
|
94
|
+
:error="mfa.error.value"
|
|
104
95
|
:setup-hint="mfaSetupHint"
|
|
105
|
-
@update:model-value="
|
|
106
|
-
@confirm="
|
|
96
|
+
@update:model-value="mfa.onVisibility"
|
|
97
|
+
@confirm="mfa.onConfirm"
|
|
107
98
|
/>
|
|
108
|
-
</
|
|
99
|
+
</AdminPage>
|
|
109
100
|
</template>
|
|
110
101
|
|
|
111
102
|
<script setup lang="ts">
|
|
103
|
+
import AdminTable from '../components/admin-page/AdminTable.vue';
|
|
112
104
|
import { computed, onMounted, ref } from 'vue';
|
|
105
|
+
import { useMfaPrompt } from '../vue/use-mfa-prompt.js';
|
|
113
106
|
import { useQuasar } from 'quasar';
|
|
114
107
|
import { formatMessage } from '../client/i18n/format.js';
|
|
115
108
|
import { useSaMessages, useSuperAdminI18n } from '../vue/use-super-admin-i18n.js';
|
|
116
109
|
import { useSuperAdminNotify } from '../quasar/notify.js';
|
|
110
|
+
import AdminBody from '../components/admin-page/AdminBody.vue';
|
|
111
|
+
import AdminHero from '../components/admin-page/AdminHero.vue';
|
|
112
|
+
import AdminSection from '../components/admin-page/AdminSection.vue';
|
|
113
|
+
import AdminKpi from '../components/admin-page/AdminKpi.vue';
|
|
114
|
+
import AdminPage from '../components/admin-page/AdminPage.vue';
|
|
115
|
+
import AdminStatistics from '../components/admin-page/AdminStatistics.vue';
|
|
117
116
|
import PilotCreateDialog from '../components/dialogs/PilotCreateDialog.vue';
|
|
118
117
|
import PilotEditDialog from '../components/dialogs/PilotEditDialog.vue';
|
|
119
118
|
import MfaPromptDialog from '../components/MfaPromptDialog.vue';
|
|
@@ -219,38 +218,11 @@ const showEdit = ref(false);
|
|
|
219
218
|
const editRow = ref<PilotRow | null>(null);
|
|
220
219
|
const bakedPlanOptions = ref<PilotPlanOption[]>([]);
|
|
221
220
|
|
|
222
|
-
//
|
|
223
|
-
//
|
|
224
|
-
|
|
225
|
-
// (or cancellation via `update:modelValue=false`).
|
|
226
|
-
const showMfa = ref(false);
|
|
227
|
-
const mfaError = ref('');
|
|
228
|
-
const mfaDescription = ref('');
|
|
229
|
-
let pendingMfaResolve: ((code: string | null) => void) | null = null;
|
|
221
|
+
// Per-flow MFA for extend/revoke: `runWithMfa` awaits `mfa.prompt`, which
|
|
222
|
+
// resolves with the code or with null when the user closes the dialog.
|
|
223
|
+
const mfa = useMfaPrompt();
|
|
230
224
|
const needsMfaDialog = computed(() => props.requireMfaForExtend || props.requireMfaForRevoke);
|
|
231
225
|
|
|
232
|
-
function promptMfa(description: string): Promise<string | null> {
|
|
233
|
-
return new Promise((resolve) => {
|
|
234
|
-
mfaDescription.value = description;
|
|
235
|
-
mfaError.value = '';
|
|
236
|
-
showMfa.value = true;
|
|
237
|
-
pendingMfaResolve = (code) => {
|
|
238
|
-
pendingMfaResolve = null;
|
|
239
|
-
resolve(code);
|
|
240
|
-
};
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
function onMfaConfirm(code: string): void {
|
|
245
|
-
pendingMfaResolve?.(code);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
function onMfaDialogVisibility(open: boolean): void {
|
|
249
|
-
showMfa.value = open;
|
|
250
|
-
if (!open && pendingMfaResolve) {
|
|
251
|
-
pendingMfaResolve(null);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
226
|
// Consumers can set `createPlanOptions` instead of `loadPlanOptions`
|
|
255
227
|
// (e.g. apps with a hard-coded plan list).
|
|
256
228
|
const effectiveCreatePlanOptions = computed<readonly (string | PilotPlanOption)[]>(() => {
|
|
@@ -388,14 +360,6 @@ const mergedActions = computed<readonly PilotRowAction[]>(() => [
|
|
|
388
360
|
|
|
389
361
|
const effectiveColumns = computed(() => {
|
|
390
362
|
const cols = [...baseColumns.value];
|
|
391
|
-
if (mergedActions.value.length > 0) {
|
|
392
|
-
cols.push({
|
|
393
|
-
name: 'actions',
|
|
394
|
-
label: '',
|
|
395
|
-
field: ((r: PilotRow) => r.id) as never,
|
|
396
|
-
align: 'right' as 'left',
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
363
|
return cols;
|
|
400
364
|
});
|
|
401
365
|
|
|
@@ -498,21 +462,21 @@ async function runAction(
|
|
|
498
462
|
// MFA loop: as long as the server returns 401, keep the dialog open and
|
|
499
463
|
// wait again for a code. Cancelling (resolver === null) ends it.
|
|
500
464
|
while (true) {
|
|
501
|
-
const code = await
|
|
465
|
+
const code = await mfa.prompt(actionLabel);
|
|
502
466
|
if (code === null) return;
|
|
503
467
|
try {
|
|
504
468
|
await invoke(code);
|
|
505
|
-
|
|
469
|
+
mfa.show.value = false;
|
|
506
470
|
notify('positive', successMessage);
|
|
507
471
|
await reload();
|
|
508
472
|
return;
|
|
509
473
|
} catch (err) {
|
|
510
474
|
const status = (err as { response?: { status?: number } })?.response?.status;
|
|
511
475
|
if (status === 401) {
|
|
512
|
-
|
|
476
|
+
mfa.error.value = msg.value.mfa.invalidOrNotSetUp;
|
|
513
477
|
continue;
|
|
514
478
|
}
|
|
515
|
-
|
|
479
|
+
mfa.show.value = false;
|
|
516
480
|
notify('negative', errMsg(err));
|
|
517
481
|
return;
|
|
518
482
|
}
|
|
@@ -574,16 +538,4 @@ function formatDate(iso: string | null | undefined): string | null {
|
|
|
574
538
|
}
|
|
575
539
|
</script>
|
|
576
540
|
|
|
577
|
-
<style scoped>
|
|
578
|
-
.sa-pilots {
|
|
579
|
-
min-height: calc(100vh - 56px);
|
|
580
|
-
background: var(--sa-bg-app, #f1f5f9);
|
|
581
|
-
padding: 20px 28px 28px;
|
|
582
|
-
}
|
|
583
|
-
.sa-pilots__card {
|
|
584
|
-
background: #fff;
|
|
585
|
-
border: 1px solid var(--sa-border, #e2e8f0);
|
|
586
|
-
border-radius: 12px;
|
|
587
|
-
overflow: hidden;
|
|
588
|
-
}
|
|
589
|
-
</style>
|
|
541
|
+
<style scoped></style>
|