@dskripchenko/laravel-admin 1.1.23 → 1.2.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.
Files changed (56) hide show
  1. package/dist/components/auth/ForgotPasswordPage.vue.d.ts +9 -0
  2. package/dist/components/auth/LoginPage.vue.d.ts +7 -3
  3. package/dist/components/auth/ResetPasswordPage.vue.d.ts +7 -0
  4. package/dist/components/dashboard/AddWidgetDialog.vue.d.ts +12 -0
  5. package/dist/components/dashboard/BarChartWidget.vue.d.ts +1 -1
  6. package/dist/components/dashboard/ChartWidget.vue.d.ts +18 -0
  7. package/dist/components/dashboard/DashboardPage.vue.d.ts +8 -6
  8. package/dist/components/dashboard/GaugeWidget.vue.d.ts +1 -1
  9. package/dist/components/dashboard/WidgetActionsOverlay.vue.d.ts +8 -0
  10. package/dist/components/dashboard/WidgetConfigDialog.vue.d.ts +24 -0
  11. package/dist/components/dashboard/builtin.d.ts +5 -0
  12. package/dist/components/fields/DateField.vue.d.ts +2 -2
  13. package/dist/components/fields/NumberField.vue.d.ts +3 -3
  14. package/dist/components/fields/SelectField.vue.d.ts +1 -1
  15. package/dist/components/fields/TagsField.vue.d.ts +38 -0
  16. package/dist/components/fields/TextAreaField.vue.d.ts +1 -1
  17. package/dist/components/fields/TextField.vue.d.ts +1 -1
  18. package/dist/components/fields/TranslatableField.vue.d.ts +24 -0
  19. package/dist/components/fields/wysiwyg/quill/QuillField.vue.d.ts +4 -5
  20. package/dist/components/infolist/BadgeEntry.vue.d.ts +1 -1
  21. package/dist/components/infolist/TextEntry.vue.d.ts +6 -1
  22. package/dist/components/profile/ApiTokensManager.vue.d.ts +2 -0
  23. package/dist/components/profile/TwoFactorSetup.vue.d.ts +24 -0
  24. package/dist/components/resource/AdminFilterToolbar.vue.d.ts +42 -0
  25. package/dist/components/resource/AuditTimeline.vue.d.ts +12 -0
  26. package/dist/components/resource/FilterEditor.d.ts +58 -0
  27. package/dist/components/resource/InlineEditCell.vue.d.ts +26 -0
  28. package/dist/components/resource/ResourceFormPage.vue.d.ts +6 -3
  29. package/dist/components/resource/ResourceIndexPage.vue.d.ts +10 -4
  30. package/dist/components/resource/ResourceViewPage.vue.d.ts +33 -4
  31. package/dist/components/shell/AdminShell.vue.d.ts +8 -2
  32. package/dist/components/shell/AdminSidebar.vue.d.ts +10 -4
  33. package/dist/components/shell/AdminTopBar.vue.d.ts +4 -4
  34. package/dist/components/shell/BrandLogo.vue.d.ts +16 -0
  35. package/dist/components/shell/NotificationsDrawer.vue.d.ts +2 -0
  36. package/dist/components/shell/iconRegistry.d.ts +18 -0
  37. package/dist/createAdminApp.d.ts +3 -0
  38. package/dist/index.cjs +3 -1
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.mjs +6200 -2499
  41. package/dist/index.mjs.map +1 -1
  42. package/dist/quill.cjs +1 -1
  43. package/dist/quill.cjs.map +1 -1
  44. package/dist/quill.mjs +21 -33
  45. package/dist/quill.mjs.map +1 -1
  46. package/dist/router/index.d.ts +4 -0
  47. package/dist/stores/dashboard.d.ts +212 -0
  48. package/dist/stores/i18n.d.ts +31 -0
  49. package/dist/stores/manifest.d.ts +111 -11
  50. package/dist/stores/navigation.d.ts +1 -1
  51. package/dist/stores/notifications.d.ts +14 -2
  52. package/dist/stores/resourceForm.d.ts +3 -3
  53. package/dist/stores/resourceIndex.d.ts +1 -1
  54. package/dist/stores/toast.d.ts +16 -0
  55. package/dist/style.css +1 -1
  56. package/package.json +1 -1
package/dist/quill.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),c=require("./formState-GlJBphEn.cjs"),u={key:0,class:"admin-field__label"},s={key:0,class:"admin-field__required","aria-hidden":"true"},m={class:"admin-field__control"},f={key:1,class:"admin-field__error"},h={key:2,class:"admin-field__help"},p=e.defineComponent({__name:"QuillField",props:{name:{},label:{default:null},help:{default:null},required:{type:Boolean,default:!1},placeholder:{default:null},toolbar:{default:"full"},theme:{default:"snow"},disabled:{type:Boolean,default:!1}},setup(l){const t=l,o=c.useFormState(),d=e.computed(()=>o.getField(t.name)??""),a=e.computed(()=>o.errors[t.name]?.[0]);function r(n){o.setField(t.name,n)}const i=e.defineComponent({props:{content:String,toolbar:[String,Array],theme:String,placeholder:String,readOnly:Boolean},setup(){return()=>e.h("div",{class:"quill-fallback"},"@vueup/vue-quill не загружен — host передаёт actual Editor через peer-dep")}});return(n,b)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["admin-field",{"admin-field--invalid":a.value!==void 0}])},[l.label?(e.openBlock(),e.createElementBlock("label",u,[e.createElementVNode("span",null,e.toDisplayString(l.label),1),l.required?(e.openBlock(),e.createElementBlock("span",s,"*")):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0),e.createElementVNode("div",m,[e.createVNode(e.unref(i),{content:d.value,toolbar:l.toolbar,theme:l.theme,placeholder:l.placeholder??void 0,"read-only":l.disabled,"onUpdate:content":r},null,8,["content","toolbar","theme","placeholder","read-only"])]),a.value?(e.openBlock(),e.createElementBlock("p",f,e.toDisplayString(a.value),1)):l.help?(e.openBlock(),e.createElementBlock("p",h,e.toDisplayString(l.help),1)):e.createCommentVNode("",!0)],2))}});exports.QuillField=p;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),r=require("@vueup/vue-quill"),c=require("./formState-GlJBphEn.cjs"),s={key:0,class:"admin-field__label"},u={key:0,class:"admin-field__required","aria-hidden":"true"},m={class:"admin-field__control admin-field__control--quill"},f={key:1,class:"admin-field__error"},h={key:2,class:"admin-field__help"},p=e.defineComponent({__name:"QuillField",props:{name:{},label:{default:null},help:{default:null},required:{type:Boolean,default:!1},placeholder:{default:null},toolbar:{default:"full"},theme:{default:"snow"},disabled:{type:Boolean,default:!1}},setup(l){const t=l,o=c.useFormState(),d=e.computed(()=>o.getField(t.name)??""),a=e.computed(()=>o.errors[t.name]?.[0]);function i(n){typeof n=="string"?o.setField(t.name,n):o.setField(t.name,JSON.stringify(n))}return(n,y)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["admin-field",{"admin-field--invalid":a.value!==void 0}])},[l.label?(e.openBlock(),e.createElementBlock("label",s,[e.createElementVNode("span",null,e.toDisplayString(l.label),1),l.required?(e.openBlock(),e.createElementBlock("span",u,"*")):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0),e.createElementVNode("div",m,[e.createVNode(e.unref(r.QuillEditor),{content:d.value,toolbar:l.toolbar,theme:l.theme,placeholder:l.placeholder??void 0,"read-only":l.disabled,"content-type":"html","onUpdate:content":i},null,8,["content","toolbar","theme","placeholder","read-only"])]),a.value?(e.openBlock(),e.createElementBlock("p",f,e.toDisplayString(a.value),1)):l.help?(e.openBlock(),e.createElementBlock("p",h,e.toDisplayString(l.help),1)):e.createCommentVNode("",!0)],2))}});exports.QuillField=p;
2
2
  //# sourceMappingURL=quill.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"quill.cjs","sources":["../resources/ts/components/fields/wysiwyg/quill/QuillField.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * QuillField — wrapper над @vueup/vue-quill для использования в\n * field-registry admin-renderer'а.\n *\n * Подключение в host-проекте:\n *\n * import { registerField } from '@dskripchenko/laravel-admin'\n * import { QuillField } from '@dskripchenko/laravel-admin/quill'\n * registerField('wysiwyg', QuillField)\n *\n * Для image upload'ов host регистрирует кастомный handler в Quill Toolbar\n * (наша обёртка предоставляет default — POST /api/admin/uploads).\n */\nimport { computed, h, defineComponent } from 'vue'\nimport { useFormState } from '../../../render/formState'\n\ninterface Props {\n name: string\n label?: string | null\n help?: string | null\n required?: boolean\n placeholder?: string | null\n /**\n * Quill toolbar config — string или array. См. https://quilljs.com/docs/modules/toolbar/.\n */\n toolbar?: string | unknown[]\n /**\n * Имя темы Quill ('snow' default | 'bubble' | 'core').\n */\n theme?: 'snow' | 'bubble' | 'core'\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n label: null,\n help: null,\n placeholder: null,\n required: false,\n toolbar: 'full',\n theme: 'snow',\n disabled: false,\n})\n\nconst form = useFormState()\nconst value = computed<string>(() => (form.getField(props.name) as string | undefined) ?? '')\nconst errorMsg = computed<string | undefined>(() => form.errors[props.name]?.[0])\n\nfunction onUpdate(next: string): void {\n form.setField(props.name, next)\n}\n\nconst Editor = defineComponent({\n props: {\n content: String,\n toolbar: [String, Array],\n theme: String,\n placeholder: String,\n readOnly: Boolean,\n },\n setup() {\n return () => h('div', {\n class: 'quill-fallback',\n }, '@vueup/vue-quill не загружен — host передаёт actual Editor через peer-dep')\n },\n})\n</script>\n\n<template>\n <div :class=\"['admin-field', { 'admin-field--invalid': errorMsg !== undefined }]\">\n <label v-if=\"label\" class=\"admin-field__label\">\n <span>{{ label }}</span>\n <span v-if=\"required\" class=\"admin-field__required\" aria-hidden=\"true\">*</span>\n </label>\n <div class=\"admin-field__control\">\n <Editor\n :content=\"value\"\n :toolbar=\"toolbar\"\n :theme=\"theme\"\n :placeholder=\"placeholder ?? undefined\"\n :read-only=\"disabled\"\n @update:content=\"onUpdate\"\n />\n </div>\n <p v-if=\"errorMsg\" class=\"admin-field__error\">{{ errorMsg }}</p>\n <p v-else-if=\"help\" class=\"admin-field__help\">{{ help }}</p>\n </div>\n</template>\n"],"names":["props","__props","form","useFormState","value","computed","errorMsg","onUpdate","next","Editor","defineComponent","h","_createElementBlock","_normalizeClass","_openBlock","_hoisted_1","_createElementVNode","_hoisted_2","_hoisted_3","_createVNode","_unref","_hoisted_4","_toDisplayString","_hoisted_5"],"mappings":"qlBAkCA,MAAMA,EAAQC,EAURC,EAAOC,EAAAA,aAAA,EACPC,EAAQC,EAAAA,SAAiB,IAAOH,EAAK,SAASF,EAAM,IAAI,GAA4B,EAAE,EACtFM,EAAWD,EAAAA,SAA6B,IAAMH,EAAK,OAAOF,EAAM,IAAI,IAAI,CAAC,CAAC,EAEhF,SAASO,EAASC,EAAoB,CACpCN,EAAK,SAASF,EAAM,KAAMQ,CAAI,CAChC,CAEA,MAAMC,EAASC,EAAAA,gBAAgB,CAC7B,MAAO,CACL,QAAS,OACT,QAAS,CAAC,OAAQ,KAAK,EACvB,MAAO,OACP,YAAa,OACb,SAAU,OAAA,EAEZ,OAAQ,CACN,MAAO,IAAMC,EAAAA,EAAE,MAAO,CACpB,MAAO,gBAAA,EACN,2EAA2E,CAChF,CAAA,CACD,8BAICC,EAAAA,mBAiBM,MAAA,CAjBA,MAAKC,EAAAA,eAAA,CAAA,cAAA,CAAA,uBAA4CP,EAAA,QAAa,OAAS,CAAA,CAAA,GAC9DL,EAAA,OAAba,EAAAA,UAAA,EAAAF,EAAAA,mBAGQ,QAHRG,EAGQ,CAFNC,EAAAA,mBAAwB,8BAAff,EAAA,KAAK,EAAA,CAAA,EACFA,EAAA,wBAAZW,qBAA+E,OAA/EK,EAAuE,GAAC,8DAE1ED,EAAAA,mBASM,MATNE,EASM,CARJC,cAOEC,EAAAA,MAAAX,CAAA,EAAA,CANC,QAASL,EAAA,MACT,QAASH,EAAA,QACT,MAAOA,EAAA,MACP,YAAaA,EAAA,aAAe,OAC5B,YAAWA,EAAA,SACX,mBAAgBM,CAAA,oEAGZD,EAAA,qBAATM,EAAAA,mBAAgE,IAAhES,EAAgEC,EAAAA,gBAAfhB,EAAA,KAAQ,EAAA,CAAA,GAC3CL,EAAA,oBAAdW,EAAAA,mBAA4D,IAA5DW,EAA4DD,EAAAA,gBAAXrB,EAAA,IAAI,EAAA,CAAA"}
1
+ {"version":3,"file":"quill.cjs","sources":["../resources/ts/components/fields/wysiwyg/quill/QuillField.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * QuillField — wrapper над @vueup/vue-quill для field-registry admin'а.\n *\n * Подключение в host-проекте (после createAdminApp):\n *\n * import { registerField } from '@dskripchenko/laravel-admin'\n * import { QuillField } from '@dskripchenko/laravel-admin/quill'\n * // peer-deps: `@vueup/vue-quill` + `quill` должны быть установлены\n * registerField('wysiwyg', QuillField)\n *\n * Если peer-dep не найден на этапе сборки vite — bundler упадёт с\n * \"Failed to resolve\". Это нормально: subpath /quill явно опциональный,\n * подключайте только если установили peer'ы.\n *\n * CSS темы импортируем здесь — побочный эффект подгружает стили в bundle.\n */\nimport { computed } from 'vue'\n// @ts-expect-error — optional peer-dep, типы доступны только когда host\n// установил `@vueup/vue-quill`. Vite-сборка core помечает пакет как external,\n// поэтому импорт остаётся в runtime и резолвится в host'е.\nimport { QuillEditor, type Delta } from '@vueup/vue-quill'\nimport { useFormState } from '../../../render/formState'\n\n/*\n * CSS-темы (snow/bubble) host подключает сам в своём entry — core их не\n * импортирует, иначе vite-сборка core упадёт на резолве путей в\n * node_modules (peer-dep optional, в core node_modules не установлен).\n *\n * // demo/resources/js/admin.js\n * import '@vueup/vue-quill/dist/vue-quill.snow.css'\n * import '@vueup/vue-quill/dist/vue-quill.bubble.css'\n */\n\ninterface Props {\n name: string\n label?: string | null\n help?: string | null\n required?: boolean\n placeholder?: string | null\n /**\n * Quill toolbar config. Принимает `'essential' | 'minimal' | 'full'`\n * либо raw-конфиг массивом групп.\n */\n toolbar?: string | unknown[]\n /** 'snow' (default toolbar) | 'bubble' (inline) | 'core' (без UI). */\n theme?: 'snow' | 'bubble' | 'core'\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n label: null,\n help: null,\n placeholder: null,\n required: false,\n toolbar: 'full',\n theme: 'snow',\n disabled: false,\n})\n\nconst form = useFormState()\nconst value = computed<string>(() => (form.getField(props.name) as string | undefined) ?? '')\nconst errorMsg = computed<string | undefined>(() => form.errors[props.name]?.[0])\n\nfunction onUpdate(next: string | Delta): void {\n // QuillEditor v-model:content по умолчанию отдаёт HTML строку (contentType\n // = 'html'). На всякий случай — поддерживаем и Delta-объект.\n if (typeof next === 'string') {\n form.setField(props.name, next)\n } else {\n form.setField(props.name, JSON.stringify(next))\n }\n}\n</script>\n\n<template>\n <div :class=\"['admin-field', { 'admin-field--invalid': errorMsg !== undefined }]\">\n <label v-if=\"label\" class=\"admin-field__label\">\n <span>{{ label }}</span>\n <span v-if=\"required\" class=\"admin-field__required\" aria-hidden=\"true\">*</span>\n </label>\n <div class=\"admin-field__control admin-field__control--quill\">\n <QuillEditor\n :content=\"value\"\n :toolbar=\"toolbar\"\n :theme=\"theme\"\n :placeholder=\"placeholder ?? undefined\"\n :read-only=\"disabled\"\n content-type=\"html\"\n @update:content=\"onUpdate\"\n />\n </div>\n <p v-if=\"errorMsg\" class=\"admin-field__error\">{{ errorMsg }}</p>\n <p v-else-if=\"help\" class=\"admin-field__help\">{{ help }}</p>\n </div>\n</template>\n\n<style>\n/* Quill принимает min-height через CSS — снимает дёрганье инициализации. */\n.admin-field__control--quill .ql-container {\n min-height: 200px;\n font-size: 14px;\n font-family: inherit;\n}\n.admin-field__control--quill .ql-toolbar.ql-snow,\n.admin-field__control--quill .ql-container.ql-snow {\n border-color: var(--uid-border-subtle);\n}\n.admin-field__control--quill .ql-toolbar.ql-snow {\n border-radius: var(--uid-radius-md) var(--uid-radius-md) 0 0;\n background: var(--uid-surface-base);\n}\n.admin-field__control--quill .ql-container.ql-snow {\n border-radius: 0 0 var(--uid-radius-md) var(--uid-radius-md);\n background: var(--uid-surface-raised);\n color: var(--uid-text-primary);\n}\n</style>\n"],"names":["props","__props","form","useFormState","value","computed","errorMsg","onUpdate","next","_createElementBlock","_normalizeClass","_openBlock","_hoisted_1","_createElementVNode","_hoisted_2","_hoisted_3","_createVNode","_unref","QuillEditor","_hoisted_4","_toDisplayString","_hoisted_5"],"mappings":"+oBAkDA,MAAMA,EAAQC,EAURC,EAAOC,EAAAA,aAAA,EACPC,EAAQC,EAAAA,SAAiB,IAAOH,EAAK,SAASF,EAAM,IAAI,GAA4B,EAAE,EACtFM,EAAWD,EAAAA,SAA6B,IAAMH,EAAK,OAAOF,EAAM,IAAI,IAAI,CAAC,CAAC,EAEhF,SAASO,EAASC,EAA4B,CAGxC,OAAOA,GAAS,SAClBN,EAAK,SAASF,EAAM,KAAMQ,CAAI,EAE9BN,EAAK,SAASF,EAAM,KAAM,KAAK,UAAUQ,CAAI,CAAC,CAElD,6BAIEC,EAAAA,mBAkBM,MAAA,CAlBA,MAAKC,EAAAA,eAAA,CAAA,cAAA,CAAA,uBAA4CJ,EAAA,QAAa,OAAS,CAAA,CAAA,GAC9DL,EAAA,OAAbU,EAAAA,UAAA,EAAAF,EAAAA,mBAGQ,QAHRG,EAGQ,CAFNC,EAAAA,mBAAwB,8BAAfZ,EAAA,KAAK,EAAA,CAAA,EACFA,EAAA,wBAAZQ,qBAA+E,OAA/EK,EAAuE,GAAC,8DAE1ED,EAAAA,mBAUM,MAVNE,EAUM,CATJC,cAQEC,EAAAA,MAAAC,EAAAA,WAAA,EAAA,CAPC,QAASd,EAAA,MACT,QAASH,EAAA,QACT,MAAOA,EAAA,MACP,YAAaA,EAAA,aAAe,OAC5B,YAAWA,EAAA,SACZ,eAAa,OACZ,mBAAgBM,CAAA,oEAGZD,EAAA,qBAATG,EAAAA,mBAAgE,IAAhEU,EAAgEC,EAAAA,gBAAfd,EAAA,KAAQ,EAAA,CAAA,GAC3CL,EAAA,oBAAdQ,EAAAA,mBAA4D,IAA5DY,EAA4DD,EAAAA,gBAAXnB,EAAA,IAAI,EAAA,CAAA"}
package/dist/quill.mjs CHANGED
@@ -1,19 +1,20 @@
1
- import { defineComponent as s, computed as u, h as p, openBlock as l, createElementBlock as t, normalizeClass as b, createElementVNode as c, toDisplayString as d, createCommentVNode as r, createVNode as v, unref as y } from "vue";
2
- import { u as _ } from "./formState-DGNcH1XQ.js";
3
- const g = {
1
+ import { defineComponent as f, computed as s, openBlock as l, createElementBlock as t, normalizeClass as h, createElementVNode as c, toDisplayString as i, createCommentVNode as r, createVNode as p, unref as y } from "vue";
2
+ import { QuillEditor as b } from "@vueup/vue-quill";
3
+ import { u as v } from "./formState-DGNcH1XQ.js";
4
+ const _ = {
4
5
  key: 0,
5
6
  class: "admin-field__label"
6
7
  }, k = {
7
8
  key: 0,
8
9
  class: "admin-field__required",
9
10
  "aria-hidden": "true"
10
- }, S = { class: "admin-field__control" }, q = {
11
+ }, F = { class: "admin-field__control admin-field__control--quill" }, g = {
11
12
  key: 1,
12
13
  class: "admin-field__error"
13
- }, B = {
14
+ }, q = {
14
15
  key: 2,
15
16
  class: "admin-field__help"
16
- }, N = /* @__PURE__ */ s({
17
+ }, Q = /* @__PURE__ */ f({
17
18
  __name: "QuillField",
18
19
  props: {
19
20
  name: {},
@@ -26,46 +27,33 @@ const g = {
26
27
  disabled: { type: Boolean, default: !1 }
27
28
  },
28
29
  setup(e) {
29
- const a = e, n = _(), m = u(() => n.getField(a.name) ?? ""), o = u(() => n.errors[a.name]?.[0]);
30
- function f(i) {
31
- n.setField(a.name, i);
30
+ const a = e, o = v(), u = s(() => o.getField(a.name) ?? ""), d = s(() => o.errors[a.name]?.[0]);
31
+ function m(n) {
32
+ typeof n == "string" ? o.setField(a.name, n) : o.setField(a.name, JSON.stringify(n));
32
33
  }
33
- const h = s({
34
- props: {
35
- content: String,
36
- toolbar: [String, Array],
37
- theme: String,
38
- placeholder: String,
39
- readOnly: Boolean
40
- },
41
- setup() {
42
- return () => p("div", {
43
- class: "quill-fallback"
44
- }, "@vueup/vue-quill не загружен — host передаёт actual Editor через peer-dep");
45
- }
46
- });
47
- return (i, F) => (l(), t("div", {
48
- class: b(["admin-field", { "admin-field--invalid": o.value !== void 0 }])
34
+ return (n, B) => (l(), t("div", {
35
+ class: h(["admin-field", { "admin-field--invalid": d.value !== void 0 }])
49
36
  }, [
50
- e.label ? (l(), t("label", g, [
51
- c("span", null, d(e.label), 1),
37
+ e.label ? (l(), t("label", _, [
38
+ c("span", null, i(e.label), 1),
52
39
  e.required ? (l(), t("span", k, "*")) : r("", !0)
53
40
  ])) : r("", !0),
54
- c("div", S, [
55
- v(y(h), {
56
- content: m.value,
41
+ c("div", F, [
42
+ p(y(b), {
43
+ content: u.value,
57
44
  toolbar: e.toolbar,
58
45
  theme: e.theme,
59
46
  placeholder: e.placeholder ?? void 0,
60
47
  "read-only": e.disabled,
61
- "onUpdate:content": f
48
+ "content-type": "html",
49
+ "onUpdate:content": m
62
50
  }, null, 8, ["content", "toolbar", "theme", "placeholder", "read-only"])
63
51
  ]),
64
- o.value ? (l(), t("p", q, d(o.value), 1)) : e.help ? (l(), t("p", B, d(e.help), 1)) : r("", !0)
52
+ d.value ? (l(), t("p", g, i(d.value), 1)) : e.help ? (l(), t("p", q, i(e.help), 1)) : r("", !0)
65
53
  ], 2));
66
54
  }
67
55
  });
68
56
  export {
69
- N as QuillField
57
+ Q as QuillField
70
58
  };
71
59
  //# sourceMappingURL=quill.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"quill.mjs","sources":["../resources/ts/components/fields/wysiwyg/quill/QuillField.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * QuillField — wrapper над @vueup/vue-quill для использования в\n * field-registry admin-renderer'а.\n *\n * Подключение в host-проекте:\n *\n * import { registerField } from '@dskripchenko/laravel-admin'\n * import { QuillField } from '@dskripchenko/laravel-admin/quill'\n * registerField('wysiwyg', QuillField)\n *\n * Для image upload'ов host регистрирует кастомный handler в Quill Toolbar\n * (наша обёртка предоставляет default — POST /api/admin/uploads).\n */\nimport { computed, h, defineComponent } from 'vue'\nimport { useFormState } from '../../../render/formState'\n\ninterface Props {\n name: string\n label?: string | null\n help?: string | null\n required?: boolean\n placeholder?: string | null\n /**\n * Quill toolbar config — string или array. См. https://quilljs.com/docs/modules/toolbar/.\n */\n toolbar?: string | unknown[]\n /**\n * Имя темы Quill ('snow' default | 'bubble' | 'core').\n */\n theme?: 'snow' | 'bubble' | 'core'\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n label: null,\n help: null,\n placeholder: null,\n required: false,\n toolbar: 'full',\n theme: 'snow',\n disabled: false,\n})\n\nconst form = useFormState()\nconst value = computed<string>(() => (form.getField(props.name) as string | undefined) ?? '')\nconst errorMsg = computed<string | undefined>(() => form.errors[props.name]?.[0])\n\nfunction onUpdate(next: string): void {\n form.setField(props.name, next)\n}\n\nconst Editor = defineComponent({\n props: {\n content: String,\n toolbar: [String, Array],\n theme: String,\n placeholder: String,\n readOnly: Boolean,\n },\n setup() {\n return () => h('div', {\n class: 'quill-fallback',\n }, '@vueup/vue-quill не загружен — host передаёт actual Editor через peer-dep')\n },\n})\n</script>\n\n<template>\n <div :class=\"['admin-field', { 'admin-field--invalid': errorMsg !== undefined }]\">\n <label v-if=\"label\" class=\"admin-field__label\">\n <span>{{ label }}</span>\n <span v-if=\"required\" class=\"admin-field__required\" aria-hidden=\"true\">*</span>\n </label>\n <div class=\"admin-field__control\">\n <Editor\n :content=\"value\"\n :toolbar=\"toolbar\"\n :theme=\"theme\"\n :placeholder=\"placeholder ?? undefined\"\n :read-only=\"disabled\"\n @update:content=\"onUpdate\"\n />\n </div>\n <p v-if=\"errorMsg\" class=\"admin-field__error\">{{ errorMsg }}</p>\n <p v-else-if=\"help\" class=\"admin-field__help\">{{ help }}</p>\n </div>\n</template>\n"],"names":["props","__props","form","useFormState","value","computed","errorMsg","onUpdate","next","Editor","defineComponent","h","_createElementBlock","_normalizeClass","_openBlock","_hoisted_1","_createElementVNode","_hoisted_2","_hoisted_3","_createVNode","_unref","_hoisted_4","_toDisplayString","_hoisted_5"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,UAAMA,IAAQC,GAURC,IAAOC,EAAA,GACPC,IAAQC,EAAiB,MAAOH,EAAK,SAASF,EAAM,IAAI,KAA4B,EAAE,GACtFM,IAAWD,EAA6B,MAAMH,EAAK,OAAOF,EAAM,IAAI,IAAI,CAAC,CAAC;AAEhF,aAASO,EAASC,GAAoB;AACpC,MAAAN,EAAK,SAASF,EAAM,MAAMQ,CAAI;AAAA,IAChC;AAEA,UAAMC,IAASC,EAAgB;AAAA,MAC7B,OAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,CAAC,QAAQ,KAAK;AAAA,QACvB,OAAO;AAAA,QACP,aAAa;AAAA,QACb,UAAU;AAAA,MAAA;AAAA,MAEZ,QAAQ;AACN,eAAO,MAAMC,EAAE,OAAO;AAAA,UACpB,OAAO;AAAA,QAAA,GACN,2EAA2E;AAAA,MAChF;AAAA,IAAA,CACD;2BAICC,EAiBM,OAAA;AAAA,MAjBA,OAAKC,EAAA,CAAA,eAAA,EAAA,wBAA4CP,EAAA,UAAa,QAAS,CAAA;AAAA,IAAA;MAC9DL,EAAA,SAAba,EAAA,GAAAF,EAGQ,SAHRG,GAGQ;AAAA,QAFNC,EAAwB,gBAAff,EAAA,KAAK,GAAA,CAAA;AAAA,QACFA,EAAA,iBAAZW,EAA+E,QAA/EK,GAAuE,GAAC;;MAE1ED,EASM,OATNE,GASM;AAAA,QARJC,EAOEC,EAAAX,CAAA,GAAA;AAAA,UANC,SAASL,EAAA;AAAA,UACT,SAASH,EAAA;AAAA,UACT,OAAOA,EAAA;AAAA,UACP,aAAaA,EAAA,eAAe;AAAA,UAC5B,aAAWA,EAAA;AAAA,UACX,oBAAgBM;AAAA,QAAA;;MAGZD,EAAA,cAATM,EAAgE,KAAhES,GAAgEC,EAAfhB,EAAA,KAAQ,GAAA,CAAA,KAC3CL,EAAA,aAAdW,EAA4D,KAA5DW,GAA4DD,EAAXrB,EAAA,IAAI,GAAA,CAAA;;;;"}
1
+ {"version":3,"file":"quill.mjs","sources":["../resources/ts/components/fields/wysiwyg/quill/QuillField.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * QuillField — wrapper над @vueup/vue-quill для field-registry admin'а.\n *\n * Подключение в host-проекте (после createAdminApp):\n *\n * import { registerField } from '@dskripchenko/laravel-admin'\n * import { QuillField } from '@dskripchenko/laravel-admin/quill'\n * // peer-deps: `@vueup/vue-quill` + `quill` должны быть установлены\n * registerField('wysiwyg', QuillField)\n *\n * Если peer-dep не найден на этапе сборки vite — bundler упадёт с\n * \"Failed to resolve\". Это нормально: subpath /quill явно опциональный,\n * подключайте только если установили peer'ы.\n *\n * CSS темы импортируем здесь — побочный эффект подгружает стили в bundle.\n */\nimport { computed } from 'vue'\n// @ts-expect-error — optional peer-dep, типы доступны только когда host\n// установил `@vueup/vue-quill`. Vite-сборка core помечает пакет как external,\n// поэтому импорт остаётся в runtime и резолвится в host'е.\nimport { QuillEditor, type Delta } from '@vueup/vue-quill'\nimport { useFormState } from '../../../render/formState'\n\n/*\n * CSS-темы (snow/bubble) host подключает сам в своём entry — core их не\n * импортирует, иначе vite-сборка core упадёт на резолве путей в\n * node_modules (peer-dep optional, в core node_modules не установлен).\n *\n * // demo/resources/js/admin.js\n * import '@vueup/vue-quill/dist/vue-quill.snow.css'\n * import '@vueup/vue-quill/dist/vue-quill.bubble.css'\n */\n\ninterface Props {\n name: string\n label?: string | null\n help?: string | null\n required?: boolean\n placeholder?: string | null\n /**\n * Quill toolbar config. Принимает `'essential' | 'minimal' | 'full'`\n * либо raw-конфиг массивом групп.\n */\n toolbar?: string | unknown[]\n /** 'snow' (default toolbar) | 'bubble' (inline) | 'core' (без UI). */\n theme?: 'snow' | 'bubble' | 'core'\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n label: null,\n help: null,\n placeholder: null,\n required: false,\n toolbar: 'full',\n theme: 'snow',\n disabled: false,\n})\n\nconst form = useFormState()\nconst value = computed<string>(() => (form.getField(props.name) as string | undefined) ?? '')\nconst errorMsg = computed<string | undefined>(() => form.errors[props.name]?.[0])\n\nfunction onUpdate(next: string | Delta): void {\n // QuillEditor v-model:content по умолчанию отдаёт HTML строку (contentType\n // = 'html'). На всякий случай — поддерживаем и Delta-объект.\n if (typeof next === 'string') {\n form.setField(props.name, next)\n } else {\n form.setField(props.name, JSON.stringify(next))\n }\n}\n</script>\n\n<template>\n <div :class=\"['admin-field', { 'admin-field--invalid': errorMsg !== undefined }]\">\n <label v-if=\"label\" class=\"admin-field__label\">\n <span>{{ label }}</span>\n <span v-if=\"required\" class=\"admin-field__required\" aria-hidden=\"true\">*</span>\n </label>\n <div class=\"admin-field__control admin-field__control--quill\">\n <QuillEditor\n :content=\"value\"\n :toolbar=\"toolbar\"\n :theme=\"theme\"\n :placeholder=\"placeholder ?? undefined\"\n :read-only=\"disabled\"\n content-type=\"html\"\n @update:content=\"onUpdate\"\n />\n </div>\n <p v-if=\"errorMsg\" class=\"admin-field__error\">{{ errorMsg }}</p>\n <p v-else-if=\"help\" class=\"admin-field__help\">{{ help }}</p>\n </div>\n</template>\n\n<style>\n/* Quill принимает min-height через CSS — снимает дёрганье инициализации. */\n.admin-field__control--quill .ql-container {\n min-height: 200px;\n font-size: 14px;\n font-family: inherit;\n}\n.admin-field__control--quill .ql-toolbar.ql-snow,\n.admin-field__control--quill .ql-container.ql-snow {\n border-color: var(--uid-border-subtle);\n}\n.admin-field__control--quill .ql-toolbar.ql-snow {\n border-radius: var(--uid-radius-md) var(--uid-radius-md) 0 0;\n background: var(--uid-surface-base);\n}\n.admin-field__control--quill .ql-container.ql-snow {\n border-radius: 0 0 var(--uid-radius-md) var(--uid-radius-md);\n background: var(--uid-surface-raised);\n color: var(--uid-text-primary);\n}\n</style>\n"],"names":["props","__props","form","useFormState","value","computed","errorMsg","onUpdate","next","_createElementBlock","_normalizeClass","_openBlock","_hoisted_1","_createElementVNode","_hoisted_2","_hoisted_3","_createVNode","_unref","QuillEditor","_hoisted_4","_toDisplayString","_hoisted_5"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA,UAAMA,IAAQC,GAURC,IAAOC,EAAA,GACPC,IAAQC,EAAiB,MAAOH,EAAK,SAASF,EAAM,IAAI,KAA4B,EAAE,GACtFM,IAAWD,EAA6B,MAAMH,EAAK,OAAOF,EAAM,IAAI,IAAI,CAAC,CAAC;AAEhF,aAASO,EAASC,GAA4B;AAG5C,MAAI,OAAOA,KAAS,WAClBN,EAAK,SAASF,EAAM,MAAMQ,CAAI,IAE9BN,EAAK,SAASF,EAAM,MAAM,KAAK,UAAUQ,CAAI,CAAC;AAAA,IAElD;2BAIEC,EAkBM,OAAA;AAAA,MAlBA,OAAKC,EAAA,CAAA,eAAA,EAAA,wBAA4CJ,EAAA,UAAa,QAAS,CAAA;AAAA,IAAA;MAC9DL,EAAA,SAAbU,EAAA,GAAAF,EAGQ,SAHRG,GAGQ;AAAA,QAFNC,EAAwB,gBAAfZ,EAAA,KAAK,GAAA,CAAA;AAAA,QACFA,EAAA,iBAAZQ,EAA+E,QAA/EK,GAAuE,GAAC;;MAE1ED,EAUM,OAVNE,GAUM;AAAA,QATJC,EAQEC,EAAAC,CAAA,GAAA;AAAA,UAPC,SAASd,EAAA;AAAA,UACT,SAASH,EAAA;AAAA,UACT,OAAOA,EAAA;AAAA,UACP,aAAaA,EAAA,eAAe;AAAA,UAC5B,aAAWA,EAAA;AAAA,UACZ,gBAAa;AAAA,UACZ,oBAAgBM;AAAA,QAAA;;MAGZD,EAAA,cAATG,EAAgE,KAAhEU,GAAgEC,EAAfd,EAAA,KAAQ,GAAA,CAAA,KAC3CL,EAAA,aAAdQ,EAA4D,KAA5DY,GAA4DD,EAAXnB,EAAA,IAAI,GAAA,CAAA;;;;"}
@@ -37,6 +37,10 @@ export interface AdminRouterOptions {
37
37
  profile?: AdminRouteComponent;
38
38
  /** Страница уведомлений. */
39
39
  notifications?: AdminRouteComponent;
40
+ /** Forgot password. */
41
+ forgotPassword?: AdminRouteComponent;
42
+ /** Reset password (по token + email из query). */
43
+ resetPassword?: AdminRouteComponent;
40
44
  };
41
45
  /** Дополнительные руты сверху динамики. */
42
46
  extraRoutes?: RouteRecordRaw[];
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Dashboard store: edit-mode + working-copy layout + save/load.
3
+ *
4
+ * Backend контракт:
5
+ * GET /api/admin/dashboard/get?key={dashboard_slug} → { layout: WidgetItem[] | null }
6
+ * POST /api/admin/dashboard/save body { key, widgets[] }
7
+ * POST /api/admin/dashboard/reset body { key }
8
+ *
9
+ * WidgetItem — это per-user override:
10
+ * { slug, size, position, hidden, config?, type? }
11
+ *
12
+ * `slug` — backend Widget::slug() (для встроенных) либо user-generated
13
+ * (для виджетов добавленных через Add Widget — host сохраняет config
14
+ * в `config` поле, type — в `type`).
15
+ */
16
+ export interface WidgetLayoutItem {
17
+ slug: string;
18
+ size?: number;
19
+ position?: number;
20
+ hidden?: boolean;
21
+ /** Тип widget'а (для user-added; для backend — синхронизируется с Widget). */
22
+ type?: string;
23
+ /** Title override + per-type конфигурация. */
24
+ config?: Record<string, unknown>;
25
+ }
26
+ export declare const useDashboardStore: import("pinia").StoreDefinition<"admin-dashboard", Pick<{
27
+ slug: import("vue").Ref<string | null, string | null>;
28
+ editMode: import("vue").Ref<boolean, boolean>;
29
+ draft: import("vue").Ref<{
30
+ slug: string;
31
+ size?: number | undefined;
32
+ position?: number | undefined;
33
+ hidden?: boolean
34
+ /** Тип widget'а (для user-added; для backend — синхронизируется с Widget). */
35
+ | undefined;
36
+ type?: string
37
+ /** Title override + per-type конфигурация. */
38
+ | undefined;
39
+ config?: Record<string, unknown> | undefined;
40
+ }[], WidgetLayoutItem[] | {
41
+ slug: string;
42
+ size?: number | undefined;
43
+ position?: number | undefined;
44
+ hidden?: boolean
45
+ /** Тип widget'а (для user-added; для backend — синхронизируется с Widget). */
46
+ | undefined;
47
+ type?: string
48
+ /** Title override + per-type конфигурация. */
49
+ | undefined;
50
+ config?: Record<string, unknown> | undefined;
51
+ }[]>;
52
+ original: import("vue").Ref<{
53
+ slug: string;
54
+ size?: number | undefined;
55
+ position?: number | undefined;
56
+ hidden?: boolean
57
+ /** Тип widget'а (для user-added; для backend — синхронизируется с Widget). */
58
+ | undefined;
59
+ type?: string
60
+ /** Title override + per-type конфигурация. */
61
+ | undefined;
62
+ config?: Record<string, unknown> | undefined;
63
+ }[], WidgetLayoutItem[] | {
64
+ slug: string;
65
+ size?: number | undefined;
66
+ position?: number | undefined;
67
+ hidden?: boolean
68
+ /** Тип widget'а (для user-added; для backend — синхронизируется с Widget). */
69
+ | undefined;
70
+ type?: string
71
+ /** Title override + per-type конфигурация. */
72
+ | undefined;
73
+ config?: Record<string, unknown> | undefined;
74
+ }[]>;
75
+ saving: import("vue").Ref<boolean, boolean>;
76
+ loading: import("vue").Ref<boolean, boolean>;
77
+ isDirty: import("vue").ComputedRef<boolean>;
78
+ openDashboard: (dashboardSlug: string) => Promise<void>;
79
+ enterEditMode: () => void;
80
+ cancelEdit: () => void;
81
+ saveLayout: () => Promise<void>;
82
+ resetToDefault: () => Promise<void>;
83
+ addWidget: (item: WidgetLayoutItem) => void;
84
+ removeWidget: (slugKey: string) => void;
85
+ updateWidget: (slugKey: string, patch: Partial<WidgetLayoutItem>) => void;
86
+ moveWidget: (fromIdx: number, toIdx: number) => void;
87
+ reset: () => void;
88
+ }, "loading" | "slug" | "editMode" | "draft" | "original" | "saving">, Pick<{
89
+ slug: import("vue").Ref<string | null, string | null>;
90
+ editMode: import("vue").Ref<boolean, boolean>;
91
+ draft: import("vue").Ref<{
92
+ slug: string;
93
+ size?: number | undefined;
94
+ position?: number | undefined;
95
+ hidden?: boolean
96
+ /** Тип widget'а (для user-added; для backend — синхронизируется с Widget). */
97
+ | undefined;
98
+ type?: string
99
+ /** Title override + per-type конфигурация. */
100
+ | undefined;
101
+ config?: Record<string, unknown> | undefined;
102
+ }[], WidgetLayoutItem[] | {
103
+ slug: string;
104
+ size?: number | undefined;
105
+ position?: number | undefined;
106
+ hidden?: boolean
107
+ /** Тип widget'а (для user-added; для backend — синхронизируется с Widget). */
108
+ | undefined;
109
+ type?: string
110
+ /** Title override + per-type конфигурация. */
111
+ | undefined;
112
+ config?: Record<string, unknown> | undefined;
113
+ }[]>;
114
+ original: import("vue").Ref<{
115
+ slug: string;
116
+ size?: number | undefined;
117
+ position?: number | undefined;
118
+ hidden?: boolean
119
+ /** Тип widget'а (для user-added; для backend — синхронизируется с Widget). */
120
+ | undefined;
121
+ type?: string
122
+ /** Title override + per-type конфигурация. */
123
+ | undefined;
124
+ config?: Record<string, unknown> | undefined;
125
+ }[], WidgetLayoutItem[] | {
126
+ slug: string;
127
+ size?: number | undefined;
128
+ position?: number | undefined;
129
+ hidden?: boolean
130
+ /** Тип widget'а (для user-added; для backend — синхронизируется с Widget). */
131
+ | undefined;
132
+ type?: string
133
+ /** Title override + per-type конфигурация. */
134
+ | undefined;
135
+ config?: Record<string, unknown> | undefined;
136
+ }[]>;
137
+ saving: import("vue").Ref<boolean, boolean>;
138
+ loading: import("vue").Ref<boolean, boolean>;
139
+ isDirty: import("vue").ComputedRef<boolean>;
140
+ openDashboard: (dashboardSlug: string) => Promise<void>;
141
+ enterEditMode: () => void;
142
+ cancelEdit: () => void;
143
+ saveLayout: () => Promise<void>;
144
+ resetToDefault: () => Promise<void>;
145
+ addWidget: (item: WidgetLayoutItem) => void;
146
+ removeWidget: (slugKey: string) => void;
147
+ updateWidget: (slugKey: string, patch: Partial<WidgetLayoutItem>) => void;
148
+ moveWidget: (fromIdx: number, toIdx: number) => void;
149
+ reset: () => void;
150
+ }, "isDirty">, Pick<{
151
+ slug: import("vue").Ref<string | null, string | null>;
152
+ editMode: import("vue").Ref<boolean, boolean>;
153
+ draft: import("vue").Ref<{
154
+ slug: string;
155
+ size?: number | undefined;
156
+ position?: number | undefined;
157
+ hidden?: boolean
158
+ /** Тип widget'а (для user-added; для backend — синхронизируется с Widget). */
159
+ | undefined;
160
+ type?: string
161
+ /** Title override + per-type конфигурация. */
162
+ | undefined;
163
+ config?: Record<string, unknown> | undefined;
164
+ }[], WidgetLayoutItem[] | {
165
+ slug: string;
166
+ size?: number | undefined;
167
+ position?: number | undefined;
168
+ hidden?: boolean
169
+ /** Тип widget'а (для user-added; для backend — синхронизируется с Widget). */
170
+ | undefined;
171
+ type?: string
172
+ /** Title override + per-type конфигурация. */
173
+ | undefined;
174
+ config?: Record<string, unknown> | undefined;
175
+ }[]>;
176
+ original: import("vue").Ref<{
177
+ slug: string;
178
+ size?: number | undefined;
179
+ position?: number | undefined;
180
+ hidden?: boolean
181
+ /** Тип widget'а (для user-added; для backend — синхронизируется с Widget). */
182
+ | undefined;
183
+ type?: string
184
+ /** Title override + per-type конфигурация. */
185
+ | undefined;
186
+ config?: Record<string, unknown> | undefined;
187
+ }[], WidgetLayoutItem[] | {
188
+ slug: string;
189
+ size?: number | undefined;
190
+ position?: number | undefined;
191
+ hidden?: boolean
192
+ /** Тип widget'а (для user-added; для backend — синхронизируется с Widget). */
193
+ | undefined;
194
+ type?: string
195
+ /** Title override + per-type конфигурация. */
196
+ | undefined;
197
+ config?: Record<string, unknown> | undefined;
198
+ }[]>;
199
+ saving: import("vue").Ref<boolean, boolean>;
200
+ loading: import("vue").Ref<boolean, boolean>;
201
+ isDirty: import("vue").ComputedRef<boolean>;
202
+ openDashboard: (dashboardSlug: string) => Promise<void>;
203
+ enterEditMode: () => void;
204
+ cancelEdit: () => void;
205
+ saveLayout: () => Promise<void>;
206
+ resetToDefault: () => Promise<void>;
207
+ addWidget: (item: WidgetLayoutItem) => void;
208
+ removeWidget: (slugKey: string) => void;
209
+ updateWidget: (slugKey: string, patch: Partial<WidgetLayoutItem>) => void;
210
+ moveWidget: (fromIdx: number, toIdx: number) => void;
211
+ reset: () => void;
212
+ }, "reset" | "openDashboard" | "enterEditMode" | "cancelEdit" | "saveLayout" | "resetToDefault" | "addWidget" | "removeWidget" | "updateWidget" | "moveWidget">>;
@@ -0,0 +1,31 @@
1
+ import type { AdminBootstrap } from '../types/bootstrap';
2
+ export declare const useI18nStore: import("pinia").StoreDefinition<"admin-i18n", Pick<{
3
+ messages: import("vue").Ref<Record<string, string>, Record<string, string>>;
4
+ locale: import("vue").Ref<string, string>;
5
+ hydrate: (bootstrap: AdminBootstrap) => void;
6
+ setMessages: (next: Record<string, string>) => void;
7
+ t: (key: string, replace?: Record<string, string | number>) => string;
8
+ has: (key: string) => boolean;
9
+ keys: import("vue").ComputedRef<string[]>;
10
+ }, "messages" | "locale">, Pick<{
11
+ messages: import("vue").Ref<Record<string, string>, Record<string, string>>;
12
+ locale: import("vue").Ref<string, string>;
13
+ hydrate: (bootstrap: AdminBootstrap) => void;
14
+ setMessages: (next: Record<string, string>) => void;
15
+ t: (key: string, replace?: Record<string, string | number>) => string;
16
+ has: (key: string) => boolean;
17
+ keys: import("vue").ComputedRef<string[]>;
18
+ }, "keys">, Pick<{
19
+ messages: import("vue").Ref<Record<string, string>, Record<string, string>>;
20
+ locale: import("vue").Ref<string, string>;
21
+ hydrate: (bootstrap: AdminBootstrap) => void;
22
+ setMessages: (next: Record<string, string>) => void;
23
+ t: (key: string, replace?: Record<string, string | number>) => string;
24
+ has: (key: string) => boolean;
25
+ keys: import("vue").ComputedRef<string[]>;
26
+ }, "hydrate" | "has" | "t" | "setMessages">>;
27
+ /**
28
+ * Convenience: глобальный t() для не-Vue контекстов (utils, services).
29
+ * В Vue-компонентах предпочтительнее `const { t } = useI18nStore()`.
30
+ */
31
+ export declare function tRaw(key: string, replace?: Record<string, string | number>): string;