@lattice-php/lattice 0.21.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/action/components/action-form.js +15 -10
- package/dist/action/components/action-form.js.map +1 -1
- package/dist/action/components/action-group.js +1 -1
- package/dist/action/components/action.js +2 -1
- package/dist/action/components/action.js.map +1 -1
- package/dist/action/hooks/use-action.js +42 -35
- package/dist/action/hooks/use-action.js.map +1 -1
- package/dist/action/lib/action-label.d.ts +2 -0
- package/dist/action/lib/action-label.js +9 -0
- package/dist/action/lib/action-label.js.map +1 -0
- package/dist/action/lib/run-action.d.ts +7 -7
- package/dist/action/lib/run-action.js +8 -7
- package/dist/action/lib/run-action.js.map +1 -1
- package/dist/chat/components/chat-box.js +1 -1
- package/dist/chat/components/prompt-input.js +1 -1
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.js +4 -1
- package/dist/core/registry.d.ts +5 -0
- package/dist/core/registry.js.map +1 -1
- package/dist/create-app.d.ts +6 -2
- package/dist/create-app.js +12 -1
- package/dist/create-app.js.map +1 -1
- package/dist/form/components/fields/rich-editor-field.js +1 -1
- package/dist/form/components/fields/row-actions.js +1 -1
- package/dist/form/components/fields/row-item.js +1 -1
- package/dist/form/components/fields/select.js +1 -1
- package/dist/form/components/fields/table-rows.js +1 -1
- package/dist/form/components/form.js +28 -5
- package/dist/form/components/form.js.map +1 -1
- package/dist/form/rich-editor/builtins.js +1 -1
- package/dist/format/number.d.ts +1 -1
- package/dist/format/number.js.map +1 -1
- package/dist/format/value.d.ts +1 -1
- package/dist/format/value.js.map +1 -1
- package/dist/i18n/backend.js +1 -1
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/instance.d.ts +1 -0
- package/dist/i18n/instance.js +5 -5
- package/dist/i18n/instance.js.map +1 -1
- package/dist/i18n/timezone.js +1 -1
- package/dist/layout/components/callouts.js +1 -1
- package/dist/notifications/components/empty-state.js +1 -1
- package/dist/notifications/components/notification-item.js +1 -1
- package/dist/notifications/components/notifications.js +2 -1
- package/dist/notifications/components/notifications.js.map +1 -1
- package/dist/remote/components/data-list.js +1 -1
- package/dist/table/components/bulk-bar.js +15 -14
- package/dist/table/components/bulk-bar.js.map +1 -1
- package/dist/table/components/cells/boolean-cell.js +1 -1
- package/dist/table/components/cells/numeric-cell.d.ts +1 -1
- package/dist/table/components/cells/numeric-cell.js.map +1 -1
- package/dist/table/components/column-header.js +1 -1
- package/dist/table/components/filter-controls.js +1 -1
- package/dist/table/components/filter-value-input.js +1 -1
- package/dist/table/components/sort-bar.js +1 -1
- package/dist/table/components/table-search.js +1 -1
- package/dist/table/components/table.js +1 -1
- package/dist/table/lib/bulk.js +2 -1
- package/dist/table/lib/bulk.js.map +1 -1
- package/dist/toast/index.d.ts +1 -1
- package/dist/toast/index.js +2 -2
- package/dist/toast/toaster.js +1 -1
- package/dist/types/generated.d.ts +4 -1
- package/dist/ui/combobox.js +1 -1
- package/dist/ui/copyable-text.js +1 -1
- package/dist/ui/info-tooltip.js +1 -1
- package/dist/ui/modal.js +3 -1
- package/dist/ui/modal.js.map +1 -1
- package/dist/ui/spinner.js +1 -1
- package/dist/ui/tabs.js +1 -1
- package/dist/ui/tree.js +1 -1
- package/dist/vite.d.ts +3 -2
- package/dist/vite.js +5 -2
- package/dist/vite.js.map +1 -1
- package/dist-standalone/chunks/{chart-view-C6R5iPra.js → chart-view-DEwGTt9d.js} +2 -2
- package/dist-standalone/chunks/{date-picker-field-DhhEB-Mh.js → date-picker-field-CCQ9nWx0.js} +1 -1
- package/dist-standalone/chunks/{page-props-DOfg30l5.js → page-props-D3FnL614.js} +1 -1
- package/dist-standalone/chunks/{rich-editor-field-DORXTHPw.js → rich-editor-field-B9Nv1qia.js} +2 -2
- package/dist-standalone/chunks/{subscriptions-B_ISgA7V.js → subscriptions-C-0lSr7X.js} +1 -1
- package/dist-standalone/chunks/use-effect-dispatcher-EVZxmfoo.js +97 -0
- package/dist-standalone/lattice.css +1 -1
- package/dist-standalone/lattice.js +15 -15
- package/dist-standalone/manifest.json +8 -8
- package/package.json +4 -4
- package/dist-standalone/chunks/use-effect-dispatcher-D1wPPwHj.js +0 -97
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { useT } from "../../../i18n/instance.js";
|
|
1
2
|
import { Icon } from "../../../icons/sprite.js";
|
|
2
3
|
import { nodeKey } from "../../../core/nodes.js";
|
|
3
4
|
import { RenderNode } from "../../../core/renderer.js";
|
|
4
|
-
import { useT } from "../../../i18n/instance.js";
|
|
5
5
|
import { FieldScopeProvider } from "../../hooks/field-scope.js";
|
|
6
6
|
import { buildRowActions } from "./row-action-menu.js";
|
|
7
7
|
import { RowActions } from "./row-actions.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { useT } from "../../../i18n/instance.js";
|
|
1
2
|
import { materializeSchema } from "../../../core/materialize.js";
|
|
2
3
|
import { cn } from "../../../lib/utils.js";
|
|
3
4
|
import { Icon } from "../../../icons/sprite.js";
|
|
4
5
|
import { Renderer } from "../../../core/renderer.js";
|
|
5
|
-
import { useT } from "../../../i18n/instance.js";
|
|
6
6
|
import { useFormContext } from "../../hooks/context.js";
|
|
7
7
|
import { useFieldScope } from "../../hooks/field-scope.js";
|
|
8
8
|
import { useResolvedNode } from "../../hooks/resolved-nodes.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { useT } from "../../../i18n/instance.js";
|
|
1
2
|
import { Icon } from "../../../icons/sprite.js";
|
|
2
3
|
import { nodeKey } from "../../../core/nodes.js";
|
|
3
4
|
import { RenderNode } from "../../../core/renderer.js";
|
|
4
|
-
import { useT } from "../../../i18n/instance.js";
|
|
5
5
|
import { useMediaQuery } from "../../../lib/use-media-query.js";
|
|
6
6
|
import { FieldScopeProvider } from "../../hooks/field-scope.js";
|
|
7
7
|
import { TableCellProvider } from "../../hooks/row-layout-context.js";
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { LATTICE_EVENT } from "../../core/event-names.js";
|
|
2
|
+
import { useT } from "../../i18n/instance.js";
|
|
2
3
|
import { useWindowEvent } from "../../core/hooks/use-window-event.js";
|
|
3
4
|
import { withHeaders } from "../../core/headers.js";
|
|
5
|
+
import { nodeKey } from "../../core/nodes.js";
|
|
6
|
+
import { RenderNode } from "../../core/renderer.js";
|
|
4
7
|
import { FormProvider } from "../hooks/context.js";
|
|
5
8
|
import { PrefillProvider } from "../hooks/prefill-context.js";
|
|
6
9
|
import { ResolvedNodesProvider } from "../hooks/resolved-nodes.js";
|
|
@@ -12,6 +15,14 @@ import { Form } from "@inertiajs/react";
|
|
|
12
15
|
import { useMemo } from "react";
|
|
13
16
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
17
|
//#region resources/js/form/components/form.tsx
|
|
18
|
+
var JUSTIFY_CLASS = {
|
|
19
|
+
start: "justify-start",
|
|
20
|
+
center: "justify-center",
|
|
21
|
+
end: "justify-end",
|
|
22
|
+
between: "justify-between",
|
|
23
|
+
around: "justify-around",
|
|
24
|
+
evenly: "justify-evenly"
|
|
25
|
+
};
|
|
15
26
|
function FormResetListener({ componentId, reset }) {
|
|
16
27
|
useWindowEvent(LATTICE_EVENT.resetForm, (event) => {
|
|
17
28
|
const detail = event.detail;
|
|
@@ -19,7 +30,7 @@ function FormResetListener({ componentId, reset }) {
|
|
|
19
30
|
});
|
|
20
31
|
return null;
|
|
21
32
|
}
|
|
22
|
-
function FormBody({ action, children, componentRef, nodes, shouldRenderSubmitButton, submitLabel, summaryLabel }) {
|
|
33
|
+
function FormBody({ action, children, componentRef, nodes, shouldRenderSubmitButton, submitButtons, submitJustify, submitLabel, submitVariant, summaryLabel }) {
|
|
23
34
|
const { nodes: resolvedNodes, markUserEdit } = useFormResolver(action, componentRef, nodes);
|
|
24
35
|
return /* @__PURE__ */ jsx(PrefillProvider, {
|
|
25
36
|
value: { markUserEdit },
|
|
@@ -28,10 +39,15 @@ function FormBody({ action, children, componentRef, nodes, shouldRenderSubmitBut
|
|
|
28
39
|
children: /* @__PURE__ */ jsxs("div", {
|
|
29
40
|
className: "flex flex-col gap-6",
|
|
30
41
|
children: [children, shouldRenderSubmitButton && /* @__PURE__ */ jsx("div", {
|
|
31
|
-
className:
|
|
32
|
-
children: /* @__PURE__ */ jsx(FormSubmitButton, {
|
|
42
|
+
className: `flex gap-3 ${JUSTIFY_CLASS[submitJustify ?? "end"]}`,
|
|
43
|
+
children: submitButtons?.length ? submitButtons.map((button, index) => button.props.buttonType === "submit" ? /* @__PURE__ */ jsx(FormSubmitButton, {
|
|
44
|
+
label: button.props.label ?? submitLabel,
|
|
45
|
+
summaryLabel,
|
|
46
|
+
variant: button.props.variant ?? submitVariant ?? "default"
|
|
47
|
+
}, nodeKey(button, index)) : /* @__PURE__ */ jsx(RenderNode, { node: button }, nodeKey(button, index))) : /* @__PURE__ */ jsx(FormSubmitButton, {
|
|
33
48
|
label: submitLabel,
|
|
34
|
-
summaryLabel
|
|
49
|
+
summaryLabel,
|
|
50
|
+
variant: submitVariant ?? "default"
|
|
35
51
|
})
|
|
36
52
|
})]
|
|
37
53
|
})
|
|
@@ -39,6 +55,7 @@ function FormBody({ action, children, componentRef, nodes, shouldRenderSubmitBut
|
|
|
39
55
|
});
|
|
40
56
|
}
|
|
41
57
|
var FormComponent = ({ children, node }) => {
|
|
58
|
+
const { t } = useT("lattice");
|
|
42
59
|
const props = node.props;
|
|
43
60
|
const action = props.action ?? "#";
|
|
44
61
|
const errorBag = props.errorBag;
|
|
@@ -54,7 +71,10 @@ var FormComponent = ({ children, node }) => {
|
|
|
54
71
|
...state
|
|
55
72
|
}), [fieldValues, state]);
|
|
56
73
|
const shouldRenderSubmitButton = props.submitButton;
|
|
57
|
-
const
|
|
74
|
+
const submitButtons = props.submitButtons ?? void 0;
|
|
75
|
+
const submitJustify = props.submitJustify ?? void 0;
|
|
76
|
+
const submitLabel = props.submitLabel ?? t("form.submit", "Submit");
|
|
77
|
+
const submitVariant = props.submitVariant ?? void 0;
|
|
58
78
|
const summaryLabel = props.validationSummaryLabel;
|
|
59
79
|
const validationTimeout = props.validationTimeout ?? void 0;
|
|
60
80
|
return /* @__PURE__ */ jsx(Form, {
|
|
@@ -96,7 +116,10 @@ var FormComponent = ({ children, node }) => {
|
|
|
96
116
|
componentRef,
|
|
97
117
|
nodes: node.schema,
|
|
98
118
|
shouldRenderSubmitButton,
|
|
119
|
+
submitButtons,
|
|
120
|
+
submitJustify,
|
|
99
121
|
submitLabel,
|
|
122
|
+
submitVariant,
|
|
100
123
|
summaryLabel,
|
|
101
124
|
children
|
|
102
125
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.js","names":[],"sources":["../../../resources/js/form/components/form.tsx"],"sourcesContent":["import { Form as InertiaForm } from \"@inertiajs/react\";\nimport { withHeaders } from \"@lattice-php/lattice/core/headers\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/core/event-names\";\nimport { useWindowEvent } from \"@lattice-php/lattice/core/hooks/use-window-event\";\nimport type { Node, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { useMemo } from \"react\";\nimport { FormSubmitButton } from \"./base/submit-button\";\nimport { FormProvider } from \"@lattice-php/lattice/form/hooks/context\";\nimport { collectFields } from \"@lattice-php/lattice/form/lib/collect-fields\";\nimport { PrefillProvider } from \"@lattice-php/lattice/form/hooks/prefill-context\";\nimport { ResolvedNodesProvider } from \"@lattice-php/lattice/form/hooks/resolved-nodes\";\nimport { useFormResolver } from \"@lattice-php/lattice/form/hooks/use-form-resolver\";\nimport { FormValuesProvider } from \"@lattice-php/lattice/form/hooks/values\";\n\nfunction FormResetListener({\n componentId,\n reset,\n}: {\n componentId?: string;\n reset: (...fields: string[]) => void;\n}) {\n useWindowEvent(LATTICE_EVENT.resetForm, (event) => {\n const detail = (event as CustomEvent<{ form: string | null }>).detail;\n\n if (!detail?.form || detail.form === componentId) {\n reset();\n }\n });\n\n return null;\n}\n\nfunction FormBody({\n action,\n children,\n componentRef,\n nodes,\n shouldRenderSubmitButton,\n submitLabel,\n summaryLabel,\n}: {\n action: string;\n children: React.ReactNode;\n componentRef: string;\n nodes: Node[] | undefined;\n shouldRenderSubmitButton: boolean;\n submitLabel: string;\n summaryLabel: string;\n}) {\n const { nodes: resolvedNodes, markUserEdit } = useFormResolver(action, componentRef, nodes);\n\n return (\n <PrefillProvider value={{ markUserEdit }}>\n <ResolvedNodesProvider nodes={resolvedNodes}>\n <div className=\"flex flex-col gap-6\">\n {children}\n\n {shouldRenderSubmitButton && (\n <div className
|
|
1
|
+
{"version":3,"file":"form.js","names":[],"sources":["../../../resources/js/form/components/form.tsx"],"sourcesContent":["import { Form as InertiaForm } from \"@inertiajs/react\";\nimport { withHeaders } from \"@lattice-php/lattice/core/headers\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/core/event-names\";\nimport { useWindowEvent } from \"@lattice-php/lattice/core/hooks/use-window-event\";\nimport { nodeKey } from \"@lattice-php/lattice/core/nodes\";\nimport { RenderNode } from \"@lattice-php/lattice/core/renderer\";\nimport type { Node, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { ButtonVariant, Justify } from \"@lattice-php/lattice/types/generated\";\nimport { useMemo } from \"react\";\nimport { FormSubmitButton } from \"./base/submit-button\";\nimport { FormProvider } from \"@lattice-php/lattice/form/hooks/context\";\nimport { collectFields } from \"@lattice-php/lattice/form/lib/collect-fields\";\nimport { PrefillProvider } from \"@lattice-php/lattice/form/hooks/prefill-context\";\nimport { ResolvedNodesProvider } from \"@lattice-php/lattice/form/hooks/resolved-nodes\";\nimport { useFormResolver } from \"@lattice-php/lattice/form/hooks/use-form-resolver\";\nimport { FormValuesProvider } from \"@lattice-php/lattice/form/hooks/values\";\n\nconst JUSTIFY_CLASS: Record<Justify, string> = {\n start: \"justify-start\",\n center: \"justify-center\",\n end: \"justify-end\",\n between: \"justify-between\",\n around: \"justify-around\",\n evenly: \"justify-evenly\",\n};\n\nfunction FormResetListener({\n componentId,\n reset,\n}: {\n componentId?: string;\n reset: (...fields: string[]) => void;\n}) {\n useWindowEvent(LATTICE_EVENT.resetForm, (event) => {\n const detail = (event as CustomEvent<{ form: string | null }>).detail;\n\n if (!detail?.form || detail.form === componentId) {\n reset();\n }\n });\n\n return null;\n}\n\nfunction FormBody({\n action,\n children,\n componentRef,\n nodes,\n shouldRenderSubmitButton,\n submitButtons,\n submitJustify,\n submitLabel,\n submitVariant,\n summaryLabel,\n}: {\n action: string;\n children: React.ReactNode;\n componentRef: string;\n nodes: Node[] | undefined;\n shouldRenderSubmitButton: boolean;\n submitButtons: Node<\"button\">[] | undefined;\n submitJustify: Justify | undefined;\n submitLabel: string;\n submitVariant: ButtonVariant | undefined;\n summaryLabel: string;\n}) {\n const { nodes: resolvedNodes, markUserEdit } = useFormResolver(action, componentRef, nodes);\n\n return (\n <PrefillProvider value={{ markUserEdit }}>\n <ResolvedNodesProvider nodes={resolvedNodes}>\n <div className=\"flex flex-col gap-6\">\n {children}\n\n {shouldRenderSubmitButton && (\n <div className={`flex gap-3 ${JUSTIFY_CLASS[submitJustify ?? \"end\"]}`}>\n {submitButtons?.length ? (\n submitButtons.map((button, index) =>\n button.props.buttonType === \"submit\" ? (\n <FormSubmitButton\n key={nodeKey(button, index)}\n label={button.props.label ?? submitLabel}\n summaryLabel={summaryLabel}\n variant={button.props.variant ?? submitVariant ?? \"default\"}\n />\n ) : (\n <RenderNode key={nodeKey(button, index)} node={button} />\n ),\n )\n ) : (\n <FormSubmitButton\n label={submitLabel}\n summaryLabel={summaryLabel}\n variant={submitVariant ?? \"default\"}\n />\n )}\n </div>\n )}\n </div>\n </ResolvedNodesProvider>\n </PrefillProvider>\n );\n}\n\nexport const FormComponent: RendererComponent<\"form\"> = ({ children, node }) => {\n const { t } = useT(\"lattice\");\n const props = node.props;\n const action = props.action ?? \"#\";\n const errorBag = props.errorBag;\n const componentRef = props.ref ?? \"\";\n const method = props.method ?? \"post\";\n const precognitive = props.precognitive;\n const resetOnError = props.resetOnError ?? false;\n const resetOnSuccess = props.resetOnSuccess ?? [];\n const state = props.state;\n const { labels: fieldLabels, values: fieldValues } = useMemo(\n () => collectFields(node.schema),\n [node.schema],\n );\n const initialValues = useMemo(() => ({ ...fieldValues, ...state }), [fieldValues, state]);\n const shouldRenderSubmitButton = props.submitButton;\n const submitButtons = props.submitButtons ?? undefined;\n const submitJustify = props.submitJustify ?? undefined;\n const submitLabel = props.submitLabel ?? t(\"form.submit\", \"Submit\");\n const submitVariant = props.submitVariant ?? undefined;\n const summaryLabel = props.validationSummaryLabel;\n const validationTimeout = props.validationTimeout ?? undefined;\n\n return (\n <InertiaForm\n action={action}\n data-slot=\"form\"\n data-lattice-component={node.id}\n errorBag={errorBag}\n method={method}\n resetOnError={resetOnError}\n resetOnSuccess={resetOnSuccess}\n validationTimeout={precognitive ? validationTimeout : undefined}\n headers={withHeaders(componentRef)}\n className=\"mx-auto flex w-full max-w-2xl flex-col gap-6\"\n >\n {({ clearErrors, errors, processing, reset, validate }) => (\n <FormProvider\n value={{\n action,\n clearErrors: (field) => clearErrors(field),\n componentId: node.id,\n componentRef,\n errors: errors as Record<string, string | undefined>,\n fieldLabels,\n precognitive,\n processing,\n validate: (field) => validate(field),\n }}\n >\n <FormResetListener componentId={node.id} reset={reset} />\n\n {props.status && (\n <div className=\"text-center text-sm font-medium text-lt-success\">{props.status}</div>\n )}\n\n <FormValuesProvider initial={initialValues}>\n <FormBody\n action={action}\n componentRef={componentRef}\n nodes={node.schema}\n shouldRenderSubmitButton={shouldRenderSubmitButton}\n submitButtons={submitButtons}\n submitJustify={submitJustify}\n submitLabel={submitLabel}\n submitVariant={submitVariant}\n summaryLabel={summaryLabel}\n >\n {children}\n </FormBody>\n </FormValuesProvider>\n </FormProvider>\n )}\n </InertiaForm>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAkBA,IAAM,gBAAyC;CAC7C,OAAO;CACP,QAAQ;CACR,KAAK;CACL,SAAS;CACT,QAAQ;CACR,QAAQ;AACV;AAEA,SAAS,kBAAkB,EACzB,aACA,SAIC;CACD,eAAe,cAAc,YAAY,UAAU;EACjD,MAAM,SAAU,MAA+C;EAE/D,IAAI,CAAC,QAAQ,QAAQ,OAAO,SAAS,aACnC,MAAM;CAEV,CAAC;CAED,OAAO;AACT;AAEA,SAAS,SAAS,EAChB,QACA,UACA,cACA,OACA,0BACA,eACA,eACA,aACA,eACA,gBAYC;CACD,MAAM,EAAE,OAAO,eAAe,iBAAiB,gBAAgB,QAAQ,cAAc,KAAK;CAE1F,OACE,oBAAC,iBAAD;EAAiB,OAAO,EAAE,aAAa;YACrC,oBAAC,uBAAD;GAAuB,OAAO;aAC5B,qBAAC,OAAD;IAAK,WAAU;cAAf,CACG,UAEA,4BACC,oBAAC,OAAD;KAAK,WAAW,cAAc,cAAc,iBAAiB;eAC1D,eAAe,SACd,cAAc,KAAK,QAAQ,UACzB,OAAO,MAAM,eAAe,WAC1B,oBAAC,kBAAD;MAEE,OAAO,OAAO,MAAM,SAAS;MACf;MACd,SAAS,OAAO,MAAM,WAAW,iBAAiB;KACnD,GAJM,QAAQ,QAAQ,KAAK,CAI3B,IAED,oBAAC,YAAD,EAAyC,MAAM,OAAS,GAAvC,QAAQ,QAAQ,KAAK,CAAkB,CAE5D,IAEA,oBAAC,kBAAD;MACE,OAAO;MACO;MACd,SAAS,iBAAiB;KAC3B,CAAA;IAEA,CAAA,CAEJ;;EACgB,CAAA;CACR,CAAA;AAErB;AAEA,IAAa,iBAA4C,EAAE,UAAU,WAAW;CAC9E,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,QAAQ,KAAK;CACnB,MAAM,SAAS,MAAM,UAAU;CAC/B,MAAM,WAAW,MAAM;CACvB,MAAM,eAAe,MAAM,OAAO;CAClC,MAAM,SAAS,MAAM,UAAU;CAC/B,MAAM,eAAe,MAAM;CAC3B,MAAM,eAAe,MAAM,gBAAgB;CAC3C,MAAM,iBAAiB,MAAM,kBAAkB,CAAC;CAChD,MAAM,QAAQ,MAAM;CACpB,MAAM,EAAE,QAAQ,aAAa,QAAQ,gBAAgB,cAC7C,cAAc,KAAK,MAAM,GAC/B,CAAC,KAAK,MAAM,CACd;CACA,MAAM,gBAAgB,eAAe;EAAE,GAAG;EAAa,GAAG;CAAM,IAAI,CAAC,aAAa,KAAK,CAAC;CACxF,MAAM,2BAA2B,MAAM;CACvC,MAAM,gBAAgB,MAAM,iBAAiB,KAAA;CAC7C,MAAM,gBAAgB,MAAM,iBAAiB,KAAA;CAC7C,MAAM,cAAc,MAAM,eAAe,EAAE,eAAe,QAAQ;CAClE,MAAM,gBAAgB,MAAM,iBAAiB,KAAA;CAC7C,MAAM,eAAe,MAAM;CAC3B,MAAM,oBAAoB,MAAM,qBAAqB,KAAA;CAErD,OACE,oBAAC,MAAD;EACU;EACR,aAAU;EACV,0BAAwB,KAAK;EACnB;EACF;EACM;EACE;EAChB,mBAAmB,eAAe,oBAAoB,KAAA;EACtD,SAAS,YAAY,YAAY;EACjC,WAAU;aAER,EAAE,aAAa,QAAQ,YAAY,OAAO,eAC1C,qBAAC,cAAD;GACE,OAAO;IACL;IACA,cAAc,UAAU,YAAY,KAAK;IACzC,aAAa,KAAK;IAClB;IACQ;IACR;IACA;IACA;IACA,WAAW,UAAU,SAAS,KAAK;GACrC;aAXF;IAaE,oBAAC,mBAAD;KAAmB,aAAa,KAAK;KAAW;IAAQ,CAAA;IAEvD,MAAM,UACL,oBAAC,OAAD;KAAK,WAAU;eAAmD,MAAM;IAAY,CAAA;IAGtF,oBAAC,oBAAD;KAAoB,SAAS;eAC3B,oBAAC,UAAD;MACU;MACM;MACd,OAAO,KAAK;MACc;MACX;MACA;MACF;MACE;MACD;MAEb;KACO,CAAA;IACQ,CAAA;GACR;;CAEL,CAAA;AAEjB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { cn } from "../../lib/utils.js";
|
|
2
1
|
import { useT } from "../../i18n/instance.js";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
3
|
import { Popover, PopoverContent, PopoverTrigger } from "../../ui/popover.js";
|
|
4
4
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../../ui/dropdown-menu.js";
|
|
5
5
|
import { seedRichEditorExtension } from "./registry.js";
|
package/dist/format/number.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { NumberFormat } from '../types/
|
|
1
|
+
import { NumberFormat } from '../types/generated.js';
|
|
2
2
|
export declare function formatNumber(value: unknown, format: NumberFormat, locale: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"number.js","names":[],"sources":["../../resources/js/format/number.ts"],"sourcesContent":["import type { NumberFormat } from \"@lattice-php/lattice/types\";\nimport { numericValue } from \"./numeric\";\n\nexport function formatNumber(value: unknown, format: NumberFormat, locale: string): string {\n const number = numericValue(value);\n\n if (number === null) {\n return String(value ?? \"\");\n }\n\n const options: Intl.NumberFormatOptions = {\n notation: format.notation as Intl.NumberFormatOptions[\"notation\"],\n minimumFractionDigits: format.minimumFractionDigits ?? undefined,\n maximumFractionDigits: format.maximumFractionDigits ?? undefined,\n };\n\n if (format.currency) {\n options.style = \"currency\";\n options.currency = format.currency;\n } else if (format.unit) {\n options.style = \"unit\";\n options.unit = format.unit;\n }\n\n return new Intl.NumberFormat(locale, options).format(number);\n}\n"],"mappings":";;AAGA,SAAgB,aAAa,OAAgB,QAAsB,QAAwB;CACzF,MAAM,SAAS,aAAa,KAAK;CAEjC,IAAI,WAAW,MACb,OAAO,OAAO,SAAS,EAAE;CAG3B,MAAM,UAAoC;EACxC,UAAU,OAAO;EACjB,uBAAuB,OAAO,yBAAyB,KAAA;EACvD,uBAAuB,OAAO,yBAAyB,KAAA;CACzD;CAEA,IAAI,OAAO,UAAU;EACnB,QAAQ,QAAQ;EAChB,QAAQ,WAAW,OAAO;CAC5B,OAAO,IAAI,OAAO,MAAM;EACtB,QAAQ,QAAQ;EAChB,QAAQ,OAAO,OAAO;CACxB;CAEA,OAAO,IAAI,KAAK,aAAa,QAAQ,OAAO,EAAE,OAAO,MAAM;AAC7D"}
|
|
1
|
+
{"version":3,"file":"number.js","names":[],"sources":["../../resources/js/format/number.ts"],"sourcesContent":["import type { NumberFormat } from \"@lattice-php/lattice/types/generated\";\nimport { numericValue } from \"./numeric\";\n\nexport function formatNumber(value: unknown, format: NumberFormat, locale: string): string {\n const number = numericValue(value);\n\n if (number === null) {\n return String(value ?? \"\");\n }\n\n const options: Intl.NumberFormatOptions = {\n notation: format.notation as Intl.NumberFormatOptions[\"notation\"],\n minimumFractionDigits: format.minimumFractionDigits ?? undefined,\n maximumFractionDigits: format.maximumFractionDigits ?? undefined,\n };\n\n if (format.currency) {\n options.style = \"currency\";\n options.currency = format.currency;\n } else if (format.unit) {\n options.style = \"unit\";\n options.unit = format.unit;\n }\n\n return new Intl.NumberFormat(locale, options).format(number);\n}\n"],"mappings":";;AAGA,SAAgB,aAAa,OAAgB,QAAsB,QAAwB;CACzF,MAAM,SAAS,aAAa,KAAK;CAEjC,IAAI,WAAW,MACb,OAAO,OAAO,SAAS,EAAE;CAG3B,MAAM,UAAoC;EACxC,UAAU,OAAO;EACjB,uBAAuB,OAAO,yBAAyB,KAAA;EACvD,uBAAuB,OAAO,yBAAyB,KAAA;CACzD;CAEA,IAAI,OAAO,UAAU;EACnB,QAAQ,QAAQ;EAChB,QAAQ,WAAW,OAAO;CAC5B,OAAO,IAAI,OAAO,MAAM;EACtB,QAAQ,QAAQ;EAChB,QAAQ,OAAO,OAAO;CACxB;CAEA,OAAO,IAAI,KAAK,aAAa,QAAQ,OAAO,EAAE,OAAO,MAAM;AAC7D"}
|
package/dist/format/value.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DateFormat, NumberFormat } from '../types/
|
|
1
|
+
import { DateFormat, NumberFormat } from '../types/generated.js';
|
|
2
2
|
export type Format = NumberFormat | DateFormat;
|
|
3
3
|
export declare function formatValue(value: unknown, format: Format | null, ctx: {
|
|
4
4
|
locale: string;
|
package/dist/format/value.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"value.js","names":[],"sources":["../../resources/js/format/value.ts"],"sourcesContent":["import type { DateFormat, NumberFormat } from \"@lattice-php/lattice/types\";\nimport { formatDateValue } from \"./date-time\";\nimport { formatNumber } from \"./number\";\n\nexport type Format = NumberFormat | DateFormat;\n\nfunction isDateFormat(format: Format): format is DateFormat {\n return format.kind === \"date\";\n}\n\nexport function formatValue(\n value: unknown,\n format: Format | null,\n ctx: { locale: string; timezone: string },\n): string {\n if (format === null) {\n return String(value ?? \"\");\n }\n\n return isDateFormat(format)\n ? formatDateValue(value, format, { locale: ctx.locale, timeZone: ctx.timezone })\n : formatNumber(value, format, ctx.locale);\n}\n"],"mappings":";;;AAMA,SAAS,aAAa,QAAsC;CAC1D,OAAO,OAAO,SAAS;AACzB;AAEA,SAAgB,YACd,OACA,QACA,KACQ;CACR,IAAI,WAAW,MACb,OAAO,OAAO,SAAS,EAAE;CAG3B,OAAO,aAAa,MAAM,IACtB,gBAAgB,OAAO,QAAQ;EAAE,QAAQ,IAAI;EAAQ,UAAU,IAAI;CAAS,CAAC,IAC7E,aAAa,OAAO,QAAQ,IAAI,MAAM;AAC5C"}
|
|
1
|
+
{"version":3,"file":"value.js","names":[],"sources":["../../resources/js/format/value.ts"],"sourcesContent":["import type { DateFormat, NumberFormat } from \"@lattice-php/lattice/types/generated\";\nimport { formatDateValue } from \"./date-time\";\nimport { formatNumber } from \"./number\";\n\nexport type Format = NumberFormat | DateFormat;\n\nfunction isDateFormat(format: Format): format is DateFormat {\n return format.kind === \"date\";\n}\n\nexport function formatValue(\n value: unknown,\n format: Format | null,\n ctx: { locale: string; timezone: string },\n): string {\n if (format === null) {\n return String(value ?? \"\");\n }\n\n return isDateFormat(format)\n ? formatDateValue(value, format, { locale: ctx.locale, timeZone: ctx.timezone })\n : formatNumber(value, format, ctx.locale);\n}\n"],"mappings":";;;AAMA,SAAS,aAAa,QAAsC;CAC1D,OAAO,OAAO,SAAS;AACzB;AAEA,SAAgB,YACd,OACA,QACA,KACQ;CACR,IAAI,WAAW,MACb,OAAO,OAAO,SAAS,EAAE;CAG3B,OAAO,aAAa,MAAM,IACtB,gBAAgB,OAAO,QAAQ;EAAE,QAAQ,IAAI;EAAQ,UAAU,IAAI;CAAS,CAAC,IAC7E,aAAa,OAAO,QAAQ,IAAI,MAAM;AAC5C"}
|
package/dist/i18n/backend.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { localeHeader } from "./locale.js";
|
|
2
1
|
import { setConfig } from "./config.js";
|
|
2
|
+
import { localeHeader } from "./locale.js";
|
|
3
3
|
import { ensureI18n, i18n, preloadLanguages } from "./instance.js";
|
|
4
4
|
import HttpBackend from "i18next-http-backend";
|
|
5
5
|
//#region resources/js/i18n/backend.ts
|
package/dist/i18n/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { LocaleReload } from "./locale-reload.js";
|
|
2
|
-
import { i18nConfigFromPageProps } from "./shared-props.js";
|
|
3
1
|
import { currentLocale, localeHeader, setLocale, useLocale } from "./locale.js";
|
|
4
2
|
import { i18n, translate, useT } from "./instance.js";
|
|
3
|
+
import { LocaleReload } from "./locale-reload.js";
|
|
4
|
+
import { i18nConfigFromPageProps } from "./shared-props.js";
|
|
5
5
|
import { configureI18n, enableBackend } from "./backend.js";
|
|
6
6
|
import { LocaleSwitcher, useLocaleOptions } from "./locale-switcher.js";
|
|
7
7
|
import { configureI18nFromPageProps } from "./page-props.js";
|
package/dist/i18n/instance.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { i18n as I18nInstance, InitOptions } from 'i18next';
|
|
2
|
+
export declare const DEFAULT_NAMESPACE = "lattice";
|
|
2
3
|
type TranslationFunction = (key: string, defaultValue?: string, options?: Record<string, unknown>) => string;
|
|
3
4
|
type TranslationResult = {
|
|
4
5
|
t: TranslationFunction;
|
package/dist/i18n/instance.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { currentLocale, subscribeLocale, useLocale } from "./locale.js";
|
|
2
1
|
import { useConfig } from "./config.js";
|
|
2
|
+
import { currentLocale, subscribeLocale, useLocale } from "./locale.js";
|
|
3
3
|
import { useCallback, useSyncExternalStore } from "react";
|
|
4
4
|
import i18next from "i18next";
|
|
5
5
|
//#region resources/js/i18n/instance.ts
|
|
6
|
-
var
|
|
6
|
+
var DEFAULT_NAMESPACE = "lattice";
|
|
7
7
|
var i18n = i18next.createInstance();
|
|
8
8
|
var initialization;
|
|
9
9
|
var revision = 0;
|
|
@@ -38,8 +38,8 @@ function ensureI18n(extend) {
|
|
|
38
38
|
const base = {
|
|
39
39
|
lng: currentLocale(),
|
|
40
40
|
fallbackLng: "en",
|
|
41
|
-
ns: [
|
|
42
|
-
defaultNS:
|
|
41
|
+
ns: [DEFAULT_NAMESPACE],
|
|
42
|
+
defaultNS: DEFAULT_NAMESPACE,
|
|
43
43
|
interpolation: { escapeValue: false }
|
|
44
44
|
};
|
|
45
45
|
initialization = i18n.init(extend ? extend(base) : base);
|
|
@@ -90,6 +90,6 @@ function translate(namespace, key, defaultValue, options) {
|
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
//#endregion
|
|
93
|
-
export { ensureI18n, i18n, preloadLanguages, translate, useT };
|
|
93
|
+
export { DEFAULT_NAMESPACE, ensureI18n, i18n, preloadLanguages, translate, useT };
|
|
94
94
|
|
|
95
95
|
//# sourceMappingURL=instance.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance.js","names":[],"sources":["../../resources/js/i18n/instance.ts"],"sourcesContent":["import i18next, { type i18n as I18nInstance, type InitOptions } from \"i18next\";\nimport { useCallback, useSyncExternalStore } from \"react\";\nimport { useConfig } from \"./config\";\nimport { currentLocale, subscribeLocale, useLocale } from \"./locale\";\n\
|
|
1
|
+
{"version":3,"file":"instance.js","names":[],"sources":["../../resources/js/i18n/instance.ts"],"sourcesContent":["import i18next, { type i18n as I18nInstance, type InitOptions } from \"i18next\";\nimport { useCallback, useSyncExternalStore } from \"react\";\nimport { useConfig } from \"./config\";\nimport { currentLocale, subscribeLocale, useLocale } from \"./locale\";\n\nexport const DEFAULT_NAMESPACE = \"lattice\";\n\ntype TranslationFunction = (\n key: string,\n defaultValue?: string,\n options?: Record<string, unknown>,\n) => string;\n\ntype TranslationResult = {\n t: TranslationFunction;\n i18n: I18nInstance;\n locale: string;\n locales: readonly string[];\n ready: boolean;\n setLocale: (locale: string) => void;\n};\n\nexport const i18n: I18nInstance = i18next.createInstance();\n\nlet initialization: Promise<unknown> | undefined;\nlet revision = 0;\n\nfunction subscribe(onStoreChange: () => void): () => void {\n const listener = () => {\n revision += 1;\n onStoreChange();\n };\n\n i18n.on(\"initialized\", listener);\n i18n.on(\"loaded\", listener);\n i18n.on(\"languageChanged\", listener);\n i18n.store?.on(\"added\", listener);\n i18n.store?.on(\"removed\", listener);\n\n return () => {\n i18n.off(\"initialized\", listener);\n i18n.off(\"loaded\", listener);\n i18n.off(\"languageChanged\", listener);\n i18n.store?.off(\"added\", listener);\n i18n.store?.off(\"removed\", listener);\n };\n}\n\nfunction snapshot(): number {\n return revision;\n}\n\n/**\n * Initialize the instance exactly once. The first caller wins — a rendered\n * component (inline English, zero config) or `enableBackend()`, which registers\n * its backend first because i18next can only wire a backend during `init`.\n */\nexport function ensureI18n(extend?: (base: InitOptions) => InitOptions): Promise<unknown> {\n if (!initialization) {\n const base: InitOptions = {\n lng: currentLocale(),\n fallbackLng: \"en\",\n ns: [DEFAULT_NAMESPACE],\n defaultNS: DEFAULT_NAMESPACE,\n interpolation: { escapeValue: false },\n };\n\n initialization = i18n.init(extend ? extend(base) : base);\n }\n\n return initialization;\n}\n\nsubscribeLocale((locale) => {\n void ensureI18n().then(() => {\n if (i18n.language !== locale) {\n void i18n.changeLanguage(locale);\n }\n });\n});\n\n/**\n * Eagerly load the namespaces for the given locales so a later\n * `changeLanguage` resolves them from the store instead of an HTTP round-trip,\n * which would otherwise flash the fallback language on switch. The active\n * locale is already loaded by {@link ensureI18n}, so it is skipped.\n */\nexport async function preloadLanguages(locales: readonly string[]): Promise<void> {\n const pending = locales.filter((locale) => locale !== currentLocale());\n\n if (pending.length === 0) {\n return;\n }\n\n await ensureI18n();\n await i18n.loadLanguages([...pending]);\n}\n\nexport function useT(namespace: string): TranslationResult {\n ensureI18n();\n useSyncExternalStore(subscribe, snapshot, snapshot);\n const { locales } = useConfig();\n const { locale, setLocale } = useLocale();\n\n const t = useCallback<TranslationFunction>(\n (key, defaultValue = key, options = {}) => translate(namespace, key, defaultValue, options),\n [namespace],\n );\n\n return { t, i18n, locale, locales, ready: i18n.isInitialized, setLocale };\n}\n\nexport function translate(\n namespace: string,\n key: string,\n defaultValue: string,\n options?: Record<string, unknown>,\n): string {\n ensureI18n();\n\n if (!i18n.isInitialized || !i18n.hasLoadedNamespace(namespace)) {\n return i18n.t(key, defaultValue, { ns: namespace, ...options, saveMissing: false });\n }\n\n return i18n.t(key, defaultValue, { ns: namespace, ...options });\n}\n"],"mappings":";;;;;AAKA,IAAa,oBAAoB;AAiBjC,IAAa,OAAqB,QAAQ,eAAe;AAEzD,IAAI;AACJ,IAAI,WAAW;AAEf,SAAS,UAAU,eAAuC;CACxD,MAAM,iBAAiB;EACrB,YAAY;EACZ,cAAc;CAChB;CAEA,KAAK,GAAG,eAAe,QAAQ;CAC/B,KAAK,GAAG,UAAU,QAAQ;CAC1B,KAAK,GAAG,mBAAmB,QAAQ;CACnC,KAAK,OAAO,GAAG,SAAS,QAAQ;CAChC,KAAK,OAAO,GAAG,WAAW,QAAQ;CAElC,aAAa;EACX,KAAK,IAAI,eAAe,QAAQ;EAChC,KAAK,IAAI,UAAU,QAAQ;EAC3B,KAAK,IAAI,mBAAmB,QAAQ;EACpC,KAAK,OAAO,IAAI,SAAS,QAAQ;EACjC,KAAK,OAAO,IAAI,WAAW,QAAQ;CACrC;AACF;AAEA,SAAS,WAAmB;CAC1B,OAAO;AACT;;;;;;AAOA,SAAgB,WAAW,QAA+D;CACxF,IAAI,CAAC,gBAAgB;EACnB,MAAM,OAAoB;GACxB,KAAK,cAAc;GACnB,aAAa;GACb,IAAI,CAAC,iBAAiB;GACtB,WAAW;GACX,eAAe,EAAE,aAAa,MAAM;EACtC;EAEA,iBAAiB,KAAK,KAAK,SAAS,OAAO,IAAI,IAAI,IAAI;CACzD;CAEA,OAAO;AACT;AAEA,iBAAiB,WAAW;CAC1B,WAAgB,EAAE,WAAW;EAC3B,IAAI,KAAK,aAAa,QACpB,KAAU,eAAe,MAAM;CAEnC,CAAC;AACH,CAAC;;;;;;;AAQD,eAAsB,iBAAiB,SAA2C;CAChF,MAAM,UAAU,QAAQ,QAAQ,WAAW,WAAW,cAAc,CAAC;CAErE,IAAI,QAAQ,WAAW,GACrB;CAGF,MAAM,WAAW;CACjB,MAAM,KAAK,cAAc,CAAC,GAAG,OAAO,CAAC;AACvC;AAEA,SAAgB,KAAK,WAAsC;CACzD,WAAW;CACX,qBAAqB,WAAW,UAAU,QAAQ;CAClD,MAAM,EAAE,YAAY,UAAU;CAC9B,MAAM,EAAE,QAAQ,cAAc,UAAU;CAOxC,OAAO;EAAE,GALC,aACP,KAAK,eAAe,KAAK,UAAU,CAAC,MAAM,UAAU,WAAW,KAAK,cAAc,OAAO,GAC1F,CAAC,SAAS,CAGH;EAAG;EAAM;EAAQ;EAAS,OAAO,KAAK;EAAe;CAAU;AAC1E;AAEA,SAAgB,UACd,WACA,KACA,cACA,SACQ;CACR,WAAW;CAEX,IAAI,CAAC,KAAK,iBAAiB,CAAC,KAAK,mBAAmB,SAAS,GAC3D,OAAO,KAAK,EAAE,KAAK,cAAc;EAAE,IAAI;EAAW,GAAG;EAAS,aAAa;CAAM,CAAC;CAGpF,OAAO,KAAK,EAAE,KAAK,cAAc;EAAE,IAAI;EAAW,GAAG;CAAQ,CAAC;AAChE"}
|
package/dist/i18n/timezone.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { LATTICE_EVENT } from "../core/event-names.js";
|
|
2
1
|
import { configTimezone, subscribeConfig } from "./config.js";
|
|
2
|
+
import { LATTICE_EVENT } from "../core/event-names.js";
|
|
3
3
|
import { useSyncExternalStore } from "react";
|
|
4
4
|
//#region resources/js/i18n/timezone.ts
|
|
5
5
|
var fallback = "UTC";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { useT } from "../../i18n/instance.js";
|
|
1
2
|
import { cn } from "../../lib/utils.js";
|
|
2
3
|
import { Icon } from "../../icons/sprite.js";
|
|
3
4
|
import { RenderNode } from "../../core/renderer.js";
|
|
4
5
|
import { onCallout } from "../../toast/callout.js";
|
|
5
|
-
import { useT } from "../../i18n/instance.js";
|
|
6
6
|
import { variantStyles } from "../../toast/variant-styles.js";
|
|
7
7
|
import { useEffect, useState } from "react";
|
|
8
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Icon } from "../../icons/sprite.js";
|
|
2
1
|
import { useT } from "../../i18n/instance.js";
|
|
2
|
+
import { Icon } from "../../icons/sprite.js";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
//#region resources/js/notifications/components/empty-state.tsx
|
|
5
5
|
function EmptyState() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { useT } from "../../i18n/instance.js";
|
|
1
2
|
import { cn } from "../../lib/utils.js";
|
|
2
3
|
import { IconRenderer } from "../../icons/icon-renderer.js";
|
|
3
4
|
import { RenderNode } from "../../core/renderer.js";
|
|
4
|
-
import { useT } from "../../i18n/instance.js";
|
|
5
5
|
import { Link } from "@inertiajs/react";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
//#region resources/js/notifications/components/notification-item.tsx
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Icon } from "../../icons/sprite.js";
|
|
2
1
|
import { useT } from "../../i18n/instance.js";
|
|
2
|
+
import { Icon } from "../../icons/sprite.js";
|
|
3
3
|
import { Popover, PopoverContent, PopoverTrigger } from "../../ui/popover.js";
|
|
4
4
|
import { Dialog, DialogContent, DialogTitle } from "../../ui/dialog.js";
|
|
5
5
|
import { Badge } from "../../ui/badge.js";
|
|
@@ -79,6 +79,7 @@ var NotificationsComponent = ({ node }) => {
|
|
|
79
79
|
open: store.open,
|
|
80
80
|
onOpenChange: store.setOpen,
|
|
81
81
|
children: /* @__PURE__ */ jsxs(DialogContent, {
|
|
82
|
+
"aria-describedby": void 0,
|
|
82
83
|
className: "p-0",
|
|
83
84
|
placement: "end",
|
|
84
85
|
width: "sm",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.js","names":[],"sources":["../../../resources/js/notifications/components/notifications.tsx"],"sourcesContent":["import { Component, lazy, Suspense, type ReactNode } from \"react\";\nimport { Badge } from \"@lattice-php/lattice/ui/badge\";\nimport { Dialog, DialogContent, DialogTitle } from \"@lattice-php/lattice/ui/dialog\";\nimport {\n Popover as PopoverRoot,\n PopoverContent,\n PopoverTrigger,\n} from \"@lattice-php/lattice/ui/popover\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { useNotifications } from \"@lattice-php/lattice/notifications/store\";\nimport type { NotificationItem } from \"@lattice-php/lattice/notifications/types\";\nimport { NotificationList } from \"./notification-list\";\n\nconst NotificationsEcho = lazy(() =>\n import(\"./notifications-echo\").then((m) => ({ default: m.NotificationsEcho })),\n);\n\nclass EchoBoundary extends Component<{ children: ReactNode }, { failed: boolean }> {\n state = { failed: false };\n\n static getDerivedStateFromError(): { failed: boolean } {\n return { failed: true };\n }\n\n componentDidCatch(): void {\n console.warn(\n \"[lattice] The notifications bell declares a realtime channel but Echo is unavailable. Install @laravel/echo-react and call configureEcho().\",\n );\n }\n\n render(): ReactNode {\n return this.state.failed ? null : this.props.children;\n }\n}\n\nconst NotificationsComponent: RendererComponent<\"notifications\"> = ({ node }) => {\n const { t } = useT(\"lattice\");\n const store = useNotifications({\n endpoint: node.props.endpoint,\n pollingInterval: node.props.pollingInterval,\n });\n\n const label = t(\"notifications.label\", \"Notifications\");\n\n const trigger = (\n <span className=\"relative inline-flex items-center justify-center rounded-lt-sm p-2 hover:bg-lt-muted\">\n <Icon name=\"bell\" className=\"size-lt-icon-md\" />\n {store.unreadCount > 0 ? (\n <Badge\n variant=\"destructive\"\n data-test=\"notifications-badge\"\n className=\"absolute -right-0.5 -top-0.5 min-w-4 px-1 py-0 text-[10px]\"\n >\n {store.unreadCount}\n </Badge>\n ) : null}\n </span>\n );\n\n const panel = (\n <div className=\"w-80\" data-test=\"notifications-panel\">\n <div className=\"flex items-center justify-between border-b border-lt-border px-3 py-2\">\n <span className=\"text-sm font-medium\">{t(\"notifications.heading\", \"Notifications\")}</span>\n {store.unreadCount > 0 ? (\n <button\n type=\"button\"\n className=\"text-xs text-lt-muted-fg hover:text-lt-fg\"\n onClick={store.markAllRead}\n >\n {t(\"notifications.mark-all-read\", \"Mark all read\")}\n </button>\n ) : null}\n </div>\n <NotificationList\n notifications={store.notifications}\n status={store.status}\n hasMore={store.hasMore}\n onMarkRead={store.markRead}\n onDismiss={store.dismiss}\n onLoadMore={store.loadMore}\n />\n </div>\n );\n\n return (\n <>\n {node.props.channel ? (\n <EchoBoundary>\n <Suspense fallback={null}>\n <NotificationsEcho\n channel={node.props.channel}\n onReceive={(item: NotificationItem) => store.receive(item)}\n />\n </Suspense>\n </EchoBoundary>\n ) : null}\n\n {node.props.slideOut ? (\n <>\n <button\n type=\"button\"\n aria-label={label}\n data-test=\"notifications-trigger\"\n onClick={() => store.setOpen(true)}\n >\n {trigger}\n </button>\n <Dialog open={store.open} onOpenChange={store.setOpen}>\n <DialogContent className=\"p-0\" placement=\"end\" width=\"sm\">\n <DialogTitle className=\"sr-only\">{label}</DialogTitle>\n {panel}\n </DialogContent>\n </Dialog>\n </>\n ) : (\n <PopoverRoot open={store.open} onOpenChange={store.setOpen}>\n <PopoverTrigger asChild>\n <button type=\"button\" aria-label={label} data-test=\"notifications-trigger\">\n {trigger}\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"p-0\">\n {panel}\n </PopoverContent>\n </PopoverRoot>\n )}\n </>\n );\n};\n\nexport default NotificationsComponent;\n"],"mappings":";;;;;;;;;;AAeA,IAAM,oBAAoB,WACxB,OAAO,2BAAwB,MAAM,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAC/E;AAEA,IAAM,eAAN,cAA2B,UAAwD;CACjF,QAAQ,EAAE,QAAQ,MAAM;CAExB,OAAO,2BAAgD;EACrD,OAAO,EAAE,QAAQ,KAAK;CACxB;CAEA,oBAA0B;EACxB,QAAQ,KACN,6IACF;CACF;CAEA,SAAoB;EAClB,OAAO,KAAK,MAAM,SAAS,OAAO,KAAK,MAAM;CAC/C;AACF;AAEA,IAAM,0BAA8D,EAAE,WAAW;CAC/E,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,QAAQ,iBAAiB;EAC7B,UAAU,KAAK,MAAM;EACrB,iBAAiB,KAAK,MAAM;CAC9B,CAAC;CAED,MAAM,QAAQ,EAAE,uBAAuB,eAAe;CAEtD,MAAM,UACJ,qBAAC,QAAD;EAAM,WAAU;YAAhB,CACE,oBAAC,MAAD;GAAM,MAAK;GAAO,WAAU;EAAmB,CAAA,GAC9C,MAAM,cAAc,IACnB,oBAAC,OAAD;GACE,SAAQ;GACR,aAAU;GACV,WAAU;aAET,MAAM;EACF,CAAA,IACL,IACA;;CAGR,MAAM,QACJ,qBAAC,OAAD;EAAK,WAAU;EAAO,aAAU;YAAhC,CACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,QAAD;IAAM,WAAU;cAAuB,EAAE,yBAAyB,eAAe;GAAQ,CAAA,GACxF,MAAM,cAAc,IACnB,oBAAC,UAAD;IACE,MAAK;IACL,WAAU;IACV,SAAS,MAAM;cAEd,EAAE,+BAA+B,eAAe;GAC3C,CAAA,IACN,IACD;MACL,oBAAC,kBAAD;GACE,eAAe,MAAM;GACrB,QAAQ,MAAM;GACd,SAAS,MAAM;GACf,YAAY,MAAM;GAClB,WAAW,MAAM;GACjB,YAAY,MAAM;EACnB,CAAA,CACE;;CAGP,OACE,qBAAA,YAAA,EAAA,UAAA,CACG,KAAK,MAAM,UACV,oBAAC,cAAD,EAAA,UACE,oBAAC,UAAD;EAAU,UAAU;YAClB,oBAAC,mBAAD;GACE,SAAS,KAAK,MAAM;GACpB,YAAY,SAA2B,MAAM,QAAQ,IAAI;EAC1D,CAAA;CACO,CAAA,EACE,CAAA,IACZ,MAEH,KAAK,MAAM,WACV,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,UAAD;EACE,MAAK;EACL,cAAY;EACZ,aAAU;EACV,eAAe,MAAM,QAAQ,IAAI;YAEhC;CACK,CAAA,GACR,oBAAC,QAAD;EAAQ,MAAM,MAAM;EAAM,cAAc,MAAM;YAC5C,qBAAC,eAAD;GAAe,WAAU;GAAM,WAAU;GAAM,OAAM;
|
|
1
|
+
{"version":3,"file":"notifications.js","names":[],"sources":["../../../resources/js/notifications/components/notifications.tsx"],"sourcesContent":["import { Component, lazy, Suspense, type ReactNode } from \"react\";\nimport { Badge } from \"@lattice-php/lattice/ui/badge\";\nimport { Dialog, DialogContent, DialogTitle } from \"@lattice-php/lattice/ui/dialog\";\nimport {\n Popover as PopoverRoot,\n PopoverContent,\n PopoverTrigger,\n} from \"@lattice-php/lattice/ui/popover\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { useNotifications } from \"@lattice-php/lattice/notifications/store\";\nimport type { NotificationItem } from \"@lattice-php/lattice/notifications/types\";\nimport { NotificationList } from \"./notification-list\";\n\nconst NotificationsEcho = lazy(() =>\n import(\"./notifications-echo\").then((m) => ({ default: m.NotificationsEcho })),\n);\n\nclass EchoBoundary extends Component<{ children: ReactNode }, { failed: boolean }> {\n state = { failed: false };\n\n static getDerivedStateFromError(): { failed: boolean } {\n return { failed: true };\n }\n\n componentDidCatch(): void {\n console.warn(\n \"[lattice] The notifications bell declares a realtime channel but Echo is unavailable. Install @laravel/echo-react and call configureEcho().\",\n );\n }\n\n render(): ReactNode {\n return this.state.failed ? null : this.props.children;\n }\n}\n\nconst NotificationsComponent: RendererComponent<\"notifications\"> = ({ node }) => {\n const { t } = useT(\"lattice\");\n const store = useNotifications({\n endpoint: node.props.endpoint,\n pollingInterval: node.props.pollingInterval,\n });\n\n const label = t(\"notifications.label\", \"Notifications\");\n\n const trigger = (\n <span className=\"relative inline-flex items-center justify-center rounded-lt-sm p-2 hover:bg-lt-muted\">\n <Icon name=\"bell\" className=\"size-lt-icon-md\" />\n {store.unreadCount > 0 ? (\n <Badge\n variant=\"destructive\"\n data-test=\"notifications-badge\"\n className=\"absolute -right-0.5 -top-0.5 min-w-4 px-1 py-0 text-[10px]\"\n >\n {store.unreadCount}\n </Badge>\n ) : null}\n </span>\n );\n\n const panel = (\n <div className=\"w-80\" data-test=\"notifications-panel\">\n <div className=\"flex items-center justify-between border-b border-lt-border px-3 py-2\">\n <span className=\"text-sm font-medium\">{t(\"notifications.heading\", \"Notifications\")}</span>\n {store.unreadCount > 0 ? (\n <button\n type=\"button\"\n className=\"text-xs text-lt-muted-fg hover:text-lt-fg\"\n onClick={store.markAllRead}\n >\n {t(\"notifications.mark-all-read\", \"Mark all read\")}\n </button>\n ) : null}\n </div>\n <NotificationList\n notifications={store.notifications}\n status={store.status}\n hasMore={store.hasMore}\n onMarkRead={store.markRead}\n onDismiss={store.dismiss}\n onLoadMore={store.loadMore}\n />\n </div>\n );\n\n return (\n <>\n {node.props.channel ? (\n <EchoBoundary>\n <Suspense fallback={null}>\n <NotificationsEcho\n channel={node.props.channel}\n onReceive={(item: NotificationItem) => store.receive(item)}\n />\n </Suspense>\n </EchoBoundary>\n ) : null}\n\n {node.props.slideOut ? (\n <>\n <button\n type=\"button\"\n aria-label={label}\n data-test=\"notifications-trigger\"\n onClick={() => store.setOpen(true)}\n >\n {trigger}\n </button>\n <Dialog open={store.open} onOpenChange={store.setOpen}>\n <DialogContent aria-describedby={undefined} className=\"p-0\" placement=\"end\" width=\"sm\">\n <DialogTitle className=\"sr-only\">{label}</DialogTitle>\n {panel}\n </DialogContent>\n </Dialog>\n </>\n ) : (\n <PopoverRoot open={store.open} onOpenChange={store.setOpen}>\n <PopoverTrigger asChild>\n <button type=\"button\" aria-label={label} data-test=\"notifications-trigger\">\n {trigger}\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"p-0\">\n {panel}\n </PopoverContent>\n </PopoverRoot>\n )}\n </>\n );\n};\n\nexport default NotificationsComponent;\n"],"mappings":";;;;;;;;;;AAeA,IAAM,oBAAoB,WACxB,OAAO,2BAAwB,MAAM,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAC/E;AAEA,IAAM,eAAN,cAA2B,UAAwD;CACjF,QAAQ,EAAE,QAAQ,MAAM;CAExB,OAAO,2BAAgD;EACrD,OAAO,EAAE,QAAQ,KAAK;CACxB;CAEA,oBAA0B;EACxB,QAAQ,KACN,6IACF;CACF;CAEA,SAAoB;EAClB,OAAO,KAAK,MAAM,SAAS,OAAO,KAAK,MAAM;CAC/C;AACF;AAEA,IAAM,0BAA8D,EAAE,WAAW;CAC/E,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,QAAQ,iBAAiB;EAC7B,UAAU,KAAK,MAAM;EACrB,iBAAiB,KAAK,MAAM;CAC9B,CAAC;CAED,MAAM,QAAQ,EAAE,uBAAuB,eAAe;CAEtD,MAAM,UACJ,qBAAC,QAAD;EAAM,WAAU;YAAhB,CACE,oBAAC,MAAD;GAAM,MAAK;GAAO,WAAU;EAAmB,CAAA,GAC9C,MAAM,cAAc,IACnB,oBAAC,OAAD;GACE,SAAQ;GACR,aAAU;GACV,WAAU;aAET,MAAM;EACF,CAAA,IACL,IACA;;CAGR,MAAM,QACJ,qBAAC,OAAD;EAAK,WAAU;EAAO,aAAU;YAAhC,CACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,QAAD;IAAM,WAAU;cAAuB,EAAE,yBAAyB,eAAe;GAAQ,CAAA,GACxF,MAAM,cAAc,IACnB,oBAAC,UAAD;IACE,MAAK;IACL,WAAU;IACV,SAAS,MAAM;cAEd,EAAE,+BAA+B,eAAe;GAC3C,CAAA,IACN,IACD;MACL,oBAAC,kBAAD;GACE,eAAe,MAAM;GACrB,QAAQ,MAAM;GACd,SAAS,MAAM;GACf,YAAY,MAAM;GAClB,WAAW,MAAM;GACjB,YAAY,MAAM;EACnB,CAAA,CACE;;CAGP,OACE,qBAAA,YAAA,EAAA,UAAA,CACG,KAAK,MAAM,UACV,oBAAC,cAAD,EAAA,UACE,oBAAC,UAAD;EAAU,UAAU;YAClB,oBAAC,mBAAD;GACE,SAAS,KAAK,MAAM;GACpB,YAAY,SAA2B,MAAM,QAAQ,IAAI;EAC1D,CAAA;CACO,CAAA,EACE,CAAA,IACZ,MAEH,KAAK,MAAM,WACV,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,UAAD;EACE,MAAK;EACL,cAAY;EACZ,aAAU;EACV,eAAe,MAAM,QAAQ,IAAI;YAEhC;CACK,CAAA,GACR,oBAAC,QAAD;EAAQ,MAAM,MAAM;EAAM,cAAc,MAAM;YAC5C,qBAAC,eAAD;GAAe,oBAAkB,KAAA;GAAW,WAAU;GAAM,WAAU;GAAM,OAAM;aAAlF,CACE,oBAAC,aAAD;IAAa,WAAU;cAAW;GAAmB,CAAA,GACpD,KACY;;CACT,CAAA,CACR,EAAA,CAAA,IAEF,qBAAC,SAAD;EAAa,MAAM,MAAM;EAAM,cAAc,MAAM;YAAnD,CACE,oBAAC,gBAAD;GAAgB,SAAA;aACd,oBAAC,UAAD;IAAQ,MAAK;IAAS,cAAY;IAAO,aAAU;cAChD;GACK,CAAA;EACM,CAAA,GAChB,oBAAC,gBAAD;GAAgB,OAAM;GAAM,WAAU;aACnC;EACa,CAAA,CACL;GAEf,EAAA,CAAA;AAEN"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { useT } from "../../i18n/instance.js";
|
|
1
2
|
import { materializeSchema } from "../../core/materialize.js";
|
|
2
3
|
import { Renderer } from "../../core/renderer.js";
|
|
3
|
-
import { useT } from "../../i18n/instance.js";
|
|
4
4
|
import { remoteJson } from "../../core/api.js";
|
|
5
5
|
import { useEffect, useState } from "react";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import { withHeaders } from "../../core/headers.js";
|
|
2
1
|
import { useT } from "../../i18n/instance.js";
|
|
3
2
|
import { prefixedTestId } from "../../core/test-id.js";
|
|
4
|
-
import { getActionEffects } from "../../effects/dispatch.js";
|
|
5
3
|
import { useEffectDispatcher } from "../../effects/use-effect-dispatcher.js";
|
|
6
4
|
import { Button } from "../../ui/button.js";
|
|
7
5
|
import { Spinner } from "../../ui/spinner.js";
|
|
8
6
|
import { ConfirmDialog } from "../../ui/confirm-dialog.js";
|
|
7
|
+
import { apiFetch } from "../../core/api.js";
|
|
9
8
|
import { runAction } from "../../action/lib/run-action.js";
|
|
10
9
|
import { ActionForm } from "../../action/components/action-form.js";
|
|
11
|
-
import { useHttp } from "@inertiajs/react";
|
|
12
10
|
import { useState } from "react";
|
|
13
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
12
|
//#region resources/js/table/components/bulk-bar.tsx
|
|
15
13
|
function BulkBar({ actions, selectedKeys, allMatching, total, query, canSelectAllMatching, onSelectAllMatching, onCompleted }) {
|
|
16
14
|
const { t } = useT("lattice");
|
|
17
|
-
const
|
|
15
|
+
const [processing, setProcessing] = useState(false);
|
|
18
16
|
const dispatch = useEffectDispatcher();
|
|
19
17
|
const [confirming, setConfirming] = useState(null);
|
|
20
18
|
const [filling, setFilling] = useState(null);
|
|
@@ -23,11 +21,15 @@ function BulkBar({ actions, selectedKeys, allMatching, total, query, canSelectAl
|
|
|
23
21
|
...query
|
|
24
22
|
} : { selected: selectedKeys };
|
|
25
23
|
async function submit(action) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
setProcessing(true);
|
|
25
|
+
const ok = await runAction(() => apiFetch(action.endpoint, {
|
|
26
|
+
method: action.method,
|
|
27
|
+
ref: action.ref,
|
|
28
|
+
body: JSON.stringify(selectionPayload()),
|
|
29
|
+
throwOnError: false
|
|
30
|
+
}), dispatch);
|
|
31
|
+
setProcessing(false);
|
|
32
|
+
if (ok) {
|
|
31
33
|
setConfirming(null);
|
|
32
34
|
onCompleted();
|
|
33
35
|
}
|
|
@@ -64,9 +66,9 @@ function BulkBar({ actions, selectedKeys, allMatching, total, query, canSelectAl
|
|
|
64
66
|
type: "button",
|
|
65
67
|
"data-test": prefixedTestId("bulk-action", action.id),
|
|
66
68
|
variant: action.variant,
|
|
67
|
-
disabled:
|
|
69
|
+
disabled: processing,
|
|
68
70
|
onClick: () => run(action),
|
|
69
|
-
children: [
|
|
71
|
+
children: [processing && /* @__PURE__ */ jsx(Spinner, {}), action.label]
|
|
70
72
|
}, action.id))
|
|
71
73
|
}),
|
|
72
74
|
confirming?.confirmation && /* @__PURE__ */ jsx(ConfirmDialog, {
|
|
@@ -75,7 +77,7 @@ function BulkBar({ actions, selectedKeys, allMatching, total, query, canSelectAl
|
|
|
75
77
|
confirmLabel: confirming.confirmation.confirmLabel ?? confirming.label,
|
|
76
78
|
cancelLabel: confirming.confirmation.cancelLabel ?? t("common.cancel", "Cancel"),
|
|
77
79
|
confirmVariant: confirming.variant,
|
|
78
|
-
processing
|
|
80
|
+
processing,
|
|
79
81
|
onConfirm: () => void submit(confirming),
|
|
80
82
|
onCancel: () => setConfirming(null)
|
|
81
83
|
}),
|
|
@@ -88,8 +90,7 @@ function BulkBar({ actions, selectedKeys, allMatching, total, query, canSelectAl
|
|
|
88
90
|
formNode: filling.form,
|
|
89
91
|
method: filling.method,
|
|
90
92
|
onClose: () => setFilling(null),
|
|
91
|
-
onSuccess: (
|
|
92
|
-
dispatch(getActionEffects(response.effects));
|
|
93
|
+
onSuccess: () => {
|
|
93
94
|
setFilling(null);
|
|
94
95
|
onCompleted();
|
|
95
96
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bulk-bar.js","names":[],"sources":["../../../resources/js/table/components/bulk-bar.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"bulk-bar.js","names":[],"sources":["../../../resources/js/table/components/bulk-bar.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { ActionForm, runAction } from \"@lattice-php/lattice/action\";\nimport { apiFetch } from \"@lattice-php/lattice/core/api\";\nimport { useEffectDispatcher } from \"@lattice-php/lattice/effects/use-effect-dispatcher\";\nimport { Button } from \"@lattice-php/lattice/ui/button\";\nimport { ConfirmDialog } from \"@lattice-php/lattice/ui/confirm-dialog\";\nimport { Spinner } from \"@lattice-php/lattice/ui/spinner\";\nimport { prefixedTestId } from \"@lattice-php/lattice/core/test-id\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { BulkAction } from \"@lattice-php/lattice/table/lib/bulk\";\n\nexport function BulkBar({\n actions,\n selectedKeys,\n allMatching,\n total,\n query,\n canSelectAllMatching,\n onSelectAllMatching,\n onCompleted,\n}: {\n actions: BulkAction[];\n selectedKeys: string[];\n allMatching: boolean;\n total?: number;\n query: Record<string, unknown>;\n canSelectAllMatching: boolean;\n onSelectAllMatching: () => void;\n onCompleted: () => void;\n}) {\n const { t } = useT(\"lattice\");\n const [processing, setProcessing] = useState(false);\n const dispatch = useEffectDispatcher();\n const [confirming, setConfirming] = useState<BulkAction | null>(null);\n const [filling, setFilling] = useState<BulkAction | null>(null);\n\n const selectionPayload = (): Record<string, unknown> =>\n allMatching ? { allMatching: true, ...query } : { selected: selectedKeys };\n\n async function submit(action: BulkAction): Promise<void> {\n setProcessing(true);\n\n const ok = await runAction(\n () =>\n apiFetch(action.endpoint, {\n method: action.method,\n ref: action.ref,\n body: JSON.stringify(selectionPayload()),\n throwOnError: false,\n }),\n dispatch,\n );\n\n setProcessing(false);\n\n if (ok) {\n setConfirming(null);\n onCompleted();\n }\n }\n\n function run(action: BulkAction): void {\n if (action.form) {\n setFilling(action);\n\n return;\n }\n\n if (action.confirmation) {\n setConfirming(action);\n\n return;\n }\n\n void submit(action);\n }\n\n const count = allMatching ? (total ?? selectedKeys.length) : selectedKeys.length;\n\n return (\n <div className=\"flex flex-wrap items-center gap-3 border-b border-lt-border bg-lt-muted/50 p-4 text-sm\">\n <span className=\"font-medium\">\n {allMatching\n ? t(\"table.bulk.all-selected\", \"All {{count}} selected\", { count })\n : t(\"table.bulk.selected\", \"{{count}} selected\", { count })}\n </span>\n {canSelectAllMatching && (\n <button\n type=\"button\"\n data-test=\"bulk-select-all-matching\"\n className=\"font-medium text-lt-primary underline underline-offset-2\"\n onClick={onSelectAllMatching}\n >\n {t(\"table.bulk.select-all-matching\", \"Select all {{total}} matching\", { total })}\n </button>\n )}\n <div className=\"flex flex-wrap items-center gap-2\">\n {actions.map((action) => (\n <Button\n key={action.id}\n type=\"button\"\n data-test={prefixedTestId(\"bulk-action\", action.id)}\n variant={action.variant}\n disabled={processing}\n onClick={() => run(action)}\n >\n {processing && <Spinner />}\n {action.label}\n </Button>\n ))}\n </div>\n\n {confirming?.confirmation && (\n <ConfirmDialog\n title={confirming.confirmation.title ?? confirming.label}\n description={confirming.confirmation.description ?? undefined}\n confirmLabel={confirming.confirmation.confirmLabel ?? confirming.label}\n cancelLabel={confirming.confirmation.cancelLabel ?? t(\"common.cancel\", \"Cancel\")}\n confirmVariant={confirming.variant}\n processing={processing}\n onConfirm={() => void submit(confirming)}\n onCancel={() => setConfirming(null)}\n />\n )}\n\n {filling?.form && (\n <ActionForm\n cancelLabel={filling.confirmation?.cancelLabel ?? t(\"common.cancel\", \"Cancel\")}\n componentRef={filling.ref}\n description={filling.confirmation?.description ?? undefined}\n endpoint={filling.endpoint}\n extraData={selectionPayload()}\n formNode={filling.form}\n method={filling.method}\n onClose={() => setFilling(null)}\n onSuccess={() => {\n setFilling(null);\n onCompleted();\n }}\n placement={filling.modalSide ?? \"center\"}\n submitLabel={filling.confirmation?.confirmLabel ?? filling.label}\n title={filling.confirmation?.title ?? filling.label}\n width={filling.modalWidth ?? undefined}\n />\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAWA,SAAgB,QAAQ,EACtB,SACA,cACA,aACA,OACA,OACA,sBACA,qBACA,eAUC;CACD,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAClD,MAAM,WAAW,oBAAoB;CACrC,MAAM,CAAC,YAAY,iBAAiB,SAA4B,IAAI;CACpE,MAAM,CAAC,SAAS,cAAc,SAA4B,IAAI;CAE9D,MAAM,yBACJ,cAAc;EAAE,aAAa;EAAM,GAAG;CAAM,IAAI,EAAE,UAAU,aAAa;CAE3E,eAAe,OAAO,QAAmC;EACvD,cAAc,IAAI;EAElB,MAAM,KAAK,MAAM,gBAEb,SAAS,OAAO,UAAU;GACxB,QAAQ,OAAO;GACf,KAAK,OAAO;GACZ,MAAM,KAAK,UAAU,iBAAiB,CAAC;GACvC,cAAc;EAChB,CAAC,GACH,QACF;EAEA,cAAc,KAAK;EAEnB,IAAI,IAAI;GACN,cAAc,IAAI;GAClB,YAAY;EACd;CACF;CAEA,SAAS,IAAI,QAA0B;EACrC,IAAI,OAAO,MAAM;GACf,WAAW,MAAM;GAEjB;EACF;EAEA,IAAI,OAAO,cAAc;GACvB,cAAc,MAAM;GAEpB;EACF;EAEA,OAAY,MAAM;CACpB;CAEA,MAAM,QAAQ,cAAe,SAAS,aAAa,SAAU,aAAa;CAE1E,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACE,oBAAC,QAAD;IAAM,WAAU;cACb,cACG,EAAE,2BAA2B,0BAA0B,EAAE,MAAM,CAAC,IAChE,EAAE,uBAAuB,sBAAsB,EAAE,MAAM,CAAC;GACxD,CAAA;GACL,wBACC,oBAAC,UAAD;IACE,MAAK;IACL,aAAU;IACV,WAAU;IACV,SAAS;cAER,EAAE,kCAAkC,iCAAiC,EAAE,MAAM,CAAC;GACzE,CAAA;GAEV,oBAAC,OAAD;IAAK,WAAU;cACZ,QAAQ,KAAK,WACZ,qBAAC,QAAD;KAEE,MAAK;KACL,aAAW,eAAe,eAAe,OAAO,EAAE;KAClD,SAAS,OAAO;KAChB,UAAU;KACV,eAAe,IAAI,MAAM;eAN3B,CAQG,cAAc,oBAAC,SAAD,CAAU,CAAA,GACxB,OAAO,KACF;OATD,OAAO,EASN,CACT;GACE,CAAA;GAEJ,YAAY,gBACX,oBAAC,eAAD;IACE,OAAO,WAAW,aAAa,SAAS,WAAW;IACnD,aAAa,WAAW,aAAa,eAAe,KAAA;IACpD,cAAc,WAAW,aAAa,gBAAgB,WAAW;IACjE,aAAa,WAAW,aAAa,eAAe,EAAE,iBAAiB,QAAQ;IAC/E,gBAAgB,WAAW;IACf;IACZ,iBAAiB,KAAK,OAAO,UAAU;IACvC,gBAAgB,cAAc,IAAI;GACnC,CAAA;GAGF,SAAS,QACR,oBAAC,YAAD;IACE,aAAa,QAAQ,cAAc,eAAe,EAAE,iBAAiB,QAAQ;IAC7E,cAAc,QAAQ;IACtB,aAAa,QAAQ,cAAc,eAAe,KAAA;IAClD,UAAU,QAAQ;IAClB,WAAW,iBAAiB;IAC5B,UAAU,QAAQ;IAClB,QAAQ,QAAQ;IAChB,eAAe,WAAW,IAAI;IAC9B,iBAAiB;KACf,WAAW,IAAI;KACf,YAAY;IACd;IACA,WAAW,QAAQ,aAAa;IAChC,aAAa,QAAQ,cAAc,gBAAgB,QAAQ;IAC3D,OAAO,QAAQ,cAAc,SAAS,QAAQ;IAC9C,OAAO,QAAQ,cAAc,KAAA;GAC9B,CAAA;EAEA;;AAET"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { useT } from "../../../i18n/instance.js";
|
|
1
2
|
import { cn } from "../../../lib/utils.js";
|
|
2
3
|
import { Icon } from "../../../icons/sprite.js";
|
|
3
|
-
import { useT } from "../../../i18n/instance.js";
|
|
4
4
|
import { isTruthy } from "../../../lib/is-truthy.js";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
//#region resources/js/table/components/cells/boolean-cell.tsx
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import { NumberFormat } from '../../../types/
|
|
2
|
+
import { NumberFormat } from '../../../types/generated.js';
|
|
3
3
|
import { TableColumn } from '../../types.js';
|
|
4
4
|
/** Shared numeric cell body for the money and number columns. */
|
|
5
5
|
export declare function NumericCell({ column, copyable, format, value, }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numeric-cell.js","names":[],"sources":["../../../../resources/js/table/components/cells/numeric-cell.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { useLocale } from \"@lattice-php/lattice/i18n\";\nimport type { NumberFormat } from \"@lattice-php/lattice/types\";\nimport { formatNumber } from \"@lattice-php/lattice/format/number\";\nimport { numericValue } from \"@lattice-php/lattice/format/numeric\";\nimport { formatCell } from \"@lattice-php/lattice/table/lib/format\";\nimport type { TableColumn } from \"@lattice-php/lattice/table/types\";\nimport { CopyableCell } from \"./copyable-cell\";\n\n/** Shared numeric cell body for the money and number columns. */\nexport function NumericCell({\n column,\n copyable,\n format,\n value,\n}: {\n column: TableColumn;\n copyable?: boolean | null;\n format: NumberFormat;\n value: unknown;\n}): ReactNode {\n const { locale } = useLocale();\n\n if (numericValue(value) === null) {\n return <span>{formatCell(value, column)}</span>;\n }\n\n return (\n <CopyableCell column={column} copyable={copyable} value={String(value)}>\n <span className=\"tabular-nums\">{formatNumber(value, format, locale)}</span>\n </CopyableCell>\n );\n}\n"],"mappings":";;;;;;;;AAUA,SAAgB,YAAY,EAC1B,QACA,UACA,QACA,SAMY;CACZ,MAAM,EAAE,WAAW,UAAU;CAE7B,IAAI,aAAa,KAAK,MAAM,MAC1B,OAAO,oBAAC,QAAD,EAAA,UAAO,WAAW,OAAO,MAAM,EAAQ,CAAA;CAGhD,OACE,oBAAC,cAAD;EAAsB;EAAkB;EAAU,OAAO,OAAO,KAAK;YACnE,oBAAC,QAAD;GAAM,WAAU;aAAgB,aAAa,OAAO,QAAQ,MAAM;EAAQ,CAAA;CAC9D,CAAA;AAElB"}
|
|
1
|
+
{"version":3,"file":"numeric-cell.js","names":[],"sources":["../../../../resources/js/table/components/cells/numeric-cell.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { useLocale } from \"@lattice-php/lattice/i18n\";\nimport type { NumberFormat } from \"@lattice-php/lattice/types/generated\";\nimport { formatNumber } from \"@lattice-php/lattice/format/number\";\nimport { numericValue } from \"@lattice-php/lattice/format/numeric\";\nimport { formatCell } from \"@lattice-php/lattice/table/lib/format\";\nimport type { TableColumn } from \"@lattice-php/lattice/table/types\";\nimport { CopyableCell } from \"./copyable-cell\";\n\n/** Shared numeric cell body for the money and number columns. */\nexport function NumericCell({\n column,\n copyable,\n format,\n value,\n}: {\n column: TableColumn;\n copyable?: boolean | null;\n format: NumberFormat;\n value: unknown;\n}): ReactNode {\n const { locale } = useLocale();\n\n if (numericValue(value) === null) {\n return <span>{formatCell(value, column)}</span>;\n }\n\n return (\n <CopyableCell column={column} copyable={copyable} value={String(value)}>\n <span className=\"tabular-nums\">{formatNumber(value, format, locale)}</span>\n </CopyableCell>\n );\n}\n"],"mappings":";;;;;;;;AAUA,SAAgB,YAAY,EAC1B,QACA,UACA,QACA,SAMY;CACZ,MAAM,EAAE,WAAW,UAAU;CAE7B,IAAI,aAAa,KAAK,MAAM,MAC1B,OAAO,oBAAC,QAAD,EAAA,UAAO,WAAW,OAAO,MAAM,EAAQ,CAAA;CAGhD,OACE,oBAAC,cAAD;EAAsB;EAAkB;EAAU,OAAO,OAAO,KAAK;YACnE,oBAAC,QAAD;GAAM,WAAU;aAAgB,aAAa,OAAO,QAAQ,MAAM;EAAQ,CAAA;CAC9D,CAAA;AAElB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { useT } from "../../i18n/instance.js";
|
|
1
2
|
import { cn } from "../../lib/utils.js";
|
|
2
3
|
import { Icon } from "../../icons/sprite.js";
|
|
3
|
-
import { useT } from "../../i18n/instance.js";
|
|
4
4
|
import { alignJustify, alignText } from "../lib/align.js";
|
|
5
5
|
import { getColumnAriaSort, getColumnSort } from "../lib/query.js";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { useT } from "../../i18n/instance.js";
|
|
1
2
|
import { cn } from "../../lib/utils.js";
|
|
2
3
|
import { Renderer } from "../../core/renderer.js";
|
|
3
|
-
import { useT } from "../../i18n/instance.js";
|
|
4
4
|
import { FormProvider } from "../../form/hooks/context.js";
|
|
5
5
|
import { PrefillProvider } from "../../form/hooks/prefill-context.js";
|
|
6
6
|
import { getPath, setPath } from "../../form/lib/form-path.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { useT } from "../../i18n/instance.js";
|
|
1
2
|
import { cn } from "../../lib/utils.js";
|
|
2
3
|
import { Icon } from "../../icons/sprite.js";
|
|
3
|
-
import { useT } from "../../i18n/instance.js";
|
|
4
4
|
import { Input } from "../../ui/input.js";
|
|
5
5
|
import { IconButton } from "../../ui/icon-button.js";
|
|
6
6
|
import { NativeSelect } from "../../ui/native-select.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Icon } from "../../icons/sprite.js";
|
|
2
1
|
import { useT } from "../../i18n/instance.js";
|
|
2
|
+
import { Icon } from "../../icons/sprite.js";
|
|
3
3
|
import { IconButton } from "../../ui/icon-button.js";
|
|
4
4
|
import { getSortDirectionLabel } from "../lib/query.js";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { useT } from "../../i18n/instance.js";
|
|
1
2
|
import { cn } from "../../lib/utils.js";
|
|
2
3
|
import { Icon } from "../../icons/sprite.js";
|
|
3
|
-
import { useT } from "../../i18n/instance.js";
|
|
4
4
|
import { useDebouncedCallback } from "../../lib/use-debounced-callback.js";
|
|
5
5
|
import { Input } from "../../ui/input.js";
|
|
6
6
|
import { IconButton } from "../../ui/icon-button.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { useT } from "../../i18n/instance.js";
|
|
1
2
|
import { cn } from "../../lib/utils.js";
|
|
2
3
|
import { Icon } from "../../icons/sprite.js";
|
|
3
4
|
import { RenderNode, Renderer } from "../../core/renderer.js";
|
|
4
|
-
import { useT } from "../../i18n/instance.js";
|
|
5
5
|
import { nodeIdentity } from "../../core/test-id.js";
|
|
6
6
|
import { useColumnResizing } from "../../core/hooks/use-column-resizing.js";
|
|
7
7
|
import { Checkbox } from "../../ui/checkbox.js";
|
package/dist/table/lib/bulk.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { actionLabel } from "../../action/lib/action-label.js";
|
|
1
2
|
//#region resources/js/table/lib/bulk.ts
|
|
2
3
|
function getBulkActions(actions) {
|
|
3
4
|
return (actions ?? []).flatMap((node) => {
|
|
@@ -6,7 +7,7 @@ function getBulkActions(actions) {
|
|
|
6
7
|
if (!props.endpoint) return [];
|
|
7
8
|
return [{
|
|
8
9
|
id: node.id ?? "",
|
|
9
|
-
label:
|
|
10
|
+
label: actionLabel(node),
|
|
10
11
|
method: props.method ?? "post",
|
|
11
12
|
endpoint: props.endpoint,
|
|
12
13
|
ref: props.ref ?? "",
|