@alepha/ui 0.16.2 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/{AdminApiKeys-CoTOTfgU.js → AdminApiKeys-CF_qOO3u.js} +20 -20
- package/dist/admin/AdminApiKeys-CF_qOO3u.js.map +1 -0
- package/dist/admin/{AdminAudits-BmsxFbDa.js → AdminAudits-BQno3hZG.js} +7 -8
- package/dist/admin/AdminAudits-BQno3hZG.js.map +1 -0
- package/dist/admin/{AdminFiles-BBB8knca.js → AdminFiles-kvuUaASF.js} +3 -5
- package/dist/admin/{AdminFiles-BBB8knca.js.map → AdminFiles-kvuUaASF.js.map} +1 -1
- package/dist/admin/AdminJobDashboard-CrPxp0W1.js +485 -0
- package/dist/admin/AdminJobDashboard-CrPxp0W1.js.map +1 -0
- package/dist/admin/AdminJobExecutions-D-b4Zt7W.js +678 -0
- package/dist/admin/AdminJobExecutions-D-b4Zt7W.js.map +1 -0
- package/dist/admin/AdminJobRegistry-CNX5cpDx.js +301 -0
- package/dist/admin/AdminJobRegistry-CNX5cpDx.js.map +1 -0
- package/dist/admin/{AdminLayout-CsjvpeD1.js → AdminLayout-e-ZP5nWw.js} +1 -1
- package/dist/admin/{AdminLayout-CsjvpeD1.js.map → AdminLayout-e-ZP5nWw.js.map} +1 -1
- package/dist/admin/{AdminNotifications-LwR6RKrx.js → AdminNotifications-DeHJFf6W.js} +3 -5
- package/dist/admin/{AdminNotifications-LwR6RKrx.js.map → AdminNotifications-DeHJFf6W.js.map} +1 -1
- package/dist/admin/{AdminParameters-B_83Vie9.js → AdminParameters-iQE8o7a7.js} +43 -36
- package/dist/admin/AdminParameters-iQE8o7a7.js.map +1 -0
- package/dist/admin/{AdminSessions-CWnPosdd.js → AdminSessions-oKJCbd7w.js} +5 -7
- package/dist/admin/AdminSessions-oKJCbd7w.js.map +1 -0
- package/dist/admin/{AdminUserAudits-nHv636E_.js → AdminUserAudits-BNCEle_E.js} +6 -8
- package/dist/admin/AdminUserAudits-BNCEle_E.js.map +1 -0
- package/dist/admin/{AdminUserCreate-CjYD3Kjc.js → AdminUserCreate-CgqeFwCt.js} +6 -7
- package/dist/admin/AdminUserCreate-CgqeFwCt.js.map +1 -0
- package/dist/admin/{AdminUserDetails-Ccq-LsZ0.js → AdminUserDetails-DDe1A1GP.js} +30 -29
- package/dist/admin/AdminUserDetails-DDe1A1GP.js.map +1 -0
- package/dist/admin/{AdminUserLayout-7s41DiF_.js → AdminUserLayout-HAlobhWf.js} +18 -16
- package/dist/admin/AdminUserLayout-HAlobhWf.js.map +1 -0
- package/dist/admin/{AdminUserSessions-Ds3ODq_d.js → AdminUserSessions-Bq1LnVLf.js} +5 -7
- package/dist/admin/AdminUserSessions-Bq1LnVLf.js.map +1 -0
- package/dist/admin/{AdminUserSettings-CGh4gROo.js → AdminUserSettings-BRsBZoxV.js} +10 -10
- package/dist/admin/AdminUserSettings-BRsBZoxV.js.map +1 -0
- package/dist/admin/{AdminUsers-CvPiBzQK.js → AdminUsers-D71kIOSn.js} +6 -8
- package/dist/admin/AdminUsers-D71kIOSn.js.map +1 -0
- package/dist/admin/index.d.ts +7 -83
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +49 -70
- package/dist/admin/index.js.map +1 -1
- package/dist/auth/{Login-DS_OqA0G.js → Login-BS_FYTy0.js} +13 -8
- package/dist/auth/Login-BS_FYTy0.js.map +1 -0
- package/dist/auth/{Profile-Di7N7HZL.js → Profile-CjDsW378.js} +16 -10
- package/dist/auth/Profile-CjDsW378.js.map +1 -0
- package/dist/auth/{Register-BRR2_gux.js → Register-C5eqzAaD.js} +21 -12
- package/dist/auth/Register-C5eqzAaD.js.map +1 -0
- package/dist/auth/{ResetPassword-oQu72lod.js → ResetPassword-XifinVao.js} +14 -8
- package/dist/auth/ResetPassword-XifinVao.js.map +1 -0
- package/dist/auth/{VerifyEmail-DC6HPZjd.js → VerifyEmail-DTgbeJOO.js} +6 -4
- package/dist/auth/VerifyEmail-DTgbeJOO.js.map +1 -0
- package/dist/auth/index.d.ts +4 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +15 -14
- package/dist/auth/index.js.map +1 -1
- package/dist/core/index.d.ts +37 -26
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +444 -193
- package/dist/core/index.js.map +1 -1
- package/dist/demo/DemoDataTable-lnBKWBf8.js +362 -0
- package/dist/demo/DemoDataTable-lnBKWBf8.js.map +1 -0
- package/dist/demo/{DemoHome-DpRrPlBC.js → DemoHome-CUMZsYaH.js} +6 -7
- package/dist/demo/DemoHome-CUMZsYaH.js.map +1 -0
- package/dist/demo/{DemoJsonViewer-zeucGKHV.js → DemoJsonViewer-_uokbGaW.js} +17 -19
- package/dist/demo/DemoJsonViewer-_uokbGaW.js.map +1 -0
- package/dist/demo/{DemoLayout-PhgbAAiQ.js → DemoLayout-DHVoacE6.js} +2 -4
- package/dist/demo/{DemoLayout-PhgbAAiQ.js.map → DemoLayout-DHVoacE6.js.map} +1 -1
- package/dist/demo/{DemoLogin-DSzP0Lkv.js → DemoLogin-DjJ9314c.js} +22 -17
- package/dist/demo/DemoLogin-DjJ9314c.js.map +1 -0
- package/dist/demo/{DemoRegister-DavFBsCz.js → DemoRegister-DzkJ5M83.js} +34 -25
- package/dist/demo/DemoRegister-DzkJ5M83.js.map +1 -0
- package/dist/demo/{DemoResetPassword-BS2rIAQK.js → DemoResetPassword-DWh4_BpQ.js} +27 -21
- package/dist/demo/DemoResetPassword-DWh4_BpQ.js.map +1 -0
- package/dist/demo/{DemoSidebar-zNkUmHRl.js → DemoSidebar-C1csnGhX.js} +2 -2
- package/dist/demo/{DemoSidebar-zNkUmHRl.js.map → DemoSidebar-C1csnGhX.js.map} +1 -1
- package/dist/demo/{DemoTypeForm-B9q7oT0b.js → DemoTypeForm-CWz6fJrJ.js} +2 -2
- package/dist/demo/{DemoTypeForm-B9q7oT0b.js.map → DemoTypeForm-CWz6fJrJ.js.map} +1 -1
- package/dist/demo/{DemoVerifyEmail-Bi4SdWz0.js → DemoVerifyEmail-DbU_tCj8.js} +13 -11
- package/dist/demo/DemoVerifyEmail-DbU_tCj8.js.map +1 -0
- package/dist/demo/{IconGoogle-CTeZyrek.js → IconGoogle-Ch1m3Uzl.js} +1 -1
- package/dist/demo/{IconGoogle-CTeZyrek.js.map → IconGoogle-Ch1m3Uzl.js.map} +1 -1
- package/dist/demo/{Showcase-C9btr_SJ.js → Showcase-BzoXNlCn.js} +10 -10
- package/dist/demo/Showcase-BzoXNlCn.js.map +1 -0
- package/dist/demo/index.d.ts +1 -68
- package/dist/demo/index.d.ts.map +1 -1
- package/dist/demo/index.js +11 -15
- package/dist/demo/index.js.map +1 -1
- package/dist/json/index.js +2 -2
- package/dist/json/index.js.map +1 -1
- package/package.json +9 -5
- package/src/admin/AdminRouter.ts +36 -5
- package/src/admin/components/audits/AdminAudits.tsx +5 -5
- package/src/admin/components/jobs/AdminJobDashboard.tsx +455 -0
- package/src/admin/components/jobs/AdminJobExecutions.tsx +693 -0
- package/src/admin/components/jobs/AdminJobRegistry.tsx +325 -0
- package/src/admin/components/keys/AdminApiKeys.tsx +28 -31
- package/src/admin/components/parameters/AdminParameters.tsx +3 -3
- package/src/admin/components/parameters/ParameterDetails.tsx +34 -29
- package/src/admin/components/parameters/ParameterEmptyState.tsx +5 -5
- package/src/admin/components/parameters/ParameterHistory.tsx +11 -19
- package/src/admin/components/parameters/ParameterTree.tsx +16 -18
- package/src/admin/components/sessions/AdminSessions.tsx +3 -3
- package/src/admin/components/shared/AdminResourceHeader.tsx +20 -16
- package/src/admin/components/users/AdminUserAudits.tsx +5 -5
- package/src/admin/components/users/AdminUserCreate.tsx +3 -3
- package/src/admin/components/users/AdminUserDetails.tsx +51 -53
- package/src/admin/components/users/AdminUserLayout.tsx +7 -7
- package/src/admin/components/users/AdminUserSessions.tsx +3 -3
- package/src/admin/components/users/AdminUserSettings.tsx +9 -9
- package/src/admin/components/users/AdminUsers.tsx +5 -5
- package/src/admin/components/verifications/AdminVerifications.tsx +3 -3
- package/src/admin/index.ts +0 -24
- package/src/auth/components/Login.tsx +13 -13
- package/src/auth/components/Profile.tsx +17 -26
- package/src/auth/components/Register.tsx +21 -31
- package/src/auth/components/ResetPassword.tsx +13 -22
- package/src/auth/components/VerifyEmail.tsx +5 -5
- package/src/auth/components/buttons/UserButton.tsx +14 -4
- package/src/core/components/buttons/ActionButton.tsx +9 -2
- package/src/core/components/data/ErrorViewer.tsx +15 -15
- package/src/core/components/dialogs/AlertDialog.tsx +3 -3
- package/src/core/components/dialogs/ConfirmDialog.tsx +3 -3
- package/src/core/components/dialogs/PromptDialog.tsx +3 -3
- package/src/core/components/form/Control.tsx +9 -0
- package/src/core/components/form/ControlArray.tsx +6 -7
- package/src/core/components/form/ControlObject.tsx +3 -3
- package/src/core/components/form/ControlQueryBuilder.tsx +20 -22
- package/src/core/components/form/ControlSelect.tsx +4 -0
- package/src/core/components/form/TypeForm.tsx +7 -0
- package/src/core/components/layout/Breadcrumb.tsx +6 -6
- package/src/core/components/layout/Omnibar.tsx +2 -1
- package/src/core/components/layout/Sidebar.tsx +5 -1
- package/src/core/components/table/ColumnPicker.tsx +47 -31
- package/src/core/components/table/DataTable.tsx +277 -201
- package/src/core/components/table/DataTableFilters.tsx +8 -0
- package/src/core/components/table/DataTableToolbar.tsx +98 -5
- package/src/core/components/table/FilterPicker.tsx +28 -26
- package/src/core/components/table/types.ts +52 -37
- package/src/core/components/table/useTableSelection.ts +83 -0
- package/src/core/styles.css +1 -0
- package/src/core/utils/parseInput.ts +1 -0
- package/src/demo/components/DemoHome.tsx +5 -5
- package/src/demo/components/core/DemoDataTable.tsx +209 -5
- package/src/demo/components/json/DemoJsonViewer.tsx +1 -1
- package/src/demo/components/shared/MacWindow.tsx +7 -7
- package/src/demo/components/shared/Showcase.tsx +3 -3
- package/src/demo/index.ts +0 -11
- package/src/json/components/JsonViewer.tsx +3 -3
- package/dist/admin/AdminApiKeys-CoTOTfgU.js.map +0 -1
- package/dist/admin/AdminAudits-BmsxFbDa.js.map +0 -1
- package/dist/admin/AdminJobs-C604joTz.js +0 -698
- package/dist/admin/AdminJobs-C604joTz.js.map +0 -1
- package/dist/admin/AdminParameters-B_83Vie9.js.map +0 -1
- package/dist/admin/AdminSessions-CWnPosdd.js.map +0 -1
- package/dist/admin/AdminUserAudits-nHv636E_.js.map +0 -1
- package/dist/admin/AdminUserCreate-CjYD3Kjc.js.map +0 -1
- package/dist/admin/AdminUserDetails-Ccq-LsZ0.js.map +0 -1
- package/dist/admin/AdminUserLayout-7s41DiF_.js.map +0 -1
- package/dist/admin/AdminUserSessions-Ds3ODq_d.js.map +0 -1
- package/dist/admin/AdminUserSettings-CGh4gROo.js.map +0 -1
- package/dist/admin/AdminUsers-CvPiBzQK.js.map +0 -1
- package/dist/admin/rolldown-runtime-CjeV3_4I.js +0 -18
- package/dist/auth/Login-DS_OqA0G.js.map +0 -1
- package/dist/auth/Profile-Di7N7HZL.js.map +0 -1
- package/dist/auth/Register-BRR2_gux.js.map +0 -1
- package/dist/auth/ResetPassword-oQu72lod.js.map +0 -1
- package/dist/auth/VerifyEmail-DC6HPZjd.js.map +0 -1
- package/dist/demo/DemoDataTable-DCsJq8v5.js +0 -149
- package/dist/demo/DemoDataTable-DCsJq8v5.js.map +0 -1
- package/dist/demo/DemoHome-DpRrPlBC.js.map +0 -1
- package/dist/demo/DemoJsonViewer-zeucGKHV.js.map +0 -1
- package/dist/demo/DemoLogin-DSzP0Lkv.js.map +0 -1
- package/dist/demo/DemoRegister-DavFBsCz.js.map +0 -1
- package/dist/demo/DemoResetPassword-BS2rIAQK.js.map +0 -1
- package/dist/demo/DemoVerifyEmail-Bi4SdWz0.js.map +0 -1
- package/dist/demo/Showcase-C9btr_SJ.js.map +0 -1
- package/dist/demo/rolldown-runtime-CjeV3_4I.js +0 -18
- package/src/admin/components/jobs/AdminJobs.tsx +0 -772
package/dist/core/index.js
CHANGED
|
@@ -3,9 +3,9 @@ import { AlephaReactForm, FormValidationError, useForm, useFormState } from "ale
|
|
|
3
3
|
import { $head, AlephaReactHead } from "alepha/react/head";
|
|
4
4
|
import { AlephaReactI18n, useI18n } from "alepha/react/i18n";
|
|
5
5
|
import { $cookie } from "alepha/server/cookies";
|
|
6
|
-
import { ActionIcon, Anchor, AppShell, Autocomplete, Badge,
|
|
6
|
+
import { ActionIcon, Anchor, AppShell, Autocomplete, Badge, Burger, Button, Card, Checkbox, Collapse, ColorInput, ColorSchemeScript, Container, CopyButton, Divider, Drawer, Fieldset, FileInput, Flex, Flex as Flex$1, Grid, Image, Input, Kbd, MantineProvider, Menu, MultiSelect, NumberInput, Pagination, PasswordInput, Popover, ScrollArea, SegmentedControl, Select, Slider, Switch, Table, TagsInput, Text, Text as Text$1, TextInput, Textarea, ThemeIcon, Tooltip, UnstyledButton, useMantineColorScheme, useMantineTheme } from "@mantine/core";
|
|
7
7
|
import { ModalsProvider, modals } from "@mantine/modals";
|
|
8
|
-
import { IconAlertTriangle, IconArrowDown, IconArrowLeft, IconArrowUp, IconArrowsSort, IconAt, IconCalendar, IconCheck, IconChevronDown, IconChevronRight, IconClock, IconColorPicker, IconColumns, IconCopy, IconFile, IconFilter, IconGripVertical, IconHash, IconInfoCircle, IconInfoTriangle, IconKey, IconLanguage, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightCollapse, IconLetterCase, IconLink, IconList, IconMail, IconMoon, IconPalette, IconPhone, IconPlus, IconRefresh, IconSearch, IconSelector, IconSquareRounded, IconSun, IconToggleLeft, IconTrash, IconX } from "@tabler/icons-react";
|
|
8
|
+
import { IconAlertTriangle, IconArrowDown, IconArrowLeft, IconArrowUp, IconArrowsSort, IconAt, IconCalendar, IconCheck, IconChevronDown, IconChevronRight, IconClipboard, IconClock, IconColorPicker, IconColumns, IconCopy, IconDownload, IconFile, IconFilter, IconGripVertical, IconHash, IconInfoCircle, IconInfoTriangle, IconKey, IconLanguage, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightCollapse, IconLetterCase, IconLink, IconList, IconMail, IconMoon, IconPalette, IconPhone, IconPlus, IconRefresh, IconSearch, IconSelector, IconSquareRounded, IconSun, IconToggleLeft, IconTrash, IconX } from "@tabler/icons-react";
|
|
9
9
|
import { Children, Fragment, createElement, isValidElement, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
10
10
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
11
11
|
import { Notifications, notifications } from "@mantine/notifications";
|
|
@@ -13,8 +13,9 @@ import { $page, Link, NestedView, useActive, useRouter, useRouterState } from "a
|
|
|
13
13
|
import { NavigationProgress, nprogress } from "@mantine/nprogress";
|
|
14
14
|
import { ClientOnly, useAction, useAlepha, useEvents, useInject, useStore } from "alepha/react";
|
|
15
15
|
import { Spotlight, spotlight } from "@mantine/spotlight";
|
|
16
|
+
import { currentUserAtom } from "alepha/security";
|
|
16
17
|
import { ui as ui$1 } from "@alepha/ui";
|
|
17
|
-
import {
|
|
18
|
+
import { useOs } from "@mantine/hooks";
|
|
18
19
|
import { DateInput, DateTimePicker, TimeInput } from "@mantine/dates";
|
|
19
20
|
import { parseQueryString } from "alepha/orm";
|
|
20
21
|
import { DateTimeProvider } from "alepha/datetime";
|
|
@@ -267,10 +268,10 @@ const ErrorViewer = ({ error, showStack = true, copyable = true, size = "sm" })
|
|
|
267
268
|
if (isError) return `${errorName}: ${errorMessage}${errorStack ? `\n\n${errorStack}` : ""}`;
|
|
268
269
|
return String(error);
|
|
269
270
|
};
|
|
270
|
-
return /* @__PURE__ */ jsxs(
|
|
271
|
+
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
271
272
|
pos: "relative",
|
|
272
273
|
w: "100%",
|
|
273
|
-
children: [copyable && /* @__PURE__ */ jsx(
|
|
274
|
+
children: [copyable && /* @__PURE__ */ jsx(Flex$1, {
|
|
274
275
|
pos: "absolute",
|
|
275
276
|
top: 0,
|
|
276
277
|
right: 0,
|
|
@@ -288,9 +289,9 @@ const ErrorViewer = ({ error, showStack = true, copyable = true, size = "sm" })
|
|
|
288
289
|
})
|
|
289
290
|
})
|
|
290
291
|
})
|
|
291
|
-
}), /* @__PURE__ */ jsxs(
|
|
292
|
+
}), /* @__PURE__ */ jsxs(Flex$1, {
|
|
292
293
|
pt: copyable ? 30 : 0,
|
|
293
|
-
children: [/* @__PURE__ */ jsxs(
|
|
294
|
+
children: [/* @__PURE__ */ jsxs(Flex$1, {
|
|
294
295
|
style: {
|
|
295
296
|
display: "flex",
|
|
296
297
|
alignItems: "flex-start",
|
|
@@ -310,9 +311,9 @@ const ErrorViewer = ({ error, showStack = true, copyable = true, size = "sm" })
|
|
|
310
311
|
style: { wordBreak: "break-word" },
|
|
311
312
|
children: errorMessage
|
|
312
313
|
})]
|
|
313
|
-
}), showStack && stackLines.length > 1 && /* @__PURE__ */ jsxs(
|
|
314
|
+
}), showStack && stackLines.length > 1 && /* @__PURE__ */ jsxs(Flex$1, {
|
|
314
315
|
mt: "sm",
|
|
315
|
-
children: [/* @__PURE__ */ jsxs(
|
|
316
|
+
children: [/* @__PURE__ */ jsxs(Flex$1, {
|
|
316
317
|
style: {
|
|
317
318
|
display: "flex",
|
|
318
319
|
alignItems: "center",
|
|
@@ -337,7 +338,7 @@ const ErrorViewer = ({ error, showStack = true, copyable = true, size = "sm" })
|
|
|
337
338
|
})]
|
|
338
339
|
}), /* @__PURE__ */ jsx(Collapse, {
|
|
339
340
|
in: stackExpanded,
|
|
340
|
-
children: /* @__PURE__ */ jsx(
|
|
341
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
341
342
|
mt: "xs",
|
|
342
343
|
pl: "md",
|
|
343
344
|
style: { borderLeft: "1px solid var(--mantine-color-default-border)" },
|
|
@@ -363,7 +364,7 @@ const ErrorViewer = ({ error, showStack = true, copyable = true, size = "sm" })
|
|
|
363
364
|
const AlertDialog = ({ options, onClose }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [options?.message && /* @__PURE__ */ jsx(Text$1, {
|
|
364
365
|
mb: "md",
|
|
365
366
|
children: options.message
|
|
366
|
-
}), /* @__PURE__ */ jsx(
|
|
367
|
+
}), /* @__PURE__ */ jsx(Flex$1, {
|
|
367
368
|
justify: "flex-end",
|
|
368
369
|
children: /* @__PURE__ */ jsx(Button, {
|
|
369
370
|
onClick: onClose,
|
|
@@ -376,7 +377,7 @@ const AlertDialog = ({ options, onClose }) => /* @__PURE__ */ jsxs(Fragment$1, {
|
|
|
376
377
|
const ConfirmDialog = ({ options, onConfirm }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [options?.message && /* @__PURE__ */ jsx(Text$1, {
|
|
377
378
|
mb: "md",
|
|
378
379
|
children: options.message
|
|
379
|
-
}), /* @__PURE__ */ jsxs(
|
|
380
|
+
}), /* @__PURE__ */ jsxs(Flex$1, {
|
|
380
381
|
justify: "flex-end",
|
|
381
382
|
children: [/* @__PURE__ */ jsx(Button, {
|
|
382
383
|
variant: "subtle",
|
|
@@ -418,7 +419,7 @@ const PromptDialog = ({ options, onSubmit }) => {
|
|
|
418
419
|
required: options?.required,
|
|
419
420
|
mb: "md"
|
|
420
421
|
}),
|
|
421
|
-
/* @__PURE__ */ jsxs(
|
|
422
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
422
423
|
justify: "flex-end",
|
|
423
424
|
children: [/* @__PURE__ */ jsx(Button, {
|
|
424
425
|
variant: "subtle",
|
|
@@ -700,7 +701,7 @@ const Omnibar = (props) => {
|
|
|
700
701
|
const searchPlaceholder = props.searchPlaceholder ?? "Search...";
|
|
701
702
|
const nothingFound = props.nothingFound ?? "Nothing found...";
|
|
702
703
|
const router = useRouter();
|
|
703
|
-
const [user] = useStore(
|
|
704
|
+
const [user] = useStore(currentUserAtom);
|
|
704
705
|
return /* @__PURE__ */ jsx(Spotlight, {
|
|
705
706
|
actions: useMemo(() => router.concretePages.filter((page) => {
|
|
706
707
|
if (page.can && !page.can()) return false;
|
|
@@ -1008,10 +1009,11 @@ const ActionHookButton = (props) => {
|
|
|
1008
1009
|
* </ActionButton>
|
|
1009
1010
|
* ```
|
|
1010
1011
|
*/
|
|
1011
|
-
const ActionClickButton = (props) => {
|
|
1012
|
+
const ActionClickButton = ({ preventDefault, ...props }) => {
|
|
1012
1013
|
const action = useAction({ handler: async (e) => {
|
|
1014
|
+
if (preventDefault) e.preventDefault();
|
|
1013
1015
|
await props.onClick(e);
|
|
1014
|
-
} }, [props.onClick]);
|
|
1016
|
+
} }, [props.onClick, preventDefault]);
|
|
1015
1017
|
return /* @__PURE__ */ jsx(Button, {
|
|
1016
1018
|
...props,
|
|
1017
1019
|
disabled: action.loading || props.disabled,
|
|
@@ -1537,7 +1539,8 @@ const ControlArray = (props) => {
|
|
|
1537
1539
|
const colSpan = 12 / columns;
|
|
1538
1540
|
const objectItemSchema = isObjectItem ? itemSchema : null;
|
|
1539
1541
|
const fieldNames = objectItemSchema ? Object.keys(objectItemSchema.properties) : [];
|
|
1540
|
-
const renderItems = () => /* @__PURE__ */ jsxs(
|
|
1542
|
+
const renderItems = () => /* @__PURE__ */ jsxs(Flex$1, {
|
|
1543
|
+
direction: "column",
|
|
1541
1544
|
gap: "sm",
|
|
1542
1545
|
children: [items.map((item, index) => /* @__PURE__ */ jsxs(Flex$1, {
|
|
1543
1546
|
gap: "sm",
|
|
@@ -1613,7 +1616,8 @@ const ControlArray = (props) => {
|
|
|
1613
1616
|
children: [/* @__PURE__ */ jsx(IconPlus, { size: 14 }), props.addLabel ?? "Add"]
|
|
1614
1617
|
})]
|
|
1615
1618
|
});
|
|
1616
|
-
if (props.variant === "plain") return /* @__PURE__ */ jsxs(
|
|
1619
|
+
if (props.variant === "plain") return /* @__PURE__ */ jsxs(Flex$1, {
|
|
1620
|
+
direction: "column",
|
|
1617
1621
|
gap: "xs",
|
|
1618
1622
|
children: [
|
|
1619
1623
|
inputProps.label && /* @__PURE__ */ jsx(Text$1, {
|
|
@@ -1636,7 +1640,8 @@ const ControlArray = (props) => {
|
|
|
1636
1640
|
});
|
|
1637
1641
|
return /* @__PURE__ */ jsx(Fieldset, {
|
|
1638
1642
|
legend: inputProps.label,
|
|
1639
|
-
children: /* @__PURE__ */ jsxs(
|
|
1643
|
+
children: /* @__PURE__ */ jsxs(Flex$1, {
|
|
1644
|
+
direction: "column",
|
|
1640
1645
|
gap: "xs",
|
|
1641
1646
|
children: [
|
|
1642
1647
|
inputProps.description && /* @__PURE__ */ jsx(Text$1, {
|
|
@@ -1827,7 +1832,8 @@ const ControlObject = (props) => {
|
|
|
1827
1832
|
if (props.variant === "plain") return renderFields();
|
|
1828
1833
|
return /* @__PURE__ */ jsx(Fieldset, {
|
|
1829
1834
|
legend: inputProps.label,
|
|
1830
|
-
children: /* @__PURE__ */ jsxs(
|
|
1835
|
+
children: /* @__PURE__ */ jsxs(Flex$1, {
|
|
1836
|
+
direction: "column",
|
|
1831
1837
|
gap: "xs",
|
|
1832
1838
|
children: [
|
|
1833
1839
|
inputProps.description && /* @__PURE__ */ jsx(Text$1, {
|
|
@@ -2051,7 +2057,7 @@ const ControlQueryBuilder = ({ schema, value = "", onChange, placeholder = "Ente
|
|
|
2051
2057
|
});
|
|
2052
2058
|
};
|
|
2053
2059
|
function QueryHelp({ fields, onInsert }) {
|
|
2054
|
-
return /* @__PURE__ */ jsxs(
|
|
2060
|
+
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
2055
2061
|
gap: "md",
|
|
2056
2062
|
align: "flex-start",
|
|
2057
2063
|
wrap: "nowrap",
|
|
@@ -2059,19 +2065,22 @@ function QueryHelp({ fields, onInsert }) {
|
|
|
2059
2065
|
p: "sm",
|
|
2060
2066
|
bdrs: "sm",
|
|
2061
2067
|
children: [
|
|
2062
|
-
/* @__PURE__ */ jsxs(
|
|
2068
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
2069
|
+
direction: "column",
|
|
2063
2070
|
gap: "md",
|
|
2064
2071
|
style: { flex: 1 },
|
|
2065
2072
|
children: [
|
|
2066
|
-
/* @__PURE__ */ jsxs(
|
|
2073
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
2074
|
+
direction: "column",
|
|
2067
2075
|
gap: "xs",
|
|
2068
2076
|
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
2069
2077
|
size: "sm",
|
|
2070
2078
|
fw: 600,
|
|
2071
2079
|
children: "Operators"
|
|
2072
|
-
}), /* @__PURE__ */ jsx(
|
|
2080
|
+
}), /* @__PURE__ */ jsx(Flex$1, {
|
|
2081
|
+
direction: "column",
|
|
2073
2082
|
gap: 4,
|
|
2074
|
-
children: Object.entries(OPERATOR_INFO).map(([key, info]) => /* @__PURE__ */ jsxs(
|
|
2083
|
+
children: Object.entries(OPERATOR_INFO).map(([key, info]) => /* @__PURE__ */ jsxs(Flex$1, {
|
|
2075
2084
|
gap: "xs",
|
|
2076
2085
|
wrap: "nowrap",
|
|
2077
2086
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
@@ -2093,15 +2102,17 @@ function QueryHelp({ fields, onInsert }) {
|
|
|
2093
2102
|
})]
|
|
2094
2103
|
}),
|
|
2095
2104
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
2096
|
-
/* @__PURE__ */ jsxs(
|
|
2105
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
2106
|
+
direction: "column",
|
|
2097
2107
|
gap: "xs",
|
|
2098
2108
|
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
2099
2109
|
size: "sm",
|
|
2100
2110
|
fw: 600,
|
|
2101
2111
|
children: "Logic"
|
|
2102
|
-
}), /* @__PURE__ */ jsxs(
|
|
2112
|
+
}), /* @__PURE__ */ jsxs(Flex$1, {
|
|
2113
|
+
direction: "column",
|
|
2103
2114
|
gap: 4,
|
|
2104
|
-
children: [/* @__PURE__ */ jsxs(
|
|
2115
|
+
children: [/* @__PURE__ */ jsxs(Flex$1, {
|
|
2105
2116
|
gap: "xs",
|
|
2106
2117
|
wrap: "nowrap",
|
|
2107
2118
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
@@ -2118,7 +2129,7 @@ function QueryHelp({ fields, onInsert }) {
|
|
|
2118
2129
|
c: "dimmed",
|
|
2119
2130
|
children: "AND"
|
|
2120
2131
|
})]
|
|
2121
|
-
}), /* @__PURE__ */ jsxs(
|
|
2132
|
+
}), /* @__PURE__ */ jsxs(Flex$1, {
|
|
2122
2133
|
gap: "xs",
|
|
2123
2134
|
wrap: "nowrap",
|
|
2124
2135
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
@@ -2184,7 +2195,7 @@ function QueryHelp({ fields, onInsert }) {
|
|
|
2184
2195
|
c: "dimmed",
|
|
2185
2196
|
lineClamp: 1,
|
|
2186
2197
|
children: field.description || field.type
|
|
2187
|
-
}), field.enum && /* @__PURE__ */ jsx(
|
|
2198
|
+
}), field.enum && /* @__PURE__ */ jsx(Flex$1, {
|
|
2188
2199
|
gap: 0,
|
|
2189
2200
|
wrap: "wrap",
|
|
2190
2201
|
children: field.enum.map((enumValue) => /* @__PURE__ */ jsx(ActionButton, {
|
|
@@ -2260,6 +2271,7 @@ const ControlSelect = (props) => {
|
|
|
2260
2271
|
const autocompleteProps = typeof props.autocomplete === "object" ? props.autocomplete : {};
|
|
2261
2272
|
return /* @__PURE__ */ jsx(Autocomplete, {
|
|
2262
2273
|
...inputProps,
|
|
2274
|
+
size: props.size,
|
|
2263
2275
|
id,
|
|
2264
2276
|
leftSection: icon,
|
|
2265
2277
|
data,
|
|
@@ -2271,6 +2283,7 @@ const ControlSelect = (props) => {
|
|
|
2271
2283
|
const tagsInputProps = typeof props.tags === "object" ? props.tags : {};
|
|
2272
2284
|
return /* @__PURE__ */ jsx(TagsInput, {
|
|
2273
2285
|
...inputProps,
|
|
2286
|
+
size: props.size,
|
|
2274
2287
|
id,
|
|
2275
2288
|
leftSection: icon,
|
|
2276
2289
|
defaultValue: Array.isArray(props.input.props.defaultValue) ? props.input.props.defaultValue : [],
|
|
@@ -2288,6 +2301,7 @@ const ControlSelect = (props) => {
|
|
|
2288
2301
|
const multiSelectProps = typeof props.multi === "object" ? props.multi : {};
|
|
2289
2302
|
return /* @__PURE__ */ jsx(MultiSelect, {
|
|
2290
2303
|
...inputProps,
|
|
2304
|
+
size: props.size,
|
|
2291
2305
|
id,
|
|
2292
2306
|
leftSection: icon,
|
|
2293
2307
|
data,
|
|
@@ -2301,6 +2315,7 @@ const ControlSelect = (props) => {
|
|
|
2301
2315
|
const selectProps = typeof props.select === "object" ? props.select : {};
|
|
2302
2316
|
return /* @__PURE__ */ jsx(Select, {
|
|
2303
2317
|
...inputProps,
|
|
2318
|
+
size: props.size,
|
|
2304
2319
|
id,
|
|
2305
2320
|
leftSection: icon,
|
|
2306
2321
|
data,
|
|
@@ -2393,6 +2408,7 @@ const Control = (_props) => {
|
|
|
2393
2408
|
const controlNumberProps = typeof props.number === "object" ? props.number : {};
|
|
2394
2409
|
if (props.slider) controlNumberProps.sliderProps ??= {};
|
|
2395
2410
|
return /* @__PURE__ */ jsx(ControlNumber, {
|
|
2411
|
+
size: props.size,
|
|
2396
2412
|
input: props.input,
|
|
2397
2413
|
title: props.title,
|
|
2398
2414
|
description: props.description,
|
|
@@ -2404,6 +2420,7 @@ const Control = (_props) => {
|
|
|
2404
2420
|
const fileInputProps = typeof props.file === "object" ? props.file : {};
|
|
2405
2421
|
return /* @__PURE__ */ jsx(FileInput, {
|
|
2406
2422
|
...inputProps,
|
|
2423
|
+
size: props.size,
|
|
2407
2424
|
id,
|
|
2408
2425
|
leftSection: icon,
|
|
2409
2426
|
onChange: (file) => {
|
|
@@ -2416,6 +2433,7 @@ const Control = (_props) => {
|
|
|
2416
2433
|
const colorInputProps = typeof props.color === "object" ? props.color : {};
|
|
2417
2434
|
return /* @__PURE__ */ jsx(ColorInput, {
|
|
2418
2435
|
...inputProps,
|
|
2436
|
+
size: props.size,
|
|
2419
2437
|
id,
|
|
2420
2438
|
leftSection: icon,
|
|
2421
2439
|
...props.input.props,
|
|
@@ -2426,6 +2444,7 @@ const Control = (_props) => {
|
|
|
2426
2444
|
const opts = typeof props.select === "object" ? props.select : {};
|
|
2427
2445
|
if (props.segmented) opts.segmented ??= {};
|
|
2428
2446
|
return /* @__PURE__ */ jsx(ControlSelect, {
|
|
2447
|
+
size: props.size,
|
|
2429
2448
|
input: props.input,
|
|
2430
2449
|
title: props.title,
|
|
2431
2450
|
description: props.description,
|
|
@@ -2437,6 +2456,7 @@ const Control = (_props) => {
|
|
|
2437
2456
|
const switchProps = typeof props.switch === "object" ? props.switch : {};
|
|
2438
2457
|
return /* @__PURE__ */ jsx(Switch, {
|
|
2439
2458
|
...inputProps,
|
|
2459
|
+
size: props.size,
|
|
2440
2460
|
id,
|
|
2441
2461
|
color: "blue",
|
|
2442
2462
|
defaultChecked: props.input.props.defaultValue,
|
|
@@ -2450,6 +2470,7 @@ const Control = (_props) => {
|
|
|
2450
2470
|
const passwordInputProps = typeof props.password === "object" ? props.password : {};
|
|
2451
2471
|
return /* @__PURE__ */ jsx(PasswordInput, {
|
|
2452
2472
|
...inputProps,
|
|
2473
|
+
size: props.size,
|
|
2453
2474
|
id,
|
|
2454
2475
|
leftSection: icon,
|
|
2455
2476
|
...props.input.props,
|
|
@@ -2460,6 +2481,7 @@ const Control = (_props) => {
|
|
|
2460
2481
|
const textAreaProps = typeof props.area === "object" ? props.area : {};
|
|
2461
2482
|
return /* @__PURE__ */ jsx(Textarea, {
|
|
2462
2483
|
...inputProps,
|
|
2484
|
+
size: props.size,
|
|
2463
2485
|
id,
|
|
2464
2486
|
leftSection: icon,
|
|
2465
2487
|
...props.input.props,
|
|
@@ -2467,6 +2489,7 @@ const Control = (_props) => {
|
|
|
2467
2489
|
});
|
|
2468
2490
|
}
|
|
2469
2491
|
if (props.date || props.datetime || props.time || format === "date" || format === "date-time" || format === "time") return /* @__PURE__ */ jsx(ControlDate, {
|
|
2492
|
+
size: props.size,
|
|
2470
2493
|
input: props.input,
|
|
2471
2494
|
title: props.title,
|
|
2472
2495
|
description: props.description,
|
|
@@ -2488,6 +2511,7 @@ const Control = (_props) => {
|
|
|
2488
2511
|
};
|
|
2489
2512
|
return /* @__PURE__ */ jsx(TextInput, {
|
|
2490
2513
|
...inputProps,
|
|
2514
|
+
size: props.size,
|
|
2491
2515
|
id,
|
|
2492
2516
|
leftSection: icon,
|
|
2493
2517
|
type: getInputType(),
|
|
@@ -2546,7 +2570,7 @@ const Control = (_props) => {
|
|
|
2546
2570
|
* ```
|
|
2547
2571
|
*/
|
|
2548
2572
|
const TypeForm = (props) => {
|
|
2549
|
-
const { form, columns = 3, children, controlProps, fieldControlProps, skipFormElement = false, skipSubmitButton = false, submitButtonProps, fill = true } = props;
|
|
2573
|
+
const { form, columns = 3, children, controlProps, fieldControlProps, skipFormElement = false, skipSubmitButton = false, submitButtonProps, fill = true, size } = props;
|
|
2550
2574
|
const schema = props.schema || form.options.schema;
|
|
2551
2575
|
if (!schema?.properties) return null;
|
|
2552
2576
|
const supportedFields = Object.keys(schema.properties);
|
|
@@ -2575,6 +2599,7 @@ const TypeForm = (props) => {
|
|
|
2575
2599
|
...controlProps,
|
|
2576
2600
|
...fieldControlProps?.[fieldName]
|
|
2577
2601
|
};
|
|
2602
|
+
if (size) mergedControlProps.size = size;
|
|
2578
2603
|
return /* @__PURE__ */ jsx(Grid.Col, {
|
|
2579
2604
|
span,
|
|
2580
2605
|
children: /* @__PURE__ */ jsx(Control, {
|
|
@@ -2777,10 +2802,10 @@ const Breadcrumb = ({ home = "Home", separator, size = "xs", ...groupProps }) =>
|
|
|
2777
2802
|
size: 12,
|
|
2778
2803
|
color: "#9ca3af"
|
|
2779
2804
|
});
|
|
2780
|
-
return /* @__PURE__ */ jsx(
|
|
2805
|
+
return /* @__PURE__ */ jsx(Flex$1, {
|
|
2781
2806
|
gap: 4,
|
|
2782
2807
|
...groupProps,
|
|
2783
|
-
children: crumbs.map((crumb, i) => /* @__PURE__ */ jsxs(
|
|
2808
|
+
children: crumbs.map((crumb, i) => /* @__PURE__ */ jsxs(Flex$1, {
|
|
2784
2809
|
gap: 4,
|
|
2785
2810
|
children: [i > 0 && sep, i < crumbs.length - 1 ? /* @__PURE__ */ jsx(Anchor, {
|
|
2786
2811
|
component: Link,
|
|
@@ -2945,7 +2970,10 @@ const SidebarItem = (props) => {
|
|
|
2945
2970
|
href: props.item.href,
|
|
2946
2971
|
target: props.item.target,
|
|
2947
2972
|
size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
|
|
2948
|
-
tooltip: item.description
|
|
2973
|
+
tooltip: item.description ? {
|
|
2974
|
+
label: item.description,
|
|
2975
|
+
position: "right"
|
|
2976
|
+
} : void 0,
|
|
2949
2977
|
color: "gray",
|
|
2950
2978
|
variant: "subtle",
|
|
2951
2979
|
variantActive: "default",
|
|
@@ -3276,11 +3304,19 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
|
|
|
3276
3304
|
bg: ui.colors.surface,
|
|
3277
3305
|
style: { borderBottom: "1px solid var(--alepha-border)" },
|
|
3278
3306
|
children: /* @__PURE__ */ jsx(TypeForm, {
|
|
3307
|
+
size: "xs",
|
|
3279
3308
|
...typeFormProps,
|
|
3280
3309
|
skipSubmitButton: true,
|
|
3281
3310
|
fill: true,
|
|
3282
3311
|
form,
|
|
3283
|
-
schema: visibleSchema
|
|
3312
|
+
schema: visibleSchema,
|
|
3313
|
+
columns: {
|
|
3314
|
+
base: 1,
|
|
3315
|
+
sm: 2,
|
|
3316
|
+
md: 3,
|
|
3317
|
+
lg: 4,
|
|
3318
|
+
xl: 6
|
|
3319
|
+
}
|
|
3284
3320
|
})
|
|
3285
3321
|
});
|
|
3286
3322
|
};
|
|
@@ -3332,6 +3368,10 @@ const DataTablePagination = ({ page, size, totalPages, onPageChange, onSizeChang
|
|
|
3332
3368
|
});
|
|
3333
3369
|
};
|
|
3334
3370
|
|
|
3371
|
+
//#endregion
|
|
3372
|
+
//#region ../../src/core/components/table/types.ts
|
|
3373
|
+
const DEFAULT_MAX_VISIBLE_COLUMNS = 8;
|
|
3374
|
+
|
|
3335
3375
|
//#endregion
|
|
3336
3376
|
//#region ../../src/core/components/table/ColumnPicker.tsx
|
|
3337
3377
|
const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
@@ -3343,11 +3383,16 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
3343
3383
|
[key]: true
|
|
3344
3384
|
}), {}));
|
|
3345
3385
|
};
|
|
3346
|
-
const
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
[key]
|
|
3350
|
-
|
|
3386
|
+
const handleDefault = () => {
|
|
3387
|
+
let count = 0;
|
|
3388
|
+
onVisibilityChange(columnEntries.reduce((acc, [key, col]) => {
|
|
3389
|
+
if (col.defaultHidden) acc[key] = false;
|
|
3390
|
+
else if (count < DEFAULT_MAX_VISIBLE_COLUMNS) {
|
|
3391
|
+
acc[key] = true;
|
|
3392
|
+
count++;
|
|
3393
|
+
} else acc[key] = false;
|
|
3394
|
+
return acc;
|
|
3395
|
+
}, {}));
|
|
3351
3396
|
};
|
|
3352
3397
|
const handleToggle = (key, checked) => {
|
|
3353
3398
|
onVisibilityChange({
|
|
@@ -3369,20 +3414,22 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
3369
3414
|
duration: 200,
|
|
3370
3415
|
timingFunction: "ease"
|
|
3371
3416
|
},
|
|
3372
|
-
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(ActionButton, {
|
|
3417
|
+
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ActionButton, {
|
|
3373
3418
|
variant: "subtle",
|
|
3374
|
-
icon: IconColumns
|
|
3375
|
-
|
|
3419
|
+
icon: IconColumns,
|
|
3420
|
+
onClick: () => setOpened((o) => !o)
|
|
3421
|
+
}) }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
3376
3422
|
bg: "transparent",
|
|
3377
3423
|
p: "xs",
|
|
3378
3424
|
bd: `1px solid ${ui.colors.border}`,
|
|
3379
3425
|
style: { backdropFilter: "blur(20px)" },
|
|
3380
|
-
children: /* @__PURE__ */ jsxs(
|
|
3426
|
+
children: /* @__PURE__ */ jsxs(Flex$1, {
|
|
3427
|
+
direction: "column",
|
|
3381
3428
|
gap: "xs",
|
|
3382
3429
|
bg: ui.colors.surface,
|
|
3383
3430
|
p: "sm",
|
|
3384
3431
|
bdrs: "sm",
|
|
3385
|
-
children: [/* @__PURE__ */ jsxs(
|
|
3432
|
+
children: [/* @__PURE__ */ jsxs(Flex$1, {
|
|
3386
3433
|
justify: "space-between",
|
|
3387
3434
|
children: [/* @__PURE__ */ jsxs(Text$1, {
|
|
3388
3435
|
size: "sm",
|
|
@@ -3394,26 +3441,27 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
3394
3441
|
columnEntries.length,
|
|
3395
3442
|
")"
|
|
3396
3443
|
]
|
|
3397
|
-
}), /* @__PURE__ */ jsxs(
|
|
3444
|
+
}), /* @__PURE__ */ jsxs(Flex$1, {
|
|
3398
3445
|
gap: 4,
|
|
3399
|
-
children: [/* @__PURE__ */ jsx(
|
|
3446
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
3400
3447
|
size: "compact-xs",
|
|
3401
3448
|
variant: "subtle",
|
|
3402
3449
|
onClick: handleShowAll,
|
|
3403
3450
|
children: "All"
|
|
3404
|
-
}), /* @__PURE__ */ jsx(
|
|
3451
|
+
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
3405
3452
|
size: "compact-xs",
|
|
3406
3453
|
variant: "subtle",
|
|
3407
|
-
onClick:
|
|
3408
|
-
children: "
|
|
3454
|
+
onClick: handleDefault,
|
|
3455
|
+
children: "Default"
|
|
3409
3456
|
})]
|
|
3410
3457
|
})]
|
|
3411
3458
|
}), /* @__PURE__ */ jsx(ScrollArea.Autosize, {
|
|
3412
3459
|
mah: 300,
|
|
3413
|
-
children: /* @__PURE__ */ jsx(
|
|
3460
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
3461
|
+
direction: "column",
|
|
3414
3462
|
gap: 4,
|
|
3415
3463
|
children: columnEntries.map(([key, col]) => /* @__PURE__ */ jsx(Checkbox, {
|
|
3416
|
-
label: col.label,
|
|
3464
|
+
label: col.label || key,
|
|
3417
3465
|
checked: visibility[key] !== false,
|
|
3418
3466
|
onChange: (e) => handleToggle(key, e.currentTarget.checked),
|
|
3419
3467
|
size: "sm"
|
|
@@ -3453,7 +3501,7 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
3453
3501
|
[key]: checked
|
|
3454
3502
|
});
|
|
3455
3503
|
};
|
|
3456
|
-
const visibleCount = filterKeys.filter((key) => visibility[key]
|
|
3504
|
+
const visibleCount = filterKeys.filter((key) => visibility[key]).length;
|
|
3457
3505
|
return /* @__PURE__ */ jsxs(Popover, {
|
|
3458
3506
|
width: 280,
|
|
3459
3507
|
position: "bottom-start",
|
|
@@ -3467,20 +3515,22 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
3467
3515
|
duration: 200,
|
|
3468
3516
|
timingFunction: "ease"
|
|
3469
3517
|
},
|
|
3470
|
-
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(ActionButton, {
|
|
3518
|
+
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ActionButton, {
|
|
3471
3519
|
variant: "subtle",
|
|
3472
|
-
icon: IconFilter
|
|
3473
|
-
|
|
3520
|
+
icon: IconFilter,
|
|
3521
|
+
onClick: () => setOpened((o) => !o)
|
|
3522
|
+
}) }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
3474
3523
|
bg: "transparent",
|
|
3475
3524
|
p: "xs",
|
|
3476
3525
|
bd: `1px solid ${ui.colors.border}`,
|
|
3477
3526
|
style: { backdropFilter: "blur(20px)" },
|
|
3478
|
-
children: /* @__PURE__ */ jsxs(
|
|
3527
|
+
children: /* @__PURE__ */ jsxs(Flex$1, {
|
|
3528
|
+
direction: "column",
|
|
3479
3529
|
gap: "xs",
|
|
3480
3530
|
bg: ui.colors.surface,
|
|
3481
3531
|
p: "sm",
|
|
3482
3532
|
bdrs: "sm",
|
|
3483
|
-
children: [/* @__PURE__ */ jsxs(
|
|
3533
|
+
children: [/* @__PURE__ */ jsxs(Flex$1, {
|
|
3484
3534
|
justify: "space-between",
|
|
3485
3535
|
children: [/* @__PURE__ */ jsxs(Text$1, {
|
|
3486
3536
|
size: "sm",
|
|
@@ -3492,14 +3542,14 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
3492
3542
|
filterKeys.length,
|
|
3493
3543
|
")"
|
|
3494
3544
|
]
|
|
3495
|
-
}), /* @__PURE__ */ jsxs(
|
|
3545
|
+
}), /* @__PURE__ */ jsxs(Flex$1, {
|
|
3496
3546
|
gap: 4,
|
|
3497
|
-
children: [/* @__PURE__ */ jsx(
|
|
3547
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
3498
3548
|
size: "compact-xs",
|
|
3499
3549
|
variant: "subtle",
|
|
3500
3550
|
onClick: handleShowAll,
|
|
3501
3551
|
children: "All"
|
|
3502
|
-
}), /* @__PURE__ */ jsx(
|
|
3552
|
+
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
3503
3553
|
size: "compact-xs",
|
|
3504
3554
|
variant: "subtle",
|
|
3505
3555
|
onClick: handleHideAll,
|
|
@@ -3508,11 +3558,12 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
3508
3558
|
})]
|
|
3509
3559
|
}), /* @__PURE__ */ jsx(ScrollArea.Autosize, {
|
|
3510
3560
|
mah: 300,
|
|
3511
|
-
children: /* @__PURE__ */ jsx(
|
|
3561
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
3562
|
+
direction: "column",
|
|
3512
3563
|
gap: 4,
|
|
3513
3564
|
children: filterKeys.map((key) => /* @__PURE__ */ jsx(Checkbox, {
|
|
3514
3565
|
label: getFieldLabel(schema, key),
|
|
3515
|
-
checked: visibility[key]
|
|
3566
|
+
checked: visibility[key] === true,
|
|
3516
3567
|
onChange: (e) => handleToggle(key, e.currentTarget.checked),
|
|
3517
3568
|
size: "sm"
|
|
3518
3569
|
}, key))
|
|
@@ -3525,8 +3576,50 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
3525
3576
|
|
|
3526
3577
|
//#endregion
|
|
3527
3578
|
//#region ../../src/core/components/table/DataTableToolbar.tsx
|
|
3528
|
-
const
|
|
3579
|
+
const escapeCsvField = (value) => {
|
|
3580
|
+
if (value.includes(",") || value.includes("\"") || value.includes("\n")) return `"${value.replace(/"/g, "\"\"")}"`;
|
|
3581
|
+
return value;
|
|
3582
|
+
};
|
|
3583
|
+
const extractText = (node) => {
|
|
3584
|
+
if (node == null || typeof node === "boolean") return "";
|
|
3585
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
3586
|
+
if (Array.isArray(node)) return node.map(extractText).join("");
|
|
3587
|
+
if (typeof node === "object" && "props" in node) return extractText(node.props.children);
|
|
3588
|
+
return "";
|
|
3589
|
+
};
|
|
3590
|
+
const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility, onColumnVisibilityChange, onFilterVisibilityChange, actions, onRefresh, items, withExport, selectedItems = [], checkboxActions, onClearSelection }) => {
|
|
3529
3591
|
const hasSelection = selectedItems.length > 0;
|
|
3592
|
+
const exportableColumns = useCallback(() => {
|
|
3593
|
+
return Object.entries(columns).filter(([key, col]) => !col.actions && columnVisibility[key] !== false);
|
|
3594
|
+
}, [columns, columnVisibility]);
|
|
3595
|
+
const buildRows = useCallback(() => {
|
|
3596
|
+
const cols = exportableColumns();
|
|
3597
|
+
return items.map((item) => cols.map(([_key, col]) => {
|
|
3598
|
+
if (!col.value) return "";
|
|
3599
|
+
return extractText(col.value(item, {}));
|
|
3600
|
+
}));
|
|
3601
|
+
}, [items, exportableColumns]);
|
|
3602
|
+
const buildCsv = useCallback(() => {
|
|
3603
|
+
const header = exportableColumns().map(([_key, col]) => escapeCsvField(col.label));
|
|
3604
|
+
const rows = buildRows().map((row) => row.map(escapeCsvField));
|
|
3605
|
+
return [header.join(","), ...rows.map((r) => r.join(","))].join("\n");
|
|
3606
|
+
}, [exportableColumns, buildRows]);
|
|
3607
|
+
const exportCsv = useCallback(() => {
|
|
3608
|
+
const csv = buildCsv();
|
|
3609
|
+
const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
|
|
3610
|
+
const url = URL.createObjectURL(blob);
|
|
3611
|
+
const a = document.createElement("a");
|
|
3612
|
+
a.href = url;
|
|
3613
|
+
a.download = "export.csv";
|
|
3614
|
+
a.click();
|
|
3615
|
+
URL.revokeObjectURL(url);
|
|
3616
|
+
}, [buildCsv]);
|
|
3617
|
+
const exportClipboard = useCallback(async () => {
|
|
3618
|
+
const header = exportableColumns().map(([_key, col]) => col.label);
|
|
3619
|
+
const rows = buildRows();
|
|
3620
|
+
const text = [header.join(" "), ...rows.map((r) => r.join(" "))].join("\n");
|
|
3621
|
+
await navigator.clipboard.writeText(text);
|
|
3622
|
+
}, [exportableColumns, buildRows]);
|
|
3530
3623
|
const handleCheckboxAction = async (action) => {
|
|
3531
3624
|
const ctx = {
|
|
3532
3625
|
selectedItems,
|
|
@@ -3552,6 +3645,19 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
3552
3645
|
visibility: columnVisibility,
|
|
3553
3646
|
onVisibilityChange: onColumnVisibilityChange
|
|
3554
3647
|
}),
|
|
3648
|
+
withExport && /* @__PURE__ */ jsx(ActionButton, {
|
|
3649
|
+
variant: "subtle",
|
|
3650
|
+
icon: IconDownload,
|
|
3651
|
+
menu: { items: [{
|
|
3652
|
+
label: "Export as CSV",
|
|
3653
|
+
icon: /* @__PURE__ */ jsx(IconDownload, { size: 14 }),
|
|
3654
|
+
onClick: exportCsv
|
|
3655
|
+
}, {
|
|
3656
|
+
label: "Copy to clipboard",
|
|
3657
|
+
icon: /* @__PURE__ */ jsx(IconClipboard, { size: 14 }),
|
|
3658
|
+
onClick: exportClipboard
|
|
3659
|
+
}] }
|
|
3660
|
+
}),
|
|
3555
3661
|
hasSelection && /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
3556
3662
|
/* @__PURE__ */ jsx(Divider, {
|
|
3557
3663
|
orientation: "vertical",
|
|
@@ -3587,18 +3693,80 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
3587
3693
|
...props,
|
|
3588
3694
|
children: props.label
|
|
3589
3695
|
}, index) : props), /* @__PURE__ */ jsx(ActionButton, {
|
|
3696
|
+
variant: "subtle",
|
|
3590
3697
|
icon: IconRefresh,
|
|
3591
|
-
onClick: onRefresh
|
|
3592
|
-
children: "Refresh"
|
|
3698
|
+
onClick: onRefresh
|
|
3593
3699
|
})]
|
|
3594
3700
|
})
|
|
3595
3701
|
]
|
|
3596
3702
|
});
|
|
3597
3703
|
};
|
|
3598
3704
|
|
|
3705
|
+
//#endregion
|
|
3706
|
+
//#region ../../src/core/components/table/useTableSelection.ts
|
|
3707
|
+
const useTableSelection = (items, getItemKey, enabled) => {
|
|
3708
|
+
const [selectedKeys, setSelectedKeys] = useState(/* @__PURE__ */ new Set());
|
|
3709
|
+
const selectedItems = useMemo(() => {
|
|
3710
|
+
if (!enabled) return [];
|
|
3711
|
+
return items.filter((item) => selectedKeys.has(getItemKey(item)));
|
|
3712
|
+
}, [
|
|
3713
|
+
items,
|
|
3714
|
+
selectedKeys,
|
|
3715
|
+
getItemKey,
|
|
3716
|
+
enabled
|
|
3717
|
+
]);
|
|
3718
|
+
const allSelected = useMemo(() => {
|
|
3719
|
+
if (items.length === 0) return false;
|
|
3720
|
+
return items.every((item) => selectedKeys.has(getItemKey(item)));
|
|
3721
|
+
}, [
|
|
3722
|
+
items,
|
|
3723
|
+
selectedKeys,
|
|
3724
|
+
getItemKey
|
|
3725
|
+
]);
|
|
3726
|
+
return {
|
|
3727
|
+
selectedItems,
|
|
3728
|
+
allSelected,
|
|
3729
|
+
someSelected: useMemo(() => {
|
|
3730
|
+
if (items.length === 0) return false;
|
|
3731
|
+
const count = items.filter((item) => selectedKeys.has(getItemKey(item))).length;
|
|
3732
|
+
return count > 0 && count < items.length;
|
|
3733
|
+
}, [
|
|
3734
|
+
items,
|
|
3735
|
+
selectedKeys,
|
|
3736
|
+
getItemKey
|
|
3737
|
+
]),
|
|
3738
|
+
toggleItem: useCallback((item) => {
|
|
3739
|
+
const key = getItemKey(item);
|
|
3740
|
+
setSelectedKeys((prev) => {
|
|
3741
|
+
const next = new Set(prev);
|
|
3742
|
+
if (next.has(key)) next.delete(key);
|
|
3743
|
+
else next.add(key);
|
|
3744
|
+
return next;
|
|
3745
|
+
});
|
|
3746
|
+
}, [getItemKey]),
|
|
3747
|
+
toggleAll: useCallback(() => {
|
|
3748
|
+
if (allSelected) setSelectedKeys((prev) => {
|
|
3749
|
+
const next = new Set(prev);
|
|
3750
|
+
for (const item of items) next.delete(getItemKey(item));
|
|
3751
|
+
return next;
|
|
3752
|
+
});
|
|
3753
|
+
else setSelectedKeys((prev) => {
|
|
3754
|
+
const next = new Set(prev);
|
|
3755
|
+
for (const item of items) next.add(getItemKey(item));
|
|
3756
|
+
return next;
|
|
3757
|
+
});
|
|
3758
|
+
}, [
|
|
3759
|
+
allSelected,
|
|
3760
|
+
items,
|
|
3761
|
+
getItemKey
|
|
3762
|
+
]),
|
|
3763
|
+
clear: useCallback(() => setSelectedKeys(/* @__PURE__ */ new Set()), []),
|
|
3764
|
+
isSelected: useCallback((item) => selectedKeys.has(getItemKey(item)), [selectedKeys, getItemKey])
|
|
3765
|
+
};
|
|
3766
|
+
};
|
|
3767
|
+
|
|
3599
3768
|
//#endregion
|
|
3600
3769
|
//#region ../../src/core/components/table/DataTable.tsx
|
|
3601
|
-
const DEFAULT_VISIBLE_COLUMN_COUNT = 10;
|
|
3602
3770
|
/**
|
|
3603
3771
|
* Parse the sort string to get direction for a specific field.
|
|
3604
3772
|
* Alepha convention: 'field' = ASC, '-field' = DESC
|
|
@@ -3623,6 +3791,15 @@ const toggleSort = (sortString, field) => {
|
|
|
3623
3791
|
else if (current === "asc") parts.unshift(`-${field}`);
|
|
3624
3792
|
return parts.length > 0 ? parts.join(",") : void 0;
|
|
3625
3793
|
};
|
|
3794
|
+
const toAriaSort = (dir) => {
|
|
3795
|
+
if (dir === "asc") return "ascending";
|
|
3796
|
+
if (dir === "desc") return "descending";
|
|
3797
|
+
return "none";
|
|
3798
|
+
};
|
|
3799
|
+
const FIT_STYLE = {
|
|
3800
|
+
width: 1,
|
|
3801
|
+
whiteSpace: "nowrap"
|
|
3802
|
+
};
|
|
3626
3803
|
const DataTable = (props) => {
|
|
3627
3804
|
const [items, setItems] = useState(typeof props.items === "function" ? { content: [] } : props.items);
|
|
3628
3805
|
const defaultSize = props.infinityScroll ? 100 : props.defaultSize || 10;
|
|
@@ -3630,31 +3807,27 @@ const DataTable = (props) => {
|
|
|
3630
3807
|
const [size, setSize] = useState(String(defaultSize));
|
|
3631
3808
|
const [currentPage, setCurrentPage] = useState(0);
|
|
3632
3809
|
const alepha = useInject(Alepha);
|
|
3810
|
+
const sentinelRef = useRef(null);
|
|
3633
3811
|
const [columnVisibility, setColumnVisibility] = useState(() => {
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3812
|
+
const entries = Object.entries(props.columns);
|
|
3813
|
+
let visibleCount = 0;
|
|
3814
|
+
return entries.reduce((acc, [key, col]) => {
|
|
3815
|
+
if (col.defaultHidden) acc[key] = false;
|
|
3816
|
+
else if (visibleCount < DEFAULT_MAX_VISIBLE_COLUMNS) {
|
|
3817
|
+
acc[key] = true;
|
|
3818
|
+
visibleCount++;
|
|
3819
|
+
} else acc[key] = false;
|
|
3820
|
+
return acc;
|
|
3821
|
+
}, {});
|
|
3641
3822
|
});
|
|
3642
3823
|
const [filterVisibility, setFilterVisibility] = useState(() => {
|
|
3643
|
-
if (props.defaultFilterVisibility) return props.defaultFilterVisibility;
|
|
3644
3824
|
if (!props.filters?.properties) return {};
|
|
3825
|
+
const defaults = new Set(props.defaultFilters ?? []);
|
|
3645
3826
|
return Object.keys(props.filters.properties).reduce((acc, key) => ({
|
|
3646
3827
|
...acc,
|
|
3647
|
-
[key]:
|
|
3828
|
+
[key]: defaults.has(key)
|
|
3648
3829
|
}), {});
|
|
3649
3830
|
});
|
|
3650
|
-
const handleColumnVisibilityChange = (visibility) => {
|
|
3651
|
-
setColumnVisibility(visibility);
|
|
3652
|
-
props.onColumnVisibilityChange?.(visibility);
|
|
3653
|
-
};
|
|
3654
|
-
const handleFilterVisibilityChange = (visibility) => {
|
|
3655
|
-
setFilterVisibility(visibility);
|
|
3656
|
-
props.onFilterVisibilityChange?.(visibility);
|
|
3657
|
-
};
|
|
3658
3831
|
const visibleColumns = useMemo(() => {
|
|
3659
3832
|
return Object.entries(props.columns).filter(([key]) => columnVisibility[key] !== false);
|
|
3660
3833
|
}, [props.columns, columnVisibility]);
|
|
@@ -3665,64 +3838,38 @@ const DataTable = (props) => {
|
|
|
3665
3838
|
form.input.sort.set(newSort);
|
|
3666
3839
|
form.input.page.set(0);
|
|
3667
3840
|
};
|
|
3668
|
-
const [selectedKeys, setSelectedKeys] = useState(/* @__PURE__ */ new Set());
|
|
3669
3841
|
const getItemKey = useCallback((item) => {
|
|
3670
3842
|
if (props.getItemKey) return props.getItemKey(item);
|
|
3843
|
+
if ("id" in item) return String(item.id);
|
|
3671
3844
|
return JSON.stringify(item);
|
|
3672
3845
|
}, [props.getItemKey]);
|
|
3673
|
-
const
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
props.
|
|
3681
|
-
]);
|
|
3682
|
-
const
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
items.content,
|
|
3696
|
-
selectedKeys,
|
|
3697
|
-
getItemKey
|
|
3698
|
-
]);
|
|
3699
|
-
const toggleItemSelection = useCallback((item) => {
|
|
3700
|
-
const key = getItemKey(item);
|
|
3701
|
-
setSelectedKeys((prev) => {
|
|
3846
|
+
const selection = useTableSelection(items.content, getItemKey, props.withCheckbox ?? false);
|
|
3847
|
+
const panelConfig = useMemo(() => {
|
|
3848
|
+
if (!props.panel) return null;
|
|
3849
|
+
if (typeof props.panel === "function") return {
|
|
3850
|
+
render: props.panel,
|
|
3851
|
+
can: void 0
|
|
3852
|
+
};
|
|
3853
|
+
return props.panel;
|
|
3854
|
+
}, [props.panel]);
|
|
3855
|
+
const [drawerItem, setDrawerItem] = useState(null);
|
|
3856
|
+
const drawerConfig = useMemo(() => {
|
|
3857
|
+
if (!props.drawer) return null;
|
|
3858
|
+
if (typeof props.drawer === "function") return {
|
|
3859
|
+
render: props.drawer,
|
|
3860
|
+
can: void 0,
|
|
3861
|
+
props: void 0
|
|
3862
|
+
};
|
|
3863
|
+
return props.drawer;
|
|
3864
|
+
}, [props.drawer]);
|
|
3865
|
+
const [expandedKeys, setExpandedKeys] = useState(/* @__PURE__ */ new Set());
|
|
3866
|
+
const toggleExpand = useCallback((key) => {
|
|
3867
|
+
setExpandedKeys((prev) => {
|
|
3702
3868
|
const next = new Set(prev);
|
|
3703
3869
|
if (next.has(key)) next.delete(key);
|
|
3704
3870
|
else next.add(key);
|
|
3705
3871
|
return next;
|
|
3706
3872
|
});
|
|
3707
|
-
}, [getItemKey]);
|
|
3708
|
-
const toggleAllSelection = useCallback(() => {
|
|
3709
|
-
if (allSelected) setSelectedKeys((prev) => {
|
|
3710
|
-
const next = new Set(prev);
|
|
3711
|
-
for (const item of items.content) next.delete(getItemKey(item));
|
|
3712
|
-
return next;
|
|
3713
|
-
});
|
|
3714
|
-
else setSelectedKeys((prev) => {
|
|
3715
|
-
const next = new Set(prev);
|
|
3716
|
-
for (const item of items.content) next.add(getItemKey(item));
|
|
3717
|
-
return next;
|
|
3718
|
-
});
|
|
3719
|
-
}, [
|
|
3720
|
-
allSelected,
|
|
3721
|
-
items.content,
|
|
3722
|
-
getItemKey
|
|
3723
|
-
]);
|
|
3724
|
-
const clearSelection = useCallback(() => {
|
|
3725
|
-
setSelectedKeys(/* @__PURE__ */ new Set());
|
|
3726
3873
|
}, []);
|
|
3727
3874
|
const form = useForm({
|
|
3728
3875
|
schema: t.object({
|
|
@@ -3744,7 +3891,7 @@ const DataTable = (props) => {
|
|
|
3744
3891
|
},
|
|
3745
3892
|
onReset: async () => {
|
|
3746
3893
|
setPage(1);
|
|
3747
|
-
setSize(
|
|
3894
|
+
setSize(String(defaultSize));
|
|
3748
3895
|
await form.submit();
|
|
3749
3896
|
},
|
|
3750
3897
|
onChange: async (key, value) => {
|
|
@@ -3761,7 +3908,6 @@ const DataTable = (props) => {
|
|
|
3761
3908
|
props.onFilterChange?.(key, value, form);
|
|
3762
3909
|
}
|
|
3763
3910
|
}, [items]);
|
|
3764
|
-
useDebouncedCallback(() => form.submit(), { delay: 800 });
|
|
3765
3911
|
const dt = useInject(DateTimeProvider);
|
|
3766
3912
|
useEffect(() => {
|
|
3767
3913
|
if (props.submitOnInit) form.submit();
|
|
@@ -3777,18 +3923,15 @@ const DataTable = (props) => {
|
|
|
3777
3923
|
}, [props.items]);
|
|
3778
3924
|
useEffect(() => {
|
|
3779
3925
|
if (!props.infinityScroll || typeof props.items !== "function") return;
|
|
3780
|
-
const
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
const
|
|
3785
|
-
if (
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
};
|
|
3790
|
-
window.addEventListener("scroll", handleScroll);
|
|
3791
|
-
return () => window.removeEventListener("scroll", handleScroll);
|
|
3926
|
+
const sentinel = sentinelRef.current;
|
|
3927
|
+
if (!sentinel) return;
|
|
3928
|
+
const observer = new IntersectionObserver((entries) => {
|
|
3929
|
+
if (!entries[0].isIntersecting || form.submitting) return;
|
|
3930
|
+
const totalPages = items.page?.totalPages ?? 1;
|
|
3931
|
+
if (currentPage + 1 < totalPages) form.input.page.set(currentPage + 1);
|
|
3932
|
+
}, { rootMargin: "300px" });
|
|
3933
|
+
observer.observe(sentinel);
|
|
3934
|
+
return () => observer.disconnect();
|
|
3792
3935
|
}, [
|
|
3793
3936
|
props.infinityScroll,
|
|
3794
3937
|
form.submitting,
|
|
@@ -3796,63 +3939,134 @@ const DataTable = (props) => {
|
|
|
3796
3939
|
currentPage,
|
|
3797
3940
|
form
|
|
3798
3941
|
]);
|
|
3942
|
+
const totalColumns = visibleColumns.length + (panelConfig ? 1 : 0) + (props.withCheckbox ? 1 : 0);
|
|
3799
3943
|
const checkboxHeader = props.withCheckbox ? /* @__PURE__ */ jsx(Table.Th, {
|
|
3800
3944
|
style: { width: 40 },
|
|
3801
3945
|
children: /* @__PURE__ */ jsx(Checkbox, {
|
|
3802
|
-
checked: allSelected,
|
|
3803
|
-
indeterminate: someSelected,
|
|
3804
|
-
onChange:
|
|
3946
|
+
checked: selection.allSelected,
|
|
3947
|
+
indeterminate: selection.someSelected,
|
|
3948
|
+
onChange: selection.toggleAll,
|
|
3805
3949
|
"aria-label": "Select all"
|
|
3806
3950
|
})
|
|
3807
3951
|
}) : null;
|
|
3808
3952
|
const head = visibleColumns.map(([key, col]) => {
|
|
3809
3953
|
const sortField = col.sortKey || key;
|
|
3810
3954
|
const sortDir = col.sortable ? getSortDirection(sortString, sortField) : null;
|
|
3811
|
-
const headerContent = /* @__PURE__ */ jsxs(Flex$1, {
|
|
3812
|
-
align: "center",
|
|
3813
|
-
gap: 4,
|
|
3814
|
-
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
3815
|
-
size: "xs",
|
|
3816
|
-
children: col.label
|
|
3817
|
-
}), col.sortable && /* @__PURE__ */ jsxs(Flex$1, {
|
|
3818
|
-
c: "dimmed",
|
|
3819
|
-
children: [
|
|
3820
|
-
sortDir === "asc" && /* @__PURE__ */ jsx(IconArrowUp, { size: ui.sizes.icon.sm }),
|
|
3821
|
-
sortDir === "desc" && /* @__PURE__ */ jsx(IconArrowDown, { size: ui.sizes.icon.sm }),
|
|
3822
|
-
sortDir === null && /* @__PURE__ */ jsx(IconArrowsSort, { size: ui.sizes.icon.sm })
|
|
3823
|
-
]
|
|
3824
|
-
})]
|
|
3825
|
-
});
|
|
3826
3955
|
return /* @__PURE__ */ jsx(Table.Th, {
|
|
3956
|
+
onClick: col.sortable ? () => handleSortClick(key, col.sortKey) : void 0,
|
|
3957
|
+
"aria-sort": col.sortable ? toAriaSort(sortDir) : void 0,
|
|
3827
3958
|
style: {
|
|
3828
|
-
...col.fit ?
|
|
3829
|
-
...col.sortable ? {
|
|
3959
|
+
...col.fit ? FIT_STYLE : {},
|
|
3960
|
+
...col.sortable ? {
|
|
3961
|
+
cursor: "pointer",
|
|
3962
|
+
userSelect: "none"
|
|
3963
|
+
} : {}
|
|
3830
3964
|
},
|
|
3831
|
-
children:
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3965
|
+
children: /* @__PURE__ */ jsxs(Flex$1, {
|
|
3966
|
+
align: "center",
|
|
3967
|
+
gap: 4,
|
|
3968
|
+
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
3969
|
+
size: "xs",
|
|
3970
|
+
children: col.label
|
|
3971
|
+
}), col.sortable && /* @__PURE__ */ jsxs(Flex$1, {
|
|
3972
|
+
c: "dimmed",
|
|
3973
|
+
children: [
|
|
3974
|
+
sortDir === "asc" && /* @__PURE__ */ jsx(IconArrowUp, { size: ui.sizes.icon.sm }),
|
|
3975
|
+
sortDir === "desc" && /* @__PURE__ */ jsx(IconArrowDown, { size: ui.sizes.icon.sm }),
|
|
3976
|
+
sortDir === null && /* @__PURE__ */ jsx(IconArrowsSort, { size: ui.sizes.icon.sm })
|
|
3977
|
+
]
|
|
3978
|
+
})]
|
|
3979
|
+
})
|
|
3835
3980
|
}, key);
|
|
3836
3981
|
});
|
|
3837
|
-
const rows = items.content.
|
|
3982
|
+
const rows = items.content.flatMap((item, index) => {
|
|
3838
3983
|
const trProps = props.tableTrProps ? props.tableTrProps(item) : {};
|
|
3839
3984
|
const itemKey = getItemKey(item);
|
|
3840
|
-
const isSelected =
|
|
3841
|
-
|
|
3985
|
+
const isSelected = selection.isSelected(item);
|
|
3986
|
+
const showPanel = panelConfig && (panelConfig.can ? panelConfig.can(item) : true);
|
|
3987
|
+
const isExpanded = expandedKeys.has(itemKey);
|
|
3988
|
+
const canOpenDrawer = drawerConfig && (drawerConfig.can ? drawerConfig.can(item) : true);
|
|
3989
|
+
const elements = [/* @__PURE__ */ jsxs(Table.Tr, {
|
|
3842
3990
|
...trProps,
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3991
|
+
style: {
|
|
3992
|
+
...canOpenDrawer ? { cursor: "pointer" } : {},
|
|
3993
|
+
...trProps.style ?? {}
|
|
3994
|
+
},
|
|
3995
|
+
onClick: (e) => {
|
|
3996
|
+
if (canOpenDrawer) setDrawerItem(item);
|
|
3997
|
+
trProps.onClick?.(e);
|
|
3998
|
+
},
|
|
3999
|
+
children: [
|
|
4000
|
+
panelConfig && /* @__PURE__ */ jsx(Table.Td, {
|
|
4001
|
+
style: {
|
|
4002
|
+
width: 36,
|
|
4003
|
+
textAlign: "center"
|
|
4004
|
+
},
|
|
4005
|
+
py: 2,
|
|
4006
|
+
px: 0,
|
|
4007
|
+
children: showPanel && /* @__PURE__ */ jsx(UnstyledButton, {
|
|
4008
|
+
onClick: (e) => {
|
|
4009
|
+
e.stopPropagation();
|
|
4010
|
+
toggleExpand(itemKey);
|
|
4011
|
+
},
|
|
4012
|
+
style: { display: "inline-flex" },
|
|
4013
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
4014
|
+
c: "dimmed",
|
|
4015
|
+
align: "center",
|
|
4016
|
+
justify: "center",
|
|
4017
|
+
children: isExpanded ? /* @__PURE__ */ jsx(IconChevronDown, { size: ui.sizes.icon.sm }) : /* @__PURE__ */ jsx(IconChevronRight, { size: ui.sizes.icon.sm })
|
|
4018
|
+
})
|
|
4019
|
+
})
|
|
4020
|
+
}),
|
|
4021
|
+
props.withCheckbox && /* @__PURE__ */ jsx(Table.Td, {
|
|
4022
|
+
style: { width: 40 },
|
|
4023
|
+
onClick: (e) => e.stopPropagation(),
|
|
4024
|
+
children: /* @__PURE__ */ jsx(Checkbox, {
|
|
4025
|
+
checked: isSelected,
|
|
4026
|
+
onChange: () => selection.toggleItem(item),
|
|
4027
|
+
"aria-label": "Select row"
|
|
4028
|
+
})
|
|
4029
|
+
}),
|
|
4030
|
+
visibleColumns.map(([key, col]) => {
|
|
4031
|
+
const ctx = {
|
|
4032
|
+
index,
|
|
4033
|
+
form,
|
|
4034
|
+
alepha
|
|
4035
|
+
};
|
|
4036
|
+
if (col.actions) {
|
|
4037
|
+
const rowActions = col.actions(item, ctx).filter((a) => a.visible !== false);
|
|
4038
|
+
return /* @__PURE__ */ jsx(Table.Td, {
|
|
4039
|
+
py: 2,
|
|
4040
|
+
px: 4,
|
|
4041
|
+
style: col.fit ? FIT_STYLE : void 0,
|
|
4042
|
+
onClick: (e) => e.stopPropagation(),
|
|
4043
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
4044
|
+
gap: 4,
|
|
4045
|
+
children: rowActions.map(({ visible: _, ...actionProps }, i) => /* @__PURE__ */ jsx(ActionButton, {
|
|
4046
|
+
variant: "subtle",
|
|
4047
|
+
size: "xs",
|
|
4048
|
+
preventDefault: true,
|
|
4049
|
+
h: 20,
|
|
4050
|
+
...actionProps
|
|
4051
|
+
}, i))
|
|
4052
|
+
})
|
|
4053
|
+
}, key);
|
|
4054
|
+
}
|
|
4055
|
+
return /* @__PURE__ */ jsx(Table.Td, {
|
|
4056
|
+
py: 2,
|
|
4057
|
+
px: 4,
|
|
4058
|
+
style: col.fit ? FIT_STYLE : void 0,
|
|
4059
|
+
children: col.value?.(item, ctx)
|
|
4060
|
+
}, key);
|
|
3849
4061
|
})
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
4062
|
+
]
|
|
4063
|
+
}, itemKey)];
|
|
4064
|
+
if (panelConfig && showPanel && isExpanded) elements.push(/* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
|
|
4065
|
+
colSpan: totalColumns,
|
|
4066
|
+
p: 0,
|
|
4067
|
+
children: panelConfig.render(item)
|
|
4068
|
+
}) }, `${itemKey}-panel`));
|
|
4069
|
+
return elements;
|
|
3856
4070
|
});
|
|
3857
4071
|
const filterSchema = useMemo(() => {
|
|
3858
4072
|
if (!props.filters) return null;
|
|
@@ -3865,9 +4079,7 @@ const DataTable = (props) => {
|
|
|
3865
4079
|
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
3866
4080
|
flex: 1,
|
|
3867
4081
|
p: 0,
|
|
3868
|
-
bg: "var(--alepha-elevated)",
|
|
3869
4082
|
bdrs: "sm",
|
|
3870
|
-
bd: "1px solid var(--alepha-border)",
|
|
3871
4083
|
direction: "column",
|
|
3872
4084
|
children: [
|
|
3873
4085
|
/* @__PURE__ */ jsx(DataTableToolbar, {
|
|
@@ -3875,13 +4087,15 @@ const DataTable = (props) => {
|
|
|
3875
4087
|
filters: props.filters,
|
|
3876
4088
|
columnVisibility,
|
|
3877
4089
|
filterVisibility,
|
|
3878
|
-
onColumnVisibilityChange:
|
|
3879
|
-
onFilterVisibilityChange:
|
|
4090
|
+
onColumnVisibilityChange: setColumnVisibility,
|
|
4091
|
+
onFilterVisibilityChange: setFilterVisibility,
|
|
3880
4092
|
actions: props.actions,
|
|
3881
4093
|
onRefresh: () => form.submit(),
|
|
3882
|
-
|
|
4094
|
+
items: items.content,
|
|
4095
|
+
withExport: props.withExport,
|
|
4096
|
+
selectedItems: selection.selectedItems,
|
|
3883
4097
|
checkboxActions: props.checkboxActions,
|
|
3884
|
-
onClearSelection:
|
|
4098
|
+
onClearSelection: selection.clear
|
|
3885
4099
|
}),
|
|
3886
4100
|
filterSchema && props.filters && /* @__PURE__ */ jsx(DataTableFilters, {
|
|
3887
4101
|
schema: filterSchema,
|
|
@@ -3892,12 +4106,41 @@ const DataTable = (props) => {
|
|
|
3892
4106
|
/* @__PURE__ */ jsx(Flex$1, {
|
|
3893
4107
|
className: "overflow-auto",
|
|
3894
4108
|
children: /* @__PURE__ */ jsxs(Table, {
|
|
4109
|
+
"aria-label": "Data table",
|
|
3895
4110
|
withColumnBorders: true,
|
|
3896
4111
|
withRowBorders: true,
|
|
3897
4112
|
...props.tableProps,
|
|
3898
|
-
children: [/* @__PURE__ */ jsx(Table.Thead, {
|
|
4113
|
+
children: [/* @__PURE__ */ jsx(Table.Thead, {
|
|
4114
|
+
style: {
|
|
4115
|
+
position: "sticky",
|
|
4116
|
+
top: 0,
|
|
4117
|
+
zIndex: 1,
|
|
4118
|
+
backgroundColor: "var(--mantine-color-body)"
|
|
4119
|
+
},
|
|
4120
|
+
children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
4121
|
+
panelConfig && /* @__PURE__ */ jsx(Table.Th, { style: { width: 36 } }),
|
|
4122
|
+
checkboxHeader,
|
|
4123
|
+
head
|
|
4124
|
+
] })
|
|
4125
|
+
}), /* @__PURE__ */ jsxs(Table.Tbody, {
|
|
4126
|
+
style: {
|
|
4127
|
+
opacity: form.submitting ? .5 : 1,
|
|
4128
|
+
transition: "opacity 150ms ease"
|
|
4129
|
+
},
|
|
4130
|
+
children: [rows, items.content.length === 0 && /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
|
|
4131
|
+
colSpan: totalColumns || 1,
|
|
4132
|
+
py: "xl",
|
|
4133
|
+
style: { textAlign: "center" },
|
|
4134
|
+
children: /* @__PURE__ */ jsx(Text$1, {
|
|
4135
|
+
c: "dimmed",
|
|
4136
|
+
size: "sm",
|
|
4137
|
+
children: form.submitting ? "Loading…" : "No results"
|
|
4138
|
+
})
|
|
4139
|
+
}) })]
|
|
4140
|
+
})]
|
|
3899
4141
|
})
|
|
3900
4142
|
}),
|
|
4143
|
+
props.infinityScroll && /* @__PURE__ */ jsx("div", { ref: sentinelRef }),
|
|
3901
4144
|
!props.infinityScroll && /* @__PURE__ */ jsx(DataTablePagination, {
|
|
3902
4145
|
page,
|
|
3903
4146
|
size,
|
|
@@ -3908,6 +4151,14 @@ const DataTable = (props) => {
|
|
|
3908
4151
|
onSizeChange: (value) => {
|
|
3909
4152
|
form.input.size.set(value);
|
|
3910
4153
|
}
|
|
4154
|
+
}),
|
|
4155
|
+
drawerConfig && /* @__PURE__ */ jsx(Drawer, {
|
|
4156
|
+
opened: drawerItem !== null,
|
|
4157
|
+
onClose: () => setDrawerItem(null),
|
|
4158
|
+
position: "right",
|
|
4159
|
+
size: "xl",
|
|
4160
|
+
...drawerConfig.props,
|
|
4161
|
+
children: drawerItem && drawerConfig.render(drawerItem)
|
|
3911
4162
|
})
|
|
3912
4163
|
]
|
|
3913
4164
|
});
|