@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,43 +1,38 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
<div class="pd-kpi-big">
|
|
2
|
+
<AdminStatistics :columns="4">
|
|
3
|
+
<AdminKpi :label="msg.kpis.activeVersion" :sub="activeVersionSub">
|
|
4
|
+
<template #value>
|
|
6
5
|
<template v-if="liveVersion">
|
|
7
6
|
v{{ liveVersion.version }}
|
|
8
7
|
<span class="chip live dot">live</span>
|
|
9
8
|
</template>
|
|
10
9
|
<template v-else>—</template>
|
|
11
|
-
</
|
|
12
|
-
|
|
13
|
-
</div>
|
|
10
|
+
</template>
|
|
11
|
+
</AdminKpi>
|
|
14
12
|
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
<AdminKpi
|
|
14
|
+
:label="msg.kpis.tenantImpact"
|
|
15
|
+
:value="tenantTotal"
|
|
16
|
+
:sub="msg.kpis.tenantsOnPlan"
|
|
17
|
+
/>
|
|
20
18
|
|
|
21
|
-
<
|
|
22
|
-
<div class="pd-kpi-label">{{ msg.kpis.versions }}</div>
|
|
23
|
-
<div class="pd-kpi-big">{{ versionCount }}</div>
|
|
24
|
-
<div class="pd-kpi-sub">{{ versionsSummary }}</div>
|
|
25
|
-
</div>
|
|
19
|
+
<AdminKpi :label="msg.kpis.versions" :value="versionCount" :sub="versionsSummary" />
|
|
26
20
|
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
21
|
+
<AdminKpi
|
|
22
|
+
:label="msg.kpis.openDraft"
|
|
23
|
+
:value="draftVersion ? `v${draftVersion.version}` : null"
|
|
24
|
+
:sub="draftVersion ? msg.kpis.readyToEdit : msg.kpis.noOpenDraft"
|
|
25
|
+
:tone="draftVersion ? 'warn' : 'neutral'"
|
|
26
|
+
emphasis="surface"
|
|
27
|
+
/>
|
|
28
|
+
</AdminStatistics>
|
|
37
29
|
</template>
|
|
38
30
|
|
|
39
31
|
<script setup lang="ts">
|
|
40
32
|
import { computed } from 'vue';
|
|
33
|
+
|
|
34
|
+
import AdminKpi from '../admin-page/AdminKpi.vue';
|
|
35
|
+
import AdminStatistics from '../admin-page/AdminStatistics.vue';
|
|
41
36
|
import type { PlanVersionRow } from '@saasicat/types';
|
|
42
37
|
import { formatMessage } from '../../client/i18n/format.js';
|
|
43
38
|
import { useSaMessages } from '../../vue/use-super-admin-i18n.js';
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<span class="pd-title-edit">
|
|
3
|
+
<template v-if="editing">
|
|
4
|
+
<input
|
|
5
|
+
ref="nameInput"
|
|
6
|
+
v-model="nameDraft"
|
|
7
|
+
class="pd-title-edit__input"
|
|
8
|
+
:aria-label="msg.header.editNameAria"
|
|
9
|
+
@keydown.enter="commit"
|
|
10
|
+
@keydown.escape="cancel"
|
|
11
|
+
@blur="commit"
|
|
12
|
+
/>
|
|
13
|
+
<span class="pd-title-edit__hint">{{ msg.header.nameEditHint }}</span>
|
|
14
|
+
</template>
|
|
15
|
+
<template v-else>
|
|
16
|
+
{{ plan.label }}
|
|
17
|
+
<button
|
|
18
|
+
v-if="editable"
|
|
19
|
+
class="pd-title-edit__btn"
|
|
20
|
+
type="button"
|
|
21
|
+
:title="msg.header.editNameTitle"
|
|
22
|
+
:aria-label="msg.header.editNameAria"
|
|
23
|
+
@click="start"
|
|
24
|
+
>
|
|
25
|
+
<q-icon name="edit" size="15px" />
|
|
26
|
+
</button>
|
|
27
|
+
</template>
|
|
28
|
+
</span>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script setup lang="ts">
|
|
32
|
+
import { nextTick, ref, watch } from 'vue';
|
|
33
|
+
import type { PlanRow } from '@saasicat/types';
|
|
34
|
+
import { useSaMessages } from '../../vue/use-super-admin-i18n.js';
|
|
35
|
+
|
|
36
|
+
// The plan name as the page heading, renameable in place.
|
|
37
|
+
//
|
|
38
|
+
// It goes into AdminHero's `title` slot rather than carrying a heading of its
|
|
39
|
+
// own: the plan detail used to render a second <h1> below the hero's, which
|
|
40
|
+
// left the page with two top-level headings and a title block that had to
|
|
41
|
+
// restate the hero's type scale to match it. Here the hero owns the element
|
|
42
|
+
// and the size; this only fills it.
|
|
43
|
+
const props = defineProps<{
|
|
44
|
+
plan: PlanRow;
|
|
45
|
+
/** Renaming a plan is only offered while an unpublished draft exists. */
|
|
46
|
+
editable: boolean;
|
|
47
|
+
}>();
|
|
48
|
+
|
|
49
|
+
const emit = defineEmits<{
|
|
50
|
+
(e: 'updatePlan', patch: { label: string }): void;
|
|
51
|
+
}>();
|
|
52
|
+
|
|
53
|
+
const msg = useSaMessages('planDetail');
|
|
54
|
+
|
|
55
|
+
const editing = ref(false);
|
|
56
|
+
const nameDraft = ref(props.plan.label);
|
|
57
|
+
const nameInput = ref<HTMLInputElement | null>(null);
|
|
58
|
+
|
|
59
|
+
watch(
|
|
60
|
+
() => props.plan.label,
|
|
61
|
+
(label) => {
|
|
62
|
+
if (!editing.value) nameDraft.value = label;
|
|
63
|
+
},
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
function start(): void {
|
|
67
|
+
nameDraft.value = props.plan.label;
|
|
68
|
+
editing.value = true;
|
|
69
|
+
void nextTick(() => nameInput.value?.focus());
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function commit(): void {
|
|
73
|
+
if (!editing.value) return;
|
|
74
|
+
const next = nameDraft.value.trim();
|
|
75
|
+
editing.value = false;
|
|
76
|
+
if (next && next !== props.plan.label) emit('updatePlan', { label: next });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function cancel(): void {
|
|
80
|
+
nameDraft.value = props.plan.label;
|
|
81
|
+
editing.value = false;
|
|
82
|
+
}
|
|
83
|
+
</script>
|
|
84
|
+
|
|
85
|
+
<style scoped>
|
|
86
|
+
.pd-title-edit {
|
|
87
|
+
display: inline-flex;
|
|
88
|
+
align-items: center;
|
|
89
|
+
gap: 8px;
|
|
90
|
+
}
|
|
91
|
+
/* `font: inherit` on purpose: the heading's type comes from the hero, so the
|
|
92
|
+
* input keeps matching it when that changes. */
|
|
93
|
+
.pd-title-edit__input {
|
|
94
|
+
font: inherit;
|
|
95
|
+
color: var(--sa-heading);
|
|
96
|
+
border: 0;
|
|
97
|
+
background: var(--sa-warning-bg);
|
|
98
|
+
outline: 2px solid var(--sa-amber-light);
|
|
99
|
+
padding: 2px 8px;
|
|
100
|
+
border-radius: var(--sa-radius-control);
|
|
101
|
+
min-width: 220px;
|
|
102
|
+
}
|
|
103
|
+
.pd-title-edit__hint {
|
|
104
|
+
font-size: 11px;
|
|
105
|
+
font-weight: 500;
|
|
106
|
+
color: var(--sa-warning);
|
|
107
|
+
background: var(--sa-warning-bg);
|
|
108
|
+
border: 1px solid var(--sa-amber-border);
|
|
109
|
+
border-radius: var(--sa-radius-control);
|
|
110
|
+
padding: 3px 8px;
|
|
111
|
+
}
|
|
112
|
+
.pd-title-edit__btn {
|
|
113
|
+
display: inline-flex;
|
|
114
|
+
align-items: center;
|
|
115
|
+
justify-content: center;
|
|
116
|
+
width: 28px;
|
|
117
|
+
height: 28px;
|
|
118
|
+
border-radius: var(--sa-radius-control);
|
|
119
|
+
background: transparent;
|
|
120
|
+
border: 1px solid transparent;
|
|
121
|
+
color: var(--sa-muted-light);
|
|
122
|
+
cursor: pointer;
|
|
123
|
+
transition:
|
|
124
|
+
background 0.12s,
|
|
125
|
+
color 0.12s,
|
|
126
|
+
border-color 0.12s;
|
|
127
|
+
}
|
|
128
|
+
.pd-title-edit__btn:hover {
|
|
129
|
+
background: var(--sa-border-soft);
|
|
130
|
+
color: var(--sa-primary);
|
|
131
|
+
border-color: var(--sa-border);
|
|
132
|
+
}
|
|
133
|
+
</style>
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
<div style="min-width: 0">
|
|
5
|
-
<h3 class="pd-panel-title">{{ panelTitle }}</h3>
|
|
6
|
-
<div class="pd-panel-sub">{{ panelSubtitle }}</div>
|
|
7
|
-
</div>
|
|
2
|
+
<AdminSection :title="panelTitle" :subtitle="panelSubtitle" class="pd-panel">
|
|
3
|
+
<template #actions>
|
|
8
4
|
<div class="pd-panel-head-right pd-diff-chips">
|
|
9
5
|
<template v-if="predecessor">
|
|
10
6
|
<span class="pd-diff-chip add">+{{ diff.featuresAdded.length }} F</span>
|
|
@@ -16,7 +12,7 @@
|
|
|
16
12
|
<span class="pd-diff-chip mod">{{ quotaCount(selectedVersion) }} Q</span>
|
|
17
13
|
</template>
|
|
18
14
|
</div>
|
|
19
|
-
</
|
|
15
|
+
</template>
|
|
20
16
|
|
|
21
17
|
<div v-if="predecessor" class="pd-diff-list">
|
|
22
18
|
<div v-for="d in diffRows" :key="d.id" :class="['pd-diff-row', d.kind]">
|
|
@@ -123,11 +119,12 @@
|
|
|
123
119
|
</div>
|
|
124
120
|
</template>
|
|
125
121
|
</div>
|
|
126
|
-
</
|
|
122
|
+
</AdminSection>
|
|
127
123
|
</template>
|
|
128
124
|
|
|
129
125
|
<script setup lang="ts">
|
|
130
126
|
import { computed } from 'vue';
|
|
127
|
+
import AdminSection from '../admin-page/AdminSection.vue';
|
|
131
128
|
import type { PlanVersionRow } from '@saasicat/types';
|
|
132
129
|
import { formatMessage } from '../../client/i18n/format.js';
|
|
133
130
|
import { useSaMessages } from '../../vue/use-super-admin-i18n.js';
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
<code class="pd-code">supersededAt</code>
|
|
9
|
-
</div>
|
|
10
|
-
</div>
|
|
2
|
+
<AdminSection :title="msg.versions.title" class="pd-panel">
|
|
3
|
+
<template #subtitle>
|
|
4
|
+
{{ msg.versions.subtitle }}
|
|
5
|
+
<code class="pd-code">supersededAt</code>
|
|
6
|
+
</template>
|
|
7
|
+
<template #actions>
|
|
11
8
|
<div class="pd-panel-head-right">
|
|
12
9
|
<button
|
|
13
10
|
v-if="!draftVersion"
|
|
@@ -28,7 +25,7 @@
|
|
|
28
25
|
<span>{{ newDraftButtonLabel }}</span>
|
|
29
26
|
</button>
|
|
30
27
|
</div>
|
|
31
|
-
</
|
|
28
|
+
</template>
|
|
32
29
|
|
|
33
30
|
<div v-if="chronological.length > 0" class="pd-timeline">
|
|
34
31
|
<div class="pd-timeline-hint">
|
|
@@ -227,11 +224,12 @@
|
|
|
227
224
|
</div>
|
|
228
225
|
</div>
|
|
229
226
|
</div>
|
|
230
|
-
</
|
|
227
|
+
</AdminSection>
|
|
231
228
|
</template>
|
|
232
229
|
|
|
233
230
|
<script setup lang="ts">
|
|
234
231
|
import { computed } from 'vue';
|
|
232
|
+
import AdminSection from '../admin-page/AdminSection.vue';
|
|
235
233
|
import type { PlanVersionRow } from '@saasicat/types';
|
|
236
234
|
import { formatMessage } from '../../client/i18n/format.js';
|
|
237
235
|
import { useSaMessages } from '../../vue/use-super-admin-i18n.js';
|