@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,80 +1,80 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
<
|
|
70
|
-
<q-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
<
|
|
2
|
+
<AdminPage class="sa-emh">
|
|
3
|
+
<AdminHero :title="resolvedTitle" :subtitle="msg.history.subtitle">
|
|
4
|
+
<template #actions>
|
|
5
|
+
<AdminRefreshBtn :loading="loading" @refresh="applyFilter" />
|
|
6
|
+
</template>
|
|
7
|
+
</AdminHero>
|
|
8
|
+
|
|
9
|
+
<AdminBody>
|
|
10
|
+
<AdminSection class="sa-emh__body">
|
|
11
|
+
<div class="sa-emh__filter">
|
|
12
|
+
<q-input
|
|
13
|
+
v-model="filter.search"
|
|
14
|
+
outlined
|
|
15
|
+
dense
|
|
16
|
+
clearable
|
|
17
|
+
:label="msg.history.searchLabel"
|
|
18
|
+
debounce="350"
|
|
19
|
+
@keyup.enter="applyFilter"
|
|
20
|
+
@update:model-value="applyFilter"
|
|
21
|
+
>
|
|
22
|
+
<template #prepend><q-icon name="search" /></template>
|
|
23
|
+
</q-input>
|
|
24
|
+
<q-select
|
|
25
|
+
v-model="filter.status"
|
|
26
|
+
outlined
|
|
27
|
+
dense
|
|
28
|
+
clearable
|
|
29
|
+
emit-value
|
|
30
|
+
map-options
|
|
31
|
+
:label="common.status"
|
|
32
|
+
:options="statusOptions"
|
|
33
|
+
@update:model-value="applyFilter"
|
|
34
|
+
/>
|
|
35
|
+
<q-input
|
|
36
|
+
v-model="filter.from"
|
|
37
|
+
outlined
|
|
38
|
+
dense
|
|
39
|
+
clearable
|
|
40
|
+
type="date"
|
|
41
|
+
:label="common.from"
|
|
42
|
+
@update:model-value="applyFilter"
|
|
43
|
+
/>
|
|
44
|
+
<q-input
|
|
45
|
+
v-model="filter.to"
|
|
46
|
+
outlined
|
|
47
|
+
dense
|
|
48
|
+
clearable
|
|
49
|
+
type="date"
|
|
50
|
+
:label="common.to"
|
|
51
|
+
@update:model-value="applyFilter"
|
|
52
|
+
/>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div class="sa-emh__card">
|
|
56
|
+
<AdminTable
|
|
57
|
+
server-side
|
|
58
|
+
:rows="rows"
|
|
59
|
+
:columns="columns"
|
|
60
|
+
:loading="loading"
|
|
61
|
+
:page="pagination.page"
|
|
62
|
+
:rows-per-page="pagination.rowsPerPage"
|
|
63
|
+
:total="pagination.rowsNumber"
|
|
64
|
+
storage-key="email-history"
|
|
65
|
+
@row-click="(_evt: Event, row: EmailHistoryRow) => openDetail(row)"
|
|
66
|
+
@update:page="onPageChange"
|
|
67
|
+
@update:rows-per-page="onRowsPerPageChange"
|
|
68
|
+
>
|
|
69
|
+
<template #body-cell-status="{ row }">
|
|
70
|
+
<q-td>
|
|
71
|
+
<q-badge
|
|
72
|
+
:color="statusColor(row.status)"
|
|
73
|
+
:label="statusLabel(row.status)"
|
|
74
|
+
/>
|
|
75
|
+
</q-td>
|
|
76
|
+
</template>
|
|
77
|
+
<template #row-actions="{ row }">
|
|
78
78
|
<q-btn
|
|
79
79
|
flat
|
|
80
80
|
dense
|
|
@@ -91,14 +91,14 @@
|
|
|
91
91
|
:title="msg.history.removeFromHistory"
|
|
92
92
|
@click.stop="askDelete(row.id)"
|
|
93
93
|
/>
|
|
94
|
-
</
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
</
|
|
99
|
-
</
|
|
100
|
-
</
|
|
101
|
-
</
|
|
94
|
+
</template>
|
|
95
|
+
<template #no-data>
|
|
96
|
+
<div class="sa-emh__empty">{{ msg.history.empty }}</div>
|
|
97
|
+
</template>
|
|
98
|
+
</AdminTable>
|
|
99
|
+
</div>
|
|
100
|
+
</AdminSection>
|
|
101
|
+
</AdminBody>
|
|
102
102
|
|
|
103
103
|
<q-dialog v-model="detailOpen">
|
|
104
104
|
<q-card class="sa-emh__detail">
|
|
@@ -206,18 +206,25 @@
|
|
|
206
206
|
|
|
207
207
|
<MfaPromptDialog
|
|
208
208
|
v-if="requireMfaForWrite"
|
|
209
|
-
:model-value="
|
|
210
|
-
:description="
|
|
211
|
-
:error="
|
|
209
|
+
:model-value="mfa.show.value"
|
|
210
|
+
:description="mfa.description.value"
|
|
211
|
+
:error="mfa.error.value"
|
|
212
212
|
:setup-hint="mfaSetupHint"
|
|
213
|
-
@update:model-value="
|
|
214
|
-
@confirm="
|
|
213
|
+
@update:model-value="mfa.onVisibility"
|
|
214
|
+
@confirm="mfa.onConfirm"
|
|
215
215
|
/>
|
|
216
|
-
</
|
|
216
|
+
</AdminPage>
|
|
217
217
|
</template>
|
|
218
218
|
|
|
219
219
|
<script setup lang="ts">
|
|
220
|
+
import AdminTable from '../components/admin-page/AdminTable.vue';
|
|
220
221
|
import { computed, reactive, ref } from 'vue';
|
|
222
|
+
import { useMfaPrompt } from '../vue/use-mfa-prompt.js';
|
|
223
|
+
import AdminRefreshBtn from '../components/admin-page/AdminRefreshBtn.vue';
|
|
224
|
+
import AdminBody from '../components/admin-page/AdminBody.vue';
|
|
225
|
+
import AdminHero from '../components/admin-page/AdminHero.vue';
|
|
226
|
+
import AdminSection from '../components/admin-page/AdminSection.vue';
|
|
227
|
+
import AdminPage from '../components/admin-page/AdminPage.vue';
|
|
221
228
|
import { useSuperAdminNotify } from '../quasar/notify.js';
|
|
222
229
|
import MfaPromptDialog from '../components/MfaPromptDialog.vue';
|
|
223
230
|
import { formatMessage } from '../client/i18n/format.js';
|
|
@@ -306,7 +313,6 @@ const columns = computed(() => [
|
|
|
306
313
|
field: (r: EmailHistoryRow) => formatTs(r.sentAt),
|
|
307
314
|
align: 'left' as const,
|
|
308
315
|
},
|
|
309
|
-
{ name: 'actions', label: '', field: 'id' as never, align: 'right' as const },
|
|
310
316
|
]);
|
|
311
317
|
|
|
312
318
|
const detailOpen = ref(false);
|
|
@@ -317,10 +323,7 @@ const confirmDeleteOpen = ref(false);
|
|
|
317
323
|
const pendingDeleteId = ref<string | null>(null);
|
|
318
324
|
|
|
319
325
|
// MFA loop analogous to PlatformEmailPage (promise-resolver pattern).
|
|
320
|
-
const
|
|
321
|
-
const mfaError = ref('');
|
|
322
|
-
const mfaDescription = ref('');
|
|
323
|
-
let pendingMfaResolve: ((code: string | null) => void) | null = null;
|
|
326
|
+
const mfa = useMfaPrompt();
|
|
324
327
|
|
|
325
328
|
// Sequence guard: with rapidly changing filters a stale (out-of-order)
|
|
326
329
|
// response must not overwrite the newest.
|
|
@@ -354,12 +357,17 @@ async function reload(): Promise<void> {
|
|
|
354
357
|
void reload();
|
|
355
358
|
defineExpose({ reload });
|
|
356
359
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
pagination.value.page =
|
|
361
|
-
|
|
362
|
-
|
|
360
|
+
// The pager owns page and size; both need a fetch, and a size change starts
|
|
361
|
+
// over at page 1 — the row it would land on otherwise is arbitrary.
|
|
362
|
+
function onPageChange(page: number): void {
|
|
363
|
+
pagination.value.page = page;
|
|
364
|
+
void reload();
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function onRowsPerPageChange(rows: number): void {
|
|
368
|
+
pagination.value.rowsPerPage = rows;
|
|
369
|
+
pagination.value.page = 1;
|
|
370
|
+
void reload();
|
|
363
371
|
}
|
|
364
372
|
|
|
365
373
|
function applyFilter(): void {
|
|
@@ -428,48 +436,25 @@ async function runWrite<T>(
|
|
|
428
436
|
}
|
|
429
437
|
}
|
|
430
438
|
for (;;) {
|
|
431
|
-
const code = await
|
|
439
|
+
const code = await mfa.prompt(label);
|
|
432
440
|
if (code === null) return { ok: false };
|
|
433
441
|
try {
|
|
434
442
|
const result = await invoke(code);
|
|
435
|
-
|
|
443
|
+
mfa.show.value = false;
|
|
436
444
|
return { ok: true, result };
|
|
437
445
|
} catch (err) {
|
|
438
446
|
const status = (err as { response?: { status?: number } })?.response?.status;
|
|
439
447
|
if (status === 401) {
|
|
440
|
-
|
|
448
|
+
mfa.error.value = shell.value.mfa.invalidCode;
|
|
441
449
|
continue;
|
|
442
450
|
}
|
|
443
|
-
|
|
451
|
+
mfa.show.value = false;
|
|
444
452
|
notify('negative', errMsg(err));
|
|
445
453
|
return { ok: false };
|
|
446
454
|
}
|
|
447
455
|
}
|
|
448
456
|
}
|
|
449
457
|
|
|
450
|
-
function promptMfa(description: string): Promise<string | null> {
|
|
451
|
-
return new Promise((resolve) => {
|
|
452
|
-
mfaDescription.value = description;
|
|
453
|
-
mfaError.value = '';
|
|
454
|
-
showMfa.value = true;
|
|
455
|
-
pendingMfaResolve = (code) => {
|
|
456
|
-
pendingMfaResolve = null;
|
|
457
|
-
resolve(code);
|
|
458
|
-
};
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
function onMfaConfirm(code: string): void {
|
|
463
|
-
pendingMfaResolve?.(code);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
function onMfaDialogVisibility(open: boolean): void {
|
|
467
|
-
showMfa.value = open;
|
|
468
|
-
if (!open && pendingMfaResolve) {
|
|
469
|
-
pendingMfaResolve(null);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
|
|
473
458
|
function statusColor(status: EmailHistoryStatus): string {
|
|
474
459
|
switch (status) {
|
|
475
460
|
case 'SENT':
|
|
@@ -521,32 +506,6 @@ function formatTs(iso: string | null | undefined): string {
|
|
|
521
506
|
</script>
|
|
522
507
|
|
|
523
508
|
<style scoped>
|
|
524
|
-
.sa-emh {
|
|
525
|
-
min-height: calc(100vh - 56px);
|
|
526
|
-
background: var(--sa-bg-app, #f1f5f9);
|
|
527
|
-
}
|
|
528
|
-
.sa-emh__head {
|
|
529
|
-
padding: 20px 28px 8px;
|
|
530
|
-
display: flex;
|
|
531
|
-
align-items: flex-start;
|
|
532
|
-
justify-content: space-between;
|
|
533
|
-
gap: 16px;
|
|
534
|
-
}
|
|
535
|
-
.sa-emh__title {
|
|
536
|
-
margin: 0;
|
|
537
|
-
font-family: var(--sa-font-head, system-ui, sans-serif);
|
|
538
|
-
font-weight: 700;
|
|
539
|
-
font-size: 22px;
|
|
540
|
-
color: var(--sa-heading, #0f172a);
|
|
541
|
-
}
|
|
542
|
-
.sa-emh__sub {
|
|
543
|
-
margin: 4px 0 0;
|
|
544
|
-
color: var(--sa-muted-dark, #475569);
|
|
545
|
-
font-size: 13.5px;
|
|
546
|
-
}
|
|
547
|
-
.sa-emh__body {
|
|
548
|
-
padding: 12px 28px 28px;
|
|
549
|
-
}
|
|
550
509
|
.sa-emh__filter {
|
|
551
510
|
display: flex;
|
|
552
511
|
gap: 10px;
|
|
@@ -559,7 +518,7 @@ function formatTs(iso: string | null | undefined): string {
|
|
|
559
518
|
}
|
|
560
519
|
.sa-emh__card {
|
|
561
520
|
background: #fff;
|
|
562
|
-
border: 1px solid var(--sa-border,
|
|
521
|
+
border: 1px solid var(--sa-border, var(--sa-border));
|
|
563
522
|
border-radius: 12px;
|
|
564
523
|
overflow: hidden;
|
|
565
524
|
padding: 8px 0;
|
|
@@ -567,7 +526,7 @@ function formatTs(iso: string | null | undefined): string {
|
|
|
567
526
|
.sa-emh__empty {
|
|
568
527
|
width: 100%;
|
|
569
528
|
text-align: center;
|
|
570
|
-
color: var(--sa-muted-dark,
|
|
529
|
+
color: var(--sa-muted-dark, var(--sa-muted));
|
|
571
530
|
padding: 24px 0;
|
|
572
531
|
}
|
|
573
532
|
.sa-emh__detail {
|
|
@@ -585,14 +544,14 @@ function formatTs(iso: string | null | undefined): string {
|
|
|
585
544
|
width: 100%;
|
|
586
545
|
min-height: 320px;
|
|
587
546
|
max-height: 60vh;
|
|
588
|
-
border: 1px solid var(--sa-border,
|
|
547
|
+
border: 1px solid var(--sa-border, var(--sa-border));
|
|
589
548
|
border-radius: 8px;
|
|
590
549
|
background: #fff;
|
|
591
550
|
}
|
|
592
551
|
.sa-emh__text,
|
|
593
552
|
.sa-emh__smtp {
|
|
594
|
-
background:
|
|
595
|
-
border: 1px solid var(--sa-border,
|
|
553
|
+
background: var(--sa-bg-surface-2);
|
|
554
|
+
border: 1px solid var(--sa-border, var(--sa-border));
|
|
596
555
|
border-radius: 8px;
|
|
597
556
|
padding: 12px;
|
|
598
557
|
font-size: 12px;
|