@saasicat/ui-vue 0.21.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-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
|
@@ -2,139 +2,135 @@
|
|
|
2
2
|
<AdminPage class="sa-tenants">
|
|
3
3
|
<AdminHero :title="msg.list.title" :subtitle="subtitle" />
|
|
4
4
|
|
|
5
|
-
<
|
|
6
|
-
<
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
5
|
+
<AdminBody>
|
|
6
|
+
<q-banner v-if="error" class="bg-red-1 text-red-9 q-mb-md" rounded>
|
|
7
|
+
<strong>{{ common.error }}:</strong> {{ error.message }}
|
|
8
|
+
</q-banner>
|
|
9
|
+
|
|
10
|
+
<AdminSection class="sa-tenants__card">
|
|
11
|
+
<AdminFilters class="q-mb-lg">
|
|
12
|
+
<q-input
|
|
13
|
+
v-model="searchInput"
|
|
14
|
+
outlined
|
|
15
|
+
dense
|
|
16
|
+
clearable
|
|
17
|
+
:label="msg.list.searchPlaceholder"
|
|
18
|
+
debounce="250"
|
|
19
|
+
@update:model-value="applyFilter"
|
|
20
|
+
>
|
|
21
|
+
<template #prepend><q-icon name="search" size="18px" /></template>
|
|
22
|
+
</q-input>
|
|
23
|
+
<q-select
|
|
24
|
+
v-model="statusFilter"
|
|
25
|
+
outlined
|
|
26
|
+
dense
|
|
27
|
+
clearable
|
|
28
|
+
emit-value
|
|
29
|
+
map-options
|
|
30
|
+
:options="statusSelectOptions"
|
|
31
|
+
:label="msg.list.allStatuses"
|
|
32
|
+
@update:model-value="applyFilter"
|
|
33
|
+
/>
|
|
34
|
+
<q-select
|
|
35
|
+
v-if="planOptions && planOptions.length > 0"
|
|
36
|
+
v-model="planFilter"
|
|
37
|
+
outlined
|
|
38
|
+
dense
|
|
39
|
+
clearable
|
|
40
|
+
:options="planOptions"
|
|
41
|
+
:label="resolvedPlanFilterLabel"
|
|
42
|
+
@update:model-value="applyFilter"
|
|
43
|
+
/>
|
|
44
|
+
<slot name="filters-extra" />
|
|
45
|
+
</AdminFilters>
|
|
46
|
+
|
|
47
|
+
<AdminTable
|
|
48
|
+
server-side
|
|
49
|
+
:rows="items"
|
|
50
|
+
:columns="tenantColumns"
|
|
51
|
+
:loading="loading"
|
|
52
|
+
:page="page"
|
|
53
|
+
:rows-per-page="rowsPerPage"
|
|
54
|
+
:total="total"
|
|
55
|
+
:empty-text="msg.list.empty"
|
|
56
|
+
storage-key="tenants"
|
|
57
|
+
@update:page="goToPage"
|
|
58
|
+
@update:rows-per-page="setPageSize"
|
|
59
|
+
>
|
|
60
|
+
<template #body-cell-tenant="{ row }">
|
|
61
|
+
<q-td>
|
|
62
|
+
<div class="sa-tenants__tenant">
|
|
63
|
+
<div class="sa-tenants__avatar" :style="avatarStyle(row)">
|
|
64
|
+
{{ tenantInitials(row.name) }}
|
|
65
65
|
</div>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
<span
|
|
70
|
-
class="sa-tenants__plan-dot"
|
|
71
|
-
:style="{ background: planAccentFor(row) }"
|
|
72
|
-
/>
|
|
73
|
-
{{ planLabel(row) }}
|
|
74
|
-
</span>
|
|
75
|
-
</td>
|
|
76
|
-
<td>
|
|
77
|
-
<div class="sa-tenants__pills">
|
|
78
|
-
<slot name="status-pills" :row="row">
|
|
79
|
-
<StatusPill
|
|
80
|
-
v-for="(p, i) in resolvedPills(row)"
|
|
81
|
-
:key="i"
|
|
82
|
-
:label="p.label"
|
|
83
|
-
:icon="p.icon"
|
|
84
|
-
:tone="p.tone"
|
|
85
|
-
/>
|
|
86
|
-
</slot>
|
|
87
|
-
</div>
|
|
88
|
-
</td>
|
|
89
|
-
<td v-if="usageFields.length > 0" class="num">
|
|
90
|
-
<div
|
|
91
|
-
v-for="(uf, i) in usageFields"
|
|
92
|
-
:key="i"
|
|
93
|
-
class="sa-tenants__usage"
|
|
94
|
-
>
|
|
95
|
-
<q-icon :name="uf.icon" size="11px" />
|
|
96
|
-
{{ usageValue(row, uf) }}
|
|
66
|
+
<div>
|
|
67
|
+
<div class="sa-tenants__name">{{ row.name }}</div>
|
|
68
|
+
<div class="sa-tenants__slug">{{ row.slug }}</div>
|
|
97
69
|
</div>
|
|
98
|
-
</
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
70
|
+
</div>
|
|
71
|
+
</q-td>
|
|
72
|
+
</template>
|
|
73
|
+
|
|
74
|
+
<template #body-cell-plan="{ row }">
|
|
75
|
+
<q-td>
|
|
76
|
+
<span class="sa-tenants__plan">
|
|
77
|
+
<span
|
|
78
|
+
class="sa-tenants__plan-dot"
|
|
79
|
+
:style="{ background: planAccentFor(row) }"
|
|
80
|
+
/>
|
|
81
|
+
{{ planLabel(row) }}
|
|
82
|
+
</span>
|
|
83
|
+
</q-td>
|
|
84
|
+
</template>
|
|
85
|
+
|
|
86
|
+
<template #body-cell-status="{ row }">
|
|
87
|
+
<q-td>
|
|
88
|
+
<div class="sa-tenants__pills">
|
|
89
|
+
<slot name="status-pills" :row="row">
|
|
90
|
+
<StatusPill
|
|
91
|
+
v-for="(p, i) in resolvedPills(row)"
|
|
92
|
+
:key="i"
|
|
93
|
+
:label="p.label"
|
|
94
|
+
:icon="p.icon"
|
|
95
|
+
:tone="p.tone"
|
|
96
|
+
/>
|
|
120
97
|
</slot>
|
|
121
|
-
</
|
|
122
|
-
</
|
|
123
|
-
</
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
98
|
+
</div>
|
|
99
|
+
</q-td>
|
|
100
|
+
</template>
|
|
101
|
+
|
|
102
|
+
<template #body-cell-usage="{ row }">
|
|
103
|
+
<q-td class="text-right">
|
|
104
|
+
<div v-for="(uf, i) in usageFields" :key="i" class="sa-tenants__usage">
|
|
105
|
+
<q-icon :name="uf.icon" size="11px" />
|
|
106
|
+
{{ usageValue(row, uf) }}
|
|
107
|
+
</div>
|
|
108
|
+
</q-td>
|
|
109
|
+
</template>
|
|
110
|
+
|
|
111
|
+
<template #body-cell-createdAt="{ row }">
|
|
112
|
+
<q-td class="text-right sa-tenants__mono">{{ formatCreatedAt(row) }}</q-td>
|
|
113
|
+
</template>
|
|
114
|
+
|
|
115
|
+
<template v-if="hasActions" #row-actions="{ row }">
|
|
116
|
+
<slot name="row-actions" :row="row" :actions="visibleActions(row)">
|
|
117
|
+
<component
|
|
118
|
+
:is="action.to ? 'a' : 'button'"
|
|
119
|
+
v-for="action in visibleActions(row)"
|
|
120
|
+
:key="action.id"
|
|
121
|
+
:href="action.to ? action.to(row) : undefined"
|
|
122
|
+
class="sa-tenants__icon-btn"
|
|
123
|
+
:class="action.tone ? `sa-tenants__icon-btn--${action.tone}` : ''"
|
|
124
|
+
:title="action.label"
|
|
125
|
+
@click="action.handler ? action.handler(row) : undefined"
|
|
126
|
+
>
|
|
127
|
+
<q-icon :name="action.icon" size="15px" />
|
|
128
|
+
</component>
|
|
129
|
+
</slot>
|
|
130
|
+
</template>
|
|
131
|
+
</AdminTable>
|
|
132
|
+
</AdminSection>
|
|
133
|
+
</AdminBody>
|
|
138
134
|
|
|
139
135
|
<!-- Manifest-Driven Action Flow: only mounted when the `manifest` prop
|
|
140
136
|
is set AND `manifestActionsEnabled` is true (default when manifest
|
|
@@ -161,12 +157,16 @@
|
|
|
161
157
|
</template>
|
|
162
158
|
|
|
163
159
|
<script setup lang="ts">
|
|
160
|
+
import AdminTable from '../components/admin-page/AdminTable.vue';
|
|
164
161
|
import { computed, ref, watch } from 'vue';
|
|
162
|
+
import type { QTableColumn } from 'quasar';
|
|
163
|
+
import AdminBody from '../components/admin-page/AdminBody.vue';
|
|
164
|
+
import AdminFilters from '../components/admin-page/AdminFilters.vue';
|
|
165
165
|
import AdminHero from '../components/admin-page/AdminHero.vue';
|
|
166
|
+
import AdminSection from '../components/admin-page/AdminSection.vue';
|
|
166
167
|
import AdminPage from '../components/admin-page/AdminPage.vue';
|
|
167
168
|
import type { AdminManifest, TenantActionDef, TenantDto, TenantListFilter } from '@saasicat/types';
|
|
168
169
|
import type { HttpClient } from '../client/types.js';
|
|
169
|
-
import { formatMessage } from '../client/i18n/format.js';
|
|
170
170
|
import { useSaMessages, useSuperAdminI18n } from '../vue/use-super-admin-i18n.js';
|
|
171
171
|
import { useTenants } from '../vue/use-tenants.js';
|
|
172
172
|
import {
|
|
@@ -333,6 +333,9 @@ const msg = useSaMessages('tenants');
|
|
|
333
333
|
const common = useSaMessages('common');
|
|
334
334
|
const { intlLocale } = useSuperAdminI18n();
|
|
335
335
|
|
|
336
|
+
const statusSelectOptions = computed(() =>
|
|
337
|
+
resolvedStatusOptions.value.map((o) => ({ label: o.label, value: o.value })),
|
|
338
|
+
);
|
|
336
339
|
const resolvedStatusOptions = computed<ReadonlyArray<{ value: string; label: string }>>(
|
|
337
340
|
() =>
|
|
338
341
|
props.statusOptions ?? [
|
|
@@ -354,28 +357,42 @@ const list = useTenants<TenantRow>({
|
|
|
354
357
|
http: props.http,
|
|
355
358
|
getAuthToken: props.getAuthToken,
|
|
356
359
|
});
|
|
357
|
-
|
|
360
|
+
// Aliased: the `pageSize` prop is the INITIAL size, `list.pageSize` is the
|
|
361
|
+
// current one. Sharing one name makes the template ambiguous about which of
|
|
362
|
+
// the two it reads.
|
|
363
|
+
const { items, page, pageSize: rowsPerPage, total, loading, error, goToPage, setPageSize } = list;
|
|
358
364
|
|
|
359
365
|
setPageSize(props.pageSize);
|
|
360
366
|
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
367
|
+
const tenantColumns = computed<QTableColumn[]>(() => {
|
|
368
|
+
const cols: QTableColumn[] = [
|
|
369
|
+
{ name: 'tenant', label: msg.value.tenant, field: 'name', align: 'left' },
|
|
370
|
+
];
|
|
371
|
+
if (props.showPlanColumn) {
|
|
372
|
+
cols.push({
|
|
373
|
+
name: 'plan',
|
|
374
|
+
label: resolvedPlanColumnLabel.value,
|
|
375
|
+
field: 'plan',
|
|
376
|
+
align: 'left',
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
cols.push({ name: 'status', label: common.value.status, field: 'status', align: 'left' });
|
|
380
|
+
if (props.usageFields.length > 0) {
|
|
381
|
+
cols.push({
|
|
382
|
+
name: 'usage',
|
|
383
|
+
label: msg.value.list.columnUsage,
|
|
384
|
+
field: 'id',
|
|
385
|
+
align: 'right',
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
cols.push({
|
|
389
|
+
name: 'createdAt',
|
|
390
|
+
label: msg.value.list.columnCreatedAt,
|
|
391
|
+
field: 'createdAt',
|
|
392
|
+
align: 'right',
|
|
393
|
+
});
|
|
394
|
+
return cols;
|
|
395
|
+
});
|
|
379
396
|
|
|
380
397
|
function applyFilter(): void {
|
|
381
398
|
// The status value is passed through unchanged. Apps configure the values
|
|
@@ -431,7 +448,6 @@ if (manifestFlow && typeof window !== 'undefined') {
|
|
|
431
448
|
manifestFlow.realOrphans,
|
|
432
449
|
(orphans) => {
|
|
433
450
|
if (orphans.length > 0) {
|
|
434
|
-
// eslint-disable-next-line no-console
|
|
435
451
|
console.warn(
|
|
436
452
|
'[PlatformTenantsPage] Manifest actions without a handler in createSuperAdminApp({ actions }):',
|
|
437
453
|
orphans,
|
|
@@ -453,7 +469,6 @@ const combinedActions = computed<TenantRowAction[]>(() => {
|
|
|
453
469
|
const filteredCustom = custom.filter((a) => {
|
|
454
470
|
if (a.actionKey && manifestKeys.has(a.actionKey)) {
|
|
455
471
|
if (typeof window !== 'undefined') {
|
|
456
|
-
// eslint-disable-next-line no-console
|
|
457
472
|
console.warn(
|
|
458
473
|
`[PlatformTenantsPage] Custom action "${a.id}" (actionKey="${a.actionKey}") ` +
|
|
459
474
|
`collides with a manifest action — the manifest wins.`,
|
|
@@ -515,89 +530,17 @@ function visibleActions(row: TenantRow): TenantRowAction[] {
|
|
|
515
530
|
</script>
|
|
516
531
|
|
|
517
532
|
<style scoped>
|
|
518
|
-
.
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
gap: 6px;
|
|
530
|
-
background: #fff;
|
|
531
|
-
border: 1px solid var(--sa-border, #e2e8f0);
|
|
532
|
-
border-radius: 8px;
|
|
533
|
-
padding: 6px 10px;
|
|
534
|
-
}
|
|
535
|
-
.sa-tenants__search :deep(.q-icon) {
|
|
536
|
-
color: var(--sa-muted, #64748b);
|
|
537
|
-
}
|
|
538
|
-
.sa-tenants__search input {
|
|
539
|
-
flex: 1;
|
|
540
|
-
border: none;
|
|
541
|
-
outline: none;
|
|
542
|
-
background: transparent;
|
|
543
|
-
font-size: 13px;
|
|
544
|
-
font-family: inherit;
|
|
545
|
-
color: var(--sa-body, #1e293b);
|
|
546
|
-
min-width: 0;
|
|
547
|
-
}
|
|
548
|
-
.sa-tenants__clear {
|
|
549
|
-
background: transparent;
|
|
550
|
-
border: none;
|
|
551
|
-
cursor: pointer;
|
|
552
|
-
padding: 2px;
|
|
553
|
-
}
|
|
554
|
-
.sa-tenants__select {
|
|
555
|
-
padding: 7px 10px;
|
|
556
|
-
font-size: 12.5px;
|
|
557
|
-
font-family: inherit;
|
|
558
|
-
border: 1px solid var(--sa-border, #e2e8f0);
|
|
559
|
-
border-radius: 8px;
|
|
560
|
-
background: #fff;
|
|
561
|
-
cursor: pointer;
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
.sa-tenants__card {
|
|
565
|
-
margin: 0 0 16px;
|
|
566
|
-
background: #fff;
|
|
567
|
-
border: 1px solid var(--sa-border, #e2e8f0);
|
|
568
|
-
border-radius: 12px;
|
|
569
|
-
overflow: hidden;
|
|
570
|
-
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
|
|
571
|
-
}
|
|
572
|
-
.sa-tenants__wrap {
|
|
573
|
-
overflow-x: auto;
|
|
574
|
-
}
|
|
575
|
-
table {
|
|
576
|
-
width: 100%;
|
|
577
|
-
border-collapse: collapse;
|
|
578
|
-
font-size: 13px;
|
|
579
|
-
min-width: 800px;
|
|
580
|
-
}
|
|
581
|
-
thead tr {
|
|
582
|
-
background: #fafbfc;
|
|
583
|
-
}
|
|
584
|
-
th {
|
|
585
|
-
padding: 10px 14px;
|
|
586
|
-
font-size: 10.5px;
|
|
587
|
-
font-weight: 700;
|
|
588
|
-
letter-spacing: 0.08em;
|
|
589
|
-
color: var(--sa-muted, #64748b);
|
|
590
|
-
text-transform: uppercase;
|
|
591
|
-
text-align: left;
|
|
592
|
-
}
|
|
593
|
-
td {
|
|
594
|
-
padding: 11px 14px;
|
|
595
|
-
vertical-align: middle;
|
|
596
|
-
border-top: 1px solid var(--sa-border-soft, #f1f5f9);
|
|
597
|
-
}
|
|
598
|
-
.num {
|
|
599
|
-
text-align: right;
|
|
600
|
-
}
|
|
533
|
+
/* No table rules here on purpose — and not because they would be inert.
|
|
534
|
+
Content passed into a child component's slot keeps THIS component's scope
|
|
535
|
+
id, so the `table`, `thead`, `th`, `td` and `.num` rules that used to sit
|
|
536
|
+
here did reach `AdminTable`'s cells. That was the bug: they drew a second
|
|
537
|
+
border on top of the one AdminTable already draws, and the tenant list was
|
|
538
|
+
the only list in the package with doubled row separators. Removing them
|
|
539
|
+
took `border-top-width` from 1px back to 0px.
|
|
540
|
+
|
|
541
|
+
The rule to carry forward: styling a table here means overriding AdminTable
|
|
542
|
+
for one page. If a table needs to look different, that belongs in
|
|
543
|
+
AdminTable, behind a prop. */
|
|
601
544
|
.sa-tenants__mono {
|
|
602
545
|
font-family: var(--sa-font-mono, ui-monospace, monospace);
|
|
603
546
|
font-size: 12px;
|
|
@@ -623,11 +566,11 @@ td {
|
|
|
623
566
|
.sa-tenants__name {
|
|
624
567
|
font-size: 13px;
|
|
625
568
|
font-weight: 600;
|
|
626
|
-
color: var(--sa-heading,
|
|
569
|
+
color: var(--sa-heading, var(--sa-heading));
|
|
627
570
|
}
|
|
628
571
|
.sa-tenants__slug {
|
|
629
572
|
font-size: 11px;
|
|
630
|
-
color: var(--sa-muted,
|
|
573
|
+
color: var(--sa-muted, var(--sa-muted));
|
|
631
574
|
font-family: var(--sa-font-mono, ui-monospace, monospace);
|
|
632
575
|
}
|
|
633
576
|
|
|
@@ -653,16 +596,13 @@ td {
|
|
|
653
596
|
align-items: center;
|
|
654
597
|
gap: 4px;
|
|
655
598
|
font-size: 12px;
|
|
656
|
-
color: var(--sa-muted-dark,
|
|
599
|
+
color: var(--sa-muted-dark, var(--sa-muted-dark));
|
|
657
600
|
margin-left: 8px;
|
|
658
601
|
}
|
|
659
602
|
.sa-tenants__usage :deep(.q-icon) {
|
|
660
|
-
color: var(--sa-muted,
|
|
603
|
+
color: var(--sa-muted, var(--sa-muted));
|
|
661
604
|
}
|
|
662
605
|
|
|
663
|
-
.sa-tenants__actions {
|
|
664
|
-
white-space: nowrap;
|
|
665
|
-
}
|
|
666
606
|
.sa-tenants__icon-btn {
|
|
667
607
|
background: transparent;
|
|
668
608
|
border: none;
|
|
@@ -674,10 +614,10 @@ td {
|
|
|
674
614
|
align-items: center;
|
|
675
615
|
justify-content: center;
|
|
676
616
|
text-decoration: none;
|
|
677
|
-
color: var(--sa-muted,
|
|
617
|
+
color: var(--sa-muted, var(--sa-muted));
|
|
678
618
|
}
|
|
679
619
|
.sa-tenants__icon-btn:hover {
|
|
680
|
-
background:
|
|
620
|
+
background: var(--sa-border-soft);
|
|
681
621
|
}
|
|
682
622
|
.sa-tenants__icon-btn :deep(.q-icon) {
|
|
683
623
|
color: inherit;
|
|
@@ -697,24 +637,4 @@ td {
|
|
|
697
637
|
.sa-tenants__icon-btn--accent {
|
|
698
638
|
color: var(--sa-accent, #7c3aed);
|
|
699
639
|
}
|
|
700
|
-
|
|
701
|
-
.sa-tenants__empty {
|
|
702
|
-
padding: 40px 16px;
|
|
703
|
-
text-align: center;
|
|
704
|
-
color: var(--sa-muted, #64748b);
|
|
705
|
-
}
|
|
706
|
-
.sa-tenants__loading {
|
|
707
|
-
padding: 24px;
|
|
708
|
-
display: flex;
|
|
709
|
-
align-items: center;
|
|
710
|
-
gap: 12px;
|
|
711
|
-
color: var(--sa-muted, #64748b);
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
.sa-tenants__foot {
|
|
715
|
-
padding: 0;
|
|
716
|
-
text-align: right;
|
|
717
|
-
font-size: 12px;
|
|
718
|
-
color: var(--sa-muted, #64748b);
|
|
719
|
-
}
|
|
720
640
|
</style>
|