@saasicat/ui-vue 0.21.0 → 0.22.1
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-BY_t9prv.d.cts → catalog-DJcfm5N2.d.cts} +20 -7
- package/dist/{catalog-BY_t9prv.d.ts → catalog-DJcfm5N2.d.ts} +20 -7
- package/dist/{chunk-JN6HZGLV.js → chunk-F7NRM6KI.js} +54 -28
- package/dist/{chunk-7IFKVGZV.js → chunk-LY52T4N4.js} +21 -2
- package/dist/{chunk-OTP3OSSW.js → chunk-XMMFN2WJ.js} +74 -3
- package/dist/client/index.cjs +132 -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 +319 -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 +76 -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-c_Eqsu9u.d.ts → use-super-admin-i18n-CHNdsSlm.d.ts} +34 -7
- package/dist/{use-super-admin-i18n-DlJRGIVq.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 +22 -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/AdminFilters.vue +12 -0
- package/src/components/admin-page/AdminHero.vue +22 -5
- package/src/components/admin-page/AdminKpi.vue +84 -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 +31 -16
- 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/PlanDetail.vue +92 -302
- package/src/components/plan-detail/PlanDetailKpis.vue +22 -27
- package/src/components/plan-detail/PlanTitleEdit.vue +133 -0
- package/src/components/plan-list/PlanList.vue +72 -290
- 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 +34 -10
- package/src/pages-standard/AdminManifestErrorPage.vue +79 -9
- package/src/pages-standard/AuditPage.vue +53 -72
- package/src/pages-standard/BundlesPage.vue +128 -144
- package/src/pages-standard/DashboardPage.vue +43 -107
- package/src/pages-standard/DiscoveryPage.vue +158 -200
- package/src/pages-standard/EmailHistoryPage.vue +98 -88
- package/src/pages-standard/MarketingCatalogPage.vue +237 -267
- package/src/pages-standard/PilotsPage.vue +44 -60
- package/src/pages-standard/PlansPage.vue +230 -105
- package/src/pages-standard/PlatformEmailPage.vue +37 -40
- package/src/pages-standard/PromoCodeDetailPage.vue +16 -30
- package/src/pages-standard/PromoCodesPage.vue +86 -112
- package/src/pages-standard/SubscriptionsPage.vue +10 -17
- package/src/pages-standard/SuperAdminLoginPage.vue +12 -12
- package/src/pages-standard/SuperAdminSetupWizard.vue +20 -17
- package/src/pages-standard/TenantDetailPage.vue +45 -41
- package/src/pages-standard/TenantsPage.vue +184 -264
- package/src/pages-standard/UsersPage.vue +69 -104
- 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 +6 -10
- 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 +1 -1
- package/src/pages-standard/marketing-catalog/MarketingCatalogHeader.vue +2 -13
- 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 +1 -1
- package/src/pages-standard/sa-theme.css +481 -71
- package/src/pages-standard/tenant-detail/TenantUsers.vue +2 -8
- 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-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 -1027
- package/src/components/plan-cockpit/PlanCockpitAuditLog.vue +0 -72
- package/src/components/plan-cockpit/PlanCockpitDiffPanel.vue +0 -99
- 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 -249
- package/src/components/plan-cockpit/types.ts +0 -72
- package/src/components/plan-detail/PlanDetailHeader.vue +0 -194
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
</q-banner>
|
|
16
16
|
|
|
17
17
|
<!-- Step 1: create SuperAdmin -->
|
|
18
|
-
<q-form v-if="step === 'form'"
|
|
18
|
+
<q-form v-if="step === 'form'" class="sa-setup-form" @submit.prevent="submitCreate">
|
|
19
19
|
<p class="sa-setup-hint">
|
|
20
20
|
{{ msg.setup.tokenHintBefore }}
|
|
21
21
|
<code>SETUP_TOKEN</code>
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
<code class="sa-setup-uri__value">{{ result.otpauthUri }}</code>
|
|
105
105
|
</details>
|
|
106
106
|
|
|
107
|
-
<q-form
|
|
107
|
+
<q-form class="sa-setup-form q-mt-md" @submit.prevent="submitConfirm">
|
|
108
108
|
<q-input
|
|
109
109
|
v-model="mfaCode"
|
|
110
110
|
:label="msg.setup.codeLabel"
|
|
@@ -216,9 +216,12 @@ async function postJson<T>(path: string, body: unknown): Promise<T> {
|
|
|
216
216
|
return await httpPostJson<T>(http, `${endpoints.apiBase}${path}`, body);
|
|
217
217
|
} catch (err) {
|
|
218
218
|
if (err instanceof HttpJsonError) {
|
|
219
|
+
// The message is translated for the user; `cause` keeps the status
|
|
220
|
+
// and the machine-readable code reachable for anything upstream.
|
|
219
221
|
throw new Error(
|
|
220
222
|
(err.code && errorByCode.value[err.code]) ||
|
|
221
223
|
formatMessage(msg.value.setup.errorHttp, { status: err.status }),
|
|
224
|
+
{ cause: err },
|
|
222
225
|
);
|
|
223
226
|
}
|
|
224
227
|
throw err;
|
|
@@ -274,7 +277,7 @@ async function submitConfirm(): Promise<void> {
|
|
|
274
277
|
align-items: center;
|
|
275
278
|
justify-content: center;
|
|
276
279
|
padding: 24px;
|
|
277
|
-
background: linear-gradient(180deg,
|
|
280
|
+
background: linear-gradient(180deg, var(--sa-heading) 0%, #1e293b 100%);
|
|
278
281
|
}
|
|
279
282
|
.sa-setup-card {
|
|
280
283
|
width: 460px;
|
|
@@ -293,7 +296,7 @@ async function submitConfirm(): Promise<void> {
|
|
|
293
296
|
.sa-setup-locale {
|
|
294
297
|
margin-left: auto;
|
|
295
298
|
align-self: flex-start;
|
|
296
|
-
color:
|
|
299
|
+
color: var(--sa-muted-dark);
|
|
297
300
|
}
|
|
298
301
|
.sa-setup-badge {
|
|
299
302
|
width: 44px;
|
|
@@ -302,7 +305,7 @@ async function submitConfirm(): Promise<void> {
|
|
|
302
305
|
display: flex;
|
|
303
306
|
align-items: center;
|
|
304
307
|
justify-content: center;
|
|
305
|
-
background: linear-gradient(135deg,
|
|
308
|
+
background: linear-gradient(135deg, var(--sa-muted-dark), #1e293b);
|
|
306
309
|
color: #fff;
|
|
307
310
|
font-weight: 800;
|
|
308
311
|
font-size: 18px;
|
|
@@ -312,21 +315,21 @@ async function submitConfirm(): Promise<void> {
|
|
|
312
315
|
margin: 0;
|
|
313
316
|
font-weight: 800;
|
|
314
317
|
font-size: 18px;
|
|
315
|
-
color:
|
|
318
|
+
color: var(--sa-heading);
|
|
316
319
|
line-height: 1.1;
|
|
317
320
|
}
|
|
318
321
|
.sa-setup-sub {
|
|
319
322
|
font-size: 12px;
|
|
320
|
-
color:
|
|
323
|
+
color: var(--sa-muted-dark);
|
|
321
324
|
}
|
|
322
325
|
.sa-setup-hint {
|
|
323
326
|
font-size: 13px;
|
|
324
|
-
color:
|
|
327
|
+
color: var(--sa-muted-dark);
|
|
325
328
|
line-height: 1.5;
|
|
326
329
|
margin: 0 0 16px;
|
|
327
330
|
}
|
|
328
331
|
.sa-setup-hint code {
|
|
329
|
-
background:
|
|
332
|
+
background: var(--sa-border);
|
|
330
333
|
padding: 1px 5px;
|
|
331
334
|
border-radius: 4px;
|
|
332
335
|
}
|
|
@@ -354,17 +357,17 @@ async function submitConfirm(): Promise<void> {
|
|
|
354
357
|
margin-bottom: 12px;
|
|
355
358
|
}
|
|
356
359
|
.sa-setup-qr img {
|
|
357
|
-
border: 1px solid
|
|
360
|
+
border: 1px solid var(--sa-border);
|
|
358
361
|
border-radius: 8px;
|
|
359
362
|
padding: 8px;
|
|
360
363
|
background: #fff;
|
|
361
364
|
}
|
|
362
365
|
.sa-setup-qr__hint {
|
|
363
366
|
font-size: 12px;
|
|
364
|
-
color:
|
|
367
|
+
color: var(--sa-muted);
|
|
365
368
|
}
|
|
366
369
|
.sa-setup-secret {
|
|
367
|
-
background:
|
|
370
|
+
background: var(--sa-border-soft);
|
|
368
371
|
border-radius: 8px;
|
|
369
372
|
padding: 10px 12px;
|
|
370
373
|
margin-bottom: 10px;
|
|
@@ -373,27 +376,27 @@ async function submitConfirm(): Promise<void> {
|
|
|
373
376
|
font-size: 11px;
|
|
374
377
|
text-transform: uppercase;
|
|
375
378
|
letter-spacing: 0.06em;
|
|
376
|
-
color:
|
|
379
|
+
color: var(--sa-muted);
|
|
377
380
|
margin-bottom: 4px;
|
|
378
381
|
}
|
|
379
382
|
.sa-setup-secret__value {
|
|
380
383
|
font-size: 15px;
|
|
381
384
|
font-weight: 700;
|
|
382
|
-
color:
|
|
385
|
+
color: var(--sa-heading);
|
|
383
386
|
word-break: break-all;
|
|
384
387
|
letter-spacing: 0.04em;
|
|
385
388
|
}
|
|
386
389
|
.sa-setup-uri {
|
|
387
390
|
margin: 4px 0 4px;
|
|
388
391
|
font-size: 12px;
|
|
389
|
-
color:
|
|
392
|
+
color: var(--sa-muted-dark);
|
|
390
393
|
}
|
|
391
394
|
.sa-setup-uri__value {
|
|
392
395
|
display: block;
|
|
393
396
|
margin-top: 6px;
|
|
394
397
|
word-break: break-all;
|
|
395
398
|
color: #334155;
|
|
396
|
-
background:
|
|
399
|
+
background: var(--sa-bg-surface-2);
|
|
397
400
|
padding: 6px 8px;
|
|
398
401
|
border-radius: 6px;
|
|
399
402
|
}
|
|
@@ -402,7 +405,7 @@ async function submitConfirm(): Promise<void> {
|
|
|
402
405
|
width: 100%;
|
|
403
406
|
background: none;
|
|
404
407
|
border: none;
|
|
405
|
-
color:
|
|
408
|
+
color: var(--sa-muted);
|
|
406
409
|
font-size: 12px;
|
|
407
410
|
cursor: pointer;
|
|
408
411
|
text-decoration: underline;
|
|
@@ -1,20 +1,32 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<AdminPage class="sa-tenant-detail">
|
|
3
3
|
<AdminHero :title="data?.name ?? labels.title">
|
|
4
|
-
<template #before-title>
|
|
5
|
-
<q-btn
|
|
6
|
-
flat
|
|
7
|
-
dense
|
|
8
|
-
icon="arrow_back"
|
|
9
|
-
:label="labels.back"
|
|
10
|
-
:to="backRoute"
|
|
11
|
-
class="sa-tenant-detail__back"
|
|
12
|
-
/>
|
|
13
|
-
</template>
|
|
14
4
|
<template v-if="data" #subtitle>
|
|
15
5
|
{{ labels.slug }}: <code>{{ data.slug }}</code>
|
|
16
6
|
</template>
|
|
7
|
+
<!--
|
|
8
|
+
Back first, then the tenant-level actions, then whatever the app
|
|
9
|
+
adds — the same order every other hero uses. Both are plain
|
|
10
|
+
`.sa-btn` buttons: a hero is where a page's own actions live, and
|
|
11
|
+
a detail page's "suspend" is exactly that. It used to sit on the
|
|
12
|
+
master-data section instead, which read as an action on that one
|
|
13
|
+
card rather than on the tenant.
|
|
14
|
+
-->
|
|
17
15
|
<template #actions>
|
|
16
|
+
<button class="sa-btn" type="button" @click="goBack">
|
|
17
|
+
<q-icon name="arrow_back" size="16px" />
|
|
18
|
+
<span>{{ labels.back }}</span>
|
|
19
|
+
</button>
|
|
20
|
+
<button
|
|
21
|
+
v-for="action in manifestActions"
|
|
22
|
+
:key="action.def.id"
|
|
23
|
+
:class="['sa-btn', toneClass(action.def.actionKey)]"
|
|
24
|
+
type="button"
|
|
25
|
+
@click="action.onClick"
|
|
26
|
+
>
|
|
27
|
+
<q-icon :name="iconForActionKey(action.def.actionKey)" size="16px" />
|
|
28
|
+
<span>{{ action.def.label }}</span>
|
|
29
|
+
</button>
|
|
18
30
|
<slot name="header-actions" :data="data" :reload="load" />
|
|
19
31
|
</template>
|
|
20
32
|
</AdminHero>
|
|
@@ -22,29 +34,15 @@
|
|
|
22
34
|
<AdminBody :loading="loading" :empty="!data">
|
|
23
35
|
<template v-if="data">
|
|
24
36
|
<!-- Master data -->
|
|
25
|
-
<AdminSection
|
|
26
|
-
:title="labels.masterData"
|
|
27
|
-
:subtitle="stammdatenSub"
|
|
28
|
-
class="sa-card q-mb-md"
|
|
29
|
-
>
|
|
37
|
+
<AdminSection :title="labels.masterData" :subtitle="stammdatenSub" class="q-mb-md">
|
|
30
38
|
<template #actions>
|
|
31
|
-
<!-- Manifest-driven default actions (Suspend/Reactivate) -->
|
|
32
|
-
<q-btn
|
|
33
|
-
v-for="action in manifestActions"
|
|
34
|
-
:key="action.def.id"
|
|
35
|
-
outline
|
|
36
|
-
:color="toneColor(action.def.actionKey)"
|
|
37
|
-
:icon="iconForActionKey(action.def.actionKey)"
|
|
38
|
-
:label="action.def.label"
|
|
39
|
-
@click="action.onClick"
|
|
40
|
-
/>
|
|
41
39
|
<slot name="card-actions" :data="data" :reload="load" />
|
|
42
40
|
</template>
|
|
43
41
|
<slot name="stammdaten" :data="data">
|
|
44
42
|
<TenantMasterData
|
|
45
43
|
:data="data"
|
|
46
44
|
:labels="labels"
|
|
47
|
-
:format-date="
|
|
45
|
+
:format-date="formatDateResolved"
|
|
48
46
|
:yes="common.yes"
|
|
49
47
|
:no="common.no"
|
|
50
48
|
>
|
|
@@ -57,17 +55,13 @@
|
|
|
57
55
|
<AdminSection
|
|
58
56
|
v-if="verbrauchFields.length > 0"
|
|
59
57
|
:title="labels.usage"
|
|
60
|
-
class="
|
|
58
|
+
class="q-mb-md"
|
|
61
59
|
>
|
|
62
60
|
<TenantUsage :data="data" :fields="verbrauchFields" />
|
|
63
61
|
</AdminSection>
|
|
64
62
|
|
|
65
63
|
<!-- Users -->
|
|
66
|
-
<AdminSection
|
|
67
|
-
v-if="showUsers && data.users"
|
|
68
|
-
:title="labels.users"
|
|
69
|
-
class="sa-card q-mb-md"
|
|
70
|
-
>
|
|
64
|
+
<AdminSection v-if="showUsers && data.users" :title="labels.users" class="q-mb-md">
|
|
71
65
|
<TenantUsers :users="data.users" :columns="userColumns ?? defaultUserColumns" />
|
|
72
66
|
</AdminSection>
|
|
73
67
|
|
|
@@ -101,7 +95,7 @@ import { useMfaPrompt } from '../vue/use-mfa-prompt.js';
|
|
|
101
95
|
import AdminHero from '../components/admin-page/AdminHero.vue';
|
|
102
96
|
import AdminSection from '../components/admin-page/AdminSection.vue';
|
|
103
97
|
import AdminPage from '../components/admin-page/AdminPage.vue';
|
|
104
|
-
import type
|
|
98
|
+
import { useRouter, type RouteLocationRaw } from 'vue-router';
|
|
105
99
|
import type { TenantDetailData, VerbrauchField } from './tenant-detail/types.js';
|
|
106
100
|
import type { QTableColumn } from 'quasar';
|
|
107
101
|
import { useSuperAdminNotify } from '../quasar/notify.js';
|
|
@@ -189,7 +183,7 @@ function defaultFormatDate(value: string | null | undefined): string {
|
|
|
189
183
|
return String(value).slice(0, 10);
|
|
190
184
|
}
|
|
191
185
|
|
|
192
|
-
function
|
|
186
|
+
function formatDateResolved(value: string | null | undefined): string {
|
|
193
187
|
return props.formatDate ? props.formatDate(value) : defaultFormatDate(value);
|
|
194
188
|
}
|
|
195
189
|
|
|
@@ -272,16 +266,29 @@ const manifestActions = computed(() => {
|
|
|
272
266
|
.map((a) => ({ def: a.def, onClick: () => void a.invoke(row) }));
|
|
273
267
|
});
|
|
274
268
|
|
|
269
|
+
const router = useRouter();
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* The hero back button navigates rather than rendering a link.
|
|
273
|
+
*
|
|
274
|
+
* `backRoute` is a `RouteLocationRaw`, not an href, so there is no anchor to
|
|
275
|
+
* build without duplicating the router's resolution — and every other hero in
|
|
276
|
+
* the package uses a button for the same step.
|
|
277
|
+
*/
|
|
278
|
+
function goBack(): void {
|
|
279
|
+
void router.push(props.backRoute);
|
|
280
|
+
}
|
|
281
|
+
|
|
275
282
|
function iconForActionKey(actionKey: string): string {
|
|
276
283
|
if (actionKey.endsWith('.suspend')) return 'block';
|
|
277
284
|
if (actionKey.endsWith('.reactivate')) return 'play_arrow';
|
|
278
285
|
return 'bolt';
|
|
279
286
|
}
|
|
280
287
|
|
|
281
|
-
function
|
|
282
|
-
if (actionKey.endsWith('.suspend')) return '
|
|
283
|
-
if (actionKey.endsWith('.reactivate')) return 'positive';
|
|
284
|
-
return 'primary';
|
|
288
|
+
function toneClass(actionKey: string): string {
|
|
289
|
+
if (actionKey.endsWith('.suspend')) return 'sa-btn--danger';
|
|
290
|
+
if (actionKey.endsWith('.reactivate')) return 'sa-btn--positive';
|
|
291
|
+
return 'sa-btn--primary';
|
|
285
292
|
}
|
|
286
293
|
|
|
287
294
|
const defaultUserColumns = computed<QTableColumn[]>(() => [
|
|
@@ -316,9 +323,6 @@ const defaultUserColumns = computed<QTableColumn[]>(() => [
|
|
|
316
323
|
</script>
|
|
317
324
|
|
|
318
325
|
<style scoped>
|
|
319
|
-
.sa-tenant-detail__back {
|
|
320
|
-
margin-bottom: 6px;
|
|
321
|
-
}
|
|
322
326
|
.sa-tenant-detail__card-head {
|
|
323
327
|
display: flex;
|
|
324
328
|
justify-content: space-between;
|