@dskripchenko/laravel-admin 1.31.3 → 1.33.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 (106) hide show
  1. package/README.md +9 -27
  2. package/dist/.vite/manifest.json +11 -0
  3. package/dist/app.d.ts +13 -0
  4. package/dist/assets/app-C5UPrfEf.css +1 -0
  5. package/dist/assets/app-POyU3uzR.js +29 -0
  6. package/dist/components/ScreenPage.test.d.ts +1 -0
  7. package/dist/components/actions/AdminActionButton.vue.d.ts +25 -0
  8. package/dist/components/actions/AdminActionDialogs.vue.d.ts +6 -0
  9. package/dist/components/actions/AdminActionForm.vue.d.ts +8 -0
  10. package/dist/components/actions/AdminActionMenuItems.vue.d.ts +14 -0
  11. package/dist/components/dashboard/BarChartWidget.vue.d.ts +3 -0
  12. package/dist/components/dashboard/CartesianChartWidget.vue.d.ts +21 -0
  13. package/dist/components/dashboard/ChartLegend.vue.d.ts +14 -0
  14. package/dist/components/dashboard/ChartTooltip.vue.d.ts +15 -0
  15. package/dist/components/dashboard/ChartWidget.test.d.ts +1 -0
  16. package/dist/components/dashboard/ChartWidget.vue.d.ts +9 -7
  17. package/dist/components/dashboard/HeatmapWidget.vue.d.ts +1 -1
  18. package/dist/components/dashboard/RadarChartWidget.vue.d.ts +15 -0
  19. package/dist/components/dashboard/chartGeometry.d.ts +62 -0
  20. package/dist/components/dashboard/chartTypes.d.ts +8 -0
  21. package/dist/components/dashboard/useChartSize.d.ts +14 -0
  22. package/dist/components/fields/CascaderField.vue.d.ts +32 -0
  23. package/dist/components/fields/CodeField.vue.d.ts +28 -0
  24. package/dist/components/fields/ColorField.vue.d.ts +23 -0
  25. package/dist/components/fields/DateRangeField.vue.d.ts +24 -0
  26. package/dist/components/fields/GroupField.vue.d.ts +21 -0
  27. package/dist/components/fields/HiddenField.vue.d.ts +8 -0
  28. package/dist/components/fields/LabelField.vue.d.ts +14 -0
  29. package/dist/components/fields/MarkdownField.vue.d.ts +29 -0
  30. package/dist/components/fields/MorphSwitcherField.vue.d.ts +23 -0
  31. package/dist/components/fields/RadioField.vue.d.ts +21 -0
  32. package/dist/components/fields/RatingField.vue.d.ts +23 -0
  33. package/dist/components/fields/SliderField.vue.d.ts +24 -0
  34. package/dist/components/fields/TimeField.vue.d.ts +26 -0
  35. package/dist/components/fields/TreeSelectField.vue.d.ts +26 -0
  36. package/dist/components/fields/WysiwygField.vue.d.ts +1 -1
  37. package/dist/components/fields/pickerFields.test.d.ts +1 -0
  38. package/dist/components/fields/support/color.d.ts +18 -0
  39. package/dist/components/fields/support/dateRange.d.ts +9 -0
  40. package/dist/components/fields/support/markdown.d.ts +14 -0
  41. package/dist/components/fields/support/support.test.d.ts +1 -0
  42. package/dist/components/fields/support/tree.d.ts +23 -0
  43. package/dist/components/infolist/CascaderEntry.vue.d.ts +21 -0
  44. package/dist/components/infolist/CodeEntry.vue.d.ts +17 -0
  45. package/dist/components/infolist/ColorEntry.vue.d.ts +15 -0
  46. package/dist/components/infolist/DateRangeEntry.vue.d.ts +11 -0
  47. package/dist/components/infolist/FieldEntry.vue.d.ts +19 -0
  48. package/dist/components/infolist/GroupEntry.vue.d.ts +19 -0
  49. package/dist/components/infolist/HiddenEntry.vue.d.ts +2 -0
  50. package/dist/components/infolist/ImageEntry.vue.d.ts +21 -0
  51. package/dist/components/infolist/MapEntry.vue.d.ts +17 -0
  52. package/dist/components/infolist/MarkdownEntry.vue.d.ts +11 -0
  53. package/dist/components/infolist/MorphEntry.vue.d.ts +19 -0
  54. package/dist/components/infolist/OptionEntry.vue.d.ts +13 -0
  55. package/dist/components/infolist/RatingEntry.vue.d.ts +19 -0
  56. package/dist/components/infolist/RelationEntry.vue.d.ts +17 -0
  57. package/dist/components/infolist/TreeSelectEntry.vue.d.ts +15 -0
  58. package/dist/components/infolist/entryValue.d.ts +10 -0
  59. package/dist/components/infolist/viewEntries.test.d.ts +1 -0
  60. package/dist/components/layouts/AccordionLayout.vue.d.ts +16 -0
  61. package/dist/components/layouts/AuditTrailLayout.vue.d.ts +13 -0
  62. package/dist/components/layouts/DrawerLayout.vue.d.ts +25 -0
  63. package/dist/components/layouts/InfolistLayout.vue.d.ts +12 -0
  64. package/dist/components/layouts/ModalLayout.vue.d.ts +22 -0
  65. package/dist/components/layouts/StepLayout.vue.d.ts +12 -0
  66. package/dist/components/layouts/ViewLayout.vue.d.ts +7 -0
  67. package/dist/components/layouts/WizardLayout.vue.d.ts +20 -0
  68. package/dist/components/layouts/WrapperLayout.vue.d.ts +12 -0
  69. package/dist/components/layouts/layouts.test.d.ts +1 -0
  70. package/dist/components/layouts/overlay.d.ts +29 -0
  71. package/dist/components/layouts/wizard.d.ts +39 -0
  72. package/dist/components/layouts/wizard.test.d.ts +1 -0
  73. package/dist/components/render/backendParity.test.d.ts +1 -0
  74. package/dist/components/render/formState.d.ts +11 -0
  75. package/dist/components/render/index.d.ts +10 -0
  76. package/dist/components/render/screenContext.d.ts +75 -0
  77. package/dist/components/render/screenContext.test.d.ts +1 -0
  78. package/dist/components/resource/AuditTimeline.vue.d.ts +5 -1
  79. package/dist/components/resource/ResourceIndexPage.vue.d.ts +5 -5
  80. package/dist/components/resource/ResourceViewPage.vue.d.ts +2 -2
  81. package/dist/composables/useActionRunner.d.ts +112 -0
  82. package/dist/composables/useActionRunner.test.d.ts +1 -0
  83. package/dist/formState-DVU2igtT.js +76 -0
  84. package/dist/formState-DVU2igtT.js.map +1 -0
  85. package/dist/formState-DqHe1Jgd.cjs +2 -0
  86. package/dist/formState-DqHe1Jgd.cjs.map +1 -0
  87. package/dist/index.cjs +19 -4
  88. package/dist/index.cjs.map +1 -1
  89. package/dist/index.d.ts +6 -2
  90. package/dist/index.mjs +18826 -15285
  91. package/dist/index.mjs.map +1 -1
  92. package/dist/quill.cjs +1 -1
  93. package/dist/quill.mjs +1 -1
  94. package/dist/source-hash.txt +1 -0
  95. package/dist/stores/screen.d.ts +3 -5
  96. package/dist/stores/toast.d.ts +21 -0
  97. package/dist/stores/toast.test.d.ts +1 -0
  98. package/dist/style.css +1 -1
  99. package/dist/tinymce.cjs +1 -1
  100. package/dist/tinymce.mjs +1 -1
  101. package/package.json +3 -2
  102. package/dist/.gitkeep +0 -0
  103. package/dist/formState-DeRZBwWH.js +0 -41
  104. package/dist/formState-DeRZBwWH.js.map +0 -1
  105. package/dist/formState-yUTD6wAR.cjs +0 -2
  106. package/dist/formState-yUTD6wAR.cjs.map +0 -1
@@ -0,0 +1,75 @@
1
+ /**
2
+ * The screen context: what a layout deep in the tree may ask of the screen it
3
+ * sits on.
4
+ *
5
+ * Two things live here:
6
+ *
7
+ * - the overlays — the open/closed state of the Modal and Drawer layouts,
8
+ * keyed by the layout's id. An action carrying `attributes.opens` (see the
9
+ * backend's `Action::opens()`) opens the overlay with that id;
10
+ * - the dispatcher — a click on an action, wherever it is drawn (the command
11
+ * bar, a modal's footer, a wizard's submit), goes through `dispatch`, which
12
+ * asks for the confirmation and opens an overlay, or hands the action to
13
+ * the page's action runner (`run`) — or, without one, calls the screen's
14
+ * method.
15
+ *
16
+ * ScreenPage provides it. Outside a screen — a resource form, a unit test —
17
+ * `useScreenContext()` returns null and the layouts degrade gracefully: an
18
+ * overlay keeps its own local state and a submit has nowhere to go.
19
+ */
20
+ import { type InjectionKey, type Ref } from 'vue';
21
+ /** The shape of an action as the backend serializes it (Action::toArray). */
22
+ export interface ScreenActionLike {
23
+ name?: string;
24
+ label?: string;
25
+ type?: string;
26
+ icon?: string | null;
27
+ primary?: boolean;
28
+ destructive?: boolean;
29
+ confirm?: {
30
+ message: string;
31
+ title?: string;
32
+ } | null;
33
+ attributes?: Record<string, unknown>;
34
+ }
35
+ export interface ScreenContext {
36
+ isOpen: (id: string) => boolean;
37
+ open: (id: string) => void;
38
+ close: (id: string) => void;
39
+ /** Whether a screen method is running right now. */
40
+ running: Readonly<Ref<boolean>>;
41
+ /**
42
+ * Calls a screen method with the current state. Resolves to true on
43
+ * success, false on a failure — the errors land in the screen store.
44
+ */
45
+ runMethod: (method: string) => Promise<boolean>;
46
+ /**
47
+ * Runs an action: the confirmation first, then either `attributes.opens`
48
+ * (an overlay) or `attributes.method` (a screen method). Resolves to true
49
+ * when the action went through.
50
+ */
51
+ dispatch: (action: ScreenActionLike) => Promise<boolean>;
52
+ }
53
+ declare const ScreenContextKey: InjectionKey<ScreenContext>;
54
+ export interface ScreenContextOptions {
55
+ running: Readonly<Ref<boolean>>;
56
+ runMethod: (method: string) => Promise<boolean>;
57
+ /** The confirmation prompt; window.confirm by default. */
58
+ confirm?: (confirm: {
59
+ message: string;
60
+ title?: string;
61
+ }) => boolean | Promise<boolean>;
62
+ /**
63
+ * Runs any action that does not open an overlay — confirmation included.
64
+ * ScreenPage passes its action runner here, so the layouts' actions get
65
+ * every action type (modal, async, link…) too. Without it only
66
+ * `attributes.method` is understood.
67
+ */
68
+ run?: (action: ScreenActionLike) => Promise<boolean>;
69
+ }
70
+ export declare function createScreenContext(options: ScreenContextOptions): ScreenContext;
71
+ export declare function provideScreenContext(options: ScreenContextOptions): ScreenContext;
72
+ /** The screen context, or null outside a screen. */
73
+ export declare function useScreenContext(): ScreenContext | null;
74
+ /** For tests and hosts that render layouts outside ScreenPage. */
75
+ export { ScreenContextKey };
@@ -0,0 +1 @@
1
+ export {};
@@ -7,6 +7,10 @@ interface Props {
7
7
  */
8
8
  subjectType: string | null;
9
9
  subjectId: string | number;
10
+ /** Show at most this many of the latest events; all of them when null. */
11
+ limit?: number | null;
10
12
  }
11
- declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
14
+ limit: number | null;
15
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
16
  export default _default;
@@ -10,20 +10,20 @@ interface Props {
10
10
  /** Router route name behind the “Create” action. */
11
11
  createRouteName?: string | null;
12
12
  }
13
- declare var __VLS_5: {}, __VLS_79: {}, __VLS_149: {
13
+ declare var __VLS_5: {}, __VLS_78: {}, __VLS_147: {
14
14
  filters: Record<string, unknown>;
15
15
  setFilter: (key: string, value: unknown) => Promise<void>;
16
- }, __VLS_215: `cell-${string}`, __VLS_216: {
16
+ }, __VLS_213: `cell-${string}`, __VLS_214: {
17
17
  row: Record<string, unknown> | undefined;
18
18
  };
19
19
  type __VLS_Slots = {} & {
20
- [K in NonNullable<typeof __VLS_215>]?: (props: typeof __VLS_216) => any;
20
+ [K in NonNullable<typeof __VLS_213>]?: (props: typeof __VLS_214) => any;
21
21
  } & {
22
22
  actions?: (props: typeof __VLS_5) => any;
23
23
  } & {
24
- 'header-menu'?: (props: typeof __VLS_79) => any;
24
+ 'header-menu'?: (props: typeof __VLS_78) => any;
25
25
  } & {
26
- filters?: (props: typeof __VLS_149) => any;
26
+ filters?: (props: typeof __VLS_147) => any;
27
27
  };
28
28
  declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
29
29
  import: () => any;
@@ -19,12 +19,12 @@ interface Props {
19
19
  /** The prefix of the UID label next to the status: 'A-' gives 'A-1284'. */
20
20
  uidPrefix?: string;
21
21
  }
22
- declare var __VLS_75: {
22
+ declare var __VLS_74: {
23
23
  record: Record<string, unknown>;
24
24
  resource: import("../..").ManifestResourceMeta | null;
25
25
  };
26
26
  type __VLS_Slots = {} & {
27
- sidebar?: (props: typeof __VLS_75) => any;
27
+ sidebar?: (props: typeof __VLS_74) => any;
28
28
  };
29
29
  declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
30
30
  indexRouteName: string | null;
@@ -0,0 +1,112 @@
1
+ import { type Router } from 'vue-router';
2
+ export interface ActionConfirm {
3
+ message: string;
4
+ title?: string;
5
+ confirmLabel?: string;
6
+ cancelLabel?: string;
7
+ }
8
+ /** An action as Action::toArray() serializes it, normalized. */
9
+ export interface AdminAction {
10
+ name: string;
11
+ label: string;
12
+ type: string;
13
+ icon: string | null;
14
+ confirm: ActionConfirm | null;
15
+ primary: boolean;
16
+ destructive: boolean;
17
+ position: string[];
18
+ attributes: Record<string, unknown>;
19
+ /** The nested actions of a dropdown. */
20
+ items: AdminAction[];
21
+ }
22
+ /** How a page runs a server-side action in its own context. */
23
+ export interface ActionExecutor {
24
+ /** Runs a button, bulk or modal action; `payload` is the modal form's values. */
25
+ execute: (action: AdminAction, payload?: Record<string, unknown>) => Promise<unknown>;
26
+ /** The record keys the actions apply to, when the context has any. */
27
+ ids?: () => Array<string | number>;
28
+ /** After a successful execute: a toast, a reload. */
29
+ onSuccess?: (action: AdminAction, result: unknown) => void | Promise<void>;
30
+ /** When execute fails; a toast with the error's message by default. */
31
+ onError?: (action: AdminAction, err: unknown) => void;
32
+ /** Reloads the context's data after an async action has finished. */
33
+ refresh?: () => void | Promise<void>;
34
+ }
35
+ export interface DelayedStatus {
36
+ uuid?: string;
37
+ status: string;
38
+ progress?: number | null;
39
+ data?: unknown;
40
+ error?: string | null;
41
+ }
42
+ /** Normalizes one serialized action; null when it has no name or label. */
43
+ export declare function normalizeAction(raw: unknown): AdminAction | null;
44
+ export declare function normalizeActions(raw: unknown): AdminAction[];
45
+ /** Row and bulk actions apply to the selected records. */
46
+ export declare function needsSelection(action: AdminAction): boolean;
47
+ /**
48
+ * Whether a selection of `count` records satisfies the action's
49
+ * requiresAtLeast / requiresAtMost (BulkAction).
50
+ */
51
+ export declare function selectionAllows(action: AdminAction, count: number): boolean;
52
+ /** The UidModal sizes; the backend's modalSize() is a free-form string. */
53
+ export declare function modalSizeOf(raw: unknown): 'sm' | 'md' | 'lg' | 'xl';
54
+ /**
55
+ * Turns an absolute href into a router path when it points inside the panel;
56
+ * null when it has to be a full navigation.
57
+ */
58
+ export declare function toRouterPath(router: Router | undefined, href: string): string | null;
59
+ export declare function useActionRunner(executor: ActionExecutor): {
60
+ run: (action: AdminAction) => Promise<boolean>;
61
+ running: import("vue").Ref<boolean, boolean>;
62
+ confirm: (opts: ActionConfirm | string, destructive?: boolean) => Promise<boolean>;
63
+ confirmState: {
64
+ open: boolean;
65
+ title: string;
66
+ message: string;
67
+ confirmLabel: string;
68
+ cancelLabel: string;
69
+ destructive: boolean;
70
+ };
71
+ resolveConfirm: (ok: boolean) => void;
72
+ modalState: {
73
+ open: boolean;
74
+ seq: number;
75
+ action: {
76
+ name: string;
77
+ label: string;
78
+ type: string;
79
+ icon: string | null;
80
+ confirm: {
81
+ message: string;
82
+ title?: string | undefined;
83
+ confirmLabel?: string | undefined;
84
+ cancelLabel?: string | undefined;
85
+ } | null;
86
+ primary: boolean;
87
+ destructive: boolean;
88
+ position: string[];
89
+ attributes: Record<string, unknown>;
90
+ items: /*elided*/ any[];
91
+ } | null;
92
+ title: string;
93
+ submitLabel: string;
94
+ size: "sm" | "md" | "lg" | "xl";
95
+ fields: Array<Record<string, unknown>>;
96
+ values: Record<string, unknown>;
97
+ errors: Record<string, string[]>;
98
+ submitting: boolean;
99
+ };
100
+ submitModal: () => Promise<void>;
101
+ closeModal: () => void;
102
+ asyncState: {
103
+ open: boolean;
104
+ label: string;
105
+ status: string;
106
+ progress: number;
107
+ error: string | null;
108
+ finished: boolean;
109
+ };
110
+ closeAsync: () => void;
111
+ };
112
+ export type ActionRunner = ReturnType<typeof useActionRunner>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,76 @@
1
+ import { reactive as u, provide as d, inject as y } from "vue";
2
+ const f = /* @__PURE__ */ Symbol("admin.form-state");
3
+ function E(e = {}, i = {}, c) {
4
+ const n = u(e), s = u({ ...i }), l = {
5
+ state: n,
6
+ errors: s,
7
+ mode: c,
8
+ setField(o, r) {
9
+ n[o] = r, s[o] && delete s[o];
10
+ },
11
+ getField(o) {
12
+ return n[o];
13
+ },
14
+ setError(o, r) {
15
+ r === null || r.length === 0 ? delete s[o] : s[o] = r;
16
+ },
17
+ setErrors(o) {
18
+ for (const r of Object.keys(s)) delete s[r];
19
+ Object.assign(s, o);
20
+ },
21
+ clearErrors() {
22
+ for (const o of Object.keys(s)) delete s[o];
23
+ }
24
+ };
25
+ return d(f, l), l;
26
+ }
27
+ function a() {
28
+ const e = y(f);
29
+ if (!e)
30
+ throw new Error("useFormState() called outside of provideFormState() scope");
31
+ return e;
32
+ }
33
+ function b() {
34
+ return y(f, null);
35
+ }
36
+ function m(e, i) {
37
+ const c = `${i}.`, n = () => {
38
+ const r = e.getField(i);
39
+ return r !== null && typeof r == "object" && !Array.isArray(r) ? r : {};
40
+ }, s = () => Object.keys(e.errors).filter((r) => r.startsWith(c)).map((r) => r.slice(c.length)), l = new Proxy({}, {
41
+ get: (r, t) => typeof t == "string" ? e.errors[c + t] : void 0,
42
+ has: (r, t) => typeof t == "string" && c + t in e.errors,
43
+ ownKeys: () => s(),
44
+ getOwnPropertyDescriptor: (r, t) => typeof t == "string" && c + t in e.errors ? { enumerable: !0, configurable: !0, value: e.errors[c + t] } : void 0
45
+ }), o = {
46
+ get state() {
47
+ return n();
48
+ },
49
+ errors: l,
50
+ mode: e.mode,
51
+ setField(r, t) {
52
+ e.setField(i, { ...n(), [r]: t }), e.setError(c + r, null);
53
+ },
54
+ getField(r) {
55
+ return n()[r];
56
+ },
57
+ setError(r, t) {
58
+ e.setError(c + r, t);
59
+ },
60
+ setErrors(r) {
61
+ for (const t of s()) e.setError(c + t, null);
62
+ for (const [t, F] of Object.entries(r)) e.setError(c + t, F);
63
+ },
64
+ clearErrors() {
65
+ for (const r of s()) e.setError(c + r, null);
66
+ }
67
+ };
68
+ return d(f, o), o;
69
+ }
70
+ export {
71
+ m as a,
72
+ E as p,
73
+ b as t,
74
+ a as u
75
+ };
76
+ //# sourceMappingURL=formState-DVU2igtT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formState-DVU2igtT.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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"}
@@ -0,0 +1,2 @@
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-DqHe1Jgd.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formState-DqHe1Jgd.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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"}