@dskripchenko/laravel-admin 1.51.1 → 1.52.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.vite/manifest.json +2 -2
- package/dist/assets/{app-RzCm9wvY.css → app--y818Ix0.css} +1 -1
- package/dist/assets/{app-Dfg_kc-5.js → app-CCP0OT4t.js} +24 -24
- package/dist/components/shell/AdminRevealDialog.vue.d.ts +2 -0
- package/dist/composables/useReveal.d.ts +31 -0
- package/dist/composables/useReveal.test.d.ts +1 -0
- package/dist/{formState-DqHe1Jgd.cjs → formState-DlGlAlif.cjs} +1 -1
- package/dist/{formState-DqHe1Jgd.cjs.map → formState-DlGlAlif.cjs.map} +1 -1
- package/dist/{formState-DVU2igtT.js → formState-diR_mnaG.js} +1 -1
- package/dist/{formState-DVU2igtT.js.map → formState-diR_mnaG.js.map} +1 -1
- package/dist/{i18n-D77Oo6mM.js → i18n-CF2S5XHW.js} +1 -1
- package/dist/{i18n-D77Oo6mM.js.map → i18n-CF2S5XHW.js.map} +1 -1
- package/dist/{i18n-D98X6Xot.cjs → i18n-DW_VQZeY.cjs} +1 -1
- package/dist/{i18n-D98X6Xot.cjs.map → i18n-DW_VQZeY.cjs.map} +1 -1
- package/dist/index.cjs +19 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +13934 -13824
- package/dist/index.mjs.map +1 -1
- package/dist/quill.cjs +1 -1
- package/dist/quill.mjs +1 -1
- package/dist/source-hash.txt +1 -1
- package/dist/style.css +1 -1
- package/dist/tinymce.cjs +1 -1
- package/dist/tinymce.mjs +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface RevealOptions {
|
|
2
|
+
value: string;
|
|
3
|
+
title?: string;
|
|
4
|
+
/** What happened, in words — the action's message. */
|
|
5
|
+
message?: string;
|
|
6
|
+
/** The caption of the value. */
|
|
7
|
+
label?: string | null;
|
|
8
|
+
}
|
|
9
|
+
export interface RevealState {
|
|
10
|
+
open: boolean;
|
|
11
|
+
title: string;
|
|
12
|
+
message: string;
|
|
13
|
+
label: string;
|
|
14
|
+
value: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const revealState: {
|
|
17
|
+
open: boolean;
|
|
18
|
+
title: string;
|
|
19
|
+
message: string;
|
|
20
|
+
label: string;
|
|
21
|
+
value: string;
|
|
22
|
+
};
|
|
23
|
+
/** Shows the value; resolves when the dialog is closed. */
|
|
24
|
+
export declare function revealOnce(opts: RevealOptions): Promise<void>;
|
|
25
|
+
/** Closes the dialog and forgets the value. */
|
|
26
|
+
export declare function closeReveal(): void;
|
|
27
|
+
/** `reveal` of an action's answer, if it carries one. */
|
|
28
|
+
export declare function actionReveal(raw: unknown): {
|
|
29
|
+
value: string;
|
|
30
|
+
label: string | null;
|
|
31
|
+
} | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use strict";const n=require("vue"),d=Symbol("admin.form-state");function y(e={},l={},c){const i=n.reactive(e),s=n.reactive({...l}),u={state:i,errors:s,mode:c,setField(o,r){i[o]=r,s[o]&&delete s[o]},getField(o){return i[o]},setError(o,r){r===null||r.length===0?delete s[o]:s[o]=r},setErrors(o){for(const r of Object.keys(s))delete s[r];Object.assign(s,o)},clearErrors(){for(const o of Object.keys(s))delete s[o]}};return n.provide(d,u),u}function F(){const e=n.inject(d);if(!e)throw new Error("useFormState() called outside of provideFormState() scope");return e}function v(){return n.inject(d,null)}function S(e,l){const c=`${l}.`,i=()=>{const r=e.getField(l);return r!==null&&typeof r=="object"&&!Array.isArray(r)?r:{}},s=()=>Object.keys(e.errors).filter(r=>r.startsWith(c)).map(r=>r.slice(c.length)),u=new Proxy({},{get:(r,t)=>typeof t=="string"?e.errors[c+t]:void 0,has:(r,t)=>typeof t=="string"&&c+t in e.errors,ownKeys:()=>s(),getOwnPropertyDescriptor:(r,t)=>typeof t=="string"&&c+t in e.errors?{enumerable:!0,configurable:!0,value:e.errors[c+t]}:void 0}),o={get state(){return i()},errors:u,mode:e.mode,setField(r,t){e.setField(l,{...i(),[r]:t}),e.setError(c+r,null)},getField(r){return i()[r]},setError(r,t){e.setError(c+r,t)},setErrors(r){for(const t of s())e.setError(c+t,null);for(const[t,f]of Object.entries(r))e.setError(c+t,f)},clearErrors(){for(const r of s())e.setError(c+r,null)}};return n.provide(d,o),o}exports.provideFormState=y;exports.provideScopedFormState=S;exports.tryUseFormState=v;exports.useFormState=F;
|
|
2
|
-
//# sourceMappingURL=formState-
|
|
2
|
+
//# sourceMappingURL=formState-DlGlAlif.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formState-
|
|
1
|
+
{"version":3,"file":"formState-DlGlAlif.cjs","sources":["../resources/ts/components/render/formState.ts"],"sourcesContent":["/**\n * The form-state composable: it exposes the state and the errors through\n * provide/inject.\n *\n * The container — a resource form, a settings page — calls\n * `provideFormState()`, and the field components in the tree call\n * `useFormState()` to read a value and change a field.\n *\n * The state is a reactive proxy that setField mutates by key; the errors are a\n * separate reactive map of field name → string[] messages.\n */\n\nimport { inject, provide, reactive, type InjectionKey } from 'vue'\n\nexport interface FormStateContext {\n state: Record<string, unknown>\n errors: Record<string, string[]>\n /** The form's context: FieldRenderer hides the fields with visibility[mode]=false. */\n mode?: 'create' | 'update' | 'view'\n setField: (name: string, value: unknown) => void\n getField: (name: string) => unknown\n setError: (name: string, messages: string[] | null) => void\n setErrors: (next: Record<string, string[]>) => void\n clearErrors: () => void\n}\n\nconst FormStateKey: InjectionKey<FormStateContext> = Symbol('admin.form-state')\n\n/**\n * Creates the form context and provides it to the descendants.\n *\n * The `initial` object given is wrapped into `reactive()`, so the mutations are\n * visible from outside too: the caller owns the state and may read it after a\n * submit.\n *\n * @param initial The state's initial values.\n * @param initialErrors The initial errors, for a re-render after a\n * ValidationError.\n */\nexport function provideFormState(\n initial: Record<string, unknown> = {},\n initialErrors: Record<string, string[]> = {},\n mode?: 'create' | 'update' | 'view',\n): FormStateContext {\n const state = reactive(initial)\n const errors = reactive<Record<string, string[]>>({ ...initialErrors })\n\n const ctx: FormStateContext = {\n state,\n errors,\n mode,\n setField(name, value) {\n ;(state as Record<string, unknown>)[name] = value\n // Clear that field's errors as it changes, as one expects.\n if (errors[name]) {\n delete errors[name]\n }\n },\n getField(name) {\n return (state as Record<string, unknown>)[name]\n },\n setError(name, messages) {\n if (messages === null || messages.length === 0) {\n delete errors[name]\n } else {\n errors[name] = messages\n }\n },\n setErrors(next) {\n for (const key of Object.keys(errors)) delete errors[key]\n Object.assign(errors, next)\n },\n clearErrors() {\n for (const key of Object.keys(errors)) delete errors[key]\n },\n }\n\n provide(FormStateKey, ctx)\n return ctx\n}\n\n/**\n * Returns the form context. It throws when called outside a\n * `provideFormState()`.\n */\nexport function useFormState(): FormStateContext {\n const ctx = inject(FormStateKey)\n if (!ctx) {\n throw new Error('useFormState() called outside of provideFormState() scope')\n }\n return ctx\n}\n\n/** The optional form: null when there is none. */\nexport function tryUseFormState(): FormStateContext | null {\n return inject(FormStateKey, null)\n}\n\n/**\n * Provides a form context scoped to one object-valued field of `parent` — the\n * backend's Field\\Group, whose state is `{city: ..., street: ...}` under its\n * own name.\n *\n * Unlike NestedFieldsGroup this keeps no copy: every read and write goes to\n * `parent.state[name]`, and the errors are the parent's `name.child` keys —\n * the shape Laravel's validator reports them in — seen without the prefix.\n * Scopes nest: a group inside a group prefixes twice.\n */\nexport function provideScopedFormState(parent: FormStateContext, name: string): FormStateContext {\n const prefix = `${name}.`\n const obj = (): Record<string, unknown> => {\n const v = parent.getField(name)\n return v !== null && typeof v === 'object' && !Array.isArray(v) ? (v as Record<string, unknown>) : {}\n }\n const ownKeys = (): string[] =>\n Object.keys(parent.errors)\n .filter((k) => k.startsWith(prefix))\n .map((k) => k.slice(prefix.length))\n\n // A live view over the parent's errors: reads go through the parent's\n // reactive map, so a component reading `errors.city` re-renders when\n // `errors['address.city']` changes.\n const errors = new Proxy({} as Record<string, string[]>, {\n get: (_t, key) => (typeof key === 'string' ? parent.errors[prefix + key] : undefined),\n has: (_t, key) => typeof key === 'string' && prefix + key in parent.errors,\n ownKeys: () => ownKeys(),\n getOwnPropertyDescriptor: (_t, key) =>\n typeof key === 'string' && prefix + key in parent.errors\n ? { enumerable: true, configurable: true, value: parent.errors[prefix + key] }\n : undefined,\n })\n\n const ctx: FormStateContext = {\n get state() {\n return obj()\n },\n errors,\n mode: parent.mode,\n setField(key, value) {\n parent.setField(name, { ...obj(), [key]: value })\n parent.setError(prefix + key, null)\n },\n getField(key) {\n return obj()[key]\n },\n setError(key, messages) {\n parent.setError(prefix + key, messages)\n },\n setErrors(next) {\n for (const key of ownKeys()) parent.setError(prefix + key, null)\n for (const [key, messages] of Object.entries(next)) parent.setError(prefix + key, messages)\n },\n clearErrors() {\n for (const key of ownKeys()) parent.setError(prefix + key, null)\n },\n }\n\n provide(FormStateKey, ctx)\n return ctx\n}\n"],"names":["FormStateKey","provideFormState","initial","initialErrors","mode","state","reactive","errors","ctx","name","value","messages","next","key","provide","useFormState","inject","tryUseFormState","provideScopedFormState","parent","prefix","obj","v","ownKeys","k","_t"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formState-
|
|
1
|
+
{"version":3,"file":"formState-diR_mnaG.js","sources":["../resources/ts/components/render/formState.ts"],"sourcesContent":["/**\n * The form-state composable: it exposes the state and the errors through\n * provide/inject.\n *\n * The container — a resource form, a settings page — calls\n * `provideFormState()`, and the field components in the tree call\n * `useFormState()` to read a value and change a field.\n *\n * The state is a reactive proxy that setField mutates by key; the errors are a\n * separate reactive map of field name → string[] messages.\n */\n\nimport { inject, provide, reactive, type InjectionKey } from 'vue'\n\nexport interface FormStateContext {\n state: Record<string, unknown>\n errors: Record<string, string[]>\n /** The form's context: FieldRenderer hides the fields with visibility[mode]=false. */\n mode?: 'create' | 'update' | 'view'\n setField: (name: string, value: unknown) => void\n getField: (name: string) => unknown\n setError: (name: string, messages: string[] | null) => void\n setErrors: (next: Record<string, string[]>) => void\n clearErrors: () => void\n}\n\nconst FormStateKey: InjectionKey<FormStateContext> = Symbol('admin.form-state')\n\n/**\n * Creates the form context and provides it to the descendants.\n *\n * The `initial` object given is wrapped into `reactive()`, so the mutations are\n * visible from outside too: the caller owns the state and may read it after a\n * submit.\n *\n * @param initial The state's initial values.\n * @param initialErrors The initial errors, for a re-render after a\n * ValidationError.\n */\nexport function provideFormState(\n initial: Record<string, unknown> = {},\n initialErrors: Record<string, string[]> = {},\n mode?: 'create' | 'update' | 'view',\n): FormStateContext {\n const state = reactive(initial)\n const errors = reactive<Record<string, string[]>>({ ...initialErrors })\n\n const ctx: FormStateContext = {\n state,\n errors,\n mode,\n setField(name, value) {\n ;(state as Record<string, unknown>)[name] = value\n // Clear that field's errors as it changes, as one expects.\n if (errors[name]) {\n delete errors[name]\n }\n },\n getField(name) {\n return (state as Record<string, unknown>)[name]\n },\n setError(name, messages) {\n if (messages === null || messages.length === 0) {\n delete errors[name]\n } else {\n errors[name] = messages\n }\n },\n setErrors(next) {\n for (const key of Object.keys(errors)) delete errors[key]\n Object.assign(errors, next)\n },\n clearErrors() {\n for (const key of Object.keys(errors)) delete errors[key]\n },\n }\n\n provide(FormStateKey, ctx)\n return ctx\n}\n\n/**\n * Returns the form context. It throws when called outside a\n * `provideFormState()`.\n */\nexport function useFormState(): FormStateContext {\n const ctx = inject(FormStateKey)\n if (!ctx) {\n throw new Error('useFormState() called outside of provideFormState() scope')\n }\n return ctx\n}\n\n/** The optional form: null when there is none. */\nexport function tryUseFormState(): FormStateContext | null {\n return inject(FormStateKey, null)\n}\n\n/**\n * Provides a form context scoped to one object-valued field of `parent` — the\n * backend's Field\\Group, whose state is `{city: ..., street: ...}` under its\n * own name.\n *\n * Unlike NestedFieldsGroup this keeps no copy: every read and write goes to\n * `parent.state[name]`, and the errors are the parent's `name.child` keys —\n * the shape Laravel's validator reports them in — seen without the prefix.\n * Scopes nest: a group inside a group prefixes twice.\n */\nexport function provideScopedFormState(parent: FormStateContext, name: string): FormStateContext {\n const prefix = `${name}.`\n const obj = (): Record<string, unknown> => {\n const v = parent.getField(name)\n return v !== null && typeof v === 'object' && !Array.isArray(v) ? (v as Record<string, unknown>) : {}\n }\n const ownKeys = (): string[] =>\n Object.keys(parent.errors)\n .filter((k) => k.startsWith(prefix))\n .map((k) => k.slice(prefix.length))\n\n // A live view over the parent's errors: reads go through the parent's\n // reactive map, so a component reading `errors.city` re-renders when\n // `errors['address.city']` changes.\n const errors = new Proxy({} as Record<string, string[]>, {\n get: (_t, key) => (typeof key === 'string' ? parent.errors[prefix + key] : undefined),\n has: (_t, key) => typeof key === 'string' && prefix + key in parent.errors,\n ownKeys: () => ownKeys(),\n getOwnPropertyDescriptor: (_t, key) =>\n typeof key === 'string' && prefix + key in parent.errors\n ? { enumerable: true, configurable: true, value: parent.errors[prefix + key] }\n : undefined,\n })\n\n const ctx: FormStateContext = {\n get state() {\n return obj()\n },\n errors,\n mode: parent.mode,\n setField(key, value) {\n parent.setField(name, { ...obj(), [key]: value })\n parent.setError(prefix + key, null)\n },\n getField(key) {\n return obj()[key]\n },\n setError(key, messages) {\n parent.setError(prefix + key, messages)\n },\n setErrors(next) {\n for (const key of ownKeys()) parent.setError(prefix + key, null)\n for (const [key, messages] of Object.entries(next)) parent.setError(prefix + key, messages)\n },\n clearErrors() {\n for (const key of ownKeys()) parent.setError(prefix + key, null)\n },\n }\n\n provide(FormStateKey, ctx)\n return ctx\n}\n"],"names":["FormStateKey","provideFormState","initial","initialErrors","mode","state","reactive","errors","ctx","name","value","messages","next","key","provide","useFormState","inject","tryUseFormState","provideScopedFormState","parent","prefix","obj","v","ownKeys","k","_t"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n-
|
|
1
|
+
{"version":3,"file":"i18n-CF2S5XHW.js","sources":["../resources/ts/stores/i18n.ts"],"sourcesContent":["/**\n * The i18n store — a plain message bag plus the t() helper.\n *\n * The backend puts the bag into `bootstrap.translations`, a\n * Record<key, string>. When the locale changes (`/system/setLocale`) either\n * the bootstrap is raised again or the helper calls `loadLocale(locale)`,\n * which POSTs for the messages.\n *\n * The form:\n * t('admin.dashboard.add_widget') // 'Add widget'\n * t('admin.records.count', { n: 42 }) // 'Records: 42', interpolating :n\n *\n * The fallback: a key that is not found is returned as it is, which makes\n * missing translations easy to spot during development.\n */\nimport { defineStore } from 'pinia'\nimport { computed, ref } from 'vue'\nimport type { AdminBootstrap } from '../types/bootstrap'\n\n/**\n * A standalone wrapper around store.tr() for the components: it does not fall\n * over without an active Pinia (unit tests, SSR edges) and returns the source\n * string instead.\n */\nexport function trSafe(text: string): string {\n try {\n return useI18nStore().tr(text)\n } catch {\n return text\n }\n}\n\n/**\n * The panel's current language, for formatting — month names, numbers: the\n * document's lang, else the bootstrap locale, else Russian, the source\n * language.\n */\nexport function currentLocale(): string {\n // The locale store keeps <html lang> in step with a switch made in place.\n if (typeof document !== 'undefined' && document.documentElement.lang) {\n return document.documentElement.lang\n }\n try {\n const locale = useI18nStore().locale\n if (locale) return locale\n } catch {\n // no active Pinia\n }\n return 'ru'\n}\n\n/**\n * A panel locale as a tag Intl accepts: Laravel's `pt_BR` becomes `pt-BR`,\n * and a tag Intl does not know falls back to English.\n */\nexport function intlLocale(locale: string): string {\n const tag = locale.replace(/_/g, '-')\n try {\n return Intl.NumberFormat.supportedLocalesOf([tag]).length > 0 ? tag : 'en'\n } catch {\n return 'en'\n }\n}\n\n/** The locale given to Intl: the panel's own; see intlLocale(). */\nexport function formatLocale(): string {\n return intlLocale(currentLocale())\n}\n\nconst numberFormats = new Map<string, Intl.NumberFormat>()\n\n/**\n * A number formatter in the panel's locale — decimal and group separators,\n * currencies — cached per locale and options. Never the browser's locale:\n * an English panel in a Russian browser shows English numbers.\n */\nexport function numberFormat(options: Intl.NumberFormatOptions = {}): Intl.NumberFormat {\n const locale = formatLocale()\n const key = `${locale}|${JSON.stringify(options)}`\n let format = numberFormats.get(key)\n if (!format) {\n format = new Intl.NumberFormat(locale, options)\n numberFormats.set(key, format)\n }\n return format\n}\n\n/** Formats a number in the panel's locale; see numberFormat(). */\nexport function formatNumber(value: number, options: Intl.NumberFormatOptions = {}): string {\n return numberFormat(options).format(value)\n}\n\n/** Formats a date in the panel's locale. */\nexport function formatDate(value: Date | string, options: Intl.DateTimeFormatOptions = {}): string {\n const date = typeof value === 'string' ? new Date(value) : value\n if (Number.isNaN(date.getTime())) return ''\n return date.toLocaleString(formatLocale(), options)\n}\n\nexport const useI18nStore = defineStore('admin-i18n', () => {\n const messages = ref<Record<string, string>>({})\n const locale = ref<string>('ru')\n\n function hydrate(bootstrap: AdminBootstrap): void {\n // The backend may put the translations into the bootstrap.\n const t = (bootstrap as unknown as { translations?: Record<string, string> }).translations\n if (t && typeof t === 'object') {\n messages.value = { ...t }\n }\n locale.value = bootstrap.locale ?? 'ru'\n }\n\n function setMessages(next: Record<string, string>): void {\n messages.value = { ...next }\n }\n\n /**\n * Translates, supporting Laravel-style `:name` interpolation. A missing key\n * is returned as it is, which makes the gap visible.\n */\n function t(key: string, replace: Record<string, string | number> = {}): string {\n let str = messages.value[key] ?? key\n for (const [k, v] of Object.entries(replace)) {\n str = str.replace(new RegExp(`:${k}`, 'g'), String(v))\n }\n return str\n }\n\n const has = (key: string): boolean => key in messages.value\n\n /**\n * Translates by a string key, JSON-style, where the key is the source string\n * in the development language. The backend mixes the current locale's JSON\n * translations — the host's lang/{locale}.json — into the bag. Without a\n * translation the string comes back untouched, with no interpolation.\n */\n function tr(text: string): string {\n return messages.value[text] ?? text\n }\n\n return {\n messages,\n locale,\n hydrate,\n setMessages,\n t,\n tr,\n has,\n keys: computed(() => Object.keys(messages.value)),\n }\n})\n\n/**\n * A convenience: the global t() for non-Vue contexts — utilities, services. In\n * a Vue component prefer `const { t } = useI18nStore()`.\n */\nexport function tRaw(key: string, replace?: Record<string, string | number>): string {\n try {\n return useI18nStore().t(key, replace ?? {})\n } catch {\n // Without an active Pinia — unit tests, a render before the\n // initialization — we return the source string with the values\n // substituted. This used to throw and take the whole component down: an\n // untranslated string beats an empty page.\n let str = key\n for (const [k, v] of Object.entries(replace ?? {})) {\n str = str.replace(new RegExp(`:${k}`, 'g'), String(v))\n }\n\n return str\n }\n}\n"],"names":["trSafe","text","useI18nStore","currentLocale","locale","intlLocale","tag","formatLocale","numberFormats","numberFormat","options","key","format","formatNumber","value","defineStore","messages","ref","hydrate","bootstrap","t","setMessages","next","replace","str","k","v","has","tr","computed","tRaw"],"mappings":";;AAwBO,SAASA,EAAOC,GAAsB;AAC3C,MAAI;AACF,WAAOC,EAAA,EAAe,GAAGD,CAAI;AAAA,EAC/B,QAAQ;AACN,WAAOA;AAAA,EACT;AACF;AAOO,SAASE,IAAwB;AAEtC,MAAI,OAAO,WAAa,OAAe,SAAS,gBAAgB;AAC9D,WAAO,SAAS,gBAAgB;AAElC,MAAI;AACF,UAAMC,IAASF,IAAe;AAC9B,QAAIE,EAAQ,QAAOA;AAAA,EACrB,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAMO,SAASC,EAAWD,GAAwB;AACjD,QAAME,IAAMF,EAAO,QAAQ,MAAM,GAAG;AACpC,MAAI;AACF,WAAO,KAAK,aAAa,mBAAmB,CAACE,CAAG,CAAC,EAAE,SAAS,IAAIA,IAAM;AAAA,EACxE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAASC,IAAuB;AACrC,SAAOF,EAAWF,GAAe;AACnC;AAEA,MAAMK,wBAAoB,IAAA;AAOnB,SAASC,EAAaC,IAAoC,IAAuB;AACtF,QAAMN,IAASG,EAAA,GACTI,IAAM,GAAGP,CAAM,IAAI,KAAK,UAAUM,CAAO,CAAC;AAChD,MAAIE,IAASJ,EAAc,IAAIG,CAAG;AAClC,SAAKC,MACHA,IAAS,IAAI,KAAK,aAAaR,GAAQM,CAAO,GAC9CF,EAAc,IAAIG,GAAKC,CAAM,IAExBA;AACT;AAGO,SAASC,EAAaC,GAAeJ,IAAoC,IAAY;AAC1F,SAAOD,EAAaC,CAAO,EAAE,OAAOI,CAAK;AAC3C;AASO,MAAMZ,IAAea,EAAY,cAAc,MAAM;AAC1D,QAAMC,IAAWC,EAA4B,EAAE,GACzCb,IAASa,EAAY,IAAI;AAE/B,WAASC,EAAQC,GAAiC;AAEhD,UAAMC,IAAKD,EAAmE;AAC9E,IAAIC,KAAK,OAAOA,KAAM,aACpBJ,EAAS,QAAQ,EAAE,GAAGI,EAAAA,IAExBhB,EAAO,QAAQe,EAAU,UAAU;AAAA,EACrC;AAEA,WAASE,EAAYC,GAAoC;AACvD,IAAAN,EAAS,QAAQ,EAAE,GAAGM,EAAA;AAAA,EACxB;AAMA,WAASF,EAAET,GAAaY,IAA2C,IAAY;AAC7E,QAAIC,IAAMR,EAAS,MAAML,CAAG,KAAKA;AACjC,eAAW,CAACc,GAAGC,CAAC,KAAK,OAAO,QAAQH,CAAO;AACzC,MAAAC,IAAMA,EAAI,QAAQ,IAAI,OAAO,IAAIC,CAAC,IAAI,GAAG,GAAG,OAAOC,CAAC,CAAC;AAEvD,WAAOF;AAAA,EACT;AAEA,QAAMG,IAAM,CAAChB,MAAyBA,KAAOK,EAAS;AAQtD,WAASY,EAAG3B,GAAsB;AAChC,WAAOe,EAAS,MAAMf,CAAI,KAAKA;AAAA,EACjC;AAEA,SAAO;AAAA,IACL,UAAAe;AAAA,IACA,QAAAZ;AAAA,IACA,SAAAc;AAAA,IACA,aAAAG;AAAA,IACA,GAAAD;AAAA,IACA,IAAAQ;AAAA,IACA,KAAAD;AAAA,IACA,MAAME,EAAS,MAAM,OAAO,KAAKb,EAAS,KAAK,CAAC;AAAA,EAAA;AAEpD,CAAC;AAMM,SAASc,EAAKnB,GAAaY,GAAmD;AACnF,MAAI;AACF,WAAOrB,IAAe,EAAES,GAAKY,KAAW,CAAA,CAAE;AAAA,EAC5C,QAAQ;AAKN,QAAIC,IAAMb;AACV,eAAW,CAACc,GAAGC,CAAC,KAAK,OAAO,QAAQH,KAAW,CAAA,CAAE;AAC/C,MAAAC,IAAMA,EAAI,QAAQ,IAAI,OAAO,IAAIC,CAAC,IAAI,GAAG,GAAG,OAAOC,CAAC,CAAC;AAGvD,WAAOF;AAAA,EACT;AACF;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use strict";const y=require("pinia"),s=require("vue");function S(e){try{return u().tr(e)}catch{return e}}function i(){if(typeof document<"u"&&document.documentElement.lang)return document.documentElement.lang;try{const e=u().locale;if(e)return e}catch{}return"ru"}function m(e){const t=e.replace(/_/g,"-");try{return Intl.NumberFormat.supportedLocalesOf([t]).length>0?t:"en"}catch{return"en"}}function g(){return m(i())}const f=new Map;function h(e={}){const t=g(),r=`${t}|${JSON.stringify(e)}`;let o=f.get(r);return o||(o=new Intl.NumberFormat(t,e),f.set(r,o)),o}function L(e,t={}){return h(t).format(e)}const u=y.defineStore("admin-i18n",()=>{const e=s.ref({}),t=s.ref("ru");function r(n){const c=n.translations;c&&typeof c=="object"&&(e.value={...c}),t.value=n.locale??"ru"}function o(n){e.value={...n}}function a(n,c={}){let l=e.value[n]??n;for(const[b,p]of Object.entries(c))l=l.replace(new RegExp(`:${b}`,"g"),String(p));return l}const d=n=>n in e.value;function v(n){return e.value[n]??n}return{messages:e,locale:t,hydrate:r,setMessages:o,t:a,tr:v,has:d,keys:s.computed(()=>Object.keys(e.value))}});function w(e,t){try{return u().t(e,t??{})}catch{let r=e;for(const[o,a]of Object.entries(t??{}))r=r.replace(new RegExp(`:${o}`,"g"),String(a));return r}}exports.currentLocale=i;exports.formatLocale=g;exports.formatNumber=L;exports.intlLocale=m;exports.tRaw=w;exports.trSafe=S;exports.useI18nStore=u;
|
|
2
|
-
//# sourceMappingURL=i18n-
|
|
2
|
+
//# sourceMappingURL=i18n-DW_VQZeY.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n-
|
|
1
|
+
{"version":3,"file":"i18n-DW_VQZeY.cjs","sources":["../resources/ts/stores/i18n.ts"],"sourcesContent":["/**\n * The i18n store — a plain message bag plus the t() helper.\n *\n * The backend puts the bag into `bootstrap.translations`, a\n * Record<key, string>. When the locale changes (`/system/setLocale`) either\n * the bootstrap is raised again or the helper calls `loadLocale(locale)`,\n * which POSTs for the messages.\n *\n * The form:\n * t('admin.dashboard.add_widget') // 'Add widget'\n * t('admin.records.count', { n: 42 }) // 'Records: 42', interpolating :n\n *\n * The fallback: a key that is not found is returned as it is, which makes\n * missing translations easy to spot during development.\n */\nimport { defineStore } from 'pinia'\nimport { computed, ref } from 'vue'\nimport type { AdminBootstrap } from '../types/bootstrap'\n\n/**\n * A standalone wrapper around store.tr() for the components: it does not fall\n * over without an active Pinia (unit tests, SSR edges) and returns the source\n * string instead.\n */\nexport function trSafe(text: string): string {\n try {\n return useI18nStore().tr(text)\n } catch {\n return text\n }\n}\n\n/**\n * The panel's current language, for formatting — month names, numbers: the\n * document's lang, else the bootstrap locale, else Russian, the source\n * language.\n */\nexport function currentLocale(): string {\n // The locale store keeps <html lang> in step with a switch made in place.\n if (typeof document !== 'undefined' && document.documentElement.lang) {\n return document.documentElement.lang\n }\n try {\n const locale = useI18nStore().locale\n if (locale) return locale\n } catch {\n // no active Pinia\n }\n return 'ru'\n}\n\n/**\n * A panel locale as a tag Intl accepts: Laravel's `pt_BR` becomes `pt-BR`,\n * and a tag Intl does not know falls back to English.\n */\nexport function intlLocale(locale: string): string {\n const tag = locale.replace(/_/g, '-')\n try {\n return Intl.NumberFormat.supportedLocalesOf([tag]).length > 0 ? tag : 'en'\n } catch {\n return 'en'\n }\n}\n\n/** The locale given to Intl: the panel's own; see intlLocale(). */\nexport function formatLocale(): string {\n return intlLocale(currentLocale())\n}\n\nconst numberFormats = new Map<string, Intl.NumberFormat>()\n\n/**\n * A number formatter in the panel's locale — decimal and group separators,\n * currencies — cached per locale and options. Never the browser's locale:\n * an English panel in a Russian browser shows English numbers.\n */\nexport function numberFormat(options: Intl.NumberFormatOptions = {}): Intl.NumberFormat {\n const locale = formatLocale()\n const key = `${locale}|${JSON.stringify(options)}`\n let format = numberFormats.get(key)\n if (!format) {\n format = new Intl.NumberFormat(locale, options)\n numberFormats.set(key, format)\n }\n return format\n}\n\n/** Formats a number in the panel's locale; see numberFormat(). */\nexport function formatNumber(value: number, options: Intl.NumberFormatOptions = {}): string {\n return numberFormat(options).format(value)\n}\n\n/** Formats a date in the panel's locale. */\nexport function formatDate(value: Date | string, options: Intl.DateTimeFormatOptions = {}): string {\n const date = typeof value === 'string' ? new Date(value) : value\n if (Number.isNaN(date.getTime())) return ''\n return date.toLocaleString(formatLocale(), options)\n}\n\nexport const useI18nStore = defineStore('admin-i18n', () => {\n const messages = ref<Record<string, string>>({})\n const locale = ref<string>('ru')\n\n function hydrate(bootstrap: AdminBootstrap): void {\n // The backend may put the translations into the bootstrap.\n const t = (bootstrap as unknown as { translations?: Record<string, string> }).translations\n if (t && typeof t === 'object') {\n messages.value = { ...t }\n }\n locale.value = bootstrap.locale ?? 'ru'\n }\n\n function setMessages(next: Record<string, string>): void {\n messages.value = { ...next }\n }\n\n /**\n * Translates, supporting Laravel-style `:name` interpolation. A missing key\n * is returned as it is, which makes the gap visible.\n */\n function t(key: string, replace: Record<string, string | number> = {}): string {\n let str = messages.value[key] ?? key\n for (const [k, v] of Object.entries(replace)) {\n str = str.replace(new RegExp(`:${k}`, 'g'), String(v))\n }\n return str\n }\n\n const has = (key: string): boolean => key in messages.value\n\n /**\n * Translates by a string key, JSON-style, where the key is the source string\n * in the development language. The backend mixes the current locale's JSON\n * translations — the host's lang/{locale}.json — into the bag. Without a\n * translation the string comes back untouched, with no interpolation.\n */\n function tr(text: string): string {\n return messages.value[text] ?? text\n }\n\n return {\n messages,\n locale,\n hydrate,\n setMessages,\n t,\n tr,\n has,\n keys: computed(() => Object.keys(messages.value)),\n }\n})\n\n/**\n * A convenience: the global t() for non-Vue contexts — utilities, services. In\n * a Vue component prefer `const { t } = useI18nStore()`.\n */\nexport function tRaw(key: string, replace?: Record<string, string | number>): string {\n try {\n return useI18nStore().t(key, replace ?? {})\n } catch {\n // Without an active Pinia — unit tests, a render before the\n // initialization — we return the source string with the values\n // substituted. This used to throw and take the whole component down: an\n // untranslated string beats an empty page.\n let str = key\n for (const [k, v] of Object.entries(replace ?? {})) {\n str = str.replace(new RegExp(`:${k}`, 'g'), String(v))\n }\n\n return str\n }\n}\n"],"names":["trSafe","text","useI18nStore","currentLocale","locale","intlLocale","tag","formatLocale","numberFormats","numberFormat","options","key","format","formatNumber","value","defineStore","messages","ref","hydrate","bootstrap","t","setMessages","next","replace","str","k","v","has","tr","computed","tRaw"],"mappings":"uDAwBO,SAASA,EAAOC,EAAsB,CAC3C,GAAI,CACF,OAAOC,EAAA,EAAe,GAAGD,CAAI,CAC/B,MAAQ,CACN,OAAOA,CACT,CACF,CAOO,SAASE,GAAwB,CAEtC,GAAI,OAAO,SAAa,KAAe,SAAS,gBAAgB,KAC9D,OAAO,SAAS,gBAAgB,KAElC,GAAI,CACF,MAAMC,EAASF,IAAe,OAC9B,GAAIE,EAAQ,OAAOA,CACrB,MAAQ,CAER,CACA,MAAO,IACT,CAMO,SAASC,EAAWD,EAAwB,CACjD,MAAME,EAAMF,EAAO,QAAQ,KAAM,GAAG,EACpC,GAAI,CACF,OAAO,KAAK,aAAa,mBAAmB,CAACE,CAAG,CAAC,EAAE,OAAS,EAAIA,EAAM,IACxE,MAAQ,CACN,MAAO,IACT,CACF,CAGO,SAASC,GAAuB,CACrC,OAAOF,EAAWF,GAAe,CACnC,CAEA,MAAMK,MAAoB,IAOnB,SAASC,EAAaC,EAAoC,GAAuB,CACtF,MAAMN,EAASG,EAAA,EACTI,EAAM,GAAGP,CAAM,IAAI,KAAK,UAAUM,CAAO,CAAC,GAChD,IAAIE,EAASJ,EAAc,IAAIG,CAAG,EAClC,OAAKC,IACHA,EAAS,IAAI,KAAK,aAAaR,EAAQM,CAAO,EAC9CF,EAAc,IAAIG,EAAKC,CAAM,GAExBA,CACT,CAGO,SAASC,EAAaC,EAAeJ,EAAoC,GAAY,CAC1F,OAAOD,EAAaC,CAAO,EAAE,OAAOI,CAAK,CAC3C,CASO,MAAMZ,EAAea,EAAAA,YAAY,aAAc,IAAM,CAC1D,MAAMC,EAAWC,EAAAA,IAA4B,EAAE,EACzCb,EAASa,EAAAA,IAAY,IAAI,EAE/B,SAASC,EAAQC,EAAiC,CAEhD,MAAMC,EAAKD,EAAmE,aAC1EC,GAAK,OAAOA,GAAM,WACpBJ,EAAS,MAAQ,CAAE,GAAGI,CAAAA,GAExBhB,EAAO,MAAQe,EAAU,QAAU,IACrC,CAEA,SAASE,EAAYC,EAAoC,CACvDN,EAAS,MAAQ,CAAE,GAAGM,CAAA,CACxB,CAMA,SAASF,EAAET,EAAaY,EAA2C,GAAY,CAC7E,IAAIC,EAAMR,EAAS,MAAML,CAAG,GAAKA,EACjC,SAAW,CAACc,EAAGC,CAAC,IAAK,OAAO,QAAQH,CAAO,EACzCC,EAAMA,EAAI,QAAQ,IAAI,OAAO,IAAIC,CAAC,GAAI,GAAG,EAAG,OAAOC,CAAC,CAAC,EAEvD,OAAOF,CACT,CAEA,MAAMG,EAAOhB,GAAyBA,KAAOK,EAAS,MAQtD,SAASY,EAAG3B,EAAsB,CAChC,OAAOe,EAAS,MAAMf,CAAI,GAAKA,CACjC,CAEA,MAAO,CACL,SAAAe,EACA,OAAAZ,EACA,QAAAc,EACA,YAAAG,EACA,EAAAD,EACA,GAAAQ,EACA,IAAAD,EACA,KAAME,EAAAA,SAAS,IAAM,OAAO,KAAKb,EAAS,KAAK,CAAC,CAAA,CAEpD,CAAC,EAMM,SAASc,EAAKnB,EAAaY,EAAmD,CACnF,GAAI,CACF,OAAOrB,IAAe,EAAES,EAAKY,GAAW,CAAA,CAAE,CAC5C,MAAQ,CAKN,IAAIC,EAAMb,EACV,SAAW,CAACc,EAAGC,CAAC,IAAK,OAAO,QAAQH,GAAW,CAAA,CAAE,EAC/CC,EAAMA,EAAI,QAAQ,IAAI,OAAO,IAAIC,CAAC,GAAI,GAAG,EAAG,OAAOC,CAAC,CAAC,EAGvD,OAAOF,CACT,CACF"}
|