@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
package/dist/quasar/index.cjs
CHANGED
|
@@ -92,17 +92,27 @@ var SUPER_ADMIN_ACTIONS_KEY = /* @__PURE__ */ Symbol.for(
|
|
|
92
92
|
var SUPER_ADMIN_MANIFEST_KEY = /* @__PURE__ */ Symbol.for(
|
|
93
93
|
"@saasicat/ui-vue/SUPER_ADMIN_MANIFEST"
|
|
94
94
|
);
|
|
95
|
+
var SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY = /* @__PURE__ */ Symbol.for("@saasicat/ui-vue/SUPER_ADMIN_MANIFEST_CLEAR_CACHE");
|
|
95
96
|
var SUPER_ADMIN_LOGIN_ADAPTER_KEY = /* @__PURE__ */ Symbol.for(
|
|
96
97
|
"@saasicat/ui-vue/SUPER_ADMIN_LOGIN_ADAPTER"
|
|
97
98
|
);
|
|
98
99
|
var SUPER_ADMIN_HTTP_KEY = /* @__PURE__ */ Symbol.for(
|
|
99
100
|
"@saasicat/ui-vue/SUPER_ADMIN_HTTP"
|
|
100
101
|
);
|
|
102
|
+
function isUnauthorizedError(err) {
|
|
103
|
+
const status = err?.status;
|
|
104
|
+
return status === 401 || status === 403;
|
|
105
|
+
}
|
|
101
106
|
function buildNavigationGuard(options) {
|
|
102
107
|
const { authGuard, manifestGuard } = options;
|
|
103
108
|
if (!authGuard && !manifestGuard) return null;
|
|
109
|
+
let redirectedForUnauthorized = false;
|
|
110
|
+
let reachedLoginAfterRedirect = false;
|
|
104
111
|
return async (to) => {
|
|
105
|
-
if (to.meta?.public === true)
|
|
112
|
+
if (to.meta?.public === true) {
|
|
113
|
+
if (redirectedForUnauthorized) reachedLoginAfterRedirect = true;
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
106
116
|
if (authGuard) {
|
|
107
117
|
if (!authGuard.isAuthenticated()) return authGuard.onUnauthenticated();
|
|
108
118
|
if (authGuard.isSuperAdmin && !authGuard.isSuperAdmin()) {
|
|
@@ -112,7 +122,15 @@ function buildNavigationGuard(options) {
|
|
|
112
122
|
if (manifestGuard) {
|
|
113
123
|
try {
|
|
114
124
|
await manifestGuard.ensureLoaded();
|
|
125
|
+
redirectedForUnauthorized = false;
|
|
126
|
+
reachedLoginAfterRedirect = false;
|
|
115
127
|
} catch (err) {
|
|
128
|
+
if (authGuard && isUnauthorizedError(err)) {
|
|
129
|
+
if (!redirectedForUnauthorized || !reachedLoginAfterRedirect) {
|
|
130
|
+
redirectedForUnauthorized = true;
|
|
131
|
+
return authGuard.onUnauthenticated();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
116
134
|
if (manifestGuard.errorRoute && to.path !== manifestGuard.errorRoute) {
|
|
117
135
|
return manifestGuard.errorRoute;
|
|
118
136
|
}
|
|
@@ -249,8 +267,7 @@ var bundlesMessages = defineMessages(
|
|
|
249
267
|
title: "Bundles",
|
|
250
268
|
subtitle: "Produktgruppen aus Features & Quotas \u2014 verwendet in Pl\xE4nen. Bundles werden im SuperAdmin kuratiert.",
|
|
251
269
|
displayLocale: "Anzeige-Sprache",
|
|
252
|
-
newBundle: "Neues Bundle"
|
|
253
|
-
reload: "Liste neu laden"
|
|
270
|
+
newBundle: "Neues Bundle"
|
|
254
271
|
},
|
|
255
272
|
filter: {
|
|
256
273
|
all: "Alle Status",
|
|
@@ -464,8 +481,7 @@ var bundlesMessages = defineMessages(
|
|
|
464
481
|
title: "Bundles",
|
|
465
482
|
subtitle: "Product groups made of features & quotas \u2014 used in plans. Bundles are curated in the SuperAdmin.",
|
|
466
483
|
displayLocale: "Display language",
|
|
467
|
-
newBundle: "New bundle"
|
|
468
|
-
reload: "Reload list"
|
|
484
|
+
newBundle: "New bundle"
|
|
469
485
|
},
|
|
470
486
|
filter: {
|
|
471
487
|
all: "All statuses",
|
|
@@ -664,6 +680,9 @@ var commonMessages = defineMessages(
|
|
|
664
680
|
loading: "Lade \u2026",
|
|
665
681
|
saving: "Speichere \u2026",
|
|
666
682
|
loadingData: "Daten werden geladen\u2026",
|
|
683
|
+
noData: "Keine Daten vorhanden",
|
|
684
|
+
filters: "Filter",
|
|
685
|
+
results: "Ergebnisse",
|
|
667
686
|
error: "Fehler",
|
|
668
687
|
errorLoadFailed: "Laden fehlgeschlagen",
|
|
669
688
|
errorSaveFailed: "Speichern fehlgeschlagen",
|
|
@@ -709,7 +728,16 @@ var commonMessages = defineMessages(
|
|
|
709
728
|
unlimited: "unbegrenzt",
|
|
710
729
|
both: "Beide",
|
|
711
730
|
createFailed: "Anlegen fehlgeschlagen",
|
|
712
|
-
noChanges: "Keine \xC4nderungen"
|
|
731
|
+
noChanges: "Keine \xC4nderungen",
|
|
732
|
+
paginator: {
|
|
733
|
+
label: "Seitennavigation",
|
|
734
|
+
rowsPerPage: "Zeilen pro Seite",
|
|
735
|
+
all: "Alle",
|
|
736
|
+
page: "Seite {page}/{pages}",
|
|
737
|
+
pageInput: "Seite, 1 bis {pages}",
|
|
738
|
+
previous: "Vorherige Seite",
|
|
739
|
+
next: "N\xE4chste Seite"
|
|
740
|
+
}
|
|
713
741
|
},
|
|
714
742
|
{
|
|
715
743
|
save: "Save",
|
|
@@ -734,6 +762,9 @@ var commonMessages = defineMessages(
|
|
|
734
762
|
loading: "Loading \u2026",
|
|
735
763
|
saving: "Saving \u2026",
|
|
736
764
|
loadingData: "Loading data\u2026",
|
|
765
|
+
noData: "No data available",
|
|
766
|
+
filters: "Filters",
|
|
767
|
+
results: "Results",
|
|
737
768
|
error: "Error",
|
|
738
769
|
errorLoadFailed: "Failed to load",
|
|
739
770
|
errorSaveFailed: "Failed to save",
|
|
@@ -779,7 +810,16 @@ var commonMessages = defineMessages(
|
|
|
779
810
|
unlimited: "unlimited",
|
|
780
811
|
both: "Both",
|
|
781
812
|
createFailed: "Creation failed",
|
|
782
|
-
noChanges: "No changes"
|
|
813
|
+
noChanges: "No changes",
|
|
814
|
+
paginator: {
|
|
815
|
+
label: "Pagination",
|
|
816
|
+
rowsPerPage: "Rows per page",
|
|
817
|
+
all: "All",
|
|
818
|
+
page: "Page {page}/{pages}",
|
|
819
|
+
pageInput: "Page, 1 to {pages}",
|
|
820
|
+
previous: "Previous page",
|
|
821
|
+
next: "Next page"
|
|
822
|
+
}
|
|
783
823
|
}
|
|
784
824
|
);
|
|
785
825
|
|
|
@@ -884,7 +924,7 @@ var discoveryMessages = defineMessages(
|
|
|
884
924
|
quota: {
|
|
885
925
|
usageProvider: "UsageProvider",
|
|
886
926
|
usageProviderMissing: "fehlt",
|
|
887
|
-
noUsageProviderWarning: "Eine harte Quota ohne UsageProvider ist nicht deploy-f\xE4hig (Preflight
|
|
927
|
+
noUsageProviderWarning: "Eine harte Quota ohne UsageProvider ist nicht deploy-f\xE4hig (Preflight).",
|
|
888
928
|
outdatedBanner: "Die code-abgeleiteten Quota-Fakten (Einheit/Enforcement/Provider) haben sich seit der letzten Freigabe ge\xE4ndert \u2014 bitte pr\xFCfen und"
|
|
889
929
|
},
|
|
890
930
|
caps: {
|
|
@@ -988,7 +1028,7 @@ var discoveryMessages = defineMessages(
|
|
|
988
1028
|
quota: {
|
|
989
1029
|
usageProvider: "UsageProvider",
|
|
990
1030
|
usageProviderMissing: "missing",
|
|
991
|
-
noUsageProviderWarning: "A hard quota without a UsageProvider is not deployable (preflight
|
|
1031
|
+
noUsageProviderWarning: "A hard quota without a UsageProvider is not deployable (preflight).",
|
|
992
1032
|
outdatedBanner: "The code-derived quota facts (unit/enforcement/provider) have changed since the last approval \u2014 please review and"
|
|
993
1033
|
},
|
|
994
1034
|
caps: {
|
|
@@ -1148,8 +1188,7 @@ var marketingMessages = defineMessages(
|
|
|
1148
1188
|
localesLabel: "Sprachen:",
|
|
1149
1189
|
defaultLocale: "Default-Sprache",
|
|
1150
1190
|
deactivateLocale: "Sprache deaktivieren",
|
|
1151
|
-
addLocale: "+ Sprache"
|
|
1152
|
-
refresh: "Aktualisieren"
|
|
1191
|
+
addLocale: "+ Sprache"
|
|
1153
1192
|
},
|
|
1154
1193
|
page: {
|
|
1155
1194
|
loading: "Lade Marketing-Catalog \u2026",
|
|
@@ -1217,7 +1256,7 @@ var marketingMessages = defineMessages(
|
|
|
1217
1256
|
},
|
|
1218
1257
|
promotionsTab: {
|
|
1219
1258
|
title: "Aktionen & Rabatte",
|
|
1220
|
-
subtitle: "Zeitlich begrenzte Preis-Aktionen \u2014 \xFCberschreiben den regul\xE4ren Preis auf der Pricing-Page
|
|
1259
|
+
subtitle: "Zeitlich begrenzte Preis-Aktionen \u2014 \xFCberschreiben den regul\xE4ren Preis auf der Pricing-Page.",
|
|
1221
1260
|
add: "+ Aktion anlegen",
|
|
1222
1261
|
timelineHead: "Aktions-Timeline \xB7 gestrichelt = heute",
|
|
1223
1262
|
today: "heute",
|
|
@@ -1276,8 +1315,7 @@ var marketingMessages = defineMessages(
|
|
|
1276
1315
|
localesLabel: "Languages:",
|
|
1277
1316
|
defaultLocale: "Default language",
|
|
1278
1317
|
deactivateLocale: "Deactivate language",
|
|
1279
|
-
addLocale: "+ Language"
|
|
1280
|
-
refresh: "Refresh"
|
|
1318
|
+
addLocale: "+ Language"
|
|
1281
1319
|
},
|
|
1282
1320
|
page: {
|
|
1283
1321
|
loading: "Loading marketing catalog \u2026",
|
|
@@ -1345,7 +1383,7 @@ var marketingMessages = defineMessages(
|
|
|
1345
1383
|
},
|
|
1346
1384
|
promotionsTab: {
|
|
1347
1385
|
title: "Promotions & discounts",
|
|
1348
|
-
subtitle: "Time-limited price promotions \u2014 they override the regular price on the pricing page
|
|
1386
|
+
subtitle: "Time-limited price promotions \u2014 they override the regular price on the pricing page.",
|
|
1349
1387
|
add: "+ Create promotion",
|
|
1350
1388
|
timelineHead: "Promotion timeline \xB7 dashed = today",
|
|
1351
1389
|
today: "today",
|
|
@@ -1660,10 +1698,8 @@ var planDetailMessages = defineMessages(
|
|
|
1660
1698
|
versionsSummary: "{published} live/superseded",
|
|
1661
1699
|
versionsSummaryWithDrafts: "{published} live/superseded \xB7 {drafts} Draft",
|
|
1662
1700
|
openDraft: "Offener Draft",
|
|
1663
|
-
noDraft: "Kein Draft",
|
|
1664
1701
|
readyToEdit: "Bereit zum Bearbeiten",
|
|
1665
|
-
noOpenDraft: "Keine Draft-Version offen"
|
|
1666
|
-
createNewDraft: "Neue Draft anlegen"
|
|
1702
|
+
noOpenDraft: "Keine Draft-Version offen"
|
|
1667
1703
|
},
|
|
1668
1704
|
versions: {
|
|
1669
1705
|
title: "Versionen",
|
|
@@ -1787,10 +1823,8 @@ var planDetailMessages = defineMessages(
|
|
|
1787
1823
|
versionsSummary: "{published} live/superseded",
|
|
1788
1824
|
versionsSummaryWithDrafts: "{published} live/superseded \xB7 {drafts} draft",
|
|
1789
1825
|
openDraft: "Open draft",
|
|
1790
|
-
noDraft: "No draft",
|
|
1791
1826
|
readyToEdit: "Ready to edit",
|
|
1792
|
-
noOpenDraft: "No draft version open"
|
|
1793
|
-
createNewDraft: "Create a new draft"
|
|
1827
|
+
noOpenDraft: "No draft version open"
|
|
1794
1828
|
},
|
|
1795
1829
|
versions: {
|
|
1796
1830
|
title: "Versions",
|
|
@@ -2177,6 +2211,7 @@ var plansMessages = defineMessages(
|
|
|
2177
2211
|
// PlansPage — shell of the plan area: loading state, toasts and the
|
|
2178
2212
|
// error texts of the draft/publish/archive/discard actions.
|
|
2179
2213
|
page: {
|
|
2214
|
+
subtitle: "Pl\xE4ne b\xFCndeln Features & Quotas zu einem Angebot. Jede \xC4nderung wird als neue Version ver\xF6ffentlicht \u2014 Live-Versionen bleiben unangetastet.",
|
|
2180
2215
|
loading: "Pl\xE4ne werden geladen\u2026",
|
|
2181
2216
|
toastPlanCreated: "Plan {planKey} angelegt \u2014 jetzt die erste Version zusammenstellen.",
|
|
2182
2217
|
toastDraftSaved: "Draft v{version} von {planKey} gespeichert.",
|
|
@@ -2223,7 +2258,10 @@ var plansMessages = defineMessages(
|
|
|
2223
2258
|
// PlanList — default plan overview with one row per plan.
|
|
2224
2259
|
list: {
|
|
2225
2260
|
title: "Alle Pl\xE4ne",
|
|
2226
|
-
|
|
2261
|
+
statPlans: "Pl\xE4ne",
|
|
2262
|
+
statLive: "Live",
|
|
2263
|
+
statDrafts: "Offene Drafts",
|
|
2264
|
+
statTenants: "Mandanten",
|
|
2227
2265
|
matrixView: "Matrix-Ansicht",
|
|
2228
2266
|
newPlan: "Neuer Plan",
|
|
2229
2267
|
searchPlaceholder: "Plan suchen\u2026",
|
|
@@ -2261,7 +2299,10 @@ var plansMessages = defineMessages(
|
|
|
2261
2299
|
// PlanMatrix — all plans side by side, components as rows.
|
|
2262
2300
|
matrix: {
|
|
2263
2301
|
title: "Pl\xE4ne \xB7 Matrix-Vergleich",
|
|
2264
|
-
|
|
2302
|
+
statPlans: "Pl\xE4ne",
|
|
2303
|
+
statFeatures: "Features",
|
|
2304
|
+
statQuotas: "Quotas",
|
|
2305
|
+
statBundles: "Bundles",
|
|
2265
2306
|
catalogPreview: "Catalog-Vorschau",
|
|
2266
2307
|
createPlan: "Plan anlegen",
|
|
2267
2308
|
createPlanSub: "oder Klon erstellen",
|
|
@@ -2402,6 +2443,7 @@ var plansMessages = defineMessages(
|
|
|
2402
2443
|
},
|
|
2403
2444
|
{
|
|
2404
2445
|
page: {
|
|
2446
|
+
subtitle: "Plans bundle features & quotas into an offering. Every change ships as a new version \u2014 live versions stay untouched.",
|
|
2405
2447
|
loading: "Loading plans\u2026",
|
|
2406
2448
|
toastPlanCreated: "Plan {planKey} created \u2014 now assemble the first version.",
|
|
2407
2449
|
toastDraftSaved: "Draft v{version} of {planKey} saved.",
|
|
@@ -2446,7 +2488,10 @@ var plansMessages = defineMessages(
|
|
|
2446
2488
|
},
|
|
2447
2489
|
list: {
|
|
2448
2490
|
title: "All plans",
|
|
2449
|
-
|
|
2491
|
+
statPlans: "Plans",
|
|
2492
|
+
statLive: "Live",
|
|
2493
|
+
statDrafts: "Open drafts",
|
|
2494
|
+
statTenants: "Tenants",
|
|
2450
2495
|
matrixView: "Matrix view",
|
|
2451
2496
|
newPlan: "New plan",
|
|
2452
2497
|
searchPlaceholder: "Search plan\u2026",
|
|
@@ -2483,7 +2528,10 @@ var plansMessages = defineMessages(
|
|
|
2483
2528
|
},
|
|
2484
2529
|
matrix: {
|
|
2485
2530
|
title: "Plans \xB7 matrix comparison",
|
|
2486
|
-
|
|
2531
|
+
statPlans: "Plans",
|
|
2532
|
+
statFeatures: "Features",
|
|
2533
|
+
statQuotas: "Quotas",
|
|
2534
|
+
statBundles: "Bundles",
|
|
2487
2535
|
catalogPreview: "Catalog preview",
|
|
2488
2536
|
createPlan: "Create plan",
|
|
2489
2537
|
createPlanSub: "or create a clone",
|
|
@@ -2972,8 +3020,7 @@ var tenantsMessages = defineMessages(
|
|
|
2972
3020
|
columnUsage: "Verbrauch",
|
|
2973
3021
|
columnCreatedAt: "Angelegt",
|
|
2974
3022
|
suspended: "Suspendiert",
|
|
2975
|
-
empty: "Keine Mandanten mit diesen Filtern."
|
|
2976
|
-
pagination: "{total} Mandanten \xB7 Seite {page} / {pages}"
|
|
3023
|
+
empty: "Keine Mandanten mit diesen Filtern."
|
|
2977
3024
|
},
|
|
2978
3025
|
detail: {
|
|
2979
3026
|
backToList: "Mandanten-Liste",
|
|
@@ -3021,8 +3068,7 @@ var tenantsMessages = defineMessages(
|
|
|
3021
3068
|
columnUsage: "Usage",
|
|
3022
3069
|
columnCreatedAt: "Created",
|
|
3023
3070
|
suspended: "Suspended",
|
|
3024
|
-
empty: "No tenants match these filters."
|
|
3025
|
-
pagination: "{total} tenants \xB7 Page {page} / {pages}"
|
|
3071
|
+
empty: "No tenants match these filters."
|
|
3026
3072
|
},
|
|
3027
3073
|
detail: {
|
|
3028
3074
|
backToList: "Tenant list",
|
|
@@ -3280,6 +3326,9 @@ function createSuperAdminApp(options) {
|
|
|
3280
3326
|
if (options.manifestGuard?.getManifest) {
|
|
3281
3327
|
app.provide(SUPER_ADMIN_MANIFEST_KEY, options.manifestGuard.getManifest);
|
|
3282
3328
|
}
|
|
3329
|
+
if (options.manifestGuard?.clearCache) {
|
|
3330
|
+
app.provide(SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY, options.manifestGuard.clearCache);
|
|
3331
|
+
}
|
|
3283
3332
|
if (options.loginAdapter) {
|
|
3284
3333
|
app.provide(SUPER_ADMIN_LOGIN_ADAPTER_KEY, options.loginAdapter);
|
|
3285
3334
|
}
|
package/dist/quasar/index.d.cts
CHANGED
|
@@ -2,8 +2,8 @@ import { Component, App } from 'vue';
|
|
|
2
2
|
import { QuasarPluginOptions } from 'quasar';
|
|
3
3
|
import { Pinia } from 'pinia';
|
|
4
4
|
import { RouteRecordRaw, RouterHistory, Router } from 'vue-router';
|
|
5
|
-
import { H as HttpClient } from '../catalog-
|
|
6
|
-
import { S as SuperAdminGuardOptions, a as SuperAdminBrand, b as SuperAdminEndpoints, E as ExtensionsMap, A as ActionsMap, c as SuperAdminLoginAdapter, U as UiNotify, I as InstallPlugin, d as SuperAdminI18nOptions, e as SuperAdminI18n } from '../use-super-admin-i18n-
|
|
5
|
+
import { H as HttpClient } from '../catalog-DJcfm5N2.cjs';
|
|
6
|
+
import { S as SuperAdminGuardOptions, a as SuperAdminBrand, b as SuperAdminEndpoints, E as ExtensionsMap, A as ActionsMap, c as SuperAdminLoginAdapter, U as UiNotify, I as InstallPlugin, d as SuperAdminI18nOptions, e as SuperAdminI18n } from '../use-super-admin-i18n-CgTuNi8h.cjs';
|
|
7
7
|
import '@saasicat/types';
|
|
8
8
|
|
|
9
9
|
interface CreateSuperAdminAppOptions extends SuperAdminGuardOptions {
|
package/dist/quasar/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { Component, App } from 'vue';
|
|
|
2
2
|
import { QuasarPluginOptions } from 'quasar';
|
|
3
3
|
import { Pinia } from 'pinia';
|
|
4
4
|
import { RouteRecordRaw, RouterHistory, Router } from 'vue-router';
|
|
5
|
-
import { H as HttpClient } from '../catalog-
|
|
6
|
-
import { S as SuperAdminGuardOptions, a as SuperAdminBrand, b as SuperAdminEndpoints, E as ExtensionsMap, A as ActionsMap, c as SuperAdminLoginAdapter, U as UiNotify, I as InstallPlugin, d as SuperAdminI18nOptions, e as SuperAdminI18n } from '../use-super-admin-i18n-
|
|
5
|
+
import { H as HttpClient } from '../catalog-DJcfm5N2.js';
|
|
6
|
+
import { S as SuperAdminGuardOptions, a as SuperAdminBrand, b as SuperAdminEndpoints, E as ExtensionsMap, A as ActionsMap, c as SuperAdminLoginAdapter, U as UiNotify, I as InstallPlugin, d as SuperAdminI18nOptions, e as SuperAdminI18n } from '../use-super-admin-i18n-CHNdsSlm.js';
|
|
7
7
|
import '@saasicat/types';
|
|
8
8
|
|
|
9
9
|
interface CreateSuperAdminAppOptions extends SuperAdminGuardOptions {
|
package/dist/quasar/index.js
CHANGED
|
@@ -6,14 +6,15 @@ import {
|
|
|
6
6
|
SUPER_ADMIN_HTTP_KEY,
|
|
7
7
|
SUPER_ADMIN_I18N_KEY,
|
|
8
8
|
SUPER_ADMIN_LOGIN_ADAPTER_KEY,
|
|
9
|
+
SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY,
|
|
9
10
|
SUPER_ADMIN_MANIFEST_KEY,
|
|
10
11
|
SUPER_ADMIN_NOTIFY_KEY,
|
|
11
12
|
buildNavigationGuard,
|
|
12
13
|
createSuperAdminI18n
|
|
13
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-LY52T4N4.js";
|
|
14
15
|
import {
|
|
15
16
|
defaultHttpClient
|
|
16
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-F7NRM6KI.js";
|
|
17
18
|
|
|
18
19
|
// src/quasar/create-super-admin-app.ts
|
|
19
20
|
import { createApp } from "vue";
|
|
@@ -74,6 +75,9 @@ function createSuperAdminApp(options) {
|
|
|
74
75
|
if (options.manifestGuard?.getManifest) {
|
|
75
76
|
app.provide(SUPER_ADMIN_MANIFEST_KEY, options.manifestGuard.getManifest);
|
|
76
77
|
}
|
|
78
|
+
if (options.manifestGuard?.clearCache) {
|
|
79
|
+
app.provide(SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY, options.manifestGuard.clearCache);
|
|
80
|
+
}
|
|
77
81
|
if (options.loginAdapter) {
|
|
78
82
|
app.provide(SUPER_ADMIN_LOGIN_ADAPTER_KEY, options.loginAdapter);
|
|
79
83
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
interface AdminPagesSuiteConfig {
|
|
4
|
+
/** Display name, e.g. 'demoapp' / 'clubapp'. */
|
|
5
|
+
appName: string;
|
|
6
|
+
/** URL of the login page (full). */
|
|
7
|
+
loginUrl: string;
|
|
8
|
+
/** Test account. */
|
|
9
|
+
email: string;
|
|
10
|
+
password: string;
|
|
11
|
+
/** Paths the smoke test should click through. */
|
|
12
|
+
pages: ReadonlyArray<{
|
|
13
|
+
/** Display name in the test description. */
|
|
14
|
+
name: string;
|
|
15
|
+
/** Path relative to the origin (e.g. '/admin/tenants'). */
|
|
16
|
+
path: string;
|
|
17
|
+
/** Optional: if set, check that this selector exists. */
|
|
18
|
+
expectVisible?: string;
|
|
19
|
+
/** Optional: HTTP patterns that are OK as 4xx/5xx (e.g. missing backend endpoints). */
|
|
20
|
+
allowedFailures?: readonly RegExp[];
|
|
21
|
+
}>;
|
|
22
|
+
/** Expected KPI card labels on the dashboard page. */
|
|
23
|
+
expectedKpiLabels: readonly string[];
|
|
24
|
+
/** Expected distribution section titles. */
|
|
25
|
+
expectedDistributionTitles?: readonly string[];
|
|
26
|
+
/** Expected shortcut titles on the dashboard. */
|
|
27
|
+
expectedShortcutTitles: readonly string[];
|
|
28
|
+
/** Shortcuts that must NOT appear (e.g. "Dashboard"). */
|
|
29
|
+
forbiddenShortcutTitles?: readonly string[];
|
|
30
|
+
/** Console error patterns that should be ignored. */
|
|
31
|
+
consoleErrorAllowlist?: readonly RegExp[];
|
|
32
|
+
/** Path to the dashboard page (default `/admin/`). */
|
|
33
|
+
dashboardPath?: string;
|
|
34
|
+
}
|
|
35
|
+
declare function runAdminPagesSuite(test: typeof test, expect: typeof expect, config: AdminPagesSuiteConfig): void;
|
|
36
|
+
|
|
37
|
+
export { type AdminPagesSuiteConfig, runAdminPagesSuite };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
interface AdminPagesSuiteConfig {
|
|
4
|
+
/** Display name, e.g. 'demoapp' / 'clubapp'. */
|
|
5
|
+
appName: string;
|
|
6
|
+
/** URL of the login page (full). */
|
|
7
|
+
loginUrl: string;
|
|
8
|
+
/** Test account. */
|
|
9
|
+
email: string;
|
|
10
|
+
password: string;
|
|
11
|
+
/** Paths the smoke test should click through. */
|
|
12
|
+
pages: ReadonlyArray<{
|
|
13
|
+
/** Display name in the test description. */
|
|
14
|
+
name: string;
|
|
15
|
+
/** Path relative to the origin (e.g. '/admin/tenants'). */
|
|
16
|
+
path: string;
|
|
17
|
+
/** Optional: if set, check that this selector exists. */
|
|
18
|
+
expectVisible?: string;
|
|
19
|
+
/** Optional: HTTP patterns that are OK as 4xx/5xx (e.g. missing backend endpoints). */
|
|
20
|
+
allowedFailures?: readonly RegExp[];
|
|
21
|
+
}>;
|
|
22
|
+
/** Expected KPI card labels on the dashboard page. */
|
|
23
|
+
expectedKpiLabels: readonly string[];
|
|
24
|
+
/** Expected distribution section titles. */
|
|
25
|
+
expectedDistributionTitles?: readonly string[];
|
|
26
|
+
/** Expected shortcut titles on the dashboard. */
|
|
27
|
+
expectedShortcutTitles: readonly string[];
|
|
28
|
+
/** Shortcuts that must NOT appear (e.g. "Dashboard"). */
|
|
29
|
+
forbiddenShortcutTitles?: readonly string[];
|
|
30
|
+
/** Console error patterns that should be ignored. */
|
|
31
|
+
consoleErrorAllowlist?: readonly RegExp[];
|
|
32
|
+
/** Path to the dashboard page (default `/admin/`). */
|
|
33
|
+
dashboardPath?: string;
|
|
34
|
+
}
|
|
35
|
+
declare function runAdminPagesSuite(test: typeof test, expect: typeof expect, config: AdminPagesSuiteConfig): void;
|
|
36
|
+
|
|
37
|
+
export { type AdminPagesSuiteConfig, runAdminPagesSuite };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Component, App, InjectionKey, Ref, ComputedRef } from 'vue';
|
|
2
2
|
import { NavigationGuardWithThis } from 'vue-router';
|
|
3
3
|
import { ActionKey, ComponentKey, AdminManifest } from '@saasicat/types';
|
|
4
|
-
import { A as ActionHandler, H as HttpClient, S as SaLocale, a as SaMessages, b as SaLocaleOption, c as SaLocaleDefinition, d as SaMessagesOverrides, K as KvStore } from './catalog-
|
|
4
|
+
import { A as ActionHandler, H as HttpClient, S as SaLocale, a as SaMessages, b as SaLocaleOption, c as SaLocaleDefinition, d as SaMessagesOverrides, K as KvStore } from './catalog-DJcfm5N2.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* App-specific branding data that the platform `AdminLayout` and other
|
|
@@ -70,6 +70,17 @@ interface SuperAdminLoginAdapter {
|
|
|
70
70
|
* storage, MFA hops etc.
|
|
71
71
|
*/
|
|
72
72
|
login(email: string, password: string): Promise<SuperAdminLoginResult>;
|
|
73
|
+
/**
|
|
74
|
+
* Undoes what `login` established — token, session storage, app store.
|
|
75
|
+
*
|
|
76
|
+
* Whoever knows how to start a session is the only one who knows how to
|
|
77
|
+
* end it, so it belongs next to `login` rather than in a second seam. The
|
|
78
|
+
* platform's own sign-out affordances call it; without it they can only
|
|
79
|
+
* navigate to `/login`, and an app whose `isAuthenticated()` reads a
|
|
80
|
+
* surviving token lets the operator straight back in — a sign-out button
|
|
81
|
+
* that does not sign out.
|
|
82
|
+
*/
|
|
83
|
+
logout?(): void | Promise<void>;
|
|
73
84
|
/**
|
|
74
85
|
* Target route after a successful login. Default: `/admin/dashboard`
|
|
75
86
|
* (platform convention for the standard pages — apps with a different
|
|
@@ -112,6 +123,20 @@ interface SuperAdminManifestGuardOptions {
|
|
|
112
123
|
* manifest guard again and produces a redirect loop.
|
|
113
124
|
*/
|
|
114
125
|
errorRoute?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Discards the cached manifest, so the next `ensureLoaded()` fetches a
|
|
128
|
+
* fresh body instead of revalidating.
|
|
129
|
+
*
|
|
130
|
+
* Needed because the loader keeps an ETag in storage. Its own documented
|
|
131
|
+
* failure — "server returned 304 but the cache body is missing" — survives
|
|
132
|
+
* a full page reload: the next request sends the same `If-None-Match`,
|
|
133
|
+
* gets another 304, and lands back on the error page. Retry is a dead end
|
|
134
|
+
* for that case unless something clears the ETag first.
|
|
135
|
+
*
|
|
136
|
+
* `ManifestLoader.clearCache()` and the manifest store's reset both fit;
|
|
137
|
+
* pass whichever the app uses.
|
|
138
|
+
*/
|
|
139
|
+
clearCache?: () => void | Promise<void>;
|
|
115
140
|
}
|
|
116
141
|
/**
|
|
117
142
|
* Guard configuration shared by `buildNavigationGuard()` and
|
|
@@ -143,6 +168,13 @@ declare const SUPER_ADMIN_ACTIONS_KEY: InjectionKey<ActionsMap>;
|
|
|
143
168
|
* `<ProjectPageHost>` needs it to resolve project pages.
|
|
144
169
|
*/
|
|
145
170
|
declare const SUPER_ADMIN_MANIFEST_KEY: InjectionKey<() => AdminManifest | null>;
|
|
171
|
+
/**
|
|
172
|
+
* Vue inject key for `manifestGuard.clearCache`.
|
|
173
|
+
*
|
|
174
|
+
* The fail-closed error page is route-mounted and gets no props, so the only
|
|
175
|
+
* way it can reach the app's cache is through the shell.
|
|
176
|
+
*/
|
|
177
|
+
declare const SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY: InjectionKey<() => void | Promise<void>>;
|
|
146
178
|
/** Vue inject key for `useSuperAdminLoginAdapter()`. */
|
|
147
179
|
declare const SUPER_ADMIN_LOGIN_ADAPTER_KEY: InjectionKey<SuperAdminLoginAdapter>;
|
|
148
180
|
/** Vue inject key for `useSuperAdminHttp()` (pre-login HttpClient). */
|
|
@@ -152,11 +184,6 @@ declare const SUPER_ADMIN_HTTP_KEY: InjectionKey<HttpClient>;
|
|
|
152
184
|
* bootstrap installs after the platform setup, before the mount.
|
|
153
185
|
*/
|
|
154
186
|
type InstallPlugin = (app: App) => void;
|
|
155
|
-
/**
|
|
156
|
-
* Internal helper, exported for isolated unit tests of the navigation
|
|
157
|
-
* behavior (auth redirect, manifest fail-closed path). Consumers should call
|
|
158
|
-
* `createSuperAdminApp()`, not this helper directly.
|
|
159
|
-
*/
|
|
160
187
|
declare function buildNavigationGuard(options: SuperAdminGuardOptions): NavigationGuardWithThis<undefined> | null;
|
|
161
188
|
|
|
162
189
|
/**
|
|
@@ -253,4 +280,4 @@ declare function useSuperAdminI18n(): SuperAdminI18n;
|
|
|
253
280
|
*/
|
|
254
281
|
declare function useSaMessages<K extends keyof SaMessages>(namespace: K): ComputedRef<SaMessages[K]>;
|
|
255
282
|
|
|
256
|
-
export { type ActionsMap as A, type ExtensionsMap as E, type InstallPlugin as I, type SuperAdminGuardOptions as S, type UiNotify as U, type SuperAdminBrand as a, type SuperAdminEndpoints as b, type SuperAdminLoginAdapter as c, type SuperAdminI18nOptions as d, type SuperAdminI18n as e, type ExtensionLoader as f, SA_LOCALE_STORAGE_KEY as g, SUPER_ADMIN_ACTIONS_KEY as h, SUPER_ADMIN_BRAND_KEY as i, SUPER_ADMIN_ENDPOINTS_KEY as j, SUPER_ADMIN_EXTENSIONS_KEY as k, SUPER_ADMIN_HTTP_KEY as l, SUPER_ADMIN_I18N_KEY as m, SUPER_ADMIN_LOGIN_ADAPTER_KEY as n,
|
|
283
|
+
export { type ActionsMap as A, type ExtensionsMap as E, type InstallPlugin as I, type SuperAdminGuardOptions as S, type UiNotify as U, type SuperAdminBrand as a, type SuperAdminEndpoints as b, type SuperAdminLoginAdapter as c, type SuperAdminI18nOptions as d, type SuperAdminI18n as e, type ExtensionLoader as f, SA_LOCALE_STORAGE_KEY as g, SUPER_ADMIN_ACTIONS_KEY as h, SUPER_ADMIN_BRAND_KEY as i, SUPER_ADMIN_ENDPOINTS_KEY as j, SUPER_ADMIN_EXTENSIONS_KEY as k, SUPER_ADMIN_HTTP_KEY as l, SUPER_ADMIN_I18N_KEY as m, SUPER_ADMIN_LOGIN_ADAPTER_KEY as n, SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY as o, SUPER_ADMIN_MANIFEST_KEY as p, SUPER_ADMIN_NOTIFY_KEY as q, type SuperAdminAuthGuardOptions as r, type SuperAdminLoginResult as s, type SuperAdminManifestGuardOptions as t, type UiNotifyKind as u, type UiNotifyOptions as v, buildNavigationGuard as w, createSuperAdminI18n as x, useSaMessages as y, useSuperAdminI18n as z };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Component, App, InjectionKey, Ref, ComputedRef } from 'vue';
|
|
2
2
|
import { NavigationGuardWithThis } from 'vue-router';
|
|
3
3
|
import { ActionKey, ComponentKey, AdminManifest } from '@saasicat/types';
|
|
4
|
-
import { A as ActionHandler, H as HttpClient, S as SaLocale, a as SaMessages, b as SaLocaleOption, c as SaLocaleDefinition, d as SaMessagesOverrides, K as KvStore } from './catalog-
|
|
4
|
+
import { A as ActionHandler, H as HttpClient, S as SaLocale, a as SaMessages, b as SaLocaleOption, c as SaLocaleDefinition, d as SaMessagesOverrides, K as KvStore } from './catalog-DJcfm5N2.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* App-specific branding data that the platform `AdminLayout` and other
|
|
@@ -70,6 +70,17 @@ interface SuperAdminLoginAdapter {
|
|
|
70
70
|
* storage, MFA hops etc.
|
|
71
71
|
*/
|
|
72
72
|
login(email: string, password: string): Promise<SuperAdminLoginResult>;
|
|
73
|
+
/**
|
|
74
|
+
* Undoes what `login` established — token, session storage, app store.
|
|
75
|
+
*
|
|
76
|
+
* Whoever knows how to start a session is the only one who knows how to
|
|
77
|
+
* end it, so it belongs next to `login` rather than in a second seam. The
|
|
78
|
+
* platform's own sign-out affordances call it; without it they can only
|
|
79
|
+
* navigate to `/login`, and an app whose `isAuthenticated()` reads a
|
|
80
|
+
* surviving token lets the operator straight back in — a sign-out button
|
|
81
|
+
* that does not sign out.
|
|
82
|
+
*/
|
|
83
|
+
logout?(): void | Promise<void>;
|
|
73
84
|
/**
|
|
74
85
|
* Target route after a successful login. Default: `/admin/dashboard`
|
|
75
86
|
* (platform convention for the standard pages — apps with a different
|
|
@@ -112,6 +123,20 @@ interface SuperAdminManifestGuardOptions {
|
|
|
112
123
|
* manifest guard again and produces a redirect loop.
|
|
113
124
|
*/
|
|
114
125
|
errorRoute?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Discards the cached manifest, so the next `ensureLoaded()` fetches a
|
|
128
|
+
* fresh body instead of revalidating.
|
|
129
|
+
*
|
|
130
|
+
* Needed because the loader keeps an ETag in storage. Its own documented
|
|
131
|
+
* failure — "server returned 304 but the cache body is missing" — survives
|
|
132
|
+
* a full page reload: the next request sends the same `If-None-Match`,
|
|
133
|
+
* gets another 304, and lands back on the error page. Retry is a dead end
|
|
134
|
+
* for that case unless something clears the ETag first.
|
|
135
|
+
*
|
|
136
|
+
* `ManifestLoader.clearCache()` and the manifest store's reset both fit;
|
|
137
|
+
* pass whichever the app uses.
|
|
138
|
+
*/
|
|
139
|
+
clearCache?: () => void | Promise<void>;
|
|
115
140
|
}
|
|
116
141
|
/**
|
|
117
142
|
* Guard configuration shared by `buildNavigationGuard()` and
|
|
@@ -143,6 +168,13 @@ declare const SUPER_ADMIN_ACTIONS_KEY: InjectionKey<ActionsMap>;
|
|
|
143
168
|
* `<ProjectPageHost>` needs it to resolve project pages.
|
|
144
169
|
*/
|
|
145
170
|
declare const SUPER_ADMIN_MANIFEST_KEY: InjectionKey<() => AdminManifest | null>;
|
|
171
|
+
/**
|
|
172
|
+
* Vue inject key for `manifestGuard.clearCache`.
|
|
173
|
+
*
|
|
174
|
+
* The fail-closed error page is route-mounted and gets no props, so the only
|
|
175
|
+
* way it can reach the app's cache is through the shell.
|
|
176
|
+
*/
|
|
177
|
+
declare const SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY: InjectionKey<() => void | Promise<void>>;
|
|
146
178
|
/** Vue inject key for `useSuperAdminLoginAdapter()`. */
|
|
147
179
|
declare const SUPER_ADMIN_LOGIN_ADAPTER_KEY: InjectionKey<SuperAdminLoginAdapter>;
|
|
148
180
|
/** Vue inject key for `useSuperAdminHttp()` (pre-login HttpClient). */
|
|
@@ -152,11 +184,6 @@ declare const SUPER_ADMIN_HTTP_KEY: InjectionKey<HttpClient>;
|
|
|
152
184
|
* bootstrap installs after the platform setup, before the mount.
|
|
153
185
|
*/
|
|
154
186
|
type InstallPlugin = (app: App) => void;
|
|
155
|
-
/**
|
|
156
|
-
* Internal helper, exported for isolated unit tests of the navigation
|
|
157
|
-
* behavior (auth redirect, manifest fail-closed path). Consumers should call
|
|
158
|
-
* `createSuperAdminApp()`, not this helper directly.
|
|
159
|
-
*/
|
|
160
187
|
declare function buildNavigationGuard(options: SuperAdminGuardOptions): NavigationGuardWithThis<undefined> | null;
|
|
161
188
|
|
|
162
189
|
/**
|
|
@@ -253,4 +280,4 @@ declare function useSuperAdminI18n(): SuperAdminI18n;
|
|
|
253
280
|
*/
|
|
254
281
|
declare function useSaMessages<K extends keyof SaMessages>(namespace: K): ComputedRef<SaMessages[K]>;
|
|
255
282
|
|
|
256
|
-
export { type ActionsMap as A, type ExtensionsMap as E, type InstallPlugin as I, type SuperAdminGuardOptions as S, type UiNotify as U, type SuperAdminBrand as a, type SuperAdminEndpoints as b, type SuperAdminLoginAdapter as c, type SuperAdminI18nOptions as d, type SuperAdminI18n as e, type ExtensionLoader as f, SA_LOCALE_STORAGE_KEY as g, SUPER_ADMIN_ACTIONS_KEY as h, SUPER_ADMIN_BRAND_KEY as i, SUPER_ADMIN_ENDPOINTS_KEY as j, SUPER_ADMIN_EXTENSIONS_KEY as k, SUPER_ADMIN_HTTP_KEY as l, SUPER_ADMIN_I18N_KEY as m, SUPER_ADMIN_LOGIN_ADAPTER_KEY as n,
|
|
283
|
+
export { type ActionsMap as A, type ExtensionsMap as E, type InstallPlugin as I, type SuperAdminGuardOptions as S, type UiNotify as U, type SuperAdminBrand as a, type SuperAdminEndpoints as b, type SuperAdminLoginAdapter as c, type SuperAdminI18nOptions as d, type SuperAdminI18n as e, type ExtensionLoader as f, SA_LOCALE_STORAGE_KEY as g, SUPER_ADMIN_ACTIONS_KEY as h, SUPER_ADMIN_BRAND_KEY as i, SUPER_ADMIN_ENDPOINTS_KEY as j, SUPER_ADMIN_EXTENSIONS_KEY as k, SUPER_ADMIN_HTTP_KEY as l, SUPER_ADMIN_I18N_KEY as m, SUPER_ADMIN_LOGIN_ADAPTER_KEY as n, SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY as o, SUPER_ADMIN_MANIFEST_KEY as p, SUPER_ADMIN_NOTIFY_KEY as q, type SuperAdminAuthGuardOptions as r, type SuperAdminLoginResult as s, type SuperAdminManifestGuardOptions as t, type UiNotifyKind as u, type UiNotifyOptions as v, buildNavigationGuard as w, createSuperAdminI18n as x, useSaMessages as y, useSuperAdminI18n as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saasicat/ui-vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Vue 3 components, resource clients and composables for the SuperAdmin UI shell. Provides boot and manifest loaders, navigation, actions and standard pages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -43,9 +43,14 @@
|
|
|
43
43
|
"./components/*": "./src/components/*",
|
|
44
44
|
"./sa-theme.css": "./src/pages-standard/sa-theme.css",
|
|
45
45
|
"./testing-e2e/*": {
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
"import": {
|
|
47
|
+
"types": "./dist/testing-e2e/*.d.ts",
|
|
48
|
+
"default": "./dist/testing-e2e/*.js"
|
|
49
|
+
},
|
|
50
|
+
"require": {
|
|
51
|
+
"types": "./dist/testing-e2e/*.d.cts",
|
|
52
|
+
"default": "./dist/testing-e2e/*.cjs"
|
|
53
|
+
}
|
|
49
54
|
}
|
|
50
55
|
},
|
|
51
56
|
"files": [
|
|
@@ -53,7 +58,7 @@
|
|
|
53
58
|
"src"
|
|
54
59
|
],
|
|
55
60
|
"dependencies": {
|
|
56
|
-
"@saasicat/types": "^0.
|
|
61
|
+
"@saasicat/types": "^0.22.0"
|
|
57
62
|
},
|
|
58
63
|
"peerDependencies": {
|
|
59
64
|
"pinia": "^2.0.0 || ^3.0.0",
|
|
@@ -74,14 +79,17 @@
|
|
|
74
79
|
},
|
|
75
80
|
"devDependencies": {
|
|
76
81
|
"@playwright/test": "^1.59.1",
|
|
82
|
+
"@quasar/vite-plugin": "^1.12.0",
|
|
77
83
|
"@types/node": "^25.6.0",
|
|
78
84
|
"@vitejs/plugin-vue": "^6.0.8",
|
|
79
85
|
"@vue/test-utils": "^2.4.11",
|
|
80
86
|
"jsdom": "^30.0.1",
|
|
81
87
|
"pinia": "^3.0.0",
|
|
82
88
|
"quasar": "^2.24.0",
|
|
89
|
+
"sass": "^1.101.3",
|
|
83
90
|
"tsup": "^8.0.0",
|
|
84
91
|
"typescript": "^6.0.0",
|
|
92
|
+
"vite": "^7.3.6",
|
|
85
93
|
"vitest": "^4.1.10",
|
|
86
94
|
"vue": "^3.5.0",
|
|
87
95
|
"vue-router": "^5.0.0",
|
|
@@ -102,11 +110,13 @@
|
|
|
102
110
|
"access": "public"
|
|
103
111
|
},
|
|
104
112
|
"scripts": {
|
|
105
|
-
"build": "tsup",
|
|
106
|
-
"typecheck": "vue-tsc --noEmit -p tsconfig.json",
|
|
113
|
+
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsup",
|
|
114
|
+
"typecheck": "vue-tsc --noEmit -p tsconfig.json && vue-tsc --noEmit -p tsconfig.tests.json",
|
|
107
115
|
"pretest": "pnpm run build",
|
|
108
116
|
"test": "node --test tests/**/*.test.js",
|
|
109
117
|
"test:component": "vitest run --config vitest.config.ts",
|
|
110
|
-
"test:e2e": "playwright test"
|
|
118
|
+
"test:e2e": "playwright test",
|
|
119
|
+
"test:visual": "playwright test --project=visual",
|
|
120
|
+
"test:visual:update": "playwright test --project=visual --update-snapshots"
|
|
111
121
|
}
|
|
112
122
|
}
|
|
@@ -40,7 +40,6 @@ export const bundlesMessages = defineMessages(
|
|
|
40
40
|
'Produktgruppen aus Features & Quotas — verwendet in Plänen. Bundles werden im SuperAdmin kuratiert.',
|
|
41
41
|
displayLocale: 'Anzeige-Sprache',
|
|
42
42
|
newBundle: 'Neues Bundle',
|
|
43
|
-
reload: 'Liste neu laden',
|
|
44
43
|
},
|
|
45
44
|
filter: {
|
|
46
45
|
all: 'Alle Status',
|
|
@@ -271,7 +270,6 @@ export const bundlesMessages = defineMessages(
|
|
|
271
270
|
'Product groups made of features & quotas — used in plans. Bundles are curated in the SuperAdmin.',
|
|
272
271
|
displayLocale: 'Display language',
|
|
273
272
|
newBundle: 'New bundle',
|
|
274
|
-
reload: 'Reload list',
|
|
275
273
|
},
|
|
276
274
|
filter: {
|
|
277
275
|
all: 'All statuses',
|