@lattice-php/lattice 0.20.0 → 0.21.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/dist/action/components/action-form.d.ts +6 -1
- package/dist/action/components/action-form.js +34 -49
- package/dist/action/components/action-form.js.map +1 -1
- package/dist/action/components/action-trigger-provider.d.ts +1 -1
- package/dist/action/components/action-trigger-provider.js.map +1 -1
- package/dist/action/hooks/use-action.d.ts +1 -1
- package/dist/action/hooks/use-action.js +3 -1
- package/dist/action/hooks/use-action.js.map +1 -1
- package/dist/action/index.d.ts +0 -2
- package/dist/action/index.js +1 -2
- package/dist/chat/plugin.d.ts +0 -1
- package/dist/chat/plugin.js.map +1 -1
- package/dist/clipboard/index.d.ts +0 -4
- package/dist/clipboard/index.js +1 -15
- package/dist/{events → core}/event-names.js +1 -1
- package/dist/core/event-names.js.map +1 -0
- package/dist/core/hooks/use-window-event.d.ts +8 -0
- package/dist/core/hooks/use-window-event.js +22 -0
- package/dist/core/hooks/use-window-event.js.map +1 -0
- package/dist/core/index.js +3 -3
- package/dist/core/types.d.ts +8 -73
- package/dist/create-app.js +1 -1
- package/dist/effects/dispatch.js +1 -1
- package/dist/effects/dispatch.js.map +1 -1
- package/dist/effects/registry.d.ts +2 -18
- package/dist/effects/registry.js +4 -8
- package/dist/effects/registry.js.map +1 -1
- package/dist/event-bridge.js +10 -23
- package/dist/event-bridge.js.map +1 -1
- package/dist/form/components/fields/date-picker-field.js +1 -1
- package/dist/form/components/fields/file-upload.js +4 -6
- package/dist/form/components/fields/file-upload.js.map +1 -1
- package/dist/form/components/fields/select.js +2 -2
- package/dist/form/components/fields/select.js.map +1 -1
- package/dist/form/components/fields/table-rows.js +3 -15
- package/dist/form/components/fields/table-rows.js.map +1 -1
- package/dist/form/components/form.js +8 -23
- package/dist/form/components/form.js.map +1 -1
- package/dist/form/embed.d.ts +4 -0
- package/dist/form/embed.js +3 -1
- package/dist/form/lib/collect-fields.d.ts +7 -0
- package/dist/form/lib/collect-fields.js +19 -0
- package/dist/form/lib/collect-fields.js.map +1 -0
- package/dist/form/lib/field-errors.d.ts +3 -0
- package/dist/form/lib/field-errors.js +11 -0
- package/dist/form/lib/field-errors.js.map +1 -0
- package/dist/format/format-context.d.ts +6 -0
- package/dist/format/format-context.js +17 -0
- package/dist/format/format-context.js.map +1 -0
- package/dist/i18n/backend.js +1 -1
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/instance.js +1 -1
- package/dist/i18n/locale-reload.d.ts +1 -1
- package/dist/i18n/locale-reload.js +7 -6
- package/dist/i18n/locale-reload.js.map +1 -1
- package/dist/i18n/locale.js +1 -1
- package/dist/i18n/locale.js.map +1 -1
- package/dist/i18n/page-props.js +1 -1
- package/dist/i18n/shared-props.js +1 -3
- package/dist/i18n/shared-props.js.map +1 -1
- package/dist/i18n/timezone.js +1 -1
- package/dist/i18n/timezone.js.map +1 -1
- package/dist/index.d.ts +6 -7
- package/dist/index.js +7 -8
- package/dist/lattice.css +105 -0
- package/dist/layout/components/callouts.js +1 -1
- package/dist/layout/components/sidebar.js +15 -48
- package/dist/layout/components/sidebar.js.map +1 -1
- package/dist/layout/plugin.d.ts +0 -1
- package/dist/layout/plugin.js.map +1 -1
- package/dist/lib/is-truthy.d.ts +2 -0
- package/dist/lib/is-truthy.js +9 -0
- package/dist/lib/is-truthy.js.map +1 -0
- package/dist/lib/use-debounced-callback.d.ts +10 -0
- package/dist/lib/use-debounced-callback.js +34 -0
- package/dist/lib/use-debounced-callback.js.map +1 -0
- package/dist/lib/use-media-query.d.ts +5 -0
- package/dist/lib/use-media-query.js +26 -0
- package/dist/lib/use-media-query.js.map +1 -0
- package/dist/lib/use-persistent-state.d.ts +13 -0
- package/dist/lib/use-persistent-state.js +62 -0
- package/dist/lib/use-persistent-state.js.map +1 -0
- package/dist/notifications/components/notifications.js +3 -1
- package/dist/notifications/components/notifications.js.map +1 -1
- package/dist/notifications/plugin.d.ts +0 -1
- package/dist/notifications/plugin.js.map +1 -1
- package/dist/provider-base.js +1 -1
- package/dist/realtime/listeners.d.ts +1 -1
- package/dist/realtime/listeners.js +1 -1
- package/dist/realtime/listeners.js.map +1 -1
- package/dist/registry.d.ts +5 -0
- package/dist/registry.js.map +1 -1
- package/dist/remote/components/data-list.js +1 -1
- package/dist/remote/plugin.d.ts +0 -1
- package/dist/remote/plugin.js.map +1 -1
- package/dist/table/components/bulk-bar.js +4 -2
- package/dist/table/components/bulk-bar.js.map +1 -1
- package/dist/table/components/cells/boolean-cell.js +1 -3
- package/dist/table/components/cells/boolean-cell.js.map +1 -1
- package/dist/table/components/cells/copyable-cell.d.ts +9 -0
- package/dist/table/components/cells/copyable-cell.js +17 -0
- package/dist/table/components/cells/copyable-cell.js.map +1 -0
- package/dist/table/components/cells/money-cell.js +7 -18
- package/dist/table/components/cells/money-cell.js.map +1 -1
- package/dist/table/components/cells/number-cell.js +14 -27
- package/dist/table/components/cells/number-cell.js.map +1 -1
- package/dist/table/components/cells/numeric-cell.d.ts +10 -0
- package/dist/table/components/cells/numeric-cell.js +25 -0
- package/dist/table/components/cells/numeric-cell.js.map +1 -0
- package/dist/table/components/cells/stack-cell.js +1 -1
- package/dist/table/components/cells/text-cell.js +4 -5
- package/dist/table/components/cells/text-cell.js.map +1 -1
- package/dist/table/components/filter-controls.js +1 -3
- package/dist/table/components/filter-controls.js.map +1 -1
- package/dist/table/components/table-cell.js.map +1 -1
- package/dist/table/components/table-search.js +4 -7
- package/dist/table/components/table-search.js.map +1 -1
- package/dist/table/components/table.js +2 -3
- package/dist/table/components/table.js.map +1 -1
- package/dist/table/hooks/use-column-visibility.js +29 -58
- package/dist/table/hooks/use-column-visibility.js.map +1 -1
- package/dist/table/hooks/use-table.js +5 -13
- package/dist/table/hooks/use-table.js.map +1 -1
- package/dist/table/lib/bulk.d.ts +2 -0
- package/dist/table/lib/bulk.js +3 -1
- package/dist/table/lib/bulk.js.map +1 -1
- package/dist/table/lib/query.js +1 -1
- package/dist/table/lib/query.js.map +1 -1
- package/dist/table/plugin.d.ts +0 -1
- package/dist/table/plugin.js.map +1 -1
- package/dist/table/types.d.ts +4 -57
- package/dist/toast/callout.js +1 -1
- package/dist/toast/callout.js.map +1 -1
- package/dist/toast/index.d.ts +1 -1
- package/dist/toast/index.js +2 -2
- package/dist/toast/toast.d.ts +0 -2
- package/dist/toast/toast.js +3 -10
- package/dist/toast/toast.js.map +1 -1
- package/dist/toast/toaster.js +2 -2
- package/dist/types/generated.d.ts +224 -80
- package/dist/types/index.d.ts +1 -1
- package/dist/ui/button.d.ts +2 -2
- package/dist/ui/chart-view.js +7 -30
- package/dist/ui/chart-view.js.map +1 -1
- package/dist/ui/click-behavior.d.ts +4 -4
- package/dist/ui/click-behavior.js.map +1 -1
- package/dist/ui/collapsible.js +3 -15
- package/dist/ui/collapsible.js.map +1 -1
- package/dist/ui/combobox.js +6 -3
- package/dist/ui/combobox.js.map +1 -1
- package/dist/ui/confirm-dialog.js +1 -1
- package/dist/ui/confirm-dialog.js.map +1 -1
- package/dist/ui/control.d.ts +1 -1
- package/dist/ui/dialog.d.ts +6 -2
- package/dist/ui/dialog.js +29 -5
- package/dist/ui/dialog.js.map +1 -1
- package/dist/ui/fragment.js +1 -1
- package/dist/ui/fragment.js.map +1 -1
- package/dist/ui/icon-button.d.ts +1 -1
- package/dist/ui/image-preview.js +1 -1
- package/dist/ui/image-preview.js.map +1 -1
- package/dist/ui/modal.js +3 -2
- package/dist/ui/modal.js.map +1 -1
- package/dist/ui/pill.d.ts +2 -0
- package/dist/ui/pill.js +10 -0
- package/dist/ui/pill.js.map +1 -0
- package/dist/ui/plugin.js.map +1 -1
- package/dist/ui/progress.js +1 -1
- package/dist/ui/section.js +2 -15
- package/dist/ui/section.js.map +1 -1
- package/dist/ui/segmented-pills.js +2 -1
- package/dist/ui/segmented-pills.js.map +1 -1
- package/dist/ui/tabs.js +12 -10
- package/dist/ui/tabs.js.map +1 -1
- package/dist/ui/tree-context.js +11 -13
- package/dist/ui/tree-context.js.map +1 -1
- package/dist/ui/tree.js +1 -1
- package/dist/ui/tree.js.map +1 -1
- package/dist/ui/use-collapsible-state.d.ts +7 -0
- package/dist/ui/use-collapsible-state.js +21 -0
- package/dist/ui/use-collapsible-state.js.map +1 -0
- package/dist-standalone/chunks/chart-view-C6R5iPra.js +36 -0
- package/dist-standalone/chunks/{date-picker-field-VbH9xrQO.js → date-picker-field-DhhEB-Mh.js} +1 -1
- package/dist-standalone/chunks/{page-props-AIa5UR6n.js → page-props-DOfg30l5.js} +1 -1
- package/dist-standalone/chunks/{rich-editor-field-DLQTyt36.js → rich-editor-field-DORXTHPw.js} +2 -2
- package/dist-standalone/chunks/{subscriptions-DY2tj9Im.js → subscriptions-B_ISgA7V.js} +1 -1
- package/dist-standalone/chunks/use-effect-dispatcher-D1wPPwHj.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 +1 -1
- package/dist/clipboard/index.js.map +0 -1
- package/dist/events/event-names.js.map +0 -1
- package/dist/table/components/table-action-node.d.ts +0 -4
- package/dist/table/components/table-action-node.js +0 -24
- package/dist/table/components/table-action-node.js.map +0 -1
- package/dist-standalone/chunks/chart-view-wJmnVu7L.js +0 -36
- package/dist-standalone/chunks/use-effect-dispatcher-feEs0GCP.js +0 -97
- /package/dist/{events → core}/event-names.d.ts +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-cell.js","names":[],"sources":["../../../../resources/js/table/components/cells/text-cell.tsx"],"sourcesContent":["import { DateTime } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { coerceColor, namedColor, toneProps } from \"@lattice-php/lattice/lib/color\";\nimport
|
|
1
|
+
{"version":3,"file":"text-cell.js","names":[],"sources":["../../../../resources/js/table/components/cells/text-cell.tsx"],"sourcesContent":["import { DateTime } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { coerceColor, namedColor, toneProps } from \"@lattice-php/lattice/lib/color\";\nimport type { ReactNode } from \"react\";\nimport { formatCell, resolveLink } from \"@lattice-php/lattice/table/lib/format\";\nimport type { ColumnCellArgs, ColumnCellComponent } from \"@lattice-php/lattice/table/registry\";\nimport type { ColumnPropsOf } from \"@lattice-php/lattice/table/types\";\nimport { CopyableCell } from \"./copyable-cell\";\n\ntype TextProps = ColumnCellArgs<\"column.text\">[\"props\"];\n\nexport const TextCell: ColumnCellComponent<\"column.text\"> = (args) => {\n if (args.props.multiple) {\n return <MultipleCell {...args} />;\n }\n\n if (args.props.badge) {\n return <SingleBadgeCell {...args} />;\n }\n\n return <PlainTextCell {...args} />;\n};\n\nfunction Badge({ label, color }: { label: string; color?: string | null }): ReactNode {\n if (label === \"\") {\n return null;\n }\n\n const tone = toneProps(coerceColor(color) ?? namedColor(\"gray\"));\n\n return (\n <span className={cn(\"lt-cell-badge\", tone.className)} style={tone.style}>\n {label}\n </span>\n );\n}\n\nfunction MultipleCell({ column, props, value }: ColumnCellArgs<\"column.text\">): ReactNode {\n const items = Array.isArray(value) ? value : [];\n\n if (items.length === 0) {\n return null;\n }\n\n if (!props.badge) {\n return <span>{items.map((item) => formatCell(item, column)).join(\", \")}</span>;\n }\n\n return (\n <div className=\"flex flex-wrap gap-1\">\n {items.map((item, index) => {\n const chip = item as { value: unknown; color?: string };\n\n return <Badge key={index} label={formatCell(chip.value, column)} color={chip.color} />;\n })}\n </div>\n );\n}\n\nfunction SingleBadgeCell({ column, props, row, value }: ColumnCellArgs<\"column.text\">): ReactNode {\n const colorKey = (props.badge as NonNullable<TextProps[\"badge\"]>).colorKey;\n\n return <Badge label={formatCell(value, column)} color={String(row[colorKey] ?? \"\")} />;\n}\n\nfunction PlainTextCell({ column, props, row, value }: ColumnCellArgs<\"column.text\">): ReactNode {\n const dateProps = (column.props as ColumnPropsOf<\"column.text\">).date;\n const href = resolveLink(column, row, value);\n const text = formatCell(value, column);\n\n const content = href ? (\n <a\n className=\"underline underline-offset-2\"\n href={href}\n rel={props.link?.external ? \"noreferrer\" : undefined}\n target={props.link?.external ? \"_blank\" : undefined}\n >\n {text}\n </a>\n ) : (\n text\n );\n\n if (dateProps && !href && !props.copyable && value !== null && value !== undefined) {\n return (\n <DateTime value={value} dateStyle={dateProps.dateStyle} timeStyle={dateProps.timeStyle} />\n );\n }\n\n return (\n <CopyableCell column={column} copyable={props.copyable} value={text}>\n {content}\n </CopyableCell>\n );\n}\n"],"mappings":";;;;;;;AAWA,IAAa,YAAgD,SAAS;CACpE,IAAI,KAAK,MAAM,UACb,OAAO,oBAAC,cAAD,EAAc,GAAI,KAAO,CAAA;CAGlC,IAAI,KAAK,MAAM,OACb,OAAO,oBAAC,iBAAD,EAAiB,GAAI,KAAO,CAAA;CAGrC,OAAO,oBAAC,eAAD,EAAe,GAAI,KAAO,CAAA;AACnC;AAEA,SAAS,MAAM,EAAE,OAAO,SAA8D;CACpF,IAAI,UAAU,IACZ,OAAO;CAGT,MAAM,OAAO,UAAU,YAAY,KAAK,KAAK,WAAW,MAAM,CAAC;CAE/D,OACE,oBAAC,QAAD;EAAM,WAAW,GAAG,iBAAiB,KAAK,SAAS;EAAG,OAAO,KAAK;YAC/D;CACG,CAAA;AAEV;AAEA,SAAS,aAAa,EAAE,QAAQ,OAAO,SAAmD;CACxF,MAAM,QAAQ,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC;CAE9C,IAAI,MAAM,WAAW,GACnB,OAAO;CAGT,IAAI,CAAC,MAAM,OACT,OAAO,oBAAC,QAAD,EAAA,UAAO,MAAM,KAAK,SAAS,WAAW,MAAM,MAAM,CAAC,EAAE,KAAK,IAAI,EAAQ,CAAA;CAG/E,OACE,oBAAC,OAAD;EAAK,WAAU;YACZ,MAAM,KAAK,MAAM,UAAU;GAC1B,MAAM,OAAO;GAEb,OAAO,oBAAC,OAAD;IAAmB,OAAO,WAAW,KAAK,OAAO,MAAM;IAAG,OAAO,KAAK;GAAQ,GAAlE,KAAkE;EACvF,CAAC;CACE,CAAA;AAET;AAEA,SAAS,gBAAgB,EAAE,QAAQ,OAAO,KAAK,SAAmD;CAChG,MAAM,WAAY,MAAM,MAA0C;CAElE,OAAO,oBAAC,OAAD;EAAO,OAAO,WAAW,OAAO,MAAM;EAAG,OAAO,OAAO,IAAI,aAAa,EAAE;CAAI,CAAA;AACvF;AAEA,SAAS,cAAc,EAAE,QAAQ,OAAO,KAAK,SAAmD;CAC9F,MAAM,YAAa,OAAO,MAAuC;CACjE,MAAM,OAAO,YAAY,QAAQ,KAAK,KAAK;CAC3C,MAAM,OAAO,WAAW,OAAO,MAAM;CAErC,MAAM,UAAU,OACd,oBAAC,KAAD;EACE,WAAU;EACJ;EACN,KAAK,MAAM,MAAM,WAAW,eAAe,KAAA;EAC3C,QAAQ,MAAM,MAAM,WAAW,WAAW,KAAA;YAEzC;CACA,CAAA,IAEH;CAGF,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,YAAY,UAAU,QAAQ,UAAU,KAAA,GACvE,OACE,oBAAC,UAAD;EAAiB;EAAO,WAAW,UAAU;EAAW,WAAW,UAAU;CAAY,CAAA;CAI7F,OACE,oBAAC,cAAD;EAAsB;EAAQ,UAAU,MAAM;EAAU,OAAO;YAC5D;CACW,CAAA;AAElB"}
|
|
@@ -11,6 +11,7 @@ import { TableCellProvider } from "../../form/hooks/row-layout-context.js";
|
|
|
11
11
|
import { Checkbox } from "../../ui/checkbox.js";
|
|
12
12
|
import { IconButton } from "../../ui/icon-button.js";
|
|
13
13
|
import { filterValue, isActiveFilterValue } from "../lib/filter-values.js";
|
|
14
|
+
import { isTruthy } from "../../lib/is-truthy.js";
|
|
14
15
|
import { useCallback, useMemo, useRef } from "react";
|
|
15
16
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
17
|
//#region resources/js/table/components/filter-controls.tsx
|
|
@@ -120,9 +121,6 @@ function ToggleControl({ filter, value, processing, onChange }) {
|
|
|
120
121
|
}), /* @__PURE__ */ jsx("span", { children: filter.props.label })]
|
|
121
122
|
});
|
|
122
123
|
}
|
|
123
|
-
function isTruthy(value) {
|
|
124
|
-
return value === true || value === "1" || value === 1 || value === "true";
|
|
125
|
-
}
|
|
126
124
|
//#endregion
|
|
127
125
|
export { TableFilterControl };
|
|
128
126
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-controls.js","names":[],"sources":["../../../resources/js/table/components/filter-controls.tsx"],"sourcesContent":["import { useCallback, useMemo, useRef } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { Checkbox } from \"@lattice-php/lattice/ui/checkbox\";\nimport { Renderer } from \"@lattice-php/lattice/core/renderer\";\nimport type { Node, Option } from \"@lattice-php/lattice/core/types\";\nimport {\n FieldCommitOverrideProvider,\n FormProvider,\n FormValuesProvider,\n getPath,\n PrefillProvider,\n ResolvedNodesProvider,\n setPath,\n TableCellProvider,\n useFormValues,\n useSetFormValue,\n} from \"@lattice-php/lattice/form/embed\";\nimport { IconButton } from \"@lattice-php/lattice/ui/icon-button\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { filterValue, isActiveFilterValue } from \"@lattice-php/lattice/table/lib/filter-values\";\nimport type { FilterNode } from \"@lattice-php/lattice/table/types\";\n\nexport type FilterOptionSearch = (\n field: string,\n query: string,\n signal: AbortSignal,\n) => Promise<Option[]>;\n\ntype FilterValue = Record<string, unknown>;\n\nexport function TableFilterControl({\n filter,\n value,\n processing,\n bare = false,\n onChange,\n onSearch,\n}: {\n filter: FilterNode;\n value: unknown;\n processing: boolean;\n bare?: boolean;\n onChange: (value: unknown) => void;\n onSearch?: FilterOptionSearch;\n}) {\n const { t } = useT(\"lattice\");\n const schema = filter.schema ?? [];\n\n if (schema.length === 0) {\n return (\n <ToggleControl filter={filter} value={value} processing={processing} onChange={onChange} />\n );\n }\n\n return (\n <div className=\"flex items-end gap-2\">\n <div className=\"min-w-0 flex-1\">\n <SchemaControl\n filter={filter}\n schema={schema}\n value={value}\n processing={processing}\n bare={bare}\n onChange={onChange}\n onSearch={onSearch}\n />\n </div>\n {isActiveFilterValue(value) && (\n <IconButton\n size=\"md\"\n icon=\"x\"\n label={t(\"table.filter.clear\", \"Clear {{label}} filter\", {\n label: filter.props.label ?? \"\",\n })}\n disabled={processing}\n onClick={() => onChange(undefined)}\n />\n )}\n </div>\n );\n}\n\nfunction SchemaControl({\n filter,\n schema,\n value,\n processing,\n bare,\n onChange,\n onSearch,\n}: {\n filter: FilterNode;\n schema: Node[];\n value: unknown;\n processing: boolean;\n bare: boolean;\n onChange: (value: unknown) => void;\n onSearch?: FilterOptionSearch;\n}) {\n const initial = useMemo(() => filterValue(value), [value]);\n const form = useMemo(\n () => ({\n action: \"#\",\n clearErrors: () => {},\n componentId: `table-filter-${filter.key}`,\n componentRef: \"\",\n errors: {},\n fieldIdPrefix: `table-filter-${filter.key}`,\n fieldLabels: {},\n precognitive: false,\n processing,\n searchOptions: (\n field: string,\n query: string,\n _values: Record<string, unknown>,\n signal: AbortSignal,\n ) => (onSearch ? onSearch(field, query, signal) : Promise.resolve([])),\n validate: () => {},\n }),\n [filter.key, onSearch, processing],\n );\n\n const content = (\n <div\n aria-disabled={processing}\n className={cn(\"grid gap-3\", processing && \"pointer-events-none opacity-60\")}\n >\n <Renderer nodes={schema} />\n </div>\n );\n\n return (\n <FormProvider value={form}>\n <PrefillProvider value={{ markUserEdit: () => {} }}>\n <ResolvedNodesProvider nodes={{}}>\n <FormValuesProvider initial={initial}>\n <TableFilterCommitBridge onChange={onChange}>\n {bare ? <TableCellProvider>{content}</TableCellProvider> : content}\n </TableFilterCommitBridge>\n </FormValuesProvider>\n </ResolvedNodesProvider>\n </PrefillProvider>\n </FormProvider>\n );\n}\n\nfunction TableFilterCommitBridge({\n children,\n onChange,\n}: {\n children: ReactNode;\n onChange: (value: FilterValue) => void;\n}) {\n const values = useFormValues();\n const setValue = useSetFormValue();\n const valuesRef = useRef(values);\n valuesRef.current = values;\n\n const write = useCallback(\n (name: string, value: unknown) => {\n const nextValue =\n typeof value === \"function\"\n ? (value as (previous: unknown) => unknown)(getPath(valuesRef.current, name))\n : value;\n const next = setPath(valuesRef.current, name, nextValue);\n\n valuesRef.current = next;\n setValue(name, nextValue);\n onChange(next);\n },\n [onChange, setValue],\n );\n\n const commit = useMemo(\n () => ({\n blur: () => {},\n change: write,\n commit: write,\n }),\n [write],\n );\n\n return <FieldCommitOverrideProvider value={commit}>{children}</FieldCommitOverrideProvider>;\n}\n\nfunction ToggleControl({\n filter,\n value,\n processing,\n onChange,\n}: {\n filter: FilterNode;\n value: unknown;\n processing: boolean;\n onChange: (value: unknown) => void;\n}) {\n const checked = isTruthy(filterValue(value).value);\n\n return (\n <label className=\"flex h-lt-control-md cursor-pointer items-center gap-2 text-sm\">\n <Checkbox\n aria-label={filter.props.label ?? undefined}\n data-test={`table-filter-${filter.key}`}\n checked={checked}\n disabled={processing}\n onCheckedChange={(next) => onChange(next === true ? { value: \"1\" } : undefined)}\n />\n <span>{filter.props.label}</span>\n </label>\n );\n}\n
|
|
1
|
+
{"version":3,"file":"filter-controls.js","names":[],"sources":["../../../resources/js/table/components/filter-controls.tsx"],"sourcesContent":["import { useCallback, useMemo, useRef } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { Checkbox } from \"@lattice-php/lattice/ui/checkbox\";\nimport { Renderer } from \"@lattice-php/lattice/core/renderer\";\nimport type { Node, Option } from \"@lattice-php/lattice/core/types\";\nimport {\n FieldCommitOverrideProvider,\n FormProvider,\n FormValuesProvider,\n getPath,\n PrefillProvider,\n ResolvedNodesProvider,\n setPath,\n TableCellProvider,\n useFormValues,\n useSetFormValue,\n} from \"@lattice-php/lattice/form/embed\";\nimport { IconButton } from \"@lattice-php/lattice/ui/icon-button\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { isTruthy } from \"@lattice-php/lattice/lib/is-truthy\";\nimport { filterValue, isActiveFilterValue } from \"@lattice-php/lattice/table/lib/filter-values\";\nimport type { FilterNode } from \"@lattice-php/lattice/table/types\";\n\nexport type FilterOptionSearch = (\n field: string,\n query: string,\n signal: AbortSignal,\n) => Promise<Option[]>;\n\ntype FilterValue = Record<string, unknown>;\n\nexport function TableFilterControl({\n filter,\n value,\n processing,\n bare = false,\n onChange,\n onSearch,\n}: {\n filter: FilterNode;\n value: unknown;\n processing: boolean;\n bare?: boolean;\n onChange: (value: unknown) => void;\n onSearch?: FilterOptionSearch;\n}) {\n const { t } = useT(\"lattice\");\n const schema = filter.schema ?? [];\n\n if (schema.length === 0) {\n return (\n <ToggleControl filter={filter} value={value} processing={processing} onChange={onChange} />\n );\n }\n\n return (\n <div className=\"flex items-end gap-2\">\n <div className=\"min-w-0 flex-1\">\n <SchemaControl\n filter={filter}\n schema={schema}\n value={value}\n processing={processing}\n bare={bare}\n onChange={onChange}\n onSearch={onSearch}\n />\n </div>\n {isActiveFilterValue(value) && (\n <IconButton\n size=\"md\"\n icon=\"x\"\n label={t(\"table.filter.clear\", \"Clear {{label}} filter\", {\n label: filter.props.label ?? \"\",\n })}\n disabled={processing}\n onClick={() => onChange(undefined)}\n />\n )}\n </div>\n );\n}\n\nfunction SchemaControl({\n filter,\n schema,\n value,\n processing,\n bare,\n onChange,\n onSearch,\n}: {\n filter: FilterNode;\n schema: Node[];\n value: unknown;\n processing: boolean;\n bare: boolean;\n onChange: (value: unknown) => void;\n onSearch?: FilterOptionSearch;\n}) {\n const initial = useMemo(() => filterValue(value), [value]);\n const form = useMemo(\n () => ({\n action: \"#\",\n clearErrors: () => {},\n componentId: `table-filter-${filter.key}`,\n componentRef: \"\",\n errors: {},\n fieldIdPrefix: `table-filter-${filter.key}`,\n fieldLabels: {},\n precognitive: false,\n processing,\n searchOptions: (\n field: string,\n query: string,\n _values: Record<string, unknown>,\n signal: AbortSignal,\n ) => (onSearch ? onSearch(field, query, signal) : Promise.resolve([])),\n validate: () => {},\n }),\n [filter.key, onSearch, processing],\n );\n\n const content = (\n <div\n aria-disabled={processing}\n className={cn(\"grid gap-3\", processing && \"pointer-events-none opacity-60\")}\n >\n <Renderer nodes={schema} />\n </div>\n );\n\n return (\n <FormProvider value={form}>\n <PrefillProvider value={{ markUserEdit: () => {} }}>\n <ResolvedNodesProvider nodes={{}}>\n <FormValuesProvider initial={initial}>\n <TableFilterCommitBridge onChange={onChange}>\n {bare ? <TableCellProvider>{content}</TableCellProvider> : content}\n </TableFilterCommitBridge>\n </FormValuesProvider>\n </ResolvedNodesProvider>\n </PrefillProvider>\n </FormProvider>\n );\n}\n\nfunction TableFilterCommitBridge({\n children,\n onChange,\n}: {\n children: ReactNode;\n onChange: (value: FilterValue) => void;\n}) {\n const values = useFormValues();\n const setValue = useSetFormValue();\n const valuesRef = useRef(values);\n valuesRef.current = values;\n\n const write = useCallback(\n (name: string, value: unknown) => {\n const nextValue =\n typeof value === \"function\"\n ? (value as (previous: unknown) => unknown)(getPath(valuesRef.current, name))\n : value;\n const next = setPath(valuesRef.current, name, nextValue);\n\n valuesRef.current = next;\n setValue(name, nextValue);\n onChange(next);\n },\n [onChange, setValue],\n );\n\n const commit = useMemo(\n () => ({\n blur: () => {},\n change: write,\n commit: write,\n }),\n [write],\n );\n\n return <FieldCommitOverrideProvider value={commit}>{children}</FieldCommitOverrideProvider>;\n}\n\nfunction ToggleControl({\n filter,\n value,\n processing,\n onChange,\n}: {\n filter: FilterNode;\n value: unknown;\n processing: boolean;\n onChange: (value: unknown) => void;\n}) {\n const checked = isTruthy(filterValue(value).value);\n\n return (\n <label className=\"flex h-lt-control-md cursor-pointer items-center gap-2 text-sm\">\n <Checkbox\n aria-label={filter.props.label ?? undefined}\n data-test={`table-filter-${filter.key}`}\n checked={checked}\n disabled={processing}\n onCheckedChange={(next) => onChange(next === true ? { value: \"1\" } : undefined)}\n />\n <span>{filter.props.label}</span>\n </label>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-cell.js","names":[],"sources":["../../../resources/js/table/components/table-cell.tsx"],"sourcesContent":["import { useColumnRegistry } from \"@lattice-php/lattice/core/registry-context\";\nimport type {
|
|
1
|
+
{"version":3,"file":"table-cell.js","names":[],"sources":["../../../resources/js/table/components/table-cell.tsx"],"sourcesContent":["import { useColumnRegistry } from \"@lattice-php/lattice/core/registry-context\";\nimport type { ColumnNodeType } from \"@lattice-php/lattice/types/generated\";\nimport {\n columnCell,\n type ColumnRegistry,\n type ColumnRegistryFor,\n} from \"@lattice-php/lattice/table/registry\";\nimport type { TableColumn, TableRow } from \"@lattice-php/lattice/table/types\";\nimport { BadgeCell } from \"./cells/badge-cell\";\nimport { BooleanCell } from \"./cells/boolean-cell\";\nimport { IconCell } from \"./cells/icon-cell\";\nimport { ImageCell } from \"./cells/image-cell\";\nimport { MoneyCell } from \"./cells/money-cell\";\nimport { NumberCell } from \"./cells/number-cell\";\nimport { StackCell } from \"./cells/stack-cell\";\nimport { TextCell } from \"./cells/text-cell\";\n\n// Built-in cells live with the (lazy-loaded) table feature rather than the\n// eager registry, so they stay code-split. Consumer-registered columns are\n// merged on top and win on type collisions.\nconst builtinColumnCells: ColumnRegistry = {\n \"column.badge\": columnCell(BadgeCell),\n \"column.boolean\": columnCell(BooleanCell),\n \"column.icon\": columnCell(IconCell),\n \"column.image\": columnCell(ImageCell),\n \"column.money\": columnCell(MoneyCell),\n \"column.number\": columnCell(NumberCell),\n \"column.stack\": columnCell(StackCell),\n \"column.text\": columnCell(TextCell),\n} satisfies ColumnRegistryFor<ColumnNodeType>;\n\nexport function ColumnCell({ column, row }: { column: TableColumn; row: TableRow }) {\n const customCells = useColumnRegistry();\n const Cell =\n customCells[column.type] ??\n builtinColumnCells[column.type] ??\n builtinColumnCells[\"column.text\"];\n\n return <Cell column={column} props={column.props} row={row} value={row[column.key]} />;\n}\n"],"mappings":";;;;;;;;;;;;AAoBA,IAAM,qBAAqC;CACzC,gBAAgB,WAAW,SAAS;CACpC,kBAAkB,WAAW,WAAW;CACxC,eAAe,WAAW,QAAQ;CAClC,gBAAgB,WAAW,SAAS;CACpC,gBAAgB,WAAW,SAAS;CACpC,iBAAiB,WAAW,UAAU;CACtC,gBAAgB,WAAW,SAAS;CACpC,eAAe,WAAW,QAAQ;AACpC;AAEA,SAAgB,WAAW,EAAE,QAAQ,OAA+C;CAOlF,OAAO,oBANa,kBAElB,EAAY,OAAO,SACnB,mBAAmB,OAAO,SAC1B,mBAAmB,gBAEd;EAAc;EAAQ,OAAO,OAAO;EAAY;EAAK,OAAO,IAAI,OAAO;CAAO,CAAA;AACvF"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { cn } from "../../lib/utils.js";
|
|
2
2
|
import { Icon } from "../../icons/sprite.js";
|
|
3
3
|
import { useT } from "../../i18n/instance.js";
|
|
4
|
+
import { useDebouncedCallback } from "../../lib/use-debounced-callback.js";
|
|
4
5
|
import { Input } from "../../ui/input.js";
|
|
5
6
|
import { IconButton } from "../../ui/icon-button.js";
|
|
6
7
|
import { useEffect, useRef, useState } from "react";
|
|
@@ -15,7 +16,6 @@ var DEBOUNCE_MS = 300;
|
|
|
15
16
|
function TableSearch({ value, onSearch }) {
|
|
16
17
|
const { t } = useT("lattice");
|
|
17
18
|
const [term, setTerm] = useState(value);
|
|
18
|
-
const timer = useRef(null);
|
|
19
19
|
const committed = useRef(value);
|
|
20
20
|
useEffect(() => {
|
|
21
21
|
if (value !== committed.current) {
|
|
@@ -23,20 +23,17 @@ function TableSearch({ value, onSearch }) {
|
|
|
23
23
|
setTerm(value);
|
|
24
24
|
}
|
|
25
25
|
}, [value]);
|
|
26
|
-
useEffect(() => () => {
|
|
27
|
-
if (timer.current) clearTimeout(timer.current);
|
|
28
|
-
}, []);
|
|
29
26
|
function commit(next) {
|
|
30
27
|
committed.current = next;
|
|
31
28
|
onSearch(next);
|
|
32
29
|
}
|
|
30
|
+
const commitDebounced = useDebouncedCallback(commit, DEBOUNCE_MS);
|
|
33
31
|
function change(next) {
|
|
34
32
|
setTerm(next);
|
|
35
|
-
|
|
36
|
-
timer.current = setTimeout(() => commit(next), DEBOUNCE_MS);
|
|
33
|
+
commitDebounced(next);
|
|
37
34
|
}
|
|
38
35
|
function clear() {
|
|
39
|
-
|
|
36
|
+
commitDebounced.cancel();
|
|
40
37
|
setTerm("");
|
|
41
38
|
commit("");
|
|
42
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-search.js","names":[],"sources":["../../../resources/js/table/components/table-search.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { IconButton } from \"@lattice-php/lattice/ui/icon-button\";\nimport { Input } from \"@lattice-php/lattice/ui/input\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\n\nconst DEBOUNCE_MS = 300;\n\n/**\n * The table-level quick-search box. Keystrokes update the input immediately and\n * commit the term to the server after a short debounce; an externally-changed\n * value (e.g. a filter reset) is adopted without echoing keystroke round-trips.\n */\nexport function TableSearch({\n value,\n onSearch,\n}: {\n value: string;\n onSearch: (term: string) => void;\n}) {\n const { t } = useT(\"lattice\");\n const [term, setTerm] = useState(value);\n const
|
|
1
|
+
{"version":3,"file":"table-search.js","names":[],"sources":["../../../resources/js/table/components/table-search.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { IconButton } from \"@lattice-php/lattice/ui/icon-button\";\nimport { Input } from \"@lattice-php/lattice/ui/input\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { useDebouncedCallback } from \"@lattice-php/lattice/lib/use-debounced-callback\";\n\nconst DEBOUNCE_MS = 300;\n\n/**\n * The table-level quick-search box. Keystrokes update the input immediately and\n * commit the term to the server after a short debounce; an externally-changed\n * value (e.g. a filter reset) is adopted without echoing keystroke round-trips.\n */\nexport function TableSearch({\n value,\n onSearch,\n}: {\n value: string;\n onSearch: (term: string) => void;\n}) {\n const { t } = useT(\"lattice\");\n const [term, setTerm] = useState(value);\n const committed = useRef(value);\n\n useEffect(() => {\n if (value !== committed.current) {\n committed.current = value;\n setTerm(value);\n }\n }, [value]);\n\n function commit(next: string): void {\n committed.current = next;\n onSearch(next);\n }\n\n const commitDebounced = useDebouncedCallback(commit, DEBOUNCE_MS);\n\n function change(next: string): void {\n setTerm(next);\n commitDebounced(next);\n }\n\n function clear(): void {\n commitDebounced.cancel();\n setTerm(\"\");\n commit(\"\");\n }\n\n const label = t(\"table.search.placeholder\", \"Search\");\n\n return (\n <div className=\"relative w-full max-w-xs\">\n <Icon\n name=\"search\"\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-2.5 top-1/2 size-lt-icon-sm -translate-y-1/2 text-lt-muted-fg\"\n />\n <Input\n type=\"search\"\n data-test=\"table-search\"\n value={term}\n placeholder={label}\n aria-label={label}\n onChange={(event) => change(event.target.value)}\n className={cn(\"px-8\", \"[&::-webkit-search-cancel-button]:hidden\")}\n />\n {term !== \"\" && (\n <IconButton\n size=\"xs\"\n icon=\"x\"\n label={t(\"table.search.clear\", \"Clear search\")}\n data-test=\"table-search-clear\"\n className=\"absolute right-1.5 top-1/2 -translate-y-1/2\"\n onClick={clear}\n />\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAQA,IAAM,cAAc;;;;;;AAOpB,SAAgB,YAAY,EAC1B,OACA,YAIC;CACD,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,YAAY,OAAO,KAAK;CAE9B,gBAAgB;EACd,IAAI,UAAU,UAAU,SAAS;GAC/B,UAAU,UAAU;GACpB,QAAQ,KAAK;EACf;CACF,GAAG,CAAC,KAAK,CAAC;CAEV,SAAS,OAAO,MAAoB;EAClC,UAAU,UAAU;EACpB,SAAS,IAAI;CACf;CAEA,MAAM,kBAAkB,qBAAqB,QAAQ,WAAW;CAEhE,SAAS,OAAO,MAAoB;EAClC,QAAQ,IAAI;EACZ,gBAAgB,IAAI;CACtB;CAEA,SAAS,QAAc;EACrB,gBAAgB,OAAO;EACvB,QAAQ,EAAE;EACV,OAAO,EAAE;CACX;CAEA,MAAM,QAAQ,EAAE,4BAA4B,QAAQ;CAEpD,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACE,oBAAC,MAAD;IACE,MAAK;IACL,eAAY;IACZ,WAAU;GACX,CAAA;GACD,oBAAC,OAAD;IACE,MAAK;IACL,aAAU;IACV,OAAO;IACP,aAAa;IACb,cAAY;IACZ,WAAW,UAAU,OAAO,MAAM,OAAO,KAAK;IAC9C,WAAW,GAAG,QAAQ,0CAA0C;GACjE,CAAA;GACA,SAAS,MACR,oBAAC,YAAD;IACE,MAAK;IACL,MAAK;IACL,OAAO,EAAE,sBAAsB,cAAc;IAC7C,aAAU;IACV,WAAU;IACV,SAAS;GACV,CAAA;EAEA;;AAET"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cn } from "../../lib/utils.js";
|
|
2
2
|
import { Icon } from "../../icons/sprite.js";
|
|
3
|
-
import { Renderer } from "../../core/renderer.js";
|
|
3
|
+
import { RenderNode, Renderer } from "../../core/renderer.js";
|
|
4
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";
|
|
@@ -21,7 +21,6 @@ import { FilterBar, FilterMenu } from "./filter-bar.js";
|
|
|
21
21
|
import { TablePagination } from "./pagination.js";
|
|
22
22
|
import { SortBar } from "./sort-bar.js";
|
|
23
23
|
import { TableSearch } from "./table-search.js";
|
|
24
|
-
import { TableActionNode } from "./table-action-node.js";
|
|
25
24
|
import { ColumnCell } from "./table-cell.js";
|
|
26
25
|
import { Fragment, useMemo } from "react";
|
|
27
26
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -296,7 +295,7 @@ var TableComponent = ({ node }) => {
|
|
|
296
295
|
hasTrailingUtility && /* @__PURE__ */ jsx("div", {
|
|
297
296
|
className: cn("items-center justify-start gap-2 px-lt-cell-x py-lt-cell-y md:justify-end", actions.length > 0 ? "flex" : "hidden md:flex"),
|
|
298
297
|
role: "cell",
|
|
299
|
-
children: actions.map((action, actionIndex) => /* @__PURE__ */ jsx(
|
|
298
|
+
children: actions.map((action, actionIndex) => /* @__PURE__ */ jsx(RenderNode, { node: action }, action.key ?? action.id ?? actionIndex))
|
|
300
299
|
})
|
|
301
300
|
]
|
|
302
301
|
}), expanded && detail && /* @__PURE__ */ jsx("div", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.js","names":[],"sources":["../../../resources/js/table/components/table.tsx"],"sourcesContent":["import { type ReactNode, Fragment, useMemo } from \"react\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { Renderer } from \"@lattice-php/lattice/core/renderer\";\nimport { useColumnResizing } from \"@lattice-php/lattice/core/hooks/use-column-resizing\";\nimport { useColumnVisibility } from \"@lattice-php/lattice/table/hooks/use-column-visibility\";\nimport { useExpandedRows } from \"@lattice-php/lattice/table/hooks/use-expanded-rows\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport { Checkbox } from \"@lattice-php/lattice/ui/checkbox\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { alignJustifyItems, alignText } from \"@lattice-php/lattice/table/lib/align\";\nimport type { TableNode } from \"@lattice-php/lattice/table/types\";\nimport { getBulkActions } from \"@lattice-php/lattice/table/lib/bulk\";\nimport { getRowActions, getRowDetail, getRowKey } from \"@lattice-php/lattice/table/lib/payload\";\nimport {\n getQueryParams,\n getTableSizingColumns,\n getTableUtilityTracks,\n getVisiblePages,\n} from \"@lattice-php/lattice/table/lib/query\";\nimport { useTable } from \"@lattice-php/lattice/table/hooks/use-table\";\nimport { useTableSelection } from \"@lattice-php/lattice/table/hooks/use-table-selection\";\nimport { BulkBar } from \"./bulk-bar\";\nimport { ColumnFilterControl } from \"./column-filter-control\";\nimport { ColumnHeader } from \"./column-header\";\nimport { ColumnVisibilityMenu } from \"./column-visibility-menu\";\nimport { FilterBar, FilterMenu } from \"./filter-bar\";\nimport { TablePagination } from \"./pagination\";\nimport { SortBar } from \"./sort-bar\";\nimport { TableSearch } from \"./table-search\";\nimport { TableActionNode } from \"./table-action-node\";\nimport { ColumnCell } from \"./table-cell\";\n\nconst TableComponent = ({ node }: { children?: ReactNode; node: TableNode }) => {\n const { t } = useT(\"lattice\");\n const {\n columns,\n rows,\n pagination,\n query,\n filters,\n tableFilters,\n search,\n addFilter,\n updateFilter,\n removeFilter,\n replaceColumnFilters,\n setTableFilter,\n resetFilters,\n setSearch,\n searchFilterOptions,\n processing,\n hasLoaded,\n infiniteLoaderRef,\n sort,\n clearSort,\n goToPage,\n loadMore,\n } = useTable(node);\n\n const bulkActions = useMemo(\n () => getBulkActions(node.props?.bulkActions),\n [node.props?.bulkActions],\n );\n const hasBulkActions = bulkActions.length > 0;\n const rowEntries = useMemo(\n () =>\n rows.map((row, index) => ({\n row,\n actions: getRowActions(row),\n detail: getRowDetail(row),\n key: getRowKey(row, index),\n })),\n [rows],\n );\n const selection = useTableSelection(rowEntries.map((entry) => entry.key));\n const { isExpanded, toggle: toggleRow } = useExpandedRows();\n const hasExpandable = rowEntries.some((entry) => entry.detail != null);\n\n const columnsByKey = useMemo(\n () => new Map(columns.map((column) => [column.key, column])),\n [columns],\n );\n const visibilityIdentity = nodeIdentity(node);\n const {\n hasToggleableColumns,\n hasHidden,\n isVisible,\n resetVisibility,\n setColumnVisible,\n toggleableColumns,\n visibleColumns,\n } = useColumnVisibility({\n columns,\n storageKey: visibilityIdentity\n ? `lattice:table-column-visibility:${visibilityIdentity}`\n : undefined,\n });\n const currentPage = pagination.currentPage ?? query.page;\n const lastPage = pagination.lastPage ?? currentPage;\n const mode = pagination.mode ?? \"table\";\n const visiblePages = getVisiblePages(currentPage, lastPage);\n const hasNextPage = pagination.hasMore ?? currentPage < lastPage;\n const hasActions = rowEntries.some((entry) => entry.actions.length > 0);\n const striped = node.props?.striped === true;\n const hasFilters = visibleColumns.some((column) => column.props.filter != null);\n const filterEntries = filters.map((clause, index) => ({ clause, index }));\n const filterDefinitions = useMemo(\n () => (Array.isArray(node.props?.filters) ? node.props.filters : []),\n [node.props?.filters],\n );\n const hasDedicatedFilters = filterDefinitions.length > 0;\n const hasTrailingUtility = hasActions || hasDedicatedFilters || hasToggleableColumns;\n const sizingColumns = useMemo(() => getTableSizingColumns(visibleColumns), [visibleColumns]);\n const utilityTracks = useMemo(\n () => getTableUtilityTracks(hasTrailingUtility, hasBulkActions, hasExpandable),\n [hasTrailingUtility, hasBulkActions, hasExpandable],\n );\n const resizingEnabled = node.props?.resizableColumns === true;\n const resizeStorageIdentity = nodeIdentity(node);\n const { getResizeHandleProps, gridTemplateColumns, hasOverrides, resizeRootRef, resetColumns } =\n useColumnResizing({\n columns: sizingColumns,\n enabled: resizingEnabled,\n leadingTracks: utilityTracks.leadingTracks,\n showIndicator: node.props?.resizeIndicator === true,\n storageKey:\n resizingEnabled && resizeStorageIdentity\n ? `lattice:table-columns:${resizeStorageIdentity}`\n : undefined,\n trailingTracks: utilityTracks.trailingTracks,\n });\n\n return (\n <div data-slot=\"table\" data-lattice-component={node.id} className=\"relative\">\n {hasOverrides && (\n <button\n aria-label={t(\"table.reset-column-widths\", \"Reset column widths\")}\n className=\"absolute right-1 top-1 z-10 hidden rounded-lt-sm p-1 text-lt-muted-fg hover:text-lt-fg md:inline-flex\"\n data-test=\"table-reset-columns\"\n onClick={resetColumns}\n title={t(\"table.reset-column-widths\", \"Reset column widths\")}\n type=\"button\"\n >\n <Icon name=\"rotate-ccw\" className=\"size-lt-icon-sm\" />\n </button>\n )}\n <div\n data-slot=\"table-scroll\"\n className=\"overflow-x-auto rounded-lt-sm border border-lt-border\"\n >\n {node.props?.searchable && (\n <div\n data-slot=\"table-toolbar\"\n className=\"flex items-center gap-2 border-b border-lt-border px-4 py-2\"\n >\n <TableSearch value={search} onSearch={setSearch} />\n </div>\n )}\n <FilterBar\n clauses={filters}\n columnsByKey={columnsByKey}\n indicators={query.tableFilterIndicators}\n processing={processing}\n onRemoveClause={removeFilter}\n onChange={setTableFilter}\n onReset={resetFilters}\n />\n {hasBulkActions && selection.active && (\n <BulkBar\n actions={bulkActions}\n selectedKeys={selection.selectedKeys}\n allMatching={selection.allMatching}\n total={pagination.total ?? undefined}\n query={getQueryParams(query)}\n canSelectAllMatching={\n selection.allVisibleSelected &&\n !selection.allMatching &&\n pagination.total != null &&\n pagination.total > selection.selectedKeys.length\n }\n onSelectAllMatching={selection.selectAllMatching}\n onCompleted={selection.clear}\n />\n )}\n {query.sorts.length > 0 && (\n <SortBar\n columnsByKey={columnsByKey}\n query={query}\n processing={processing}\n onClear={clearSort}\n />\n )}\n <div\n ref={resizeRootRef}\n className=\"min-w-full text-base\"\n role=\"table\"\n style={{ \"--lattice-table-columns\": gridTemplateColumns } as never}\n >\n <div\n data-slot=\"table-header\"\n className=\"border-b border-lt-border bg-lt-muted/50\"\n role=\"rowgroup\"\n >\n <div\n className=\"hidden min-w-full md:grid md:grid-cols-[var(--lattice-table-columns)]\"\n role=\"row\"\n >\n {hasExpandable && (\n <div className=\"px-2 py-3\" role=\"columnheader\" aria-hidden=\"true\" />\n )}\n {hasBulkActions && (\n <div className=\"flex items-center px-4 py-3\" role=\"columnheader\">\n <Checkbox\n aria-label={t(\"table.select-all-rows\", \"Select all rows\")}\n data-test=\"select-all\"\n checked={selection.allSelected}\n onCheckedChange={() => selection.toggleAll()}\n />\n </div>\n )}\n {visibleColumns.map((column, index) => (\n <ColumnHeader\n column={column}\n key={column.key}\n processing={processing}\n resizeHandleProps={\n resizingEnabled ? getResizeHandleProps(sizingColumns[index]) : undefined\n }\n sort={sort}\n query={query}\n />\n ))}\n {hasTrailingUtility && (\n <div\n className=\"flex items-center justify-end gap-2 px-4 py-2 align-middle font-semibold text-lt-fg\"\n role=\"columnheader\"\n >\n {hasDedicatedFilters && (\n <FilterMenu\n filters={filterDefinitions}\n values={tableFilters}\n processing={processing}\n onChange={setTableFilter}\n onSearch={searchFilterOptions}\n />\n )}\n {hasToggleableColumns && (\n <ColumnVisibilityMenu\n columns={toggleableColumns}\n isVisible={isVisible}\n visibleColumnCount={visibleColumns.length}\n hasHidden={hasHidden}\n onToggle={setColumnVisible}\n onReset={resetVisibility}\n processing={processing}\n />\n )}\n {hasActions && (\n <span className=\"sr-only\">\n {node.props?.actionsLabel ?? t(\"table.actions\", \"Actions\")}\n </span>\n )}\n </div>\n )}\n </div>\n {hasFilters && (\n <div\n className=\"hidden min-w-full border-t border-lt-border md:grid md:grid-cols-[var(--lattice-table-columns)]\"\n role=\"row\"\n >\n {hasExpandable && <div className=\"px-2 py-2\" role=\"cell\" />}\n {hasBulkActions && <div className=\"px-4 py-2\" role=\"cell\" />}\n {visibleColumns.map((column) => (\n <div key={column.key} className=\"min-w-0 px-2 py-2\" role=\"cell\">\n {column.props.filter != null && (\n <ColumnFilterControl\n column={column}\n clauses={filterEntries.filter((entry) => entry.clause.field === column.key)}\n processing={processing}\n onAdd={addFilter}\n onUpdate={updateFilter}\n onRemove={removeFilter}\n onReplace={replaceColumnFilters}\n onSearch={(query, signal) =>\n searchFilterOptions(`column:${column.key}`, query, signal)\n }\n />\n )}\n </div>\n ))}\n {hasTrailingUtility && <div className=\"px-4 py-2\" role=\"cell\" />}\n </div>\n )}\n </div>\n <div role=\"rowgroup\">\n {!hasLoaded ? (\n <div className=\"p-4 text-lt-muted-fg\" role=\"row\">\n <div role=\"cell\">{t(\"table.loading\", \"Loading rows...\")}</div>\n </div>\n ) : rowEntries.length === 0 ? (\n <div data-slot=\"table-empty\" className=\"p-8 text-center text-lt-muted-fg\" role=\"row\">\n <div role=\"cell\">{node.props?.emptyLabel ?? t(\"table.empty\", \"No results\")}</div>\n </div>\n ) : (\n rowEntries.map(({ row, actions, detail, key }) => {\n const expanded = detail != null && isExpanded(key);\n const detailId = `${nodeIdentity(node) ?? \"table\"}-row-detail-${key}`;\n\n return (\n <Fragment key={key}>\n <div\n data-slot=\"table-row\"\n className={`grid grid-cols-1 border-b border-lt-border last:border-b-0 md:grid-cols-[var(--lattice-table-columns)] ${\n striped ? \"odd:bg-lt-muted/30\" : \"\"\n }`}\n role=\"row\"\n >\n {hasExpandable && (\n <div className=\"flex items-center px-2 py-lt-cell-y\" role=\"cell\">\n {detail && (\n <button\n type=\"button\"\n data-test={`row-expand-${key}`}\n aria-expanded={expanded}\n aria-controls={detailId}\n aria-label={t(\"table.row-detail.toggle\", \"Toggle detail\")}\n className=\"inline-flex size-6 items-center justify-center rounded-lt-sm text-lt-muted-fg hover:bg-lt-muted hover:text-lt-fg\"\n onClick={() => toggleRow(key)}\n >\n <Icon\n name=\"chevron-down\"\n aria-hidden=\"true\"\n className={cn(\n \"size-lt-icon-md transition-transform\",\n !expanded && \"-rotate-90\",\n )}\n />\n </button>\n )}\n </div>\n )}\n {hasBulkActions && (\n <div className=\"flex items-center px-lt-cell-x py-lt-cell-y\" role=\"cell\">\n <Checkbox\n aria-label={t(\"table.select-row\", \"Select row {{key}}\", { key })}\n data-test={`select-row-${key}`}\n checked={selection.isSelected(key)}\n onCheckedChange={() => selection.toggle(key)}\n />\n </div>\n )}\n {visibleColumns.map((column) => (\n <div\n key={column.key}\n data-slot=\"table-cell\"\n className={cn(\n \"grid min-w-0 gap-1 overflow-hidden px-lt-cell-x py-lt-cell-y align-middle\",\n alignText(column.props.align),\n alignJustifyItems(column.props.align),\n )}\n role=\"cell\"\n >\n <span\n aria-hidden=\"true\"\n className=\"text-xs font-medium text-lt-muted-fg md:hidden\"\n >\n {column.props.label}\n </span>\n <div\n data-slot=\"table-cell-content\"\n className=\"min-w-0 max-w-full overflow-hidden truncate\"\n >\n <ColumnCell column={column} row={row} />\n </div>\n </div>\n ))}\n {hasTrailingUtility && (\n <div\n className={cn(\n \"items-center justify-start gap-2 px-lt-cell-x py-lt-cell-y md:justify-end\",\n actions.length > 0 ? \"flex\" : \"hidden md:flex\",\n )}\n role=\"cell\"\n >\n {actions.map((action, actionIndex) => (\n <TableActionNode\n key={action.key ?? action.id ?? actionIndex}\n node={action}\n />\n ))}\n </div>\n )}\n </div>\n {expanded && detail && (\n <div\n id={detailId}\n role=\"region\"\n data-slot=\"table-row-detail\"\n className=\"border-b border-lt-border bg-lt-muted/20 px-lt-cell-x py-lt-cell-y\"\n >\n <Renderer nodes={[detail]} />\n </div>\n )}\n </Fragment>\n );\n })\n )}\n </div>\n </div>\n {hasLoaded && (\n <TablePagination\n pagination={pagination}\n currentPage={currentPage}\n processing={processing}\n mode={mode}\n hasNextPage={hasNextPage}\n visiblePages={visiblePages}\n infiniteLoaderRef={infiniteLoaderRef}\n onPage={goToPage}\n onLoadMore={loadMore}\n />\n )}\n </div>\n </div>\n );\n};\n\nexport default TableComponent;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"table.js","names":[],"sources":["../../../resources/js/table/components/table.tsx"],"sourcesContent":["import { type ReactNode, Fragment, useMemo } from \"react\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { Renderer, RenderNode } from \"@lattice-php/lattice/core/renderer\";\nimport { useColumnResizing } from \"@lattice-php/lattice/core/hooks/use-column-resizing\";\nimport { useColumnVisibility } from \"@lattice-php/lattice/table/hooks/use-column-visibility\";\nimport { useExpandedRows } from \"@lattice-php/lattice/table/hooks/use-expanded-rows\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport { Checkbox } from \"@lattice-php/lattice/ui/checkbox\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { alignJustifyItems, alignText } from \"@lattice-php/lattice/table/lib/align\";\nimport type { TableNode } from \"@lattice-php/lattice/table/types\";\nimport { getBulkActions } from \"@lattice-php/lattice/table/lib/bulk\";\nimport { getRowActions, getRowDetail, getRowKey } from \"@lattice-php/lattice/table/lib/payload\";\nimport {\n getQueryParams,\n getTableSizingColumns,\n getTableUtilityTracks,\n getVisiblePages,\n} from \"@lattice-php/lattice/table/lib/query\";\nimport { useTable } from \"@lattice-php/lattice/table/hooks/use-table\";\nimport { useTableSelection } from \"@lattice-php/lattice/table/hooks/use-table-selection\";\nimport { BulkBar } from \"./bulk-bar\";\nimport { ColumnFilterControl } from \"./column-filter-control\";\nimport { ColumnHeader } from \"./column-header\";\nimport { ColumnVisibilityMenu } from \"./column-visibility-menu\";\nimport { FilterBar, FilterMenu } from \"./filter-bar\";\nimport { TablePagination } from \"./pagination\";\nimport { SortBar } from \"./sort-bar\";\nimport { TableSearch } from \"./table-search\";\nimport { ColumnCell } from \"./table-cell\";\n\nconst TableComponent = ({ node }: { children?: ReactNode; node: TableNode }) => {\n const { t } = useT(\"lattice\");\n const {\n columns,\n rows,\n pagination,\n query,\n filters,\n tableFilters,\n search,\n addFilter,\n updateFilter,\n removeFilter,\n replaceColumnFilters,\n setTableFilter,\n resetFilters,\n setSearch,\n searchFilterOptions,\n processing,\n hasLoaded,\n infiniteLoaderRef,\n sort,\n clearSort,\n goToPage,\n loadMore,\n } = useTable(node);\n\n const bulkActions = useMemo(\n () => getBulkActions(node.props?.bulkActions),\n [node.props?.bulkActions],\n );\n const hasBulkActions = bulkActions.length > 0;\n const rowEntries = useMemo(\n () =>\n rows.map((row, index) => ({\n row,\n actions: getRowActions(row),\n detail: getRowDetail(row),\n key: getRowKey(row, index),\n })),\n [rows],\n );\n const selection = useTableSelection(rowEntries.map((entry) => entry.key));\n const { isExpanded, toggle: toggleRow } = useExpandedRows();\n const hasExpandable = rowEntries.some((entry) => entry.detail != null);\n\n const columnsByKey = useMemo(\n () => new Map(columns.map((column) => [column.key, column])),\n [columns],\n );\n const visibilityIdentity = nodeIdentity(node);\n const {\n hasToggleableColumns,\n hasHidden,\n isVisible,\n resetVisibility,\n setColumnVisible,\n toggleableColumns,\n visibleColumns,\n } = useColumnVisibility({\n columns,\n storageKey: visibilityIdentity\n ? `lattice:table-column-visibility:${visibilityIdentity}`\n : undefined,\n });\n const currentPage = pagination.currentPage ?? query.page;\n const lastPage = pagination.lastPage ?? currentPage;\n const mode = pagination.mode ?? \"table\";\n const visiblePages = getVisiblePages(currentPage, lastPage);\n const hasNextPage = pagination.hasMore ?? currentPage < lastPage;\n const hasActions = rowEntries.some((entry) => entry.actions.length > 0);\n const striped = node.props?.striped === true;\n const hasFilters = visibleColumns.some((column) => column.props.filter != null);\n const filterEntries = filters.map((clause, index) => ({ clause, index }));\n const filterDefinitions = useMemo(\n () => (Array.isArray(node.props?.filters) ? node.props.filters : []),\n [node.props?.filters],\n );\n const hasDedicatedFilters = filterDefinitions.length > 0;\n const hasTrailingUtility = hasActions || hasDedicatedFilters || hasToggleableColumns;\n const sizingColumns = useMemo(() => getTableSizingColumns(visibleColumns), [visibleColumns]);\n const utilityTracks = useMemo(\n () => getTableUtilityTracks(hasTrailingUtility, hasBulkActions, hasExpandable),\n [hasTrailingUtility, hasBulkActions, hasExpandable],\n );\n const resizingEnabled = node.props?.resizableColumns === true;\n const resizeStorageIdentity = nodeIdentity(node);\n const { getResizeHandleProps, gridTemplateColumns, hasOverrides, resizeRootRef, resetColumns } =\n useColumnResizing({\n columns: sizingColumns,\n enabled: resizingEnabled,\n leadingTracks: utilityTracks.leadingTracks,\n showIndicator: node.props?.resizeIndicator === true,\n storageKey:\n resizingEnabled && resizeStorageIdentity\n ? `lattice:table-columns:${resizeStorageIdentity}`\n : undefined,\n trailingTracks: utilityTracks.trailingTracks,\n });\n\n return (\n <div data-slot=\"table\" data-lattice-component={node.id} className=\"relative\">\n {hasOverrides && (\n <button\n aria-label={t(\"table.reset-column-widths\", \"Reset column widths\")}\n className=\"absolute right-1 top-1 z-10 hidden rounded-lt-sm p-1 text-lt-muted-fg hover:text-lt-fg md:inline-flex\"\n data-test=\"table-reset-columns\"\n onClick={resetColumns}\n title={t(\"table.reset-column-widths\", \"Reset column widths\")}\n type=\"button\"\n >\n <Icon name=\"rotate-ccw\" className=\"size-lt-icon-sm\" />\n </button>\n )}\n <div\n data-slot=\"table-scroll\"\n className=\"overflow-x-auto rounded-lt-sm border border-lt-border\"\n >\n {node.props?.searchable && (\n <div\n data-slot=\"table-toolbar\"\n className=\"flex items-center gap-2 border-b border-lt-border px-4 py-2\"\n >\n <TableSearch value={search} onSearch={setSearch} />\n </div>\n )}\n <FilterBar\n clauses={filters}\n columnsByKey={columnsByKey}\n indicators={query.tableFilterIndicators}\n processing={processing}\n onRemoveClause={removeFilter}\n onChange={setTableFilter}\n onReset={resetFilters}\n />\n {hasBulkActions && selection.active && (\n <BulkBar\n actions={bulkActions}\n selectedKeys={selection.selectedKeys}\n allMatching={selection.allMatching}\n total={pagination.total ?? undefined}\n query={getQueryParams(query)}\n canSelectAllMatching={\n selection.allVisibleSelected &&\n !selection.allMatching &&\n pagination.total != null &&\n pagination.total > selection.selectedKeys.length\n }\n onSelectAllMatching={selection.selectAllMatching}\n onCompleted={selection.clear}\n />\n )}\n {query.sorts.length > 0 && (\n <SortBar\n columnsByKey={columnsByKey}\n query={query}\n processing={processing}\n onClear={clearSort}\n />\n )}\n <div\n ref={resizeRootRef}\n className=\"min-w-full text-base\"\n role=\"table\"\n style={{ \"--lattice-table-columns\": gridTemplateColumns } as never}\n >\n <div\n data-slot=\"table-header\"\n className=\"border-b border-lt-border bg-lt-muted/50\"\n role=\"rowgroup\"\n >\n <div\n className=\"hidden min-w-full md:grid md:grid-cols-[var(--lattice-table-columns)]\"\n role=\"row\"\n >\n {hasExpandable && (\n <div className=\"px-2 py-3\" role=\"columnheader\" aria-hidden=\"true\" />\n )}\n {hasBulkActions && (\n <div className=\"flex items-center px-4 py-3\" role=\"columnheader\">\n <Checkbox\n aria-label={t(\"table.select-all-rows\", \"Select all rows\")}\n data-test=\"select-all\"\n checked={selection.allSelected}\n onCheckedChange={() => selection.toggleAll()}\n />\n </div>\n )}\n {visibleColumns.map((column, index) => (\n <ColumnHeader\n column={column}\n key={column.key}\n processing={processing}\n resizeHandleProps={\n resizingEnabled ? getResizeHandleProps(sizingColumns[index]) : undefined\n }\n sort={sort}\n query={query}\n />\n ))}\n {hasTrailingUtility && (\n <div\n className=\"flex items-center justify-end gap-2 px-4 py-2 align-middle font-semibold text-lt-fg\"\n role=\"columnheader\"\n >\n {hasDedicatedFilters && (\n <FilterMenu\n filters={filterDefinitions}\n values={tableFilters}\n processing={processing}\n onChange={setTableFilter}\n onSearch={searchFilterOptions}\n />\n )}\n {hasToggleableColumns && (\n <ColumnVisibilityMenu\n columns={toggleableColumns}\n isVisible={isVisible}\n visibleColumnCount={visibleColumns.length}\n hasHidden={hasHidden}\n onToggle={setColumnVisible}\n onReset={resetVisibility}\n processing={processing}\n />\n )}\n {hasActions && (\n <span className=\"sr-only\">\n {node.props?.actionsLabel ?? t(\"table.actions\", \"Actions\")}\n </span>\n )}\n </div>\n )}\n </div>\n {hasFilters && (\n <div\n className=\"hidden min-w-full border-t border-lt-border md:grid md:grid-cols-[var(--lattice-table-columns)]\"\n role=\"row\"\n >\n {hasExpandable && <div className=\"px-2 py-2\" role=\"cell\" />}\n {hasBulkActions && <div className=\"px-4 py-2\" role=\"cell\" />}\n {visibleColumns.map((column) => (\n <div key={column.key} className=\"min-w-0 px-2 py-2\" role=\"cell\">\n {column.props.filter != null && (\n <ColumnFilterControl\n column={column}\n clauses={filterEntries.filter((entry) => entry.clause.field === column.key)}\n processing={processing}\n onAdd={addFilter}\n onUpdate={updateFilter}\n onRemove={removeFilter}\n onReplace={replaceColumnFilters}\n onSearch={(query, signal) =>\n searchFilterOptions(`column:${column.key}`, query, signal)\n }\n />\n )}\n </div>\n ))}\n {hasTrailingUtility && <div className=\"px-4 py-2\" role=\"cell\" />}\n </div>\n )}\n </div>\n <div role=\"rowgroup\">\n {!hasLoaded ? (\n <div className=\"p-4 text-lt-muted-fg\" role=\"row\">\n <div role=\"cell\">{t(\"table.loading\", \"Loading rows...\")}</div>\n </div>\n ) : rowEntries.length === 0 ? (\n <div data-slot=\"table-empty\" className=\"p-8 text-center text-lt-muted-fg\" role=\"row\">\n <div role=\"cell\">{node.props?.emptyLabel ?? t(\"table.empty\", \"No results\")}</div>\n </div>\n ) : (\n rowEntries.map(({ row, actions, detail, key }) => {\n const expanded = detail != null && isExpanded(key);\n const detailId = `${nodeIdentity(node) ?? \"table\"}-row-detail-${key}`;\n\n return (\n <Fragment key={key}>\n <div\n data-slot=\"table-row\"\n className={`grid grid-cols-1 border-b border-lt-border last:border-b-0 md:grid-cols-[var(--lattice-table-columns)] ${\n striped ? \"odd:bg-lt-muted/30\" : \"\"\n }`}\n role=\"row\"\n >\n {hasExpandable && (\n <div className=\"flex items-center px-2 py-lt-cell-y\" role=\"cell\">\n {detail && (\n <button\n type=\"button\"\n data-test={`row-expand-${key}`}\n aria-expanded={expanded}\n aria-controls={detailId}\n aria-label={t(\"table.row-detail.toggle\", \"Toggle detail\")}\n className=\"inline-flex size-6 items-center justify-center rounded-lt-sm text-lt-muted-fg hover:bg-lt-muted hover:text-lt-fg\"\n onClick={() => toggleRow(key)}\n >\n <Icon\n name=\"chevron-down\"\n aria-hidden=\"true\"\n className={cn(\n \"size-lt-icon-md transition-transform\",\n !expanded && \"-rotate-90\",\n )}\n />\n </button>\n )}\n </div>\n )}\n {hasBulkActions && (\n <div className=\"flex items-center px-lt-cell-x py-lt-cell-y\" role=\"cell\">\n <Checkbox\n aria-label={t(\"table.select-row\", \"Select row {{key}}\", { key })}\n data-test={`select-row-${key}`}\n checked={selection.isSelected(key)}\n onCheckedChange={() => selection.toggle(key)}\n />\n </div>\n )}\n {visibleColumns.map((column) => (\n <div\n key={column.key}\n data-slot=\"table-cell\"\n className={cn(\n \"grid min-w-0 gap-1 overflow-hidden px-lt-cell-x py-lt-cell-y align-middle\",\n alignText(column.props.align),\n alignJustifyItems(column.props.align),\n )}\n role=\"cell\"\n >\n <span\n aria-hidden=\"true\"\n className=\"text-xs font-medium text-lt-muted-fg md:hidden\"\n >\n {column.props.label}\n </span>\n <div\n data-slot=\"table-cell-content\"\n className=\"min-w-0 max-w-full overflow-hidden truncate\"\n >\n <ColumnCell column={column} row={row} />\n </div>\n </div>\n ))}\n {hasTrailingUtility && (\n <div\n className={cn(\n \"items-center justify-start gap-2 px-lt-cell-x py-lt-cell-y md:justify-end\",\n actions.length > 0 ? \"flex\" : \"hidden md:flex\",\n )}\n role=\"cell\"\n >\n {actions.map((action, actionIndex) => (\n <RenderNode\n key={action.key ?? action.id ?? actionIndex}\n node={action}\n />\n ))}\n </div>\n )}\n </div>\n {expanded && detail && (\n <div\n id={detailId}\n role=\"region\"\n data-slot=\"table-row-detail\"\n className=\"border-b border-lt-border bg-lt-muted/20 px-lt-cell-x py-lt-cell-y\"\n >\n <Renderer nodes={[detail]} />\n </div>\n )}\n </Fragment>\n );\n })\n )}\n </div>\n </div>\n {hasLoaded && (\n <TablePagination\n pagination={pagination}\n currentPage={currentPage}\n processing={processing}\n mode={mode}\n hasNextPage={hasNextPage}\n visiblePages={visiblePages}\n infiniteLoaderRef={infiniteLoaderRef}\n onPage={goToPage}\n onLoadMore={loadMore}\n />\n )}\n </div>\n </div>\n );\n};\n\nexport default TableComponent;\n"],"mappings":"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"}
|
|
@@ -1,28 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { usePersistentState } from "../../lib/use-persistent-state.js";
|
|
2
|
+
import { useCallback, useMemo } from "react";
|
|
2
3
|
//#region resources/js/table/hooks/use-column-visibility.ts
|
|
3
4
|
function useColumnVisibility({ columns, storageKey }) {
|
|
4
5
|
const toggleableColumns = useMemo(() => columns.filter((column) => column.props.toggleable), [columns]);
|
|
5
6
|
const toggleableKeys = useMemo(() => toggleableColumns.map((column) => column.key), [toggleableColumns]);
|
|
6
|
-
const [overrides, setOverrides] =
|
|
7
|
+
const [overrides, setOverrides] = usePersistentState(storageKey ?? "", {}, {
|
|
8
|
+
enabled: Boolean(storageKey),
|
|
9
|
+
parse: (raw) => parseStoredVisibility(raw, toggleableKeys),
|
|
10
|
+
serialize: (value) => serializeVisibility(value, toggleableKeys)
|
|
11
|
+
});
|
|
7
12
|
const isVisible = useCallback((column) => {
|
|
8
13
|
if (!column.props.toggleable) return true;
|
|
9
14
|
return overrides[column.key] ?? !column.props.hiddenByDefault;
|
|
10
15
|
}, [overrides]);
|
|
11
16
|
const visibleColumns = useMemo(() => columns.filter((column) => isVisible(column)), [columns, isVisible]);
|
|
12
17
|
const setColumnVisible = useCallback((key, visible) => {
|
|
13
|
-
setOverrides((current) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return next;
|
|
20
|
-
});
|
|
21
|
-
}, [storageKey, toggleableKeys]);
|
|
22
|
-
const resetVisibility = useCallback(() => {
|
|
23
|
-
setOverrides({});
|
|
24
|
-
writeStoredVisibility(storageKey, toggleableKeys, {});
|
|
25
|
-
}, [storageKey, toggleableKeys]);
|
|
18
|
+
setOverrides((current) => ({
|
|
19
|
+
...current,
|
|
20
|
+
[key]: visible
|
|
21
|
+
}));
|
|
22
|
+
}, [setOverrides]);
|
|
23
|
+
const resetVisibility = useCallback(() => setOverrides({}), [setOverrides]);
|
|
26
24
|
const hasToggleableColumns = toggleableColumns.length > 0;
|
|
27
25
|
return {
|
|
28
26
|
hasHidden: toggleableColumns.some((column) => !isVisible(column)),
|
|
@@ -34,51 +32,24 @@ function useColumnVisibility({ columns, storageKey }) {
|
|
|
34
32
|
visibleColumns
|
|
35
33
|
};
|
|
36
34
|
}
|
|
37
|
-
function
|
|
38
|
-
if (!storageKey || typeof window === "undefined") return {};
|
|
39
|
-
try {
|
|
40
|
-
const raw = window.localStorage.getItem(storageKey);
|
|
41
|
-
if (raw === null) return {};
|
|
42
|
-
const stored = JSON.parse(raw);
|
|
43
|
-
if (!isStoredColumnVisibility(stored)) {
|
|
44
|
-
removeStoredVisibility(storageKey);
|
|
45
|
-
return {};
|
|
46
|
-
}
|
|
47
|
-
const known = new Set(toggleableKeys);
|
|
48
|
-
const overrides = {};
|
|
49
|
-
for (const [key, value] of Object.entries(stored.overrides)) if (known.has(key) && typeof value === "boolean") overrides[key] = value;
|
|
50
|
-
if (Object.keys(overrides).length === 0) removeStoredVisibility(storageKey);
|
|
51
|
-
return overrides;
|
|
52
|
-
} catch {
|
|
53
|
-
removeStoredVisibility(storageKey);
|
|
54
|
-
return {};
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
function writeStoredVisibility(storageKey, toggleableKeys, overrides) {
|
|
58
|
-
if (!storageKey || typeof window === "undefined") return;
|
|
35
|
+
function pickKnownBooleans(source, toggleableKeys) {
|
|
59
36
|
const known = new Set(toggleableKeys);
|
|
60
|
-
const
|
|
61
|
-
for (const [key, value] of Object.entries(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
columns: toggleableKeys,
|
|
69
|
-
overrides: stored
|
|
70
|
-
}));
|
|
71
|
-
} catch {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
37
|
+
const result = {};
|
|
38
|
+
for (const [key, value] of Object.entries(source)) if (known.has(key) && typeof value === "boolean") result[key] = value;
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
function parseStoredVisibility(raw, toggleableKeys) {
|
|
42
|
+
const stored = JSON.parse(raw);
|
|
43
|
+
if (!isStoredColumnVisibility(stored)) throw new Error("unexpected stored column visibility shape");
|
|
44
|
+
return pickKnownBooleans(stored.overrides, toggleableKeys);
|
|
74
45
|
}
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
46
|
+
function serializeVisibility(overrides, toggleableKeys) {
|
|
47
|
+
const stored = pickKnownBooleans(overrides, toggleableKeys);
|
|
48
|
+
if (Object.keys(stored).length === 0) return null;
|
|
49
|
+
return JSON.stringify({
|
|
50
|
+
columns: toggleableKeys,
|
|
51
|
+
overrides: stored
|
|
52
|
+
});
|
|
82
53
|
}
|
|
83
54
|
function isStoredColumnVisibility(value) {
|
|
84
55
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-column-visibility.js","names":[],"sources":["../../../resources/js/table/hooks/use-column-visibility.ts"],"sourcesContent":["import { useCallback, useMemo
|
|
1
|
+
{"version":3,"file":"use-column-visibility.js","names":[],"sources":["../../../resources/js/table/hooks/use-column-visibility.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport { usePersistentState } from \"@lattice-php/lattice/lib/use-persistent-state\";\n\nexport type ToggleableColumn = {\n key: string;\n props: {\n label?: string | null;\n toggleable?: boolean;\n hiddenByDefault?: boolean;\n };\n};\n\ntype StoredColumnVisibility = {\n columns: string[];\n overrides: Record<string, boolean>;\n};\n\nexport function useColumnVisibility<TColumn extends ToggleableColumn>({\n columns,\n storageKey,\n}: {\n columns: TColumn[];\n storageKey?: string;\n}) {\n const toggleableColumns = useMemo(\n () => columns.filter((column) => column.props.toggleable),\n [columns],\n );\n const toggleableKeys = useMemo(\n () => toggleableColumns.map((column) => column.key),\n [toggleableColumns],\n );\n\n const [overrides, setOverrides] = usePersistentState<Record<string, boolean>>(\n storageKey ?? \"\",\n {},\n {\n enabled: Boolean(storageKey),\n parse: (raw) => parseStoredVisibility(raw, toggleableKeys),\n serialize: (value) => serializeVisibility(value, toggleableKeys),\n },\n );\n\n const isVisible = useCallback(\n (column: ToggleableColumn): boolean => {\n if (!column.props.toggleable) {\n return true;\n }\n\n return overrides[column.key] ?? !column.props.hiddenByDefault;\n },\n [overrides],\n );\n\n const visibleColumns = useMemo(\n () => columns.filter((column) => isVisible(column)),\n [columns, isVisible],\n );\n\n const setColumnVisible = useCallback(\n (key: string, visible: boolean) => {\n setOverrides((current) => ({ ...current, [key]: visible }));\n },\n [setOverrides],\n );\n\n const resetVisibility = useCallback(() => setOverrides({}), [setOverrides]);\n\n const hasToggleableColumns = toggleableColumns.length > 0;\n const hasHidden = toggleableColumns.some((column) => !isVisible(column));\n\n return {\n hasHidden,\n hasToggleableColumns,\n isVisible,\n resetVisibility,\n setColumnVisible,\n toggleableColumns,\n visibleColumns,\n };\n}\n\nfunction pickKnownBooleans(\n source: Record<string, unknown>,\n toggleableKeys: string[],\n): Record<string, boolean> {\n const known = new Set(toggleableKeys);\n const result: Record<string, boolean> = {};\n\n for (const [key, value] of Object.entries(source)) {\n if (known.has(key) && typeof value === \"boolean\") {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nfunction parseStoredVisibility(raw: string, toggleableKeys: string[]): Record<string, boolean> {\n const stored = JSON.parse(raw) as unknown;\n\n if (!isStoredColumnVisibility(stored)) {\n throw new Error(\"unexpected stored column visibility shape\");\n }\n\n return pickKnownBooleans(stored.overrides, toggleableKeys);\n}\n\nfunction serializeVisibility(\n overrides: Record<string, boolean>,\n toggleableKeys: string[],\n): string | null {\n const stored = pickKnownBooleans(overrides, toggleableKeys);\n\n if (Object.keys(stored).length === 0) {\n return null;\n }\n\n return JSON.stringify({ columns: toggleableKeys, overrides: stored });\n}\n\nfunction isStoredColumnVisibility(value: unknown): value is StoredColumnVisibility {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n const record = value as Record<string, unknown>;\n\n return (\n Array.isArray(record.columns) &&\n record.columns.every((column) => typeof column === \"string\") &&\n typeof record.overrides === \"object\" &&\n record.overrides !== null &&\n !Array.isArray(record.overrides)\n );\n}\n"],"mappings":";;;AAiBA,SAAgB,oBAAsD,EACpE,SACA,cAIC;CACD,MAAM,oBAAoB,cAClB,QAAQ,QAAQ,WAAW,OAAO,MAAM,UAAU,GACxD,CAAC,OAAO,CACV;CACA,MAAM,iBAAiB,cACf,kBAAkB,KAAK,WAAW,OAAO,GAAG,GAClD,CAAC,iBAAiB,CACpB;CAEA,MAAM,CAAC,WAAW,gBAAgB,mBAChC,cAAc,IACd,CAAC,GACD;EACE,SAAS,QAAQ,UAAU;EAC3B,QAAQ,QAAQ,sBAAsB,KAAK,cAAc;EACzD,YAAY,UAAU,oBAAoB,OAAO,cAAc;CACjE,CACF;CAEA,MAAM,YAAY,aACf,WAAsC;EACrC,IAAI,CAAC,OAAO,MAAM,YAChB,OAAO;EAGT,OAAO,UAAU,OAAO,QAAQ,CAAC,OAAO,MAAM;CAChD,GACA,CAAC,SAAS,CACZ;CAEA,MAAM,iBAAiB,cACf,QAAQ,QAAQ,WAAW,UAAU,MAAM,CAAC,GAClD,CAAC,SAAS,SAAS,CACrB;CAEA,MAAM,mBAAmB,aACtB,KAAa,YAAqB;EACjC,cAAc,aAAa;GAAE,GAAG;IAAU,MAAM;EAAQ,EAAE;CAC5D,GACA,CAAC,YAAY,CACf;CAEA,MAAM,kBAAkB,kBAAkB,aAAa,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC;CAE1E,MAAM,uBAAuB,kBAAkB,SAAS;CAGxD,OAAO;EACL,WAHgB,kBAAkB,MAAM,WAAW,CAAC,UAAU,MAAM,CAGpE;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;AAEA,SAAS,kBACP,QACA,gBACyB;CACzB,MAAM,QAAQ,IAAI,IAAI,cAAc;CACpC,MAAM,SAAkC,CAAC;CAEzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,GAC9C,IAAI,MAAM,IAAI,GAAG,KAAK,OAAO,UAAU,WACrC,OAAO,OAAO;CAIlB,OAAO;AACT;AAEA,SAAS,sBAAsB,KAAa,gBAAmD;CAC7F,MAAM,SAAS,KAAK,MAAM,GAAG;CAE7B,IAAI,CAAC,yBAAyB,MAAM,GAClC,MAAM,IAAI,MAAM,2CAA2C;CAG7D,OAAO,kBAAkB,OAAO,WAAW,cAAc;AAC3D;AAEA,SAAS,oBACP,WACA,gBACe;CACf,MAAM,SAAS,kBAAkB,WAAW,cAAc;CAE1D,IAAI,OAAO,KAAK,MAAM,EAAE,WAAW,GACjC,OAAO;CAGT,OAAO,KAAK,UAAU;EAAE,SAAS;EAAgB,WAAW;CAAO,CAAC;AACtE;AAEA,SAAS,yBAAyB,OAAiD;CACjF,IAAI,OAAO,UAAU,YAAY,UAAU,MACzC,OAAO;CAGT,MAAM,SAAS;CAEf,OACE,MAAM,QAAQ,OAAO,OAAO,KAC5B,OAAO,QAAQ,OAAO,WAAW,OAAO,WAAW,QAAQ,KAC3D,OAAO,OAAO,cAAc,YAC5B,OAAO,cAAc,QACrB,CAAC,MAAM,QAAQ,OAAO,SAAS;AAEnC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { LATTICE_EVENT } from "../../
|
|
1
|
+
import { LATTICE_EVENT } from "../../core/event-names.js";
|
|
2
|
+
import { useWindowEvent } from "../../core/hooks/use-window-event.js";
|
|
2
3
|
import { apiFetch, apiJson } from "../../core/api.js";
|
|
3
4
|
import { getColumns, getPagination, getQuery, getRows } from "../lib/payload.js";
|
|
4
5
|
import { isEmptyFilterValue, isFilterValue } from "../lib/filter-values.js";
|
|
@@ -159,18 +160,9 @@ function useTable(node) {
|
|
|
159
160
|
load,
|
|
160
161
|
query
|
|
161
162
|
]);
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
load(query);
|
|
166
|
-
}
|
|
167
|
-
window.addEventListener(LATTICE_EVENT.reloadComponent, reload);
|
|
168
|
-
return () => window.removeEventListener(LATTICE_EVENT.reloadComponent, reload);
|
|
169
|
-
}, [
|
|
170
|
-
load,
|
|
171
|
-
node.id,
|
|
172
|
-
query
|
|
173
|
-
]);
|
|
163
|
+
useWindowEvent(LATTICE_EVENT.reloadComponent, (event) => {
|
|
164
|
+
if (event.detail?.component === node.id) load(query);
|
|
165
|
+
});
|
|
174
166
|
useEffect(() => {
|
|
175
167
|
if (!isInfinite || !pagination.hasMore || processing || !infiniteLoaderRef.current || typeof IntersectionObserver === "undefined") return;
|
|
176
168
|
const observer = new IntersectionObserver((entries) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-table.js","names":[],"sources":["../../../resources/js/table/hooks/use-table.ts"],"sourcesContent":["import { apiFetch, apiJson } from \"@lattice-php/lattice/core/api\";\nimport { LATTICE_EVENT, type ReloadComponentEvent } from \"@lattice-php/lattice/events/event-names\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { Option } from \"@lattice-php/lattice/types/generated\";\nimport { isEmptyFilterValue, isFilterValue } from \"@lattice-php/lattice/table/lib/filter-values\";\nimport {\n getColumns,\n getPagination,\n getRows,\n getQuery,\n} from \"@lattice-php/lattice/table/lib/payload\";\nimport { buildEndpoint, nextSort } from \"@lattice-php/lattice/table/lib/query\";\nimport type {\n FilterClause,\n TableColumn,\n TableNode,\n TableResult,\n TableSort,\n TableQuery,\n} from \"@lattice-php/lattice/table/types\";\n\nexport function useTable(node: TableNode) {\n const columns = useMemo(() => getColumns(node.props?.columns), [node.props?.columns]);\n const endpoint = typeof node.props?.endpoint === \"string\" ? node.props.endpoint : null;\n const componentRef = typeof node.props?.ref === \"string\" ? node.props.ref : \"\";\n const isLazy = node.props?.lazy === true;\n const initialQuery = useMemo(() => getQuery(node.props?.query), [node.props?.query]);\n const initialRows = useMemo(() => getRows(node.props?.data), [node.props?.data]);\n const initialPagination = useMemo(\n () => getPagination(node.props?.pagination),\n [node.props?.pagination],\n );\n const [rows, setRows] = useState(initialRows);\n const [pagination, setPagination] = useState(initialPagination);\n const [query, setQuery] = useState(initialQuery);\n const [processing, setProcessing] = useState(isLazy);\n const [hasLoaded, setHasLoaded] = useState(!isLazy);\n const infiniteLoaderRef = useRef<HTMLDivElement | null>(null);\n const currentPage = pagination.currentPage ?? query.page;\n const isInfinite = (pagination.mode ?? \"table\") === \"infinite\";\n\n const load = useCallback(\n async (nextQuery: TableQuery, append = false): Promise<void> => {\n if (!endpoint) {\n return;\n }\n\n setProcessing(true);\n\n try {\n const result = await apiJson<TableResult>(buildEndpoint(endpoint, nextQuery), {\n ref: componentRef,\n });\n const resultQuery = getQuery(result.query);\n const resultRows = getRows(result.data);\n\n setRows((currentRows) => (append ? [...currentRows, ...resultRows] : resultRows));\n setPagination(getPagination(result.pagination));\n setQuery(resultQuery);\n setHasLoaded(true);\n } finally {\n setProcessing(false);\n }\n },\n [endpoint, componentRef],\n );\n\n function sort(column: TableColumn): void {\n void load({\n ...query,\n page: 1,\n sorts: nextSort(query.sorts, column),\n });\n }\n\n function clearSort(sort: TableSort): void {\n void load({\n ...query,\n page: 1,\n sorts: query.sorts.filter((currentSort) => currentSort.key !== sort.key),\n });\n }\n\n function applyFilters(next: FilterClause[]): void {\n const nextQuery = { ...query, filters: next, page: 1 };\n\n setQuery(nextQuery);\n void load(nextQuery);\n }\n\n function addFilter(clause: FilterClause): void {\n applyFilters([...query.filters, clause]);\n }\n\n function updateFilter(index: number, clause: FilterClause): void {\n applyFilters(query.filters.map((current, position) => (position === index ? clause : current)));\n }\n\n function removeFilter(index: number): void {\n applyFilters(query.filters.filter((_, current) => current !== index));\n }\n\n function replaceColumnFilters(field: string, clauses: FilterClause[]): void {\n applyFilters([...query.filters.filter((clause) => clause.field !== field), ...clauses]);\n }\n\n function setTableFilter(key: string, value: unknown): void {\n const next = { ...query.tableFilters };\n\n if (isEmptyFilterValue(value) || !isFilterValue(value)) {\n delete next[key];\n } else {\n next[key] = value;\n }\n\n const nextQuery = {\n ...query,\n tableFilters: next,\n tableFilterIndicators: query.tableFilterIndicators.filter(\n (indicator) => indicator.filter !== key,\n ),\n page: 1,\n };\n\n setQuery(nextQuery);\n void load(nextQuery);\n }\n\n function resetFilters(): void {\n const nextQuery = {\n ...query,\n filters: [],\n tableFilters: {},\n tableFilterIndicators: [],\n search: \"\",\n page: 1,\n };\n\n setQuery(nextQuery);\n void load(nextQuery);\n }\n\n function setSearch(search: string): void {\n const nextQuery = { ...query, search, page: 1 };\n\n setQuery(nextQuery);\n void load(nextQuery);\n }\n\n const searchFilterOptions = useCallback(\n async (searchKey: string, search: string, signal?: AbortSignal): Promise<Option[]> => {\n if (!endpoint) {\n return [];\n }\n\n const url = new URL(endpoint, window.location.origin);\n url.searchParams.set(\"_search\", searchKey);\n url.searchParams.set(\"_q\", search);\n\n const response = await apiFetch(`${url.pathname}${url.search}`, {\n ref: componentRef,\n signal,\n throwOnError: false,\n });\n\n if (!response.ok) {\n return [];\n }\n\n const result = (await response.json()) as { options?: Option[] };\n\n return result.options ?? [];\n },\n [endpoint, componentRef],\n );\n\n function goToPage(page: number): void {\n void load({\n ...query,\n page,\n });\n }\n\n const loadMore = useCallback((): void => {\n if (processing || !pagination.hasMore) {\n return;\n }\n\n void load(\n {\n ...query,\n page: pagination.nextPage ?? currentPage + 1,\n },\n true,\n );\n }, [currentPage, load, pagination.hasMore, pagination.nextPage, processing, query]);\n\n useEffect(() => {\n setRows(initialRows);\n setPagination(initialPagination);\n setQuery(initialQuery);\n setProcessing(isLazy);\n setHasLoaded(!isLazy);\n }, [initialRows, initialPagination, initialQuery, isLazy]);\n\n useEffect(() => {\n if (!isLazy || hasLoaded) {\n return;\n }\n\n void load(query);\n }, [hasLoaded, isLazy, load, query]);\n\n useEffect(() => {\n function reload(event: Event): void {\n const detail = (event as ReloadComponentEvent).detail;\n\n if (detail?.component !== node.id) {\n return;\n }\n\n void load(query);\n }\n\n window.addEventListener(LATTICE_EVENT.reloadComponent, reload);\n\n return () => window.removeEventListener(LATTICE_EVENT.reloadComponent, reload);\n }, [load, node.id, query]);\n\n useEffect(() => {\n if (\n !isInfinite ||\n !pagination.hasMore ||\n processing ||\n !infiniteLoaderRef.current ||\n typeof IntersectionObserver === \"undefined\"\n ) {\n return;\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) {\n loadMore();\n }\n },\n {\n rootMargin: \"240px\",\n },\n );\n\n observer.observe(infiniteLoaderRef.current);\n\n return () => observer.disconnect();\n }, [isInfinite, loadMore, pagination.hasMore, processing]);\n\n return {\n columns,\n rows,\n pagination,\n query,\n filters: query.filters,\n tableFilters: query.tableFilters,\n search: query.search,\n addFilter,\n updateFilter,\n removeFilter,\n replaceColumnFilters,\n setTableFilter,\n resetFilters,\n setSearch,\n searchFilterOptions,\n processing,\n hasLoaded,\n infiniteLoaderRef,\n sort,\n clearSort,\n goToPage,\n loadMore,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-table.js","names":[],"sources":["../../../resources/js/table/hooks/use-table.ts"],"sourcesContent":["import { apiFetch, apiJson } from \"@lattice-php/lattice/core/api\";\nimport { LATTICE_EVENT, type ReloadComponentEvent } from \"@lattice-php/lattice/core/event-names\";\nimport { useWindowEvent } from \"@lattice-php/lattice/core/hooks/use-window-event\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { Option } from \"@lattice-php/lattice/types/generated\";\nimport { isEmptyFilterValue, isFilterValue } from \"@lattice-php/lattice/table/lib/filter-values\";\nimport {\n getColumns,\n getPagination,\n getRows,\n getQuery,\n} from \"@lattice-php/lattice/table/lib/payload\";\nimport { buildEndpoint, nextSort } from \"@lattice-php/lattice/table/lib/query\";\nimport type {\n FilterClause,\n TableColumn,\n TableNode,\n TableResult,\n TableSort,\n TableQuery,\n} from \"@lattice-php/lattice/table/types\";\n\nexport function useTable(node: TableNode) {\n const columns = useMemo(() => getColumns(node.props?.columns), [node.props?.columns]);\n const endpoint = typeof node.props?.endpoint === \"string\" ? node.props.endpoint : null;\n const componentRef = typeof node.props?.ref === \"string\" ? node.props.ref : \"\";\n const isLazy = node.props?.lazy === true;\n const initialQuery = useMemo(() => getQuery(node.props?.query), [node.props?.query]);\n const initialRows = useMemo(() => getRows(node.props?.data), [node.props?.data]);\n const initialPagination = useMemo(\n () => getPagination(node.props?.pagination),\n [node.props?.pagination],\n );\n const [rows, setRows] = useState(initialRows);\n const [pagination, setPagination] = useState(initialPagination);\n const [query, setQuery] = useState(initialQuery);\n const [processing, setProcessing] = useState(isLazy);\n const [hasLoaded, setHasLoaded] = useState(!isLazy);\n const infiniteLoaderRef = useRef<HTMLDivElement | null>(null);\n const currentPage = pagination.currentPage ?? query.page;\n const isInfinite = (pagination.mode ?? \"table\") === \"infinite\";\n\n const load = useCallback(\n async (nextQuery: TableQuery, append = false): Promise<void> => {\n if (!endpoint) {\n return;\n }\n\n setProcessing(true);\n\n try {\n const result = await apiJson<TableResult>(buildEndpoint(endpoint, nextQuery), {\n ref: componentRef,\n });\n const resultQuery = getQuery(result.query);\n const resultRows = getRows(result.data);\n\n setRows((currentRows) => (append ? [...currentRows, ...resultRows] : resultRows));\n setPagination(getPagination(result.pagination));\n setQuery(resultQuery);\n setHasLoaded(true);\n } finally {\n setProcessing(false);\n }\n },\n [endpoint, componentRef],\n );\n\n function sort(column: TableColumn): void {\n void load({\n ...query,\n page: 1,\n sorts: nextSort(query.sorts, column),\n });\n }\n\n function clearSort(sort: TableSort): void {\n void load({\n ...query,\n page: 1,\n sorts: query.sorts.filter((currentSort) => currentSort.key !== sort.key),\n });\n }\n\n function applyFilters(next: FilterClause[]): void {\n const nextQuery = { ...query, filters: next, page: 1 };\n\n setQuery(nextQuery);\n void load(nextQuery);\n }\n\n function addFilter(clause: FilterClause): void {\n applyFilters([...query.filters, clause]);\n }\n\n function updateFilter(index: number, clause: FilterClause): void {\n applyFilters(query.filters.map((current, position) => (position === index ? clause : current)));\n }\n\n function removeFilter(index: number): void {\n applyFilters(query.filters.filter((_, current) => current !== index));\n }\n\n function replaceColumnFilters(field: string, clauses: FilterClause[]): void {\n applyFilters([...query.filters.filter((clause) => clause.field !== field), ...clauses]);\n }\n\n function setTableFilter(key: string, value: unknown): void {\n const next = { ...query.tableFilters };\n\n if (isEmptyFilterValue(value) || !isFilterValue(value)) {\n delete next[key];\n } else {\n next[key] = value;\n }\n\n const nextQuery = {\n ...query,\n tableFilters: next,\n tableFilterIndicators: query.tableFilterIndicators.filter(\n (indicator) => indicator.filter !== key,\n ),\n page: 1,\n };\n\n setQuery(nextQuery);\n void load(nextQuery);\n }\n\n function resetFilters(): void {\n const nextQuery = {\n ...query,\n filters: [],\n tableFilters: {},\n tableFilterIndicators: [],\n search: \"\",\n page: 1,\n };\n\n setQuery(nextQuery);\n void load(nextQuery);\n }\n\n function setSearch(search: string): void {\n const nextQuery = { ...query, search, page: 1 };\n\n setQuery(nextQuery);\n void load(nextQuery);\n }\n\n const searchFilterOptions = useCallback(\n async (searchKey: string, search: string, signal?: AbortSignal): Promise<Option[]> => {\n if (!endpoint) {\n return [];\n }\n\n const url = new URL(endpoint, window.location.origin);\n url.searchParams.set(\"_search\", searchKey);\n url.searchParams.set(\"_q\", search);\n\n const response = await apiFetch(`${url.pathname}${url.search}`, {\n ref: componentRef,\n signal,\n throwOnError: false,\n });\n\n if (!response.ok) {\n return [];\n }\n\n const result = (await response.json()) as { options?: Option[] };\n\n return result.options ?? [];\n },\n [endpoint, componentRef],\n );\n\n function goToPage(page: number): void {\n void load({\n ...query,\n page,\n });\n }\n\n const loadMore = useCallback((): void => {\n if (processing || !pagination.hasMore) {\n return;\n }\n\n void load(\n {\n ...query,\n page: pagination.nextPage ?? currentPage + 1,\n },\n true,\n );\n }, [currentPage, load, pagination.hasMore, pagination.nextPage, processing, query]);\n\n useEffect(() => {\n setRows(initialRows);\n setPagination(initialPagination);\n setQuery(initialQuery);\n setProcessing(isLazy);\n setHasLoaded(!isLazy);\n }, [initialRows, initialPagination, initialQuery, isLazy]);\n\n useEffect(() => {\n if (!isLazy || hasLoaded) {\n return;\n }\n\n void load(query);\n }, [hasLoaded, isLazy, load, query]);\n\n useWindowEvent(LATTICE_EVENT.reloadComponent, (event) => {\n const detail = (event as ReloadComponentEvent).detail;\n\n if (detail?.component === node.id) {\n void load(query);\n }\n });\n\n useEffect(() => {\n if (\n !isInfinite ||\n !pagination.hasMore ||\n processing ||\n !infiniteLoaderRef.current ||\n typeof IntersectionObserver === \"undefined\"\n ) {\n return;\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) {\n loadMore();\n }\n },\n {\n rootMargin: \"240px\",\n },\n );\n\n observer.observe(infiniteLoaderRef.current);\n\n return () => observer.disconnect();\n }, [isInfinite, loadMore, pagination.hasMore, processing]);\n\n return {\n columns,\n rows,\n pagination,\n query,\n filters: query.filters,\n tableFilters: query.tableFilters,\n search: query.search,\n addFilter,\n updateFilter,\n removeFilter,\n replaceColumnFilters,\n setTableFilter,\n resetFilters,\n setSearch,\n searchFilterOptions,\n processing,\n hasLoaded,\n infiniteLoaderRef,\n sort,\n clearSort,\n goToPage,\n loadMore,\n };\n}\n"],"mappings":"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"}
|
package/dist/table/lib/bulk.d.ts
CHANGED
|
@@ -11,5 +11,7 @@ export type BulkAction = {
|
|
|
11
11
|
variant: ButtonVariant;
|
|
12
12
|
confirmation: Action["confirmation"];
|
|
13
13
|
form: Node | null;
|
|
14
|
+
modalSide: Action["modalSide"];
|
|
15
|
+
modalWidth: Action["modalWidth"];
|
|
14
16
|
};
|
|
15
17
|
export declare function getBulkActions(actions: ActionNode[] | undefined): BulkAction[];
|
package/dist/table/lib/bulk.js
CHANGED
|
@@ -12,7 +12,9 @@ function getBulkActions(actions) {
|
|
|
12
12
|
ref: props.ref ?? "",
|
|
13
13
|
variant: props.variant ?? "default",
|
|
14
14
|
confirmation: props.confirmation,
|
|
15
|
-
form: props.form
|
|
15
|
+
form: props.form,
|
|
16
|
+
modalSide: props.modalSide,
|
|
17
|
+
modalWidth: props.modalWidth
|
|
16
18
|
}];
|
|
17
19
|
});
|
|
18
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bulk.js","names":[],"sources":["../../../resources/js/table/lib/bulk.ts"],"sourcesContent":["import type { Method } from \"@inertiajs/core\";\nimport type { Node } from \"@lattice-php/lattice/core/types\";\nimport type { Action, ButtonVariant } from \"@lattice-php/lattice/types/generated\";\nimport type { ActionNode } from \"@lattice-php/lattice/table/types\";\n\nexport type BulkAction = {\n id: string;\n label: string;\n method: Method;\n endpoint: string;\n ref: string;\n variant: ButtonVariant;\n confirmation: Action[\"confirmation\"];\n form: Node | null;\n};\n\nexport function getBulkActions(actions: ActionNode[] | undefined): BulkAction[] {\n return (actions ?? []).flatMap((node): BulkAction[] => {\n if (node.type === \"action.group\") {\n return [];\n }\n\n const props = node.props;\n\n if (!props.endpoint) {\n return [];\n }\n\n return [\n {\n id: node.id ?? \"\",\n label: props.label ?? \"Run action\",\n method: props.method ?? \"post\",\n endpoint: props.endpoint,\n ref: props.ref ?? \"\",\n variant: props.variant ?? \"default\",\n confirmation: props.confirmation,\n form: props.form,\n },\n ];\n });\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"bulk.js","names":[],"sources":["../../../resources/js/table/lib/bulk.ts"],"sourcesContent":["import type { Method } from \"@inertiajs/core\";\nimport type { Node } from \"@lattice-php/lattice/core/types\";\nimport type { Action, ButtonVariant } from \"@lattice-php/lattice/types/generated\";\nimport type { ActionNode } from \"@lattice-php/lattice/table/types\";\n\nexport type BulkAction = {\n id: string;\n label: string;\n method: Method;\n endpoint: string;\n ref: string;\n variant: ButtonVariant;\n confirmation: Action[\"confirmation\"];\n form: Node | null;\n modalSide: Action[\"modalSide\"];\n modalWidth: Action[\"modalWidth\"];\n};\n\nexport function getBulkActions(actions: ActionNode[] | undefined): BulkAction[] {\n return (actions ?? []).flatMap((node): BulkAction[] => {\n if (node.type === \"action.group\") {\n return [];\n }\n\n const props = node.props;\n\n if (!props.endpoint) {\n return [];\n }\n\n return [\n {\n id: node.id ?? \"\",\n label: props.label ?? \"Run action\",\n method: props.method ?? \"post\",\n endpoint: props.endpoint,\n ref: props.ref ?? \"\",\n variant: props.variant ?? \"default\",\n confirmation: props.confirmation,\n form: props.form,\n modalSide: props.modalSide,\n modalWidth: props.modalWidth,\n },\n ];\n });\n}\n"],"mappings":";AAkBA,SAAgB,eAAe,SAAiD;CAC9E,QAAQ,WAAW,CAAC,GAAG,SAAS,SAAuB;EACrD,IAAI,KAAK,SAAS,gBAChB,OAAO,CAAC;EAGV,MAAM,QAAQ,KAAK;EAEnB,IAAI,CAAC,MAAM,UACT,OAAO,CAAC;EAGV,OAAO,CACL;GACE,IAAI,KAAK,MAAM;GACf,OAAO,MAAM,SAAS;GACtB,QAAQ,MAAM,UAAU;GACxB,UAAU,MAAM;GAChB,KAAK,MAAM,OAAO;GAClB,SAAS,MAAM,WAAW;GAC1B,cAAc,MAAM;GACpB,MAAM,MAAM;GACZ,WAAW,MAAM;GACjB,YAAY,MAAM;EACpB,CACF;CACF,CAAC;AACH"}
|
package/dist/table/lib/query.js
CHANGED
|
@@ -125,7 +125,7 @@ function getTableSizingColumns(columns) {
|
|
|
125
125
|
}));
|
|
126
126
|
}
|
|
127
127
|
function columnWidthOrDefault(column) {
|
|
128
|
-
return column.props.width ??
|
|
128
|
+
return column.props.width ?? "md";
|
|
129
129
|
}
|
|
130
130
|
function getTableUtilityTracks(hasActions, hasSelection, hasExpander = false) {
|
|
131
131
|
return {
|