@saasicat/ui-vue 0.15.1 → 0.17.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/README.md +13 -10
- package/dist/{messages-BIYw32u1.d.ts → catalog-C4Gv2_KM.d.cts} +126 -39
- package/dist/{messages-BIYw32u1.d.cts → catalog-C4Gv2_KM.d.ts} +126 -39
- package/dist/{chunk-TY2WYKME.js → chunk-247RJPU4.js} +38 -11
- package/dist/{chunk-TBLXKSTR.js → chunk-IZGFS5RS.js} +90 -21
- package/dist/{chunk-66BUSVC5.js → chunk-XPSD5HKG.js} +30 -4
- package/dist/client/index.cjs +122 -22
- package/dist/client/index.d.cts +51 -5
- package/dist/client/index.d.ts +51 -5
- package/dist/client/index.js +14 -2
- package/dist/index.cjs +152 -30
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +17 -3
- package/dist/quasar/index.cjs +110 -14
- package/dist/quasar/index.d.cts +2 -2
- package/dist/quasar/index.d.ts +2 -2
- package/dist/quasar/index.js +2 -2
- package/dist/{use-super-admin-i18n-DL_qI1BY.d.cts → use-super-admin-i18n-BdPqeTHl.d.cts} +51 -5
- package/dist/{use-super-admin-i18n-CWNu_W3u.d.ts → use-super-admin-i18n-uteRCL9q.d.ts} +51 -5
- package/package.json +8 -3
- package/src/client/i18n/catalog.ts +120 -0
- package/src/client/i18n/currency.ts +7 -2
- package/src/client/i18n/define.ts +2 -2
- package/src/client/i18n/index.ts +1 -0
- package/src/client/i18n/locale.ts +52 -8
- package/src/client/i18n/messages/bundles.ts +2 -3
- package/src/client/i18n/messages/marketing.ts +2 -2
- package/src/client/i18n/messages/nav.ts +3 -3
- package/src/client/i18n/messages/shell.ts +2 -0
- package/src/client/i18n/messages.ts +7 -4
- package/src/client/index.ts +1 -0
- package/src/client/login-branding.ts +61 -0
- package/src/client/nav-builder.ts +33 -6
- package/src/client/types.ts +51 -14
- package/src/components/LocaleSwitcher.vue +77 -0
- package/src/components/bundle-editor/bundle-version-status.ts +16 -8
- package/src/pages-standard/AdminLayout.vue +9 -3
- package/src/pages-standard/SuperAdminLoginPage.vue +17 -9
- package/src/pages-standard/SuperAdminSetupWizard.vue +7 -0
- package/src/pages-standard/discovery-page/discovery-ui.ts +8 -8
- package/src/pages-standard/plan-versions/format.ts +2 -2
- package/src/vue/use-super-admin-i18n.ts +116 -19
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from "./chunk-TBLXKSTR.js";
|
|
2
|
+
createSaCatalog,
|
|
3
|
+
defaultKvStore
|
|
4
|
+
} from "./chunk-IZGFS5RS.js";
|
|
6
5
|
|
|
7
6
|
// src/vue/super-admin-context.ts
|
|
8
7
|
var SUPER_ADMIN_BRAND_KEY = /* @__PURE__ */ Symbol.for(
|
|
@@ -57,23 +56,50 @@ var SUPER_ADMIN_NOTIFY_KEY = /* @__PURE__ */ Symbol.for(
|
|
|
57
56
|
);
|
|
58
57
|
|
|
59
58
|
// src/vue/use-super-admin-i18n.ts
|
|
60
|
-
import {
|
|
59
|
+
import {
|
|
60
|
+
computed,
|
|
61
|
+
inject,
|
|
62
|
+
isReadonly,
|
|
63
|
+
isRef,
|
|
64
|
+
ref,
|
|
65
|
+
watch
|
|
66
|
+
} from "vue";
|
|
67
|
+
var SA_LOCALE_STORAGE_KEY = "sa:locale";
|
|
61
68
|
var SUPER_ADMIN_I18N_KEY = /* @__PURE__ */ Symbol.for(
|
|
62
69
|
"@saasicat/ui-vue/SUPER_ADMIN_I18N"
|
|
63
70
|
);
|
|
64
71
|
function createSuperAdminI18n(options = {}) {
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
|
|
72
|
+
const catalog = createSaCatalog(options);
|
|
73
|
+
const locale = isRef(options.locale) ? options.locale : createOwnedLocale(options, catalog);
|
|
74
|
+
const active = computed(
|
|
75
|
+
() => catalog.has(locale.value) ? locale.value : catalog.defaultLocale
|
|
68
76
|
);
|
|
69
|
-
const
|
|
70
|
-
|
|
77
|
+
const messages = computed(() => catalog.messagesFor(active.value));
|
|
78
|
+
const intlLocale = computed(() => catalog.intlLocaleFor(active.value));
|
|
79
|
+
const writable = !isReadonly(locale);
|
|
80
|
+
return {
|
|
81
|
+
locale,
|
|
82
|
+
messages,
|
|
83
|
+
intlLocale,
|
|
84
|
+
switcherEnabled: (options.switcher ?? true) && writable && catalog.locales.length > 1,
|
|
85
|
+
availableLocales: catalog.locales
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function createOwnedLocale(options, catalog) {
|
|
89
|
+
const initial = options.locale ?? catalog.defaultLocale;
|
|
90
|
+
if (options.persist === false) return ref(initial);
|
|
91
|
+
const storage = options.storage ?? defaultKvStore();
|
|
92
|
+
const key = `${options.storageKeyPrefix ?? ""}${SA_LOCALE_STORAGE_KEY}`;
|
|
93
|
+
const stored = storage.get(key);
|
|
94
|
+
const locale = ref(stored && catalog.has(stored) ? stored : initial);
|
|
95
|
+
watch(locale, (next) => storage.set(key, next));
|
|
96
|
+
return locale;
|
|
71
97
|
}
|
|
72
98
|
var fallbackI18n = null;
|
|
73
99
|
function useSuperAdminI18n() {
|
|
74
100
|
const injected = inject(SUPER_ADMIN_I18N_KEY, null);
|
|
75
101
|
if (injected) return injected;
|
|
76
|
-
fallbackI18n ??= createSuperAdminI18n();
|
|
102
|
+
fallbackI18n ??= createSuperAdminI18n({ persist: false });
|
|
77
103
|
return fallbackI18n;
|
|
78
104
|
}
|
|
79
105
|
function useSaMessages(namespace) {
|
|
@@ -91,6 +117,7 @@ export {
|
|
|
91
117
|
SUPER_ADMIN_HTTP_KEY,
|
|
92
118
|
buildNavigationGuard,
|
|
93
119
|
SUPER_ADMIN_NOTIFY_KEY,
|
|
120
|
+
SA_LOCALE_STORAGE_KEY,
|
|
94
121
|
SUPER_ADMIN_I18N_KEY,
|
|
95
122
|
createSuperAdminI18n,
|
|
96
123
|
useSuperAdminI18n,
|
|
@@ -1,21 +1,43 @@
|
|
|
1
1
|
// src/client/types.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
},
|
|
8
|
-
remove: () => {
|
|
9
|
-
}
|
|
10
|
-
};
|
|
2
|
+
var NOOP_KV_STORE = {
|
|
3
|
+
get: () => null,
|
|
4
|
+
set: () => {
|
|
5
|
+
},
|
|
6
|
+
remove: () => {
|
|
11
7
|
}
|
|
12
|
-
|
|
8
|
+
};
|
|
9
|
+
function defaultKvStore() {
|
|
10
|
+
const ls = resolveLocalStorage();
|
|
11
|
+
if (!ls) return NOOP_KV_STORE;
|
|
13
12
|
return {
|
|
14
|
-
get: (k) =>
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
get: (k) => {
|
|
14
|
+
try {
|
|
15
|
+
return ls.getItem(k);
|
|
16
|
+
} catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
set: (k, v) => {
|
|
21
|
+
try {
|
|
22
|
+
ls.setItem(k, v);
|
|
23
|
+
} catch {
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
remove: (k) => {
|
|
27
|
+
try {
|
|
28
|
+
ls.removeItem(k);
|
|
29
|
+
} catch {
|
|
30
|
+
}
|
|
31
|
+
}
|
|
17
32
|
};
|
|
18
33
|
}
|
|
34
|
+
function resolveLocalStorage() {
|
|
35
|
+
try {
|
|
36
|
+
return globalThis.localStorage ?? null;
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
19
41
|
function defaultHttpClient() {
|
|
20
42
|
return (url, init) => fetch(url, init);
|
|
21
43
|
}
|
|
@@ -27,6 +49,16 @@ var SA_INTL_LOCALES = {
|
|
|
27
49
|
de: "de-DE",
|
|
28
50
|
en: "en-US"
|
|
29
51
|
};
|
|
52
|
+
var SA_LOCALE_LABELS = {
|
|
53
|
+
de: "Deutsch",
|
|
54
|
+
en: "English"
|
|
55
|
+
};
|
|
56
|
+
function isSaBuiltinLocale(value) {
|
|
57
|
+
return typeof value === "string" && SA_LOCALES.includes(value);
|
|
58
|
+
}
|
|
59
|
+
function builtinLocaleOf(locale, fallback = DEFAULT_SA_LOCALE) {
|
|
60
|
+
return isSaBuiltinLocale(locale) ? locale : fallback;
|
|
61
|
+
}
|
|
30
62
|
|
|
31
63
|
// src/client/i18n/define.ts
|
|
32
64
|
function defineMessages(de, en) {
|
|
@@ -64,7 +96,7 @@ function formatterFor(locale, currency, decimals) {
|
|
|
64
96
|
const key = `${locale}:${currency}:${decimals}`;
|
|
65
97
|
let formatter = formatters.get(key);
|
|
66
98
|
if (!formatter) {
|
|
67
|
-
formatter = new Intl.NumberFormat(SA_INTL_LOCALES[locale], {
|
|
99
|
+
formatter = new Intl.NumberFormat(SA_INTL_LOCALES[locale] ?? locale, {
|
|
68
100
|
style: "currency",
|
|
69
101
|
currency,
|
|
70
102
|
minimumFractionDigits: decimals,
|
|
@@ -230,7 +262,7 @@ var bundlesMessages = defineMessages(
|
|
|
230
262
|
bundleKeyHint: "API-stabil \xB7 wird aus dem Label erzeugt",
|
|
231
263
|
errorKeyFormat: "Nur A-Z, 0-9, Underscore; muss mit Buchstabe beginnen.",
|
|
232
264
|
errorKeyExists: "Dieser Bundle-Key existiert bereits.",
|
|
233
|
-
descriptionPlaceholder: "z. B. Kampagnen, WhatsApp und Korrespondenz
|
|
265
|
+
descriptionPlaceholder: "z. B. Kampagnen, WhatsApp und Korrespondenz.",
|
|
234
266
|
sectionPricing: "v1 \xB7 Pricing & G\xFCltigkeit",
|
|
235
267
|
pricingHint: "Monats- & Jahrespreis sowie Datum, ab dem das Bundle verkaufbar wird.",
|
|
236
268
|
validFromImmediate: "\u2713 Bundle ist nach Anlage sofort live und verkaufbar.",
|
|
@@ -442,7 +474,7 @@ var bundlesMessages = defineMessages(
|
|
|
442
474
|
bundleKeyHint: "API-stable \xB7 derived from the label",
|
|
443
475
|
errorKeyFormat: "Only A-Z, 0-9, underscore; must start with a letter.",
|
|
444
476
|
errorKeyExists: "This bundle key already exists.",
|
|
445
|
-
descriptionPlaceholder: "e.g. Campaigns, WhatsApp and correspondence
|
|
477
|
+
descriptionPlaceholder: "e.g. Campaigns, WhatsApp and correspondence.",
|
|
446
478
|
sectionPricing: "v1 \xB7 pricing & validity",
|
|
447
479
|
pricingHint: "Monthly & yearly price plus the date from which the bundle becomes sellable.",
|
|
448
480
|
validFromImmediate: "\u2713 The bundle is live and sellable right after creation.",
|
|
@@ -1116,7 +1148,7 @@ var marketingMessages = defineMessages(
|
|
|
1116
1148
|
ctaOverrideLabel: "CTA-Text \xFCberschreiben (optional)",
|
|
1117
1149
|
ctaOverrideHint: "leer lassen f\xFCr Auto-Text",
|
|
1118
1150
|
topFeatureCount: "{count} Eintr\xE4ge",
|
|
1119
|
-
featureLabelPlaceholder: "z. B.
|
|
1151
|
+
featureLabelPlaceholder: "z. B. Erweiterte Berichte",
|
|
1120
1152
|
featureStrongPlaceholder: "Highlight, z. B. bis 100",
|
|
1121
1153
|
moveUp: "Nach oben",
|
|
1122
1154
|
moveDown: "Nach unten",
|
|
@@ -1244,7 +1276,7 @@ var marketingMessages = defineMessages(
|
|
|
1244
1276
|
ctaOverrideLabel: "Override CTA text (optional)",
|
|
1245
1277
|
ctaOverrideHint: "leave empty for the auto text",
|
|
1246
1278
|
topFeatureCount: "{count} entries",
|
|
1247
|
-
featureLabelPlaceholder: "e.g.
|
|
1279
|
+
featureLabelPlaceholder: "e.g. Advanced reporting",
|
|
1248
1280
|
featureStrongPlaceholder: "Highlight, e.g. up to 100",
|
|
1249
1281
|
moveUp: "Move up",
|
|
1250
1282
|
moveDown: "Move down",
|
|
@@ -2737,7 +2769,8 @@ var shellMessages = defineMessages(
|
|
|
2737
2769
|
productionWarning: "Aktionen wirken sich sofort auf alle Mandanten aus.",
|
|
2738
2770
|
subtitle: "SuperAdmin \xB7 Plattform-Verwaltung",
|
|
2739
2771
|
roleBadge: "SUPER ADMIN",
|
|
2740
|
-
logout: "Abmelden"
|
|
2772
|
+
logout: "Abmelden",
|
|
2773
|
+
language: "Sprache"
|
|
2741
2774
|
},
|
|
2742
2775
|
drawer: {
|
|
2743
2776
|
docs: "Doku \xF6ffnen"
|
|
@@ -2805,7 +2838,8 @@ var shellMessages = defineMessages(
|
|
|
2805
2838
|
productionWarning: "Actions take effect immediately for all tenants.",
|
|
2806
2839
|
subtitle: "SuperAdmin \xB7 Platform administration",
|
|
2807
2840
|
roleBadge: "SUPER ADMIN",
|
|
2808
|
-
logout: "Sign out"
|
|
2841
|
+
logout: "Sign out",
|
|
2842
|
+
language: "Language"
|
|
2809
2843
|
},
|
|
2810
2844
|
drawer: {
|
|
2811
2845
|
docs: "Open documentation"
|
|
@@ -3078,17 +3112,52 @@ function resolveMessages(locale, overrides) {
|
|
|
3078
3112
|
return mergeMessages(SA_MESSAGES[locale], overrides);
|
|
3079
3113
|
}
|
|
3080
3114
|
|
|
3115
|
+
// src/client/i18n/catalog.ts
|
|
3116
|
+
function createSaCatalog(options = {}) {
|
|
3117
|
+
const additional = options.additionalLocales ?? {};
|
|
3118
|
+
const known = /* @__PURE__ */ new Set([...SA_LOCALES, ...Object.keys(additional)]);
|
|
3119
|
+
const requested = options.locales?.filter((code) => known.has(code));
|
|
3120
|
+
const offered = requested && requested.length > 0 ? requested : [...SA_LOCALES, ...Object.keys(additional)];
|
|
3121
|
+
const labelFor = (locale) => additional[locale]?.label ?? (isSaBuiltinLocale(locale) ? SA_LOCALE_LABELS[locale] : locale);
|
|
3122
|
+
const cache = /* @__PURE__ */ new Map();
|
|
3123
|
+
const messagesFor = (locale) => {
|
|
3124
|
+
const hit = cache.get(locale);
|
|
3125
|
+
if (hit) return hit;
|
|
3126
|
+
const definition = additional[locale];
|
|
3127
|
+
const base = SA_MESSAGES[definition?.basedOn ?? (isSaBuiltinLocale(locale) ? locale : "en")];
|
|
3128
|
+
const translated = definition ? mergeMessages(base, definition.messages) : base;
|
|
3129
|
+
const resolved = mergeMessages(translated, options.overrides?.[locale]);
|
|
3130
|
+
cache.set(locale, resolved);
|
|
3131
|
+
return resolved;
|
|
3132
|
+
};
|
|
3133
|
+
const offeredSet = new Set(offered);
|
|
3134
|
+
return {
|
|
3135
|
+
locales: offered.map((code) => ({ code, label: labelFor(code) })),
|
|
3136
|
+
has: (locale) => offeredSet.has(locale),
|
|
3137
|
+
// The app's first offered locale beats the platform default: an app
|
|
3138
|
+
// shipping English only must not start in German.
|
|
3139
|
+
defaultLocale: offered.includes(DEFAULT_SA_LOCALE) ? DEFAULT_SA_LOCALE : offered[0],
|
|
3140
|
+
messagesFor,
|
|
3141
|
+
intlLocaleFor: (locale) => additional[locale]?.intlLocale ?? (isSaBuiltinLocale(locale) ? SA_INTL_LOCALES[locale] : locale),
|
|
3142
|
+
labelFor
|
|
3143
|
+
};
|
|
3144
|
+
}
|
|
3145
|
+
|
|
3081
3146
|
export {
|
|
3082
3147
|
defaultKvStore,
|
|
3083
3148
|
defaultHttpClient,
|
|
3084
3149
|
SA_LOCALES,
|
|
3085
3150
|
DEFAULT_SA_LOCALE,
|
|
3086
3151
|
SA_INTL_LOCALES,
|
|
3152
|
+
SA_LOCALE_LABELS,
|
|
3153
|
+
isSaBuiltinLocale,
|
|
3154
|
+
builtinLocaleOf,
|
|
3087
3155
|
defineMessages,
|
|
3088
3156
|
mergeMessages,
|
|
3089
3157
|
navMessages,
|
|
3090
3158
|
formatMessage,
|
|
3091
3159
|
formatCurrency,
|
|
3092
3160
|
SA_MESSAGES,
|
|
3093
|
-
resolveMessages
|
|
3161
|
+
resolveMessages,
|
|
3162
|
+
createSaCatalog
|
|
3094
3163
|
};
|
|
@@ -2,8 +2,9 @@ import {
|
|
|
2
2
|
DEFAULT_SA_LOCALE,
|
|
3
3
|
defaultHttpClient,
|
|
4
4
|
defaultKvStore,
|
|
5
|
+
isSaBuiltinLocale,
|
|
5
6
|
navMessages
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-IZGFS5RS.js";
|
|
7
8
|
|
|
8
9
|
// src/client/version.ts
|
|
9
10
|
var ADMIN_UI_VERSION = "1.2.0";
|
|
@@ -213,15 +214,21 @@ var PAGE_SECTIONS = {
|
|
|
213
214
|
platformEmail: "system",
|
|
214
215
|
platformEmailHistory: "system"
|
|
215
216
|
};
|
|
217
|
+
function resolveNav(options) {
|
|
218
|
+
return options.nav ?? builtinNav(options.locale);
|
|
219
|
+
}
|
|
220
|
+
function builtinNav(locale) {
|
|
221
|
+
return navMessages[isSaBuiltinLocale(locale) ? locale : DEFAULT_SA_LOCALE];
|
|
222
|
+
}
|
|
216
223
|
function defaultSectionOrder(locale = DEFAULT_SA_LOCALE) {
|
|
217
|
-
const sections =
|
|
224
|
+
const sections = typeof locale === "string" ? builtinNav(locale).sections : locale.sections;
|
|
218
225
|
return [sections.overview, sections.catalog, sections.customers, sections.system];
|
|
219
226
|
}
|
|
220
227
|
function buildRoutes(manifest, options = {}) {
|
|
221
228
|
const routes = [];
|
|
222
229
|
const capabilities = manifest.capabilities ?? {};
|
|
223
230
|
const standard = manifest.navigation?.standardPages ?? {};
|
|
224
|
-
const nav =
|
|
231
|
+
const nav = resolveNav(options);
|
|
225
232
|
const defaultNavSections = Object.fromEntries(
|
|
226
233
|
Object.entries(PAGE_SECTIONS).map(([page, section]) => [page, nav.sections[section]])
|
|
227
234
|
);
|
|
@@ -541,6 +548,23 @@ function queryString(params) {
|
|
|
541
548
|
return value ? `?${value}` : "";
|
|
542
549
|
}
|
|
543
550
|
|
|
551
|
+
// src/client/login-branding.ts
|
|
552
|
+
var DEFAULT_TAG = "SuperAdmin";
|
|
553
|
+
function resolveLoginBranding(boot, fallback = {}) {
|
|
554
|
+
const project = boot?.project ?? null;
|
|
555
|
+
const environment = project?.environment ?? null;
|
|
556
|
+
return {
|
|
557
|
+
name: project?.displayName || fallback.name || "",
|
|
558
|
+
tag: project?.label || fallback.tag || DEFAULT_TAG,
|
|
559
|
+
icon: project?.icon || fallback.logoText || "",
|
|
560
|
+
logoUrl: project?.logoUrl || null,
|
|
561
|
+
environment: environment && environment !== "production" ? environment : null
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
function isProductionBoot(boot) {
|
|
565
|
+
return boot?.project?.environment === "production";
|
|
566
|
+
}
|
|
567
|
+
|
|
544
568
|
export {
|
|
545
569
|
ADMIN_UI_VERSION,
|
|
546
570
|
HttpJsonError,
|
|
@@ -561,5 +585,7 @@ export {
|
|
|
561
585
|
ActionRegistry,
|
|
562
586
|
BatchColumnDriftError,
|
|
563
587
|
BatchColumnFetcher,
|
|
564
|
-
createAdminResourceClient
|
|
588
|
+
createAdminResourceClient,
|
|
589
|
+
resolveLoginBranding,
|
|
590
|
+
isProductionBoot
|
|
565
591
|
};
|
package/dist/client/index.cjs
CHANGED
|
@@ -35,10 +35,13 @@ __export(client_exports, {
|
|
|
35
35
|
MissingHandlerError: () => MissingHandlerError,
|
|
36
36
|
SA_INTL_LOCALES: () => SA_INTL_LOCALES,
|
|
37
37
|
SA_LOCALES: () => SA_LOCALES,
|
|
38
|
+
SA_LOCALE_LABELS: () => SA_LOCALE_LABELS,
|
|
38
39
|
SA_MESSAGES: () => SA_MESSAGES,
|
|
39
40
|
buildRoutes: () => buildRoutes,
|
|
40
41
|
buildSidebar: () => buildSidebar,
|
|
42
|
+
builtinLocaleOf: () => builtinLocaleOf,
|
|
41
43
|
createAdminResourceClient: () => createAdminResourceClient,
|
|
44
|
+
createSaCatalog: () => createSaCatalog,
|
|
42
45
|
defaultHttpClient: () => defaultHttpClient,
|
|
43
46
|
defaultKvStore: () => defaultKvStore,
|
|
44
47
|
defaultSectionOrder: () => defaultSectionOrder,
|
|
@@ -46,9 +49,12 @@ __export(client_exports, {
|
|
|
46
49
|
formatCurrency: () => formatCurrency,
|
|
47
50
|
formatMessage: () => formatMessage,
|
|
48
51
|
getJson: () => getJson,
|
|
52
|
+
isProductionBoot: () => isProductionBoot,
|
|
53
|
+
isSaBuiltinLocale: () => isSaBuiltinLocale,
|
|
49
54
|
mergeMessages: () => mergeMessages,
|
|
50
55
|
postJson: () => postJson,
|
|
51
56
|
resolveExtension: () => resolveExtension,
|
|
57
|
+
resolveLoginBranding: () => resolveLoginBranding,
|
|
52
58
|
resolveMessages: () => resolveMessages,
|
|
53
59
|
trimTrailingSlashes: () => trimTrailingSlashes
|
|
54
60
|
});
|
|
@@ -58,23 +64,45 @@ module.exports = __toCommonJS(client_exports);
|
|
|
58
64
|
var ADMIN_UI_VERSION = "1.2.0";
|
|
59
65
|
|
|
60
66
|
// src/client/types.ts
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
},
|
|
67
|
-
remove: () => {
|
|
68
|
-
}
|
|
69
|
-
};
|
|
67
|
+
var NOOP_KV_STORE = {
|
|
68
|
+
get: () => null,
|
|
69
|
+
set: () => {
|
|
70
|
+
},
|
|
71
|
+
remove: () => {
|
|
70
72
|
}
|
|
71
|
-
|
|
73
|
+
};
|
|
74
|
+
function defaultKvStore() {
|
|
75
|
+
const ls = resolveLocalStorage();
|
|
76
|
+
if (!ls) return NOOP_KV_STORE;
|
|
72
77
|
return {
|
|
73
|
-
get: (k) =>
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
get: (k) => {
|
|
79
|
+
try {
|
|
80
|
+
return ls.getItem(k);
|
|
81
|
+
} catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
set: (k, v) => {
|
|
86
|
+
try {
|
|
87
|
+
ls.setItem(k, v);
|
|
88
|
+
} catch {
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
remove: (k) => {
|
|
92
|
+
try {
|
|
93
|
+
ls.removeItem(k);
|
|
94
|
+
} catch {
|
|
95
|
+
}
|
|
96
|
+
}
|
|
76
97
|
};
|
|
77
98
|
}
|
|
99
|
+
function resolveLocalStorage() {
|
|
100
|
+
try {
|
|
101
|
+
return globalThis.localStorage ?? null;
|
|
102
|
+
} catch {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
78
106
|
function defaultHttpClient() {
|
|
79
107
|
return (url, init) => fetch(url, init);
|
|
80
108
|
}
|
|
@@ -242,6 +270,16 @@ var SA_INTL_LOCALES = {
|
|
|
242
270
|
de: "de-DE",
|
|
243
271
|
en: "en-US"
|
|
244
272
|
};
|
|
273
|
+
var SA_LOCALE_LABELS = {
|
|
274
|
+
de: "Deutsch",
|
|
275
|
+
en: "English"
|
|
276
|
+
};
|
|
277
|
+
function isSaBuiltinLocale(value) {
|
|
278
|
+
return typeof value === "string" && SA_LOCALES.includes(value);
|
|
279
|
+
}
|
|
280
|
+
function builtinLocaleOf(locale, fallback = DEFAULT_SA_LOCALE) {
|
|
281
|
+
return isSaBuiltinLocale(locale) ? locale : fallback;
|
|
282
|
+
}
|
|
245
283
|
|
|
246
284
|
// src/client/i18n/define.ts
|
|
247
285
|
function defineMessages(de, en) {
|
|
@@ -363,15 +401,21 @@ var PAGE_SECTIONS = {
|
|
|
363
401
|
platformEmail: "system",
|
|
364
402
|
platformEmailHistory: "system"
|
|
365
403
|
};
|
|
404
|
+
function resolveNav(options) {
|
|
405
|
+
return options.nav ?? builtinNav(options.locale);
|
|
406
|
+
}
|
|
407
|
+
function builtinNav(locale) {
|
|
408
|
+
return navMessages[isSaBuiltinLocale(locale) ? locale : DEFAULT_SA_LOCALE];
|
|
409
|
+
}
|
|
366
410
|
function defaultSectionOrder(locale = DEFAULT_SA_LOCALE) {
|
|
367
|
-
const sections =
|
|
411
|
+
const sections = typeof locale === "string" ? builtinNav(locale).sections : locale.sections;
|
|
368
412
|
return [sections.overview, sections.catalog, sections.customers, sections.system];
|
|
369
413
|
}
|
|
370
414
|
function buildRoutes(manifest, options = {}) {
|
|
371
415
|
const routes = [];
|
|
372
416
|
const capabilities = manifest.capabilities ?? {};
|
|
373
417
|
const standard = manifest.navigation?.standardPages ?? {};
|
|
374
|
-
const nav =
|
|
418
|
+
const nav = resolveNav(options);
|
|
375
419
|
const defaultNavSections = Object.fromEntries(
|
|
376
420
|
Object.entries(PAGE_SECTIONS).map(([page, section]) => [page, nav.sections[section]])
|
|
377
421
|
);
|
|
@@ -706,7 +750,7 @@ function formatterFor(locale, currency, decimals) {
|
|
|
706
750
|
const key = `${locale}:${currency}:${decimals}`;
|
|
707
751
|
let formatter = formatters.get(key);
|
|
708
752
|
if (!formatter) {
|
|
709
|
-
formatter = new Intl.NumberFormat(SA_INTL_LOCALES[locale], {
|
|
753
|
+
formatter = new Intl.NumberFormat(SA_INTL_LOCALES[locale] ?? locale, {
|
|
710
754
|
style: "currency",
|
|
711
755
|
currency,
|
|
712
756
|
minimumFractionDigits: decimals,
|
|
@@ -872,7 +916,7 @@ var bundlesMessages = defineMessages(
|
|
|
872
916
|
bundleKeyHint: "API-stabil \xB7 wird aus dem Label erzeugt",
|
|
873
917
|
errorKeyFormat: "Nur A-Z, 0-9, Underscore; muss mit Buchstabe beginnen.",
|
|
874
918
|
errorKeyExists: "Dieser Bundle-Key existiert bereits.",
|
|
875
|
-
descriptionPlaceholder: "z. B. Kampagnen, WhatsApp und Korrespondenz
|
|
919
|
+
descriptionPlaceholder: "z. B. Kampagnen, WhatsApp und Korrespondenz.",
|
|
876
920
|
sectionPricing: "v1 \xB7 Pricing & G\xFCltigkeit",
|
|
877
921
|
pricingHint: "Monats- & Jahrespreis sowie Datum, ab dem das Bundle verkaufbar wird.",
|
|
878
922
|
validFromImmediate: "\u2713 Bundle ist nach Anlage sofort live und verkaufbar.",
|
|
@@ -1084,7 +1128,7 @@ var bundlesMessages = defineMessages(
|
|
|
1084
1128
|
bundleKeyHint: "API-stable \xB7 derived from the label",
|
|
1085
1129
|
errorKeyFormat: "Only A-Z, 0-9, underscore; must start with a letter.",
|
|
1086
1130
|
errorKeyExists: "This bundle key already exists.",
|
|
1087
|
-
descriptionPlaceholder: "e.g. Campaigns, WhatsApp and correspondence
|
|
1131
|
+
descriptionPlaceholder: "e.g. Campaigns, WhatsApp and correspondence.",
|
|
1088
1132
|
sectionPricing: "v1 \xB7 pricing & validity",
|
|
1089
1133
|
pricingHint: "Monthly & yearly price plus the date from which the bundle becomes sellable.",
|
|
1090
1134
|
validFromImmediate: "\u2713 The bundle is live and sellable right after creation.",
|
|
@@ -1758,7 +1802,7 @@ var marketingMessages = defineMessages(
|
|
|
1758
1802
|
ctaOverrideLabel: "CTA-Text \xFCberschreiben (optional)",
|
|
1759
1803
|
ctaOverrideHint: "leer lassen f\xFCr Auto-Text",
|
|
1760
1804
|
topFeatureCount: "{count} Eintr\xE4ge",
|
|
1761
|
-
featureLabelPlaceholder: "z. B.
|
|
1805
|
+
featureLabelPlaceholder: "z. B. Erweiterte Berichte",
|
|
1762
1806
|
featureStrongPlaceholder: "Highlight, z. B. bis 100",
|
|
1763
1807
|
moveUp: "Nach oben",
|
|
1764
1808
|
moveDown: "Nach unten",
|
|
@@ -1886,7 +1930,7 @@ var marketingMessages = defineMessages(
|
|
|
1886
1930
|
ctaOverrideLabel: "Override CTA text (optional)",
|
|
1887
1931
|
ctaOverrideHint: "leave empty for the auto text",
|
|
1888
1932
|
topFeatureCount: "{count} entries",
|
|
1889
|
-
featureLabelPlaceholder: "e.g.
|
|
1933
|
+
featureLabelPlaceholder: "e.g. Advanced reporting",
|
|
1890
1934
|
featureStrongPlaceholder: "Highlight, e.g. up to 100",
|
|
1891
1935
|
moveUp: "Move up",
|
|
1892
1936
|
moveDown: "Move down",
|
|
@@ -3329,7 +3373,8 @@ var shellMessages = defineMessages(
|
|
|
3329
3373
|
productionWarning: "Aktionen wirken sich sofort auf alle Mandanten aus.",
|
|
3330
3374
|
subtitle: "SuperAdmin \xB7 Plattform-Verwaltung",
|
|
3331
3375
|
roleBadge: "SUPER ADMIN",
|
|
3332
|
-
logout: "Abmelden"
|
|
3376
|
+
logout: "Abmelden",
|
|
3377
|
+
language: "Sprache"
|
|
3333
3378
|
},
|
|
3334
3379
|
drawer: {
|
|
3335
3380
|
docs: "Doku \xF6ffnen"
|
|
@@ -3397,7 +3442,8 @@ var shellMessages = defineMessages(
|
|
|
3397
3442
|
productionWarning: "Actions take effect immediately for all tenants.",
|
|
3398
3443
|
subtitle: "SuperAdmin \xB7 Platform administration",
|
|
3399
3444
|
roleBadge: "SUPER ADMIN",
|
|
3400
|
-
logout: "Sign out"
|
|
3445
|
+
logout: "Sign out",
|
|
3446
|
+
language: "Language"
|
|
3401
3447
|
},
|
|
3402
3448
|
drawer: {
|
|
3403
3449
|
docs: "Open documentation"
|
|
@@ -3669,6 +3715,54 @@ function resolveMessages(locale, overrides) {
|
|
|
3669
3715
|
if (!overrides) return SA_MESSAGES[locale];
|
|
3670
3716
|
return mergeMessages(SA_MESSAGES[locale], overrides);
|
|
3671
3717
|
}
|
|
3718
|
+
|
|
3719
|
+
// src/client/i18n/catalog.ts
|
|
3720
|
+
function createSaCatalog(options = {}) {
|
|
3721
|
+
const additional = options.additionalLocales ?? {};
|
|
3722
|
+
const known = /* @__PURE__ */ new Set([...SA_LOCALES, ...Object.keys(additional)]);
|
|
3723
|
+
const requested = options.locales?.filter((code) => known.has(code));
|
|
3724
|
+
const offered = requested && requested.length > 0 ? requested : [...SA_LOCALES, ...Object.keys(additional)];
|
|
3725
|
+
const labelFor = (locale) => additional[locale]?.label ?? (isSaBuiltinLocale(locale) ? SA_LOCALE_LABELS[locale] : locale);
|
|
3726
|
+
const cache = /* @__PURE__ */ new Map();
|
|
3727
|
+
const messagesFor = (locale) => {
|
|
3728
|
+
const hit = cache.get(locale);
|
|
3729
|
+
if (hit) return hit;
|
|
3730
|
+
const definition = additional[locale];
|
|
3731
|
+
const base = SA_MESSAGES[definition?.basedOn ?? (isSaBuiltinLocale(locale) ? locale : "en")];
|
|
3732
|
+
const translated = definition ? mergeMessages(base, definition.messages) : base;
|
|
3733
|
+
const resolved = mergeMessages(translated, options.overrides?.[locale]);
|
|
3734
|
+
cache.set(locale, resolved);
|
|
3735
|
+
return resolved;
|
|
3736
|
+
};
|
|
3737
|
+
const offeredSet = new Set(offered);
|
|
3738
|
+
return {
|
|
3739
|
+
locales: offered.map((code) => ({ code, label: labelFor(code) })),
|
|
3740
|
+
has: (locale) => offeredSet.has(locale),
|
|
3741
|
+
// The app's first offered locale beats the platform default: an app
|
|
3742
|
+
// shipping English only must not start in German.
|
|
3743
|
+
defaultLocale: offered.includes(DEFAULT_SA_LOCALE) ? DEFAULT_SA_LOCALE : offered[0],
|
|
3744
|
+
messagesFor,
|
|
3745
|
+
intlLocaleFor: (locale) => additional[locale]?.intlLocale ?? (isSaBuiltinLocale(locale) ? SA_INTL_LOCALES[locale] : locale),
|
|
3746
|
+
labelFor
|
|
3747
|
+
};
|
|
3748
|
+
}
|
|
3749
|
+
|
|
3750
|
+
// src/client/login-branding.ts
|
|
3751
|
+
var DEFAULT_TAG = "SuperAdmin";
|
|
3752
|
+
function resolveLoginBranding(boot, fallback = {}) {
|
|
3753
|
+
const project = boot?.project ?? null;
|
|
3754
|
+
const environment = project?.environment ?? null;
|
|
3755
|
+
return {
|
|
3756
|
+
name: project?.displayName || fallback.name || "",
|
|
3757
|
+
tag: project?.label || fallback.tag || DEFAULT_TAG,
|
|
3758
|
+
icon: project?.icon || fallback.logoText || "",
|
|
3759
|
+
logoUrl: project?.logoUrl || null,
|
|
3760
|
+
environment: environment && environment !== "production" ? environment : null
|
|
3761
|
+
};
|
|
3762
|
+
}
|
|
3763
|
+
function isProductionBoot(boot) {
|
|
3764
|
+
return boot?.project?.environment === "production";
|
|
3765
|
+
}
|
|
3672
3766
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3673
3767
|
0 && (module.exports = {
|
|
3674
3768
|
ADMIN_UI_VERSION,
|
|
@@ -3686,10 +3780,13 @@ function resolveMessages(locale, overrides) {
|
|
|
3686
3780
|
MissingHandlerError,
|
|
3687
3781
|
SA_INTL_LOCALES,
|
|
3688
3782
|
SA_LOCALES,
|
|
3783
|
+
SA_LOCALE_LABELS,
|
|
3689
3784
|
SA_MESSAGES,
|
|
3690
3785
|
buildRoutes,
|
|
3691
3786
|
buildSidebar,
|
|
3787
|
+
builtinLocaleOf,
|
|
3692
3788
|
createAdminResourceClient,
|
|
3789
|
+
createSaCatalog,
|
|
3693
3790
|
defaultHttpClient,
|
|
3694
3791
|
defaultKvStore,
|
|
3695
3792
|
defaultSectionOrder,
|
|
@@ -3697,9 +3794,12 @@ function resolveMessages(locale, overrides) {
|
|
|
3697
3794
|
formatCurrency,
|
|
3698
3795
|
formatMessage,
|
|
3699
3796
|
getJson,
|
|
3797
|
+
isProductionBoot,
|
|
3798
|
+
isSaBuiltinLocale,
|
|
3700
3799
|
mergeMessages,
|
|
3701
3800
|
postJson,
|
|
3702
3801
|
resolveExtension,
|
|
3802
|
+
resolveLoginBranding,
|
|
3703
3803
|
resolveMessages,
|
|
3704
3804
|
trimTrailingSlashes
|
|
3705
3805
|
});
|