@alepha/ui 0.16.1 → 0.17.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/admin/{AdminApiKeys-GMORg-1l.js → AdminApiKeys-CF_qOO3u.js} +20 -19
- package/dist/admin/AdminApiKeys-CF_qOO3u.js.map +1 -0
- package/dist/admin/{AdminAudits-pkWrjq1Z.js → AdminAudits-BQno3hZG.js} +7 -7
- package/dist/admin/AdminAudits-BQno3hZG.js.map +1 -0
- package/dist/admin/{AdminFiles-WeQbsCsl.js → AdminFiles-kvuUaASF.js} +3 -4
- package/dist/admin/{AdminFiles-WeQbsCsl.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-BqZiXx4H.js → AdminLayout-e-ZP5nWw.js} +6 -9
- package/dist/admin/AdminLayout-e-ZP5nWw.js.map +1 -0
- package/dist/admin/{AdminNotifications-Ds5Un0NJ.js → AdminNotifications-DeHJFf6W.js} +3 -4
- package/dist/admin/{AdminNotifications-Ds5Un0NJ.js.map → AdminNotifications-DeHJFf6W.js.map} +1 -1
- package/dist/admin/AdminParameters-iQE8o7a7.js +774 -0
- package/dist/admin/AdminParameters-iQE8o7a7.js.map +1 -0
- package/dist/admin/{AdminSessions-DzIOxM3b.js → AdminSessions-oKJCbd7w.js} +5 -6
- package/dist/admin/AdminSessions-oKJCbd7w.js.map +1 -0
- package/dist/admin/{AdminUserAudits-CiUPN2BC.js → AdminUserAudits-BNCEle_E.js} +6 -7
- package/dist/admin/AdminUserAudits-BNCEle_E.js.map +1 -0
- package/dist/admin/{AdminUserCreate-BwQKr4xE.js → AdminUserCreate-CgqeFwCt.js} +6 -6
- package/dist/admin/AdminUserCreate-CgqeFwCt.js.map +1 -0
- package/dist/admin/{AdminUserDetails-uqtC5aJ1.js → AdminUserDetails-DDe1A1GP.js} +30 -28
- package/dist/admin/AdminUserDetails-DDe1A1GP.js.map +1 -0
- package/dist/admin/{AdminUserLayout-CiPay35T.js → AdminUserLayout-HAlobhWf.js} +20 -19
- package/dist/admin/AdminUserLayout-HAlobhWf.js.map +1 -0
- package/dist/admin/{AdminUserSessions-DAE8Nf1F.js → AdminUserSessions-Bq1LnVLf.js} +5 -6
- package/dist/admin/AdminUserSessions-Bq1LnVLf.js.map +1 -0
- package/dist/admin/{AdminUserSettings-EbahaV2a.js → AdminUserSettings-BRsBZoxV.js} +10 -9
- package/dist/admin/AdminUserSettings-BRsBZoxV.js.map +1 -0
- package/dist/admin/{AdminUsers-Dcjh0KNW.js → AdminUsers-D71kIOSn.js} +6 -7
- package/dist/admin/AdminUsers-D71kIOSn.js.map +1 -0
- package/dist/admin/index.d.ts +21 -85
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +66 -88
- package/dist/admin/index.js.map +1 -1
- package/dist/auth/{AuthLayout-Dj5K4SIN.js → AuthLayout-CdJcrPs4.js} +2 -3
- package/dist/auth/{AuthLayout-Dj5K4SIN.js.map → AuthLayout-CdJcrPs4.js.map} +1 -1
- package/dist/{demo/IconGoogle-CbBF8Hqq.js → auth/IconGoogle-Bm18QD2q.js} +2 -4
- package/dist/auth/{IconGoogle-DpSlPZ1u.js.map → IconGoogle-Bm18QD2q.js.map} +1 -1
- package/dist/auth/{Login-BBqTosqZ.js → Login-BS_FYTy0.js} +19 -13
- package/dist/auth/Login-BS_FYTy0.js.map +1 -0
- package/dist/auth/{Profile-Bxj8Nwom.js → Profile-CjDsW378.js} +17 -12
- package/dist/auth/Profile-CjDsW378.js.map +1 -0
- package/dist/auth/{Register-Ce675Crg.js → Register-C5eqzAaD.js} +27 -17
- package/dist/auth/Register-C5eqzAaD.js.map +1 -0
- package/dist/auth/{ResetPassword-DWdt7c40.js → ResetPassword-XifinVao.js} +17 -10
- package/dist/auth/ResetPassword-XifinVao.js.map +1 -0
- package/dist/auth/{VerifyEmail-CI4JwByV.js → VerifyEmail-DTgbeJOO.js} +9 -6
- package/dist/auth/VerifyEmail-DTgbeJOO.js.map +1 -0
- package/dist/auth/index.d.ts +18 -14
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +19 -18
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/rolldown-runtime-CjeV3_4I.js +18 -0
- package/dist/core/index.d.ts +182 -92
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +789 -476
- 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-Cce2bWmg.js → DemoHome-CUMZsYaH.js} +6 -6
- package/dist/demo/DemoHome-CUMZsYaH.js.map +1 -0
- package/dist/demo/{DemoJsonViewer-Dgdk3Txb.js → DemoJsonViewer-_uokbGaW.js} +18 -19
- package/dist/demo/DemoJsonViewer-_uokbGaW.js.map +1 -0
- package/dist/demo/{DemoLayout-B20TEuhV.js → DemoLayout-DHVoacE6.js} +4 -5
- package/dist/demo/DemoLayout-DHVoacE6.js.map +1 -0
- package/dist/demo/{DemoLogin-CvCG2WVh.js → DemoLogin-DjJ9314c.js} +27 -24
- package/dist/demo/DemoLogin-DjJ9314c.js.map +1 -0
- package/dist/demo/{DemoRegister-CmeHbOAs.js → DemoRegister-DzkJ5M83.js} +39 -32
- package/dist/demo/DemoRegister-DzkJ5M83.js.map +1 -0
- package/dist/demo/{DemoResetPassword-CKO5iA_6.js → DemoResetPassword-DWh4_BpQ.js} +30 -26
- package/dist/demo/DemoResetPassword-DWh4_BpQ.js.map +1 -0
- package/dist/demo/{DemoSidebar-MVmQKfMt.js → DemoSidebar-C1csnGhX.js} +4 -5
- package/dist/demo/DemoSidebar-C1csnGhX.js.map +1 -0
- package/dist/demo/{DemoTypeForm-w-qtfRlC.js → DemoTypeForm-CWz6fJrJ.js} +4 -5
- package/dist/demo/DemoTypeForm-CWz6fJrJ.js.map +1 -0
- package/dist/demo/{DemoVerifyEmail-C8FFJT5A.js → DemoVerifyEmail-DbU_tCj8.js} +16 -16
- package/dist/demo/DemoVerifyEmail-DbU_tCj8.js.map +1 -0
- package/dist/{auth/IconGoogle-DpSlPZ1u.js → demo/IconGoogle-Ch1m3Uzl.js} +2 -4
- package/dist/demo/{IconGoogle-CbBF8Hqq.js.map → IconGoogle-Ch1m3Uzl.js.map} +1 -1
- package/dist/demo/{Showcase-CQrMWars.js → Showcase-BzoXNlCn.js} +11 -13
- package/dist/demo/Showcase-BzoXNlCn.js.map +1 -0
- package/dist/demo/index.d.ts +3 -70
- 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 +11 -5
- package/src/admin/AdminRouter.ts +51 -29
- package/src/admin/components/AdminLayout.tsx +6 -9
- 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 +156 -78
- package/src/admin/components/parameters/ParameterDetails.tsx +173 -108
- package/src/admin/components/parameters/ParameterEmptyState.tsx +27 -0
- package/src/admin/components/parameters/ParameterHistory.tsx +22 -35
- package/src/admin/components/parameters/ParameterTree.tsx +283 -109
- package/src/admin/components/parameters/types.ts +3 -3
- 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/admin/primitives/$uiAdmin.ts +2 -2
- package/src/auth/AuthRouter.ts +1 -0
- 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 +13 -17
- package/src/core/components/buttons/DarkModeButton.tsx +8 -4
- package/src/core/components/buttons/ToggleSidebarButton.tsx +3 -5
- 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 +19 -32
- package/src/core/components/form/ControlArray.tsx +206 -96
- 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.browser.spec.tsx +727 -0
- package/src/core/components/form/TypeForm.tsx +7 -0
- package/src/core/components/layout/AlephaMantineProvider.tsx +1 -0
- package/src/core/components/layout/Breadcrumb.tsx +91 -0
- package/src/core/components/layout/{AdminShell.tsx → DashboardShell.tsx} +77 -32
- package/src/core/components/layout/Omnibar.tsx +2 -1
- package/src/core/components/layout/Sidebar.tsx +63 -19
- 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/constants/ui.ts +1 -1
- package/src/core/helpers/renderIcon.tsx +5 -2
- package/src/core/index.ts +9 -5
- package/src/core/styles.css +8 -7
- package/src/core/utils/parseInput.ts +1 -0
- package/src/core/utils/string.ts +28 -4
- package/src/demo/components/DemoHome.tsx +5 -5
- package/src/demo/components/DemoLayout.tsx +6 -2
- 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-DsmGnHNh.js +0 -3
- package/dist/admin/AdminApiKeys-GMORg-1l.js.map +0 -1
- package/dist/admin/AdminAudits-8SM96viT.js +0 -3
- package/dist/admin/AdminAudits-pkWrjq1Z.js.map +0 -1
- package/dist/admin/AdminFiles-B56ocq4H.js +0 -3
- package/dist/admin/AdminJobs-B-q9iGO3.js +0 -697
- package/dist/admin/AdminJobs-B-q9iGO3.js.map +0 -1
- package/dist/admin/AdminJobs-CED1syCn.js +0 -3
- package/dist/admin/AdminLayout-BqZiXx4H.js.map +0 -1
- package/dist/admin/AdminNotifications-B0B1rdc4.js +0 -3
- package/dist/admin/AdminParameters-BU3lATdJ.js +0 -3
- package/dist/admin/AdminParameters-CfDUpc78.js +0 -575
- package/dist/admin/AdminParameters-CfDUpc78.js.map +0 -1
- package/dist/admin/AdminSessions-BDGK2MS6.js +0 -3
- package/dist/admin/AdminSessions-DzIOxM3b.js.map +0 -1
- package/dist/admin/AdminUserAudits-CiUPN2BC.js.map +0 -1
- package/dist/admin/AdminUserAudits-Cj79gENT.js +0 -3
- package/dist/admin/AdminUserCreate-BwQKr4xE.js.map +0 -1
- package/dist/admin/AdminUserCreate-Cq-mUmBs.js +0 -3
- package/dist/admin/AdminUserDetails-DRjVAPFd.js +0 -3
- package/dist/admin/AdminUserDetails-uqtC5aJ1.js.map +0 -1
- package/dist/admin/AdminUserLayout-CGzmHHby.js +0 -3
- package/dist/admin/AdminUserLayout-CiPay35T.js.map +0 -1
- package/dist/admin/AdminUserSessions-DAE8Nf1F.js.map +0 -1
- package/dist/admin/AdminUserSessions-DcdzuNZ9.js +0 -3
- package/dist/admin/AdminUserSettings-D7V6-ceX.js +0 -3
- package/dist/admin/AdminUserSettings-EbahaV2a.js.map +0 -1
- package/dist/admin/AdminUsers-D9nyzGqQ.js +0 -3
- package/dist/admin/AdminUsers-Dcjh0KNW.js.map +0 -1
- package/dist/auth/Login-BBqTosqZ.js.map +0 -1
- package/dist/auth/Login-CoU63mMR.js +0 -4
- package/dist/auth/Profile-Bxj8Nwom.js.map +0 -1
- package/dist/auth/Register-BV_oa_AK.js +0 -4
- package/dist/auth/Register-Ce675Crg.js.map +0 -1
- package/dist/auth/ResetPassword-D5wC8GAA.js +0 -3
- package/dist/auth/ResetPassword-DWdt7c40.js.map +0 -1
- package/dist/auth/VerifyEmail-CI4JwByV.js.map +0 -1
- package/dist/auth/VerifyEmail-DAfqVm5s.js +0 -3
- package/dist/demo/DemoDataTable-CguplbR7.js +0 -150
- package/dist/demo/DemoDataTable-CguplbR7.js.map +0 -1
- package/dist/demo/DemoHome-Cce2bWmg.js.map +0 -1
- package/dist/demo/DemoHome-DC9qkMNe.js +0 -3
- package/dist/demo/DemoJsonViewer-DIssGVlJ.js +0 -4
- package/dist/demo/DemoJsonViewer-Dgdk3Txb.js.map +0 -1
- package/dist/demo/DemoLayout-B20TEuhV.js.map +0 -1
- package/dist/demo/DemoLayout-DSRyf4qJ.js +0 -3
- package/dist/demo/DemoLogin-CvCG2WVh.js.map +0 -1
- package/dist/demo/DemoRegister-CmeHbOAs.js.map +0 -1
- package/dist/demo/DemoResetPassword-CKO5iA_6.js.map +0 -1
- package/dist/demo/DemoSidebar-MVmQKfMt.js.map +0 -1
- package/dist/demo/DemoTypeForm-w-qtfRlC.js.map +0 -1
- package/dist/demo/DemoVerifyEmail-C8FFJT5A.js.map +0 -1
- package/dist/demo/Showcase-CQrMWars.js.map +0 -1
- package/src/admin/components/jobs/AdminJobs.tsx +0 -772
package/dist/core/index.js
CHANGED
|
@@ -3,18 +3,19 @@ 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";
|
|
9
|
-
import { Children, createElement, isValidElement, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
10
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
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
|
+
import { Children, Fragment, createElement, isValidElement, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
10
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
11
11
|
import { Notifications, notifications } from "@mantine/notifications";
|
|
12
|
-
import { $page, Link, NestedView, useActive, useRouter } from "alepha/react/router";
|
|
12
|
+
import { $page, Link, NestedView, useActive, useRouter, useRouterState } from "alepha/react/router";
|
|
13
13
|
import { NavigationProgress, nprogress } from "@mantine/nprogress";
|
|
14
|
-
import { ClientOnly, useAction, useEvents, useInject, useStore } from "alepha/react";
|
|
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)" },
|
|
@@ -357,28 +358,26 @@ const ErrorViewer = ({ error, showStack = true, copyable = true, size = "sm" })
|
|
|
357
358
|
})]
|
|
358
359
|
});
|
|
359
360
|
};
|
|
360
|
-
var ErrorViewer_default = ErrorViewer;
|
|
361
361
|
|
|
362
362
|
//#endregion
|
|
363
363
|
//#region ../../src/core/components/dialogs/AlertDialog.tsx
|
|
364
|
-
const AlertDialog = ({ options, onClose }) => /* @__PURE__ */ jsxs(Fragment, { children: [options?.message && /* @__PURE__ */ jsx(Text$1, {
|
|
364
|
+
const AlertDialog = ({ options, onClose }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [options?.message && /* @__PURE__ */ jsx(Text$1, {
|
|
365
365
|
mb: "md",
|
|
366
366
|
children: options.message
|
|
367
|
-
}), /* @__PURE__ */ jsx(
|
|
367
|
+
}), /* @__PURE__ */ jsx(Flex$1, {
|
|
368
368
|
justify: "flex-end",
|
|
369
369
|
children: /* @__PURE__ */ jsx(Button, {
|
|
370
370
|
onClick: onClose,
|
|
371
371
|
children: options?.okLabel || "OK"
|
|
372
372
|
})
|
|
373
373
|
})] });
|
|
374
|
-
var AlertDialog_default = AlertDialog;
|
|
375
374
|
|
|
376
375
|
//#endregion
|
|
377
376
|
//#region ../../src/core/components/dialogs/ConfirmDialog.tsx
|
|
378
|
-
const ConfirmDialog = ({ options, onConfirm }) => /* @__PURE__ */ jsxs(Fragment, { children: [options?.message && /* @__PURE__ */ jsx(Text$1, {
|
|
377
|
+
const ConfirmDialog = ({ options, onConfirm }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [options?.message && /* @__PURE__ */ jsx(Text$1, {
|
|
379
378
|
mb: "md",
|
|
380
379
|
children: options.message
|
|
381
|
-
}), /* @__PURE__ */ jsxs(
|
|
380
|
+
}), /* @__PURE__ */ jsxs(Flex$1, {
|
|
382
381
|
justify: "flex-end",
|
|
383
382
|
children: [/* @__PURE__ */ jsx(Button, {
|
|
384
383
|
variant: "subtle",
|
|
@@ -390,7 +389,6 @@ const ConfirmDialog = ({ options, onConfirm }) => /* @__PURE__ */ jsxs(Fragment,
|
|
|
390
389
|
children: options?.confirmLabel || "Confirm"
|
|
391
390
|
})]
|
|
392
391
|
})] });
|
|
393
|
-
var ConfirmDialog_default = ConfirmDialog;
|
|
394
392
|
|
|
395
393
|
//#endregion
|
|
396
394
|
//#region ../../src/core/components/dialogs/PromptDialog.tsx
|
|
@@ -406,7 +404,7 @@ const PromptDialog = ({ options, onSubmit }) => {
|
|
|
406
404
|
const handleKeyDown = (event) => {
|
|
407
405
|
if (event.key === "Enter") handleSubmit();
|
|
408
406
|
};
|
|
409
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
407
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
410
408
|
options?.message && /* @__PURE__ */ jsx(Text$1, {
|
|
411
409
|
mb: "md",
|
|
412
410
|
children: options.message
|
|
@@ -421,7 +419,7 @@ const PromptDialog = ({ options, onSubmit }) => {
|
|
|
421
419
|
required: options?.required,
|
|
422
420
|
mb: "md"
|
|
423
421
|
}),
|
|
424
|
-
/* @__PURE__ */ jsxs(
|
|
422
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
425
423
|
justify: "flex-end",
|
|
426
424
|
children: [/* @__PURE__ */ jsx(Button, {
|
|
427
425
|
variant: "subtle",
|
|
@@ -435,7 +433,6 @@ const PromptDialog = ({ options, onSubmit }) => {
|
|
|
435
433
|
})
|
|
436
434
|
] });
|
|
437
435
|
};
|
|
438
|
-
var PromptDialog_default = PromptDialog;
|
|
439
436
|
|
|
440
437
|
//#endregion
|
|
441
438
|
//#region ../../src/core/constants/ui.ts
|
|
@@ -448,7 +445,7 @@ const ui = {
|
|
|
448
445
|
border: "var(--alepha-border)"
|
|
449
446
|
},
|
|
450
447
|
sizes: { icon: {
|
|
451
|
-
xs:
|
|
448
|
+
xs: 14,
|
|
452
449
|
sm: 16,
|
|
453
450
|
md: 20,
|
|
454
451
|
lg: 24,
|
|
@@ -480,7 +477,7 @@ var DialogService = class {
|
|
|
480
477
|
const modalId = this.open({
|
|
481
478
|
...options,
|
|
482
479
|
title: options?.title || "Alert",
|
|
483
|
-
content: /* @__PURE__ */ jsx(
|
|
480
|
+
content: /* @__PURE__ */ jsx(AlertDialog, {
|
|
484
481
|
options,
|
|
485
482
|
onClose: () => {
|
|
486
483
|
this.close(modalId);
|
|
@@ -500,7 +497,7 @@ var DialogService = class {
|
|
|
500
497
|
title: options?.title || "Confirm",
|
|
501
498
|
closeOnClickOutside: false,
|
|
502
499
|
closeOnEscape: false,
|
|
503
|
-
content: /* @__PURE__ */ jsx(
|
|
500
|
+
content: /* @__PURE__ */ jsx(ConfirmDialog, {
|
|
504
501
|
options,
|
|
505
502
|
onConfirm: (confirmed) => {
|
|
506
503
|
this.close(modalId);
|
|
@@ -520,7 +517,7 @@ var DialogService = class {
|
|
|
520
517
|
title: options?.title || "Input",
|
|
521
518
|
closeOnClickOutside: false,
|
|
522
519
|
closeOnEscape: false,
|
|
523
|
-
content: /* @__PURE__ */ jsx(
|
|
520
|
+
content: /* @__PURE__ */ jsx(PromptDialog, {
|
|
524
521
|
options,
|
|
525
522
|
onSubmit: (value) => {
|
|
526
523
|
this.close(modalId);
|
|
@@ -561,7 +558,7 @@ var DialogService = class {
|
|
|
561
558
|
flex: 1,
|
|
562
559
|
p: "sm",
|
|
563
560
|
bg: ui.colors.surface,
|
|
564
|
-
children: /* @__PURE__ */ jsx(
|
|
561
|
+
children: /* @__PURE__ */ jsx(ErrorViewer, {
|
|
565
562
|
size: "xs",
|
|
566
563
|
error,
|
|
567
564
|
showStack: options?.showStack ?? true
|
|
@@ -690,10 +687,10 @@ function isComponentType(param) {
|
|
|
690
687
|
|
|
691
688
|
//#endregion
|
|
692
689
|
//#region ../../src/core/helpers/renderIcon.tsx
|
|
693
|
-
const renderIcon = (icon) => {
|
|
690
|
+
const renderIcon = (icon, size) => {
|
|
694
691
|
if (!icon) return null;
|
|
695
692
|
if (isValidElement(icon)) return icon;
|
|
696
|
-
if (isComponentType(icon)) return /* @__PURE__ */ jsx(icon, { size: ui$1.sizes.icon.md });
|
|
693
|
+
if (isComponentType(icon)) return /* @__PURE__ */ jsx(icon, { size: size ?? ui$1.sizes.icon.md });
|
|
697
694
|
return icon;
|
|
698
695
|
};
|
|
699
696
|
|
|
@@ -704,7 +701,7 @@ const Omnibar = (props) => {
|
|
|
704
701
|
const searchPlaceholder = props.searchPlaceholder ?? "Search...";
|
|
705
702
|
const nothingFound = props.nothingFound ?? "Nothing found...";
|
|
706
703
|
const router = useRouter();
|
|
707
|
-
const [user] = useStore(
|
|
704
|
+
const [user] = useStore(currentUserAtom);
|
|
708
705
|
return /* @__PURE__ */ jsx(Spotlight, {
|
|
709
706
|
actions: useMemo(() => router.concretePages.filter((page) => {
|
|
710
707
|
if (page.can && !page.can()) return false;
|
|
@@ -728,7 +725,6 @@ const Omnibar = (props) => {
|
|
|
728
725
|
nothingFound
|
|
729
726
|
});
|
|
730
727
|
};
|
|
731
|
-
var Omnibar_default = Omnibar;
|
|
732
728
|
|
|
733
729
|
//#endregion
|
|
734
730
|
//#region ../../src/core/components/layout/AlephaMantineProvider.tsx
|
|
@@ -751,13 +747,14 @@ const AlephaMantineProvider = (props) => {
|
|
|
751
747
|
}
|
|
752
748
|
}, []);
|
|
753
749
|
const defaultColorScheme = props.mantine?.defaultColorScheme ?? theme.defaultColorScheme;
|
|
754
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ColorSchemeScript, {
|
|
750
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ColorSchemeScript, {
|
|
755
751
|
defaultColorScheme,
|
|
756
752
|
...props.colorSchemeScript
|
|
757
753
|
}), /* @__PURE__ */ jsxs(MantineProvider, {
|
|
758
754
|
...props.mantine,
|
|
759
755
|
defaultColorScheme,
|
|
760
756
|
theme: {
|
|
757
|
+
cursorType: "pointer",
|
|
761
758
|
...theme,
|
|
762
759
|
...props.mantine?.theme
|
|
763
760
|
},
|
|
@@ -766,12 +763,11 @@ const AlephaMantineProvider = (props) => {
|
|
|
766
763
|
/* @__PURE__ */ jsx(NavigationProgress, { ...props.navigationProgress }),
|
|
767
764
|
/* @__PURE__ */ jsxs(ModalsProvider, {
|
|
768
765
|
...props.modals,
|
|
769
|
-
children: [props.omnibar !== false && /* @__PURE__ */ jsx(
|
|
766
|
+
children: [props.omnibar !== false && /* @__PURE__ */ jsx(Omnibar, { ...props.omnibar }), props.children ?? /* @__PURE__ */ jsx(NestedView, {})]
|
|
770
767
|
})
|
|
771
768
|
]
|
|
772
769
|
})] });
|
|
773
770
|
};
|
|
774
|
-
var AlephaMantineProvider_default = AlephaMantineProvider;
|
|
775
771
|
|
|
776
772
|
//#endregion
|
|
777
773
|
//#region ../../src/core/UiRouter.ts
|
|
@@ -784,7 +780,7 @@ var AlephaMantineProvider_default = AlephaMantineProvider;
|
|
|
784
780
|
var UiRouter = class {
|
|
785
781
|
root = $page({
|
|
786
782
|
path: "/",
|
|
787
|
-
component:
|
|
783
|
+
component: AlephaMantineProvider
|
|
788
784
|
});
|
|
789
785
|
};
|
|
790
786
|
|
|
@@ -831,40 +827,25 @@ const ActionButton = (_props) => {
|
|
|
831
827
|
const theme = useMantineTheme();
|
|
832
828
|
const props = { ..._props };
|
|
833
829
|
const { tooltip, menu, icon, ...restProps } = props;
|
|
834
|
-
if (props.variant === "subtle")
|
|
835
|
-
restProps.c ??= "var(--mantine-color-text)";
|
|
836
|
-
restProps.color ??= "gray";
|
|
837
|
-
}
|
|
830
|
+
if (props.variant === "subtle" || props.variant === "outline") restProps.color ??= "gray";
|
|
838
831
|
if (props.intent) {
|
|
839
|
-
if (props.intent === "none")
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
} else if (props.intent === "primary") {
|
|
843
|
-
restProps.c ??= "white";
|
|
844
|
-
restProps.color ??= theme.primaryColor;
|
|
845
|
-
} else if (props.intent === "success") {
|
|
832
|
+
if (props.intent === "none") restProps.color ??= "gray";
|
|
833
|
+
else if (props.intent === "primary") restProps.color ??= theme.primaryColor;
|
|
834
|
+
else if (props.intent === "success") {
|
|
846
835
|
restProps.c ??= "white";
|
|
847
836
|
restProps.color ??= "green";
|
|
848
837
|
} else if (props.intent === "danger") {
|
|
849
838
|
restProps.c ??= "white";
|
|
850
839
|
restProps.color ??= "red";
|
|
851
|
-
} else if (props.intent === "warning")
|
|
852
|
-
|
|
853
|
-
restProps.color ??= "yellow";
|
|
854
|
-
} else if (props.intent === "info") {
|
|
840
|
+
} else if (props.intent === "warning") restProps.color ??= "yellow";
|
|
841
|
+
else if (props.intent === "info") {
|
|
855
842
|
restProps.c ??= "white";
|
|
856
843
|
restProps.color ??= "blue";
|
|
857
844
|
}
|
|
858
845
|
}
|
|
859
846
|
if (props.icon) {
|
|
860
|
-
const
|
|
861
|
-
|
|
862
|
-
variant: "transparent",
|
|
863
|
-
size: "sm",
|
|
864
|
-
c: "var(--mantine-color-text)",
|
|
865
|
-
...props.themeIconProps,
|
|
866
|
-
children: props.icon
|
|
867
|
-
});
|
|
847
|
+
const sizes = ui.sizes.icon;
|
|
848
|
+
const icon = isComponentType(props.icon) ? /* @__PURE__ */ jsx(props.icon, { size: sizes[props.size || "md"] }) : /* @__PURE__ */ jsx("span", { children: props.icon });
|
|
868
849
|
if (!props.children) {
|
|
869
850
|
restProps.children = Children.only(icon);
|
|
870
851
|
restProps.px ??= "xs";
|
|
@@ -873,7 +854,7 @@ const ActionButton = (_props) => {
|
|
|
873
854
|
if (props.leftSection && !props.children) restProps.px ??= "xs";
|
|
874
855
|
if (props.textVisibleFrom) {
|
|
875
856
|
const { children, textVisibleFrom, leftSection, ...rest } = restProps;
|
|
876
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Flex$1, {
|
|
857
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Flex$1, {
|
|
877
858
|
w: "100%",
|
|
878
859
|
visibleFrom: textVisibleFrom,
|
|
879
860
|
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
@@ -967,7 +948,6 @@ const ActionButton = (_props) => {
|
|
|
967
948
|
}
|
|
968
949
|
return actionElement;
|
|
969
950
|
};
|
|
970
|
-
var ActionButton_default = ActionButton;
|
|
971
951
|
/**
|
|
972
952
|
* Action button that submits a form with loading and disabled state handling.
|
|
973
953
|
*/
|
|
@@ -1029,10 +1009,11 @@ const ActionHookButton = (props) => {
|
|
|
1029
1009
|
* </ActionButton>
|
|
1030
1010
|
* ```
|
|
1031
1011
|
*/
|
|
1032
|
-
const ActionClickButton = (props) => {
|
|
1012
|
+
const ActionClickButton = ({ preventDefault, ...props }) => {
|
|
1033
1013
|
const action = useAction({ handler: async (e) => {
|
|
1014
|
+
if (preventDefault) e.preventDefault();
|
|
1034
1015
|
await props.onClick(e);
|
|
1035
|
-
} }, [props.onClick]);
|
|
1016
|
+
} }, [props.onClick, preventDefault]);
|
|
1036
1017
|
return /* @__PURE__ */ jsx(Button, {
|
|
1037
1018
|
...props,
|
|
1038
1019
|
disabled: action.loading || props.disabled,
|
|
@@ -1100,7 +1081,6 @@ const BurgerButton = (props) => {
|
|
|
1100
1081
|
...props
|
|
1101
1082
|
});
|
|
1102
1083
|
};
|
|
1103
|
-
var BurgerButton_default = BurgerButton;
|
|
1104
1084
|
|
|
1105
1085
|
//#endregion
|
|
1106
1086
|
//#region ../../src/core/components/buttons/ClipboardButton.tsx
|
|
@@ -1112,7 +1092,7 @@ const ClipboardButton = (props) => {
|
|
|
1112
1092
|
children: ({ copied, copy }) => /* @__PURE__ */ jsx(Tooltip, {
|
|
1113
1093
|
label: copied ? copiedLabel : copyLabel,
|
|
1114
1094
|
openDelay: 500,
|
|
1115
|
-
children: /* @__PURE__ */ jsx(
|
|
1095
|
+
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
1116
1096
|
color: copied ? "teal" : void 0,
|
|
1117
1097
|
onClick: copy,
|
|
1118
1098
|
icon: copied ? IconCheck : IconCopy,
|
|
@@ -1122,7 +1102,6 @@ const ClipboardButton = (props) => {
|
|
|
1122
1102
|
})
|
|
1123
1103
|
});
|
|
1124
1104
|
};
|
|
1125
|
-
var ClipboardButton_default = ClipboardButton;
|
|
1126
1105
|
|
|
1127
1106
|
//#endregion
|
|
1128
1107
|
//#region ../../src/core/components/buttons/DarkModeButton.tsx
|
|
@@ -1138,23 +1117,29 @@ const DarkModeButton = (props) => {
|
|
|
1138
1117
|
const toggleColorScheme = () => {
|
|
1139
1118
|
setColorScheme((document.documentElement.getAttribute("data-mantine-color-scheme") ?? "light") === "dark" ? "light" : "dark");
|
|
1140
1119
|
};
|
|
1141
|
-
|
|
1120
|
+
const size = props.size ?? "md";
|
|
1121
|
+
const iconSize = ui.sizes.icon[size] ?? ui.sizes.icon.md;
|
|
1122
|
+
return /* @__PURE__ */ jsx(ActionButton, {
|
|
1142
1123
|
onClick: toggleColorScheme,
|
|
1143
1124
|
variant: props.variant ?? "subtle",
|
|
1144
|
-
size
|
|
1125
|
+
size,
|
|
1145
1126
|
"aria-label": "Toggle color scheme",
|
|
1146
|
-
|
|
1147
|
-
|
|
1127
|
+
icon: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(IconSun, {
|
|
1128
|
+
size: iconSize,
|
|
1129
|
+
className: "alepha-light-hidden"
|
|
1130
|
+
}), /* @__PURE__ */ jsx(IconMoon, {
|
|
1131
|
+
size: iconSize,
|
|
1132
|
+
className: "alepha-dark-hidden"
|
|
1133
|
+
})] }),
|
|
1148
1134
|
...props
|
|
1149
1135
|
});
|
|
1150
1136
|
};
|
|
1151
|
-
var DarkModeButton_default = DarkModeButton;
|
|
1152
1137
|
|
|
1153
1138
|
//#endregion
|
|
1154
1139
|
//#region ../../src/core/components/buttons/LanguageButton.tsx
|
|
1155
1140
|
const LanguageButton = (props) => {
|
|
1156
1141
|
const i18n = useI18n();
|
|
1157
|
-
return /* @__PURE__ */ jsx(
|
|
1142
|
+
return /* @__PURE__ */ jsx(ActionButton, {
|
|
1158
1143
|
variant: "default",
|
|
1159
1144
|
icon: IconLanguage,
|
|
1160
1145
|
menu: { items: i18n.languages.map((lang) => ({
|
|
@@ -1165,14 +1150,13 @@ const LanguageButton = (props) => {
|
|
|
1165
1150
|
...props
|
|
1166
1151
|
});
|
|
1167
1152
|
};
|
|
1168
|
-
var LanguageButton_default = LanguageButton;
|
|
1169
1153
|
|
|
1170
1154
|
//#endregion
|
|
1171
1155
|
//#region ../../src/core/components/buttons/OmnibarButton.tsx
|
|
1172
1156
|
const OmnibarButton = (props) => {
|
|
1173
1157
|
const os = useOs();
|
|
1174
1158
|
const shortcut = os === "macos" || os === "ios" ? "⌘" : "Ctrl";
|
|
1175
|
-
if (props.collapsed) return /* @__PURE__ */ jsx(
|
|
1159
|
+
if (props.collapsed) return /* @__PURE__ */ jsx(ActionButton, {
|
|
1176
1160
|
variant: "subtle",
|
|
1177
1161
|
onClick: spotlight.open,
|
|
1178
1162
|
radius: "md",
|
|
@@ -1183,7 +1167,7 @@ const OmnibarButton = (props) => {
|
|
|
1183
1167
|
},
|
|
1184
1168
|
...props.actionProps
|
|
1185
1169
|
});
|
|
1186
|
-
return /* @__PURE__ */ jsx(
|
|
1170
|
+
return /* @__PURE__ */ jsx(ActionButton, {
|
|
1187
1171
|
variant: "default",
|
|
1188
1172
|
onClick: spotlight.open,
|
|
1189
1173
|
justify: "space-between",
|
|
@@ -1212,14 +1196,13 @@ const OmnibarButton = (props) => {
|
|
|
1212
1196
|
})
|
|
1213
1197
|
});
|
|
1214
1198
|
};
|
|
1215
|
-
var OmnibarButton_default = OmnibarButton;
|
|
1216
1199
|
|
|
1217
1200
|
//#endregion
|
|
1218
1201
|
//#region ../../src/core/components/buttons/ThemeButton.tsx
|
|
1219
1202
|
const ThemeButton = (props) => {
|
|
1220
1203
|
const [theme, setTheme] = useTheme();
|
|
1221
1204
|
const themeList = useStore(alephaThemeListAtom)[0];
|
|
1222
|
-
return /* @__PURE__ */ jsx(
|
|
1205
|
+
return /* @__PURE__ */ jsx(ActionButton, {
|
|
1223
1206
|
variant: "subtle",
|
|
1224
1207
|
icon: IconPalette,
|
|
1225
1208
|
menu: { items: themeList.map((it, index) => ({
|
|
@@ -1230,14 +1213,13 @@ const ThemeButton = (props) => {
|
|
|
1230
1213
|
...props
|
|
1231
1214
|
});
|
|
1232
1215
|
};
|
|
1233
|
-
var ThemeButton_default = ThemeButton;
|
|
1234
1216
|
|
|
1235
1217
|
//#endregion
|
|
1236
1218
|
//#region ../../src/core/components/buttons/ToggleSidebarButton.tsx
|
|
1237
1219
|
const ToggleSidebarButton = (props) => {
|
|
1238
1220
|
const [sidebar, setSidebar] = useStore(alephaSidebarAtom);
|
|
1239
|
-
return /* @__PURE__ */ jsx(
|
|
1240
|
-
icon: sidebar.collapsed ?
|
|
1221
|
+
return /* @__PURE__ */ jsx(ActionButton, {
|
|
1222
|
+
icon: sidebar.collapsed ? IconLayoutSidebarRightCollapse : IconLayoutSidebarLeftCollapse,
|
|
1241
1223
|
visibleFrom: "sm",
|
|
1242
1224
|
variant: "subtle",
|
|
1243
1225
|
size: "md",
|
|
@@ -1256,7 +1238,6 @@ const ToggleSidebarButton = (props) => {
|
|
|
1256
1238
|
...props
|
|
1257
1239
|
});
|
|
1258
1240
|
};
|
|
1259
|
-
var ToggleSidebarButton_default = ToggleSidebarButton;
|
|
1260
1241
|
|
|
1261
1242
|
//#endregion
|
|
1262
1243
|
//#region ../../src/core/utils/icons.tsx
|
|
@@ -1312,15 +1293,30 @@ const capitalize = (str) => {
|
|
|
1312
1293
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
1313
1294
|
};
|
|
1314
1295
|
/**
|
|
1296
|
+
* Converts camelCase or snake_case to Title Case with spaces.
|
|
1297
|
+
*
|
|
1298
|
+
* @example
|
|
1299
|
+
* toTitleCase("userName") // "User Name"
|
|
1300
|
+
* toTitleCase("first_name") // "First Name"
|
|
1301
|
+
* toTitleCase("email") // "Email"
|
|
1302
|
+
*/
|
|
1303
|
+
const toTitleCase = (str) => {
|
|
1304
|
+
return str.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
1305
|
+
};
|
|
1306
|
+
/**
|
|
1315
1307
|
* Converts a path or identifier string into a pretty display name.
|
|
1316
|
-
*
|
|
1308
|
+
* For paths like "/contacts/0/name", extracts just the field name "Name".
|
|
1309
|
+
* Handles camelCase and snake_case conversion to Title Case.
|
|
1317
1310
|
*
|
|
1318
1311
|
* @example
|
|
1319
|
-
* prettyName("/userName") // "
|
|
1320
|
-
* prettyName("email") // "Email"
|
|
1312
|
+
* prettyName("/userName") // "User Name"
|
|
1313
|
+
* prettyName("/contacts/0/email") // "Email"
|
|
1314
|
+
* prettyName("/address/streetName") // "Street Name"
|
|
1315
|
+
* prettyName("first_name") // "First Name"
|
|
1321
1316
|
*/
|
|
1322
1317
|
const prettyName = (name) => {
|
|
1323
|
-
|
|
1318
|
+
const segments = name.split("/").filter((s) => s && !/^\d+$/.test(s));
|
|
1319
|
+
return toTitleCase(segments[segments.length - 1] || name.replaceAll("/", ""));
|
|
1324
1320
|
};
|
|
1325
1321
|
|
|
1326
1322
|
//#endregion
|
|
@@ -1364,6 +1360,107 @@ const parseInput = (props, form) => {
|
|
|
1364
1360
|
//#endregion
|
|
1365
1361
|
//#region ../../src/core/components/form/ControlArray.tsx
|
|
1366
1362
|
/**
|
|
1363
|
+
* Custom hook to sync array items with form state.
|
|
1364
|
+
* Uses form events as the source of truth, eliminating dual-state issues.
|
|
1365
|
+
*/
|
|
1366
|
+
const useArrayItems = (input) => {
|
|
1367
|
+
const alepha = useAlepha();
|
|
1368
|
+
const keyCounter = useRef(0);
|
|
1369
|
+
const [items, setItemsState] = useState(() => {
|
|
1370
|
+
const defaultValue = input?.props?.defaultValue;
|
|
1371
|
+
if (Array.isArray(defaultValue)) return defaultValue.map((value) => ({
|
|
1372
|
+
key: keyCounter.current++,
|
|
1373
|
+
value
|
|
1374
|
+
}));
|
|
1375
|
+
return [];
|
|
1376
|
+
});
|
|
1377
|
+
const syncFromFormValue = useCallback((formValue) => {
|
|
1378
|
+
if (!Array.isArray(formValue)) {
|
|
1379
|
+
setItemsState([]);
|
|
1380
|
+
return;
|
|
1381
|
+
}
|
|
1382
|
+
setItemsState((prevItems) => {
|
|
1383
|
+
if (prevItems.length === formValue.length) {
|
|
1384
|
+
if (prevItems.every((item, i) => item.value === formValue[i])) return prevItems;
|
|
1385
|
+
}
|
|
1386
|
+
keyCounter.current = 0;
|
|
1387
|
+
return formValue.map((value) => ({
|
|
1388
|
+
key: keyCounter.current++,
|
|
1389
|
+
value
|
|
1390
|
+
}));
|
|
1391
|
+
});
|
|
1392
|
+
}, []);
|
|
1393
|
+
useEffect(() => {
|
|
1394
|
+
if (!input?.form) return;
|
|
1395
|
+
const formId = input.form.id;
|
|
1396
|
+
const fieldPath = input.path;
|
|
1397
|
+
const listeners = [alepha.events.on("form:reset", (event) => {
|
|
1398
|
+
if (event.id === formId) {
|
|
1399
|
+
const defaultValue = input.props?.defaultValue;
|
|
1400
|
+
keyCounter.current = 0;
|
|
1401
|
+
if (Array.isArray(defaultValue)) setItemsState(defaultValue.map((value) => ({
|
|
1402
|
+
key: keyCounter.current++,
|
|
1403
|
+
value
|
|
1404
|
+
})));
|
|
1405
|
+
else setItemsState([]);
|
|
1406
|
+
}
|
|
1407
|
+
}), alepha.events.on("form:change", (event) => {
|
|
1408
|
+
if (event.id === formId && event.path === fieldPath) syncFromFormValue(event.value);
|
|
1409
|
+
})];
|
|
1410
|
+
return () => {
|
|
1411
|
+
for (const unsub of listeners) unsub();
|
|
1412
|
+
};
|
|
1413
|
+
}, [
|
|
1414
|
+
alepha,
|
|
1415
|
+
input,
|
|
1416
|
+
syncFromFormValue
|
|
1417
|
+
]);
|
|
1418
|
+
return {
|
|
1419
|
+
items,
|
|
1420
|
+
setItems: useCallback((newItems) => {
|
|
1421
|
+
setItemsState(newItems);
|
|
1422
|
+
input?.set(newItems.map((item) => item.value));
|
|
1423
|
+
}, [input]),
|
|
1424
|
+
nextKey: useCallback(() => keyCounter.current++, [])
|
|
1425
|
+
};
|
|
1426
|
+
};
|
|
1427
|
+
/**
|
|
1428
|
+
* Creates a proper InputField for an array item that integrates with the form system.
|
|
1429
|
+
* Uses array index for test IDs to ensure predictable, testable element identifiers.
|
|
1430
|
+
*/
|
|
1431
|
+
const createArrayItemInput = (parentInput, itemSchema, index, _itemKey, value, onValueChange) => {
|
|
1432
|
+
return {
|
|
1433
|
+
schema: itemSchema,
|
|
1434
|
+
path: `${parentInput.path}/${index}`,
|
|
1435
|
+
required: false,
|
|
1436
|
+
form: parentInput.form,
|
|
1437
|
+
props: {
|
|
1438
|
+
id: `${parentInput.props.id}-${index}`,
|
|
1439
|
+
name: `${parentInput.props.name}[${index}]`,
|
|
1440
|
+
defaultValue: value
|
|
1441
|
+
},
|
|
1442
|
+
set: onValueChange
|
|
1443
|
+
};
|
|
1444
|
+
};
|
|
1445
|
+
/**
|
|
1446
|
+
* Creates a proper InputField for a nested object field within an array item.
|
|
1447
|
+
* Uses array index for test IDs to ensure predictable, testable element identifiers.
|
|
1448
|
+
*/
|
|
1449
|
+
const createArrayItemFieldInput = (parentInput, itemSchema, fieldName, index, _itemKey, itemValue, onFieldChange) => {
|
|
1450
|
+
return {
|
|
1451
|
+
schema: itemSchema.properties[fieldName],
|
|
1452
|
+
path: `${parentInput.path}/${index}/${fieldName}`,
|
|
1453
|
+
required: itemSchema.required?.includes(fieldName) ?? false,
|
|
1454
|
+
form: parentInput.form,
|
|
1455
|
+
props: {
|
|
1456
|
+
id: `${parentInput.props.id}-${index}-${fieldName}`,
|
|
1457
|
+
name: `${parentInput.props.name}[${index}].${fieldName}`,
|
|
1458
|
+
defaultValue: itemValue?.[fieldName]
|
|
1459
|
+
},
|
|
1460
|
+
set: (value) => onFieldChange(fieldName, value)
|
|
1461
|
+
};
|
|
1462
|
+
};
|
|
1463
|
+
/**
|
|
1367
1464
|
* ControlArray component for editing arrays of schema items.
|
|
1368
1465
|
*
|
|
1369
1466
|
* Features:
|
|
@@ -1372,6 +1469,7 @@ const parseInput = (props, form) => {
|
|
|
1372
1469
|
* - Supports arrays of primitives
|
|
1373
1470
|
* - Grid layout for object items
|
|
1374
1471
|
* - Min/max constraints
|
|
1472
|
+
* - Syncs with form state (handles external updates and resets)
|
|
1375
1473
|
*
|
|
1376
1474
|
* @example
|
|
1377
1475
|
* ```tsx
|
|
@@ -1395,36 +1493,13 @@ const parseInput = (props, form) => {
|
|
|
1395
1493
|
*/
|
|
1396
1494
|
const ControlArray = (props) => {
|
|
1397
1495
|
const { inputProps } = parseInput(props, {});
|
|
1398
|
-
const
|
|
1399
|
-
const [items, setItems] = useState(() => {
|
|
1400
|
-
const defaultValue = props.input?.props?.defaultValue;
|
|
1401
|
-
if (Array.isArray(defaultValue)) return defaultValue.map((value) => ({
|
|
1402
|
-
key: idCounter.current++,
|
|
1403
|
-
value
|
|
1404
|
-
}));
|
|
1405
|
-
return [];
|
|
1406
|
-
});
|
|
1407
|
-
useEvents({ "form:reset": (event) => {
|
|
1408
|
-
if (event.id === props.input?.form?.id) {
|
|
1409
|
-
const defaultValue = props.input?.props?.defaultValue;
|
|
1410
|
-
if (Array.isArray(defaultValue)) {
|
|
1411
|
-
idCounter.current = 0;
|
|
1412
|
-
setItems(defaultValue.map((value) => ({
|
|
1413
|
-
key: idCounter.current++,
|
|
1414
|
-
value
|
|
1415
|
-
})));
|
|
1416
|
-
} else setItems([]);
|
|
1417
|
-
}
|
|
1418
|
-
} }, [props.input]);
|
|
1496
|
+
const { items, setItems, nextKey } = useArrayItems(props.input);
|
|
1419
1497
|
if (!props.input?.props) return null;
|
|
1420
1498
|
const schema = props.input.schema;
|
|
1421
1499
|
if (!schema || !("items" in schema)) return null;
|
|
1422
1500
|
const itemSchema = schema.items;
|
|
1423
1501
|
const isObjectItem = itemSchema && "properties" in itemSchema;
|
|
1424
1502
|
const { min = 0, max = Number.POSITIVE_INFINITY, columns = 1 } = props;
|
|
1425
|
-
const updateFormValue = (newItems) => {
|
|
1426
|
-
props.input.set(newItems.map((item) => item.value));
|
|
1427
|
-
};
|
|
1428
1503
|
const handleAdd = () => {
|
|
1429
1504
|
if (items.length >= max) return;
|
|
1430
1505
|
let newValue;
|
|
@@ -1433,18 +1508,14 @@ const ControlArray = (props) => {
|
|
|
1433
1508
|
const objSchema = itemSchema;
|
|
1434
1509
|
for (const [key, propSchema] of Object.entries(objSchema.properties)) if ("default" in propSchema) newValue[key] = propSchema.default;
|
|
1435
1510
|
} else newValue = "";
|
|
1436
|
-
|
|
1437
|
-
key:
|
|
1511
|
+
setItems([...items, {
|
|
1512
|
+
key: nextKey(),
|
|
1438
1513
|
value: newValue
|
|
1439
|
-
}];
|
|
1440
|
-
setItems(newItems);
|
|
1441
|
-
updateFormValue(newItems);
|
|
1514
|
+
}]);
|
|
1442
1515
|
};
|
|
1443
1516
|
const handleRemove = (index) => {
|
|
1444
1517
|
if (items.length <= min) return;
|
|
1445
|
-
|
|
1446
|
-
setItems(newItems);
|
|
1447
|
-
updateFormValue(newItems);
|
|
1518
|
+
setItems(items.filter((_, i) => i !== index));
|
|
1448
1519
|
};
|
|
1449
1520
|
const handleItemChange = (index, value) => {
|
|
1450
1521
|
const newItems = [...items];
|
|
@@ -1453,7 +1524,6 @@ const ControlArray = (props) => {
|
|
|
1453
1524
|
value
|
|
1454
1525
|
};
|
|
1455
1526
|
setItems(newItems);
|
|
1456
|
-
updateFormValue(newItems);
|
|
1457
1527
|
};
|
|
1458
1528
|
const handleFieldChange = (index, field, value) => {
|
|
1459
1529
|
const newItems = [...items];
|
|
@@ -1465,11 +1535,12 @@ const ControlArray = (props) => {
|
|
|
1465
1535
|
}
|
|
1466
1536
|
};
|
|
1467
1537
|
setItems(newItems);
|
|
1468
|
-
updateFormValue(newItems);
|
|
1469
1538
|
};
|
|
1470
1539
|
const colSpan = 12 / columns;
|
|
1471
|
-
const
|
|
1472
|
-
const
|
|
1540
|
+
const objectItemSchema = isObjectItem ? itemSchema : null;
|
|
1541
|
+
const fieldNames = objectItemSchema ? Object.keys(objectItemSchema.properties) : [];
|
|
1542
|
+
const renderItems = () => /* @__PURE__ */ jsxs(Flex$1, {
|
|
1543
|
+
direction: "column",
|
|
1473
1544
|
gap: "sm",
|
|
1474
1545
|
children: [items.map((item, index) => /* @__PURE__ */ jsxs(Flex$1, {
|
|
1475
1546
|
gap: "sm",
|
|
@@ -1484,47 +1555,24 @@ const ControlArray = (props) => {
|
|
|
1484
1555
|
style: { cursor: "grab" },
|
|
1485
1556
|
children: /* @__PURE__ */ jsx(IconGripVertical, { size: 16 })
|
|
1486
1557
|
}),
|
|
1487
|
-
|
|
1558
|
+
objectItemSchema ? /* @__PURE__ */ jsx(Grid, {
|
|
1488
1559
|
style: { flex: 1 },
|
|
1489
1560
|
gutter: "sm",
|
|
1490
1561
|
children: fieldNames.map((fieldName) => {
|
|
1491
|
-
const fieldSchema = itemSchema.properties[fieldName];
|
|
1492
1562
|
const fieldControlProps = props.controlProps?.[fieldName] ?? {};
|
|
1493
|
-
const
|
|
1494
|
-
schema: fieldSchema,
|
|
1495
|
-
props: {
|
|
1496
|
-
id: `${props.input.props.id}-${item.key}-${fieldName}`,
|
|
1497
|
-
name: `${props.input.props.name}[${index}].${fieldName}`,
|
|
1498
|
-
defaultValue: item.value?.[fieldName]
|
|
1499
|
-
},
|
|
1500
|
-
path: `${props.input.path}/${index}/${fieldName}`,
|
|
1501
|
-
required: itemSchema.required?.includes(fieldName) ?? false,
|
|
1502
|
-
form: props.input.form,
|
|
1503
|
-
set: (value) => handleFieldChange(index, fieldName, value)
|
|
1504
|
-
};
|
|
1563
|
+
const fieldInput = createArrayItemFieldInput(props.input, objectItemSchema, fieldName, index, item.key, item.value, (field, value) => handleFieldChange(index, field, value));
|
|
1505
1564
|
return /* @__PURE__ */ jsx(Grid.Col, {
|
|
1506
1565
|
span: colSpan,
|
|
1507
|
-
children: /* @__PURE__ */ jsx(
|
|
1508
|
-
input:
|
|
1566
|
+
children: /* @__PURE__ */ jsx(Control, {
|
|
1567
|
+
input: fieldInput,
|
|
1509
1568
|
...fieldControlProps
|
|
1510
1569
|
})
|
|
1511
1570
|
}, fieldName);
|
|
1512
1571
|
})
|
|
1513
1572
|
}) : /* @__PURE__ */ jsx(Flex$1, {
|
|
1514
1573
|
style: { flex: 1 },
|
|
1515
|
-
children: /* @__PURE__ */ jsx(
|
|
1516
|
-
input:
|
|
1517
|
-
schema: itemSchema,
|
|
1518
|
-
props: {
|
|
1519
|
-
id: `${props.input.props.id}-${item.key}`,
|
|
1520
|
-
name: `${props.input.props.name}[${index}]`,
|
|
1521
|
-
defaultValue: item.value
|
|
1522
|
-
},
|
|
1523
|
-
path: `${props.input.path}/${index}`,
|
|
1524
|
-
required: false,
|
|
1525
|
-
form: props.input.form,
|
|
1526
|
-
set: (value) => handleItemChange(index, value)
|
|
1527
|
-
},
|
|
1574
|
+
children: /* @__PURE__ */ jsx(Control, {
|
|
1575
|
+
input: createArrayItemInput(props.input, itemSchema, index, item.key, item.value, (value) => handleItemChange(index, value)),
|
|
1528
1576
|
...props.itemControlProps
|
|
1529
1577
|
})
|
|
1530
1578
|
}),
|
|
@@ -1568,7 +1616,8 @@ const ControlArray = (props) => {
|
|
|
1568
1616
|
children: [/* @__PURE__ */ jsx(IconPlus, { size: 14 }), props.addLabel ?? "Add"]
|
|
1569
1617
|
})]
|
|
1570
1618
|
});
|
|
1571
|
-
if (props.variant === "plain") return /* @__PURE__ */ jsxs(
|
|
1619
|
+
if (props.variant === "plain") return /* @__PURE__ */ jsxs(Flex$1, {
|
|
1620
|
+
direction: "column",
|
|
1572
1621
|
gap: "xs",
|
|
1573
1622
|
children: [
|
|
1574
1623
|
inputProps.label && /* @__PURE__ */ jsx(Text$1, {
|
|
@@ -1591,7 +1640,8 @@ const ControlArray = (props) => {
|
|
|
1591
1640
|
});
|
|
1592
1641
|
return /* @__PURE__ */ jsx(Fieldset, {
|
|
1593
1642
|
legend: inputProps.label,
|
|
1594
|
-
children: /* @__PURE__ */ jsxs(
|
|
1643
|
+
children: /* @__PURE__ */ jsxs(Flex$1, {
|
|
1644
|
+
direction: "column",
|
|
1595
1645
|
gap: "xs",
|
|
1596
1646
|
children: [
|
|
1597
1647
|
inputProps.description && /* @__PURE__ */ jsx(Text$1, {
|
|
@@ -1609,7 +1659,6 @@ const ControlArray = (props) => {
|
|
|
1609
1659
|
})
|
|
1610
1660
|
});
|
|
1611
1661
|
};
|
|
1612
|
-
var ControlArray_default = ControlArray;
|
|
1613
1662
|
|
|
1614
1663
|
//#endregion
|
|
1615
1664
|
//#region ../../src/core/components/form/ControlDate.tsx
|
|
@@ -1667,7 +1716,6 @@ const ControlDate = (props) => {
|
|
|
1667
1716
|
}
|
|
1668
1717
|
return null;
|
|
1669
1718
|
};
|
|
1670
|
-
var ControlDate_default = ControlDate;
|
|
1671
1719
|
|
|
1672
1720
|
//#endregion
|
|
1673
1721
|
//#region ../../src/core/components/form/ControlNumber.tsx
|
|
@@ -1726,7 +1774,6 @@ const ControlNumber = (props) => {
|
|
|
1726
1774
|
}
|
|
1727
1775
|
});
|
|
1728
1776
|
};
|
|
1729
|
-
var ControlNumber_default = ControlNumber;
|
|
1730
1777
|
|
|
1731
1778
|
//#endregion
|
|
1732
1779
|
//#region ../../src/core/components/form/ControlObject.tsx
|
|
@@ -1776,7 +1823,7 @@ const ControlObject = (props) => {
|
|
|
1776
1823
|
if (!field) return null;
|
|
1777
1824
|
return /* @__PURE__ */ jsx(Grid.Col, {
|
|
1778
1825
|
span: colSpan,
|
|
1779
|
-
children: /* @__PURE__ */ jsx(
|
|
1826
|
+
children: /* @__PURE__ */ jsx(Control, {
|
|
1780
1827
|
input: field,
|
|
1781
1828
|
...fieldControlProps
|
|
1782
1829
|
})
|
|
@@ -1785,7 +1832,8 @@ const ControlObject = (props) => {
|
|
|
1785
1832
|
if (props.variant === "plain") return renderFields();
|
|
1786
1833
|
return /* @__PURE__ */ jsx(Fieldset, {
|
|
1787
1834
|
legend: inputProps.label,
|
|
1788
|
-
children: /* @__PURE__ */ jsxs(
|
|
1835
|
+
children: /* @__PURE__ */ jsxs(Flex$1, {
|
|
1836
|
+
direction: "column",
|
|
1789
1837
|
gap: "xs",
|
|
1790
1838
|
children: [
|
|
1791
1839
|
inputProps.description && /* @__PURE__ */ jsx(Text$1, {
|
|
@@ -1803,7 +1851,6 @@ const ControlObject = (props) => {
|
|
|
1803
1851
|
})
|
|
1804
1852
|
});
|
|
1805
1853
|
};
|
|
1806
|
-
var ControlObject_default = ControlObject;
|
|
1807
1854
|
|
|
1808
1855
|
//#endregion
|
|
1809
1856
|
//#region ../../src/core/utils/extractSchemaFields.ts
|
|
@@ -2010,7 +2057,7 @@ const ControlQueryBuilder = ({ schema, value = "", onChange, placeholder = "Ente
|
|
|
2010
2057
|
});
|
|
2011
2058
|
};
|
|
2012
2059
|
function QueryHelp({ fields, onInsert }) {
|
|
2013
|
-
return /* @__PURE__ */ jsxs(
|
|
2060
|
+
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
2014
2061
|
gap: "md",
|
|
2015
2062
|
align: "flex-start",
|
|
2016
2063
|
wrap: "nowrap",
|
|
@@ -2018,22 +2065,25 @@ function QueryHelp({ fields, onInsert }) {
|
|
|
2018
2065
|
p: "sm",
|
|
2019
2066
|
bdrs: "sm",
|
|
2020
2067
|
children: [
|
|
2021
|
-
/* @__PURE__ */ jsxs(
|
|
2068
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
2069
|
+
direction: "column",
|
|
2022
2070
|
gap: "md",
|
|
2023
2071
|
style: { flex: 1 },
|
|
2024
2072
|
children: [
|
|
2025
|
-
/* @__PURE__ */ jsxs(
|
|
2073
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
2074
|
+
direction: "column",
|
|
2026
2075
|
gap: "xs",
|
|
2027
2076
|
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
2028
2077
|
size: "sm",
|
|
2029
2078
|
fw: 600,
|
|
2030
2079
|
children: "Operators"
|
|
2031
|
-
}), /* @__PURE__ */ jsx(
|
|
2080
|
+
}), /* @__PURE__ */ jsx(Flex$1, {
|
|
2081
|
+
direction: "column",
|
|
2032
2082
|
gap: 4,
|
|
2033
|
-
children: Object.entries(OPERATOR_INFO).map(([key, info]) => /* @__PURE__ */ jsxs(
|
|
2083
|
+
children: Object.entries(OPERATOR_INFO).map(([key, info]) => /* @__PURE__ */ jsxs(Flex$1, {
|
|
2034
2084
|
gap: "xs",
|
|
2035
2085
|
wrap: "nowrap",
|
|
2036
|
-
children: [/* @__PURE__ */ jsx(
|
|
2086
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2037
2087
|
px: "xs",
|
|
2038
2088
|
size: "xs",
|
|
2039
2089
|
h: 24,
|
|
@@ -2052,18 +2102,20 @@ function QueryHelp({ fields, onInsert }) {
|
|
|
2052
2102
|
})]
|
|
2053
2103
|
}),
|
|
2054
2104
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
2055
|
-
/* @__PURE__ */ jsxs(
|
|
2105
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
2106
|
+
direction: "column",
|
|
2056
2107
|
gap: "xs",
|
|
2057
2108
|
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
2058
2109
|
size: "sm",
|
|
2059
2110
|
fw: 600,
|
|
2060
2111
|
children: "Logic"
|
|
2061
|
-
}), /* @__PURE__ */ jsxs(
|
|
2112
|
+
}), /* @__PURE__ */ jsxs(Flex$1, {
|
|
2113
|
+
direction: "column",
|
|
2062
2114
|
gap: 4,
|
|
2063
|
-
children: [/* @__PURE__ */ jsxs(
|
|
2115
|
+
children: [/* @__PURE__ */ jsxs(Flex$1, {
|
|
2064
2116
|
gap: "xs",
|
|
2065
2117
|
wrap: "nowrap",
|
|
2066
|
-
children: [/* @__PURE__ */ jsx(
|
|
2118
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2067
2119
|
px: "xs",
|
|
2068
2120
|
size: "xs",
|
|
2069
2121
|
h: 24,
|
|
@@ -2077,10 +2129,10 @@ function QueryHelp({ fields, onInsert }) {
|
|
|
2077
2129
|
c: "dimmed",
|
|
2078
2130
|
children: "AND"
|
|
2079
2131
|
})]
|
|
2080
|
-
}), /* @__PURE__ */ jsxs(
|
|
2132
|
+
}), /* @__PURE__ */ jsxs(Flex$1, {
|
|
2081
2133
|
gap: "xs",
|
|
2082
2134
|
wrap: "nowrap",
|
|
2083
|
-
children: [/* @__PURE__ */ jsx(
|
|
2135
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2084
2136
|
px: "xs",
|
|
2085
2137
|
size: "xs",
|
|
2086
2138
|
h: 24,
|
|
@@ -2120,7 +2172,7 @@ function QueryHelp({ fields, onInsert }) {
|
|
|
2120
2172
|
wrap: "nowrap",
|
|
2121
2173
|
align: "flex-start",
|
|
2122
2174
|
children: [
|
|
2123
|
-
/* @__PURE__ */ jsx(
|
|
2175
|
+
/* @__PURE__ */ jsx(ActionButton, {
|
|
2124
2176
|
px: "xs",
|
|
2125
2177
|
size: "xs",
|
|
2126
2178
|
h: 24,
|
|
@@ -2143,10 +2195,10 @@ function QueryHelp({ fields, onInsert }) {
|
|
|
2143
2195
|
c: "dimmed",
|
|
2144
2196
|
lineClamp: 1,
|
|
2145
2197
|
children: field.description || field.type
|
|
2146
|
-
}), field.enum && /* @__PURE__ */ jsx(
|
|
2198
|
+
}), field.enum && /* @__PURE__ */ jsx(Flex$1, {
|
|
2147
2199
|
gap: 0,
|
|
2148
2200
|
wrap: "wrap",
|
|
2149
|
-
children: field.enum.map((enumValue) => /* @__PURE__ */ jsx(
|
|
2201
|
+
children: field.enum.map((enumValue) => /* @__PURE__ */ jsx(ActionButton, {
|
|
2150
2202
|
px: "xs",
|
|
2151
2203
|
size: "xs",
|
|
2152
2204
|
h: 24,
|
|
@@ -2168,7 +2220,6 @@ function QueryHelp({ fields, onInsert }) {
|
|
|
2168
2220
|
]
|
|
2169
2221
|
});
|
|
2170
2222
|
}
|
|
2171
|
-
var ControlQueryBuilder_default = ControlQueryBuilder;
|
|
2172
2223
|
|
|
2173
2224
|
//#endregion
|
|
2174
2225
|
//#region ../../src/core/components/form/ControlSelect.tsx
|
|
@@ -2220,6 +2271,7 @@ const ControlSelect = (props) => {
|
|
|
2220
2271
|
const autocompleteProps = typeof props.autocomplete === "object" ? props.autocomplete : {};
|
|
2221
2272
|
return /* @__PURE__ */ jsx(Autocomplete, {
|
|
2222
2273
|
...inputProps,
|
|
2274
|
+
size: props.size,
|
|
2223
2275
|
id,
|
|
2224
2276
|
leftSection: icon,
|
|
2225
2277
|
data,
|
|
@@ -2231,6 +2283,7 @@ const ControlSelect = (props) => {
|
|
|
2231
2283
|
const tagsInputProps = typeof props.tags === "object" ? props.tags : {};
|
|
2232
2284
|
return /* @__PURE__ */ jsx(TagsInput, {
|
|
2233
2285
|
...inputProps,
|
|
2286
|
+
size: props.size,
|
|
2234
2287
|
id,
|
|
2235
2288
|
leftSection: icon,
|
|
2236
2289
|
defaultValue: Array.isArray(props.input.props.defaultValue) ? props.input.props.defaultValue : [],
|
|
@@ -2248,6 +2301,7 @@ const ControlSelect = (props) => {
|
|
|
2248
2301
|
const multiSelectProps = typeof props.multi === "object" ? props.multi : {};
|
|
2249
2302
|
return /* @__PURE__ */ jsx(MultiSelect, {
|
|
2250
2303
|
...inputProps,
|
|
2304
|
+
size: props.size,
|
|
2251
2305
|
id,
|
|
2252
2306
|
leftSection: icon,
|
|
2253
2307
|
data,
|
|
@@ -2261,6 +2315,7 @@ const ControlSelect = (props) => {
|
|
|
2261
2315
|
const selectProps = typeof props.select === "object" ? props.select : {};
|
|
2262
2316
|
return /* @__PURE__ */ jsx(Select, {
|
|
2263
2317
|
...inputProps,
|
|
2318
|
+
size: props.size,
|
|
2264
2319
|
id,
|
|
2265
2320
|
leftSection: icon,
|
|
2266
2321
|
data,
|
|
@@ -2268,7 +2323,6 @@ const ControlSelect = (props) => {
|
|
|
2268
2323
|
...selectProps
|
|
2269
2324
|
});
|
|
2270
2325
|
};
|
|
2271
|
-
var ControlSelect_default = ControlSelect;
|
|
2272
2326
|
|
|
2273
2327
|
//#endregion
|
|
2274
2328
|
//#region ../../src/core/components/form/Control.tsx
|
|
@@ -2304,7 +2358,7 @@ const Control = (_props) => {
|
|
|
2304
2358
|
..._props,
|
|
2305
2359
|
...schema.$control
|
|
2306
2360
|
};
|
|
2307
|
-
if (props.query) return /* @__PURE__ */ jsx(
|
|
2361
|
+
if (props.query) return /* @__PURE__ */ jsx(ControlQueryBuilder, {
|
|
2308
2362
|
...props.input.props,
|
|
2309
2363
|
...inputProps,
|
|
2310
2364
|
schema: props.query,
|
|
@@ -2332,7 +2386,7 @@ const Control = (_props) => {
|
|
|
2332
2386
|
const isObject = props.input.schema && "type" in props.input.schema && props.input.schema.type === "object" && "properties" in props.input.schema;
|
|
2333
2387
|
if (props.object || isObject) {
|
|
2334
2388
|
const controlObjectProps = typeof props.object === "object" ? props.object : {};
|
|
2335
|
-
return /* @__PURE__ */ jsx(
|
|
2389
|
+
return /* @__PURE__ */ jsx(ControlObject, {
|
|
2336
2390
|
input: props.input,
|
|
2337
2391
|
title: props.title,
|
|
2338
2392
|
description: props.description,
|
|
@@ -2343,7 +2397,7 @@ const Control = (_props) => {
|
|
|
2343
2397
|
const isArrayOfObjects = isArray && "items" in props.input.schema && props.input.schema.items && typeof props.input.schema.items === "object" && "properties" in props.input.schema.items;
|
|
2344
2398
|
if (props.array || isArrayOfObjects) {
|
|
2345
2399
|
const controlArrayProps = typeof props.array === "object" ? props.array : {};
|
|
2346
|
-
return /* @__PURE__ */ jsx(
|
|
2400
|
+
return /* @__PURE__ */ jsx(ControlArray, {
|
|
2347
2401
|
input: props.input,
|
|
2348
2402
|
title: props.title,
|
|
2349
2403
|
description: props.description,
|
|
@@ -2353,7 +2407,8 @@ const Control = (_props) => {
|
|
|
2353
2407
|
if (props.number || props.input.schema && "type" in props.input.schema && (props.input.schema.type === "number" || props.input.schema.type === "integer")) {
|
|
2354
2408
|
const controlNumberProps = typeof props.number === "object" ? props.number : {};
|
|
2355
2409
|
if (props.slider) controlNumberProps.sliderProps ??= {};
|
|
2356
|
-
return /* @__PURE__ */ jsx(
|
|
2410
|
+
return /* @__PURE__ */ jsx(ControlNumber, {
|
|
2411
|
+
size: props.size,
|
|
2357
2412
|
input: props.input,
|
|
2358
2413
|
title: props.title,
|
|
2359
2414
|
description: props.description,
|
|
@@ -2365,6 +2420,7 @@ const Control = (_props) => {
|
|
|
2365
2420
|
const fileInputProps = typeof props.file === "object" ? props.file : {};
|
|
2366
2421
|
return /* @__PURE__ */ jsx(FileInput, {
|
|
2367
2422
|
...inputProps,
|
|
2423
|
+
size: props.size,
|
|
2368
2424
|
id,
|
|
2369
2425
|
leftSection: icon,
|
|
2370
2426
|
onChange: (file) => {
|
|
@@ -2377,6 +2433,7 @@ const Control = (_props) => {
|
|
|
2377
2433
|
const colorInputProps = typeof props.color === "object" ? props.color : {};
|
|
2378
2434
|
return /* @__PURE__ */ jsx(ColorInput, {
|
|
2379
2435
|
...inputProps,
|
|
2436
|
+
size: props.size,
|
|
2380
2437
|
id,
|
|
2381
2438
|
leftSection: icon,
|
|
2382
2439
|
...props.input.props,
|
|
@@ -2386,7 +2443,8 @@ const Control = (_props) => {
|
|
|
2386
2443
|
if (props.input.schema && "enum" in props.input.schema && props.input.schema.enum || isArray && !isArrayOfObjects || props.select) {
|
|
2387
2444
|
const opts = typeof props.select === "object" ? props.select : {};
|
|
2388
2445
|
if (props.segmented) opts.segmented ??= {};
|
|
2389
|
-
return /* @__PURE__ */ jsx(
|
|
2446
|
+
return /* @__PURE__ */ jsx(ControlSelect, {
|
|
2447
|
+
size: props.size,
|
|
2390
2448
|
input: props.input,
|
|
2391
2449
|
title: props.title,
|
|
2392
2450
|
description: props.description,
|
|
@@ -2395,48 +2453,24 @@ const Control = (_props) => {
|
|
|
2395
2453
|
});
|
|
2396
2454
|
}
|
|
2397
2455
|
if (props.input.schema && "type" in props.input.schema && props.input.schema.type === "boolean") {
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
});
|
|
2410
|
-
}
|
|
2411
|
-
const selectProps = {
|
|
2412
|
-
loader: async () => [
|
|
2413
|
-
{
|
|
2414
|
-
value: "true",
|
|
2415
|
-
label: "Yes"
|
|
2416
|
-
},
|
|
2417
|
-
{
|
|
2418
|
-
value: "false",
|
|
2419
|
-
label: "No"
|
|
2420
|
-
},
|
|
2421
|
-
{
|
|
2422
|
-
value: "",
|
|
2423
|
-
label: ""
|
|
2424
|
-
}
|
|
2425
|
-
],
|
|
2426
|
-
...props.input.props
|
|
2427
|
-
};
|
|
2428
|
-
return /* @__PURE__ */ jsx(ControlSelect_default, {
|
|
2429
|
-
input: props.input,
|
|
2430
|
-
title: props.title,
|
|
2431
|
-
description: props.description,
|
|
2432
|
-
icon,
|
|
2433
|
-
...selectProps
|
|
2456
|
+
const switchProps = typeof props.switch === "object" ? props.switch : {};
|
|
2457
|
+
return /* @__PURE__ */ jsx(Switch, {
|
|
2458
|
+
...inputProps,
|
|
2459
|
+
size: props.size,
|
|
2460
|
+
id,
|
|
2461
|
+
color: "blue",
|
|
2462
|
+
defaultChecked: props.input.props.defaultValue,
|
|
2463
|
+
onChange: (event) => {
|
|
2464
|
+
props.input.set(event.currentTarget.checked);
|
|
2465
|
+
},
|
|
2466
|
+
...switchProps
|
|
2434
2467
|
});
|
|
2435
2468
|
}
|
|
2436
2469
|
if (props.password || props.input.props.name?.includes("password")) {
|
|
2437
2470
|
const passwordInputProps = typeof props.password === "object" ? props.password : {};
|
|
2438
2471
|
return /* @__PURE__ */ jsx(PasswordInput, {
|
|
2439
2472
|
...inputProps,
|
|
2473
|
+
size: props.size,
|
|
2440
2474
|
id,
|
|
2441
2475
|
leftSection: icon,
|
|
2442
2476
|
...props.input.props,
|
|
@@ -2447,13 +2481,15 @@ const Control = (_props) => {
|
|
|
2447
2481
|
const textAreaProps = typeof props.area === "object" ? props.area : {};
|
|
2448
2482
|
return /* @__PURE__ */ jsx(Textarea, {
|
|
2449
2483
|
...inputProps,
|
|
2484
|
+
size: props.size,
|
|
2450
2485
|
id,
|
|
2451
2486
|
leftSection: icon,
|
|
2452
2487
|
...props.input.props,
|
|
2453
2488
|
...textAreaProps
|
|
2454
2489
|
});
|
|
2455
2490
|
}
|
|
2456
|
-
if (props.date || props.datetime || props.time || format === "date" || format === "date-time" || format === "time") return /* @__PURE__ */ jsx(
|
|
2491
|
+
if (props.date || props.datetime || props.time || format === "date" || format === "date-time" || format === "time") return /* @__PURE__ */ jsx(ControlDate, {
|
|
2492
|
+
size: props.size,
|
|
2457
2493
|
input: props.input,
|
|
2458
2494
|
title: props.title,
|
|
2459
2495
|
description: props.description,
|
|
@@ -2475,6 +2511,7 @@ const Control = (_props) => {
|
|
|
2475
2511
|
};
|
|
2476
2512
|
return /* @__PURE__ */ jsx(TextInput, {
|
|
2477
2513
|
...inputProps,
|
|
2514
|
+
size: props.size,
|
|
2478
2515
|
id,
|
|
2479
2516
|
leftSection: icon,
|
|
2480
2517
|
type: getInputType(),
|
|
@@ -2488,7 +2525,6 @@ const Control = (_props) => {
|
|
|
2488
2525
|
]
|
|
2489
2526
|
});
|
|
2490
2527
|
};
|
|
2491
|
-
var Control_default = Control;
|
|
2492
2528
|
|
|
2493
2529
|
//#endregion
|
|
2494
2530
|
//#region ../../src/core/components/form/TypeForm.tsx
|
|
@@ -2534,7 +2570,7 @@ var Control_default = Control;
|
|
|
2534
2570
|
* ```
|
|
2535
2571
|
*/
|
|
2536
2572
|
const TypeForm = (props) => {
|
|
2537
|
-
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;
|
|
2538
2574
|
const schema = props.schema || form.options.schema;
|
|
2539
2575
|
if (!schema?.properties) return null;
|
|
2540
2576
|
const supportedFields = Object.keys(schema.properties);
|
|
@@ -2551,7 +2587,7 @@ const TypeForm = (props) => {
|
|
|
2551
2587
|
xl: columns.xl ? 12 / columns.xl : void 0
|
|
2552
2588
|
};
|
|
2553
2589
|
const renderFields = () => {
|
|
2554
|
-
if (children) return /* @__PURE__ */ jsx(Fragment, { children: children(form.input) });
|
|
2590
|
+
if (children) return /* @__PURE__ */ jsx(Fragment$1, { children: children(form.input) });
|
|
2555
2591
|
return /* @__PURE__ */ jsx(Grid, { children: supportedFields.map((fieldName) => {
|
|
2556
2592
|
const field = form.input[fieldName];
|
|
2557
2593
|
const fieldSchema = schema.properties[fieldName];
|
|
@@ -2563,9 +2599,10 @@ const TypeForm = (props) => {
|
|
|
2563
2599
|
...controlProps,
|
|
2564
2600
|
...fieldControlProps?.[fieldName]
|
|
2565
2601
|
};
|
|
2602
|
+
if (size) mergedControlProps.size = size;
|
|
2566
2603
|
return /* @__PURE__ */ jsx(Grid.Col, {
|
|
2567
2604
|
span,
|
|
2568
|
-
children: /* @__PURE__ */ jsx(
|
|
2605
|
+
children: /* @__PURE__ */ jsx(Control, {
|
|
2569
2606
|
input: field,
|
|
2570
2607
|
...mergedControlProps
|
|
2571
2608
|
})
|
|
@@ -2593,11 +2630,11 @@ const TypeForm = (props) => {
|
|
|
2593
2630
|
/* @__PURE__ */ jsx(Flex$1, { flex: 1 }),
|
|
2594
2631
|
/* @__PURE__ */ jsxs(Flex$1, {
|
|
2595
2632
|
gap: "sm",
|
|
2596
|
-
children: [/* @__PURE__ */ jsx(
|
|
2633
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2597
2634
|
variant: "subtle",
|
|
2598
2635
|
type: "reset",
|
|
2599
2636
|
children: "Reset"
|
|
2600
|
-
}), /* @__PURE__ */ jsx(
|
|
2637
|
+
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
2601
2638
|
intent: "primary",
|
|
2602
2639
|
form,
|
|
2603
2640
|
...submitButtonProps,
|
|
@@ -2617,7 +2654,6 @@ const TypeForm = (props) => {
|
|
|
2617
2654
|
children: content
|
|
2618
2655
|
});
|
|
2619
2656
|
};
|
|
2620
|
-
var TypeForm_default = TypeForm;
|
|
2621
2657
|
|
|
2622
2658
|
//#endregion
|
|
2623
2659
|
//#region ../../src/core/components/layout/AppBar.tsx
|
|
@@ -2627,10 +2663,10 @@ const AppBar = (props) => {
|
|
|
2627
2663
|
const renderItem = (item, index) => {
|
|
2628
2664
|
if (item.can && !item.can()) return null;
|
|
2629
2665
|
if ("type" in item) {
|
|
2630
|
-
if (item.type === "burger") return /* @__PURE__ */ jsx(
|
|
2631
|
-
if (item.type === "dark") return /* @__PURE__ */ jsx(
|
|
2632
|
-
if (item.type === "search") return /* @__PURE__ */ jsx(
|
|
2633
|
-
if (item.type === "lang") return /* @__PURE__ */ jsx(
|
|
2666
|
+
if (item.type === "burger") return /* @__PURE__ */ jsx(BurgerButton, {}, index);
|
|
2667
|
+
if (item.type === "dark") return /* @__PURE__ */ jsx(DarkModeButton, { ...item.props }, index);
|
|
2668
|
+
if (item.type === "search") return /* @__PURE__ */ jsx(OmnibarButton, { ...item.props }, index);
|
|
2669
|
+
if (item.type === "lang") return /* @__PURE__ */ jsx(LanguageButton, { ...item.props }, index);
|
|
2634
2670
|
if (item.type === "spacer") return /* @__PURE__ */ jsx(Flex$1, { w: 16 }, index);
|
|
2635
2671
|
if (item.type === "divider") return /* @__PURE__ */ jsx(Divider, { orientation: "vertical" }, index);
|
|
2636
2672
|
if (item.type === "logo") return renderLogo(item, index);
|
|
@@ -2672,7 +2708,7 @@ const AppBar = (props) => {
|
|
|
2672
2708
|
if (href) router.push(href);
|
|
2673
2709
|
else router.back();
|
|
2674
2710
|
};
|
|
2675
|
-
if (iconOnly) return /* @__PURE__ */ jsx(
|
|
2711
|
+
if (iconOnly) return /* @__PURE__ */ jsx(ActionButton, {
|
|
2676
2712
|
icon: iconElement,
|
|
2677
2713
|
variant: "subtle",
|
|
2678
2714
|
color: "gray",
|
|
@@ -2682,7 +2718,7 @@ const AppBar = (props) => {
|
|
|
2682
2718
|
position: "bottom"
|
|
2683
2719
|
}
|
|
2684
2720
|
}, index);
|
|
2685
|
-
return /* @__PURE__ */ jsx(
|
|
2721
|
+
return /* @__PURE__ */ jsx(ActionButton, {
|
|
2686
2722
|
leftSection: iconElement,
|
|
2687
2723
|
variant: "subtle",
|
|
2688
2724
|
color: "gray",
|
|
@@ -2732,19 +2768,71 @@ const AppBar = (props) => {
|
|
|
2732
2768
|
});
|
|
2733
2769
|
return content;
|
|
2734
2770
|
};
|
|
2735
|
-
|
|
2771
|
+
|
|
2772
|
+
//#endregion
|
|
2773
|
+
//#region ../../src/core/components/layout/Breadcrumb.tsx
|
|
2774
|
+
/**
|
|
2775
|
+
* Automatic breadcrumb component that reads the current route hierarchy
|
|
2776
|
+
* from the Alepha router's layer stack.
|
|
2777
|
+
*
|
|
2778
|
+
* Pages should define a `label` in their `$page()` options for best results.
|
|
2779
|
+
* Falls back to the page name converted to Title Case.
|
|
2780
|
+
*/
|
|
2781
|
+
const Breadcrumb = ({ home = "Home", separator, size = "xs", ...groupProps }) => {
|
|
2782
|
+
const state = useRouterState();
|
|
2783
|
+
const router = useRouter();
|
|
2784
|
+
const crumbs = [];
|
|
2785
|
+
if (home !== false) crumbs.push({
|
|
2786
|
+
label: home,
|
|
2787
|
+
href: "/"
|
|
2788
|
+
});
|
|
2789
|
+
for (let i = 1; i < state.layers.length; i++) {
|
|
2790
|
+
const layer = state.layers[i];
|
|
2791
|
+
const route = layer.route;
|
|
2792
|
+
if (route?.path === "/" || route?.path === "") continue;
|
|
2793
|
+
const label = route?.label ?? toTitleCase(layer.name);
|
|
2794
|
+
const href = router.path(layer.name);
|
|
2795
|
+
crumbs.push({
|
|
2796
|
+
label,
|
|
2797
|
+
href
|
|
2798
|
+
});
|
|
2799
|
+
}
|
|
2800
|
+
if (crumbs.length === 0) return null;
|
|
2801
|
+
const sep = separator ?? /* @__PURE__ */ jsx(IconChevronRight, {
|
|
2802
|
+
size: 12,
|
|
2803
|
+
color: "#9ca3af"
|
|
2804
|
+
});
|
|
2805
|
+
return /* @__PURE__ */ jsx(Flex$1, {
|
|
2806
|
+
gap: 4,
|
|
2807
|
+
...groupProps,
|
|
2808
|
+
children: crumbs.map((crumb, i) => /* @__PURE__ */ jsxs(Flex$1, {
|
|
2809
|
+
gap: 4,
|
|
2810
|
+
children: [i > 0 && sep, i < crumbs.length - 1 ? /* @__PURE__ */ jsx(Anchor, {
|
|
2811
|
+
component: Link,
|
|
2812
|
+
href: crumb.href,
|
|
2813
|
+
size,
|
|
2814
|
+
c: "dimmed",
|
|
2815
|
+
children: crumb.label
|
|
2816
|
+
}) : /* @__PURE__ */ jsx(Text$1, {
|
|
2817
|
+
size,
|
|
2818
|
+
fw: 500,
|
|
2819
|
+
children: crumb.label
|
|
2820
|
+
})]
|
|
2821
|
+
}, crumb.href))
|
|
2822
|
+
});
|
|
2823
|
+
};
|
|
2736
2824
|
|
|
2737
2825
|
//#endregion
|
|
2738
2826
|
//#region ../../src/core/components/layout/Sidebar.tsx
|
|
2739
2827
|
const Sidebar = (props) => {
|
|
2740
2828
|
const router = useRouter();
|
|
2741
2829
|
const { onItemClick } = props;
|
|
2742
|
-
const divider = (key) => {
|
|
2830
|
+
const divider = (key, fill) => {
|
|
2743
2831
|
return /* @__PURE__ */ jsx(Flex$1, {
|
|
2744
2832
|
h: 1,
|
|
2745
|
-
bg: "var(--
|
|
2833
|
+
bg: "var(--mantine-color-default-border)",
|
|
2746
2834
|
my: "xs",
|
|
2747
|
-
mx: props.collapsed ? 0 : "sm"
|
|
2835
|
+
mx: fill ? "calc(-1 * var(--mantine-spacing-md))" : props.collapsed ? 0 : "sm"
|
|
2748
2836
|
}, key);
|
|
2749
2837
|
};
|
|
2750
2838
|
const renderNode = (item, key) => {
|
|
@@ -2753,29 +2841,32 @@ const Sidebar = (props) => {
|
|
|
2753
2841
|
if (props.collapsed) return null;
|
|
2754
2842
|
return /* @__PURE__ */ jsx(Flex$1, { h: 16 }, key);
|
|
2755
2843
|
}
|
|
2756
|
-
if (item.type === "divider") return divider(key);
|
|
2844
|
+
if (item.type === "divider") return divider(key, item.fill);
|
|
2757
2845
|
if (item.type === "search") return /* @__PURE__ */ jsx(Flex$1, {
|
|
2758
2846
|
mb: "xs",
|
|
2759
|
-
children: /* @__PURE__ */ jsx(
|
|
2847
|
+
children: /* @__PURE__ */ jsx(OmnibarButton, { collapsed: props.collapsed })
|
|
2760
2848
|
}, key);
|
|
2761
|
-
if (item.type === "toggle") return /* @__PURE__ */ jsx(
|
|
2849
|
+
if (item.type === "toggle") return /* @__PURE__ */ jsx(ToggleSidebarButton, {}, key);
|
|
2762
2850
|
if (item.type === "section") {
|
|
2763
|
-
if (
|
|
2764
|
-
|
|
2851
|
+
if (item.children && item.children.length > 0) {
|
|
2852
|
+
if (!item.children.some((child) => !("can" in child) || !child.can || child.can())) return null;
|
|
2853
|
+
}
|
|
2854
|
+
if (props.collapsed) return /* @__PURE__ */ jsxs(Fragment, { children: [divider(`${key}-d`), item.children?.map((child, index) => renderNode(child, `s${key}-${index}`))] }, key);
|
|
2855
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(Flex$1, {
|
|
2765
2856
|
mt: "md",
|
|
2766
2857
|
align: "center",
|
|
2767
2858
|
gap: "xs",
|
|
2768
|
-
children: [renderIcon(item.icon), /* @__PURE__ */ jsx(Text$1, {
|
|
2859
|
+
children: [renderIcon(item.icon, ui.sizes.icon.sm), /* @__PURE__ */ jsx(Text$1, {
|
|
2769
2860
|
size: "xs",
|
|
2770
2861
|
c: "dimmed",
|
|
2771
2862
|
tt: "uppercase",
|
|
2772
2863
|
fw: "bold",
|
|
2773
2864
|
children: item.label
|
|
2774
2865
|
})]
|
|
2775
|
-
}, key);
|
|
2866
|
+
}), item.children?.map((child, index) => renderNode(child, `s${key}-${index}`))] }, key);
|
|
2776
2867
|
}
|
|
2777
2868
|
}
|
|
2778
|
-
if ("element" in item) return /* @__PURE__ */ jsx(
|
|
2869
|
+
if ("element" in item) return /* @__PURE__ */ jsx(Fragment, { children: item.element }, key);
|
|
2779
2870
|
if (item.can && !item.can()) return null;
|
|
2780
2871
|
if (item.children && item.children.length > 0) {
|
|
2781
2872
|
if (!item.children.some((child) => !child.can || child.can())) return null;
|
|
@@ -2810,7 +2901,7 @@ const Sidebar = (props) => {
|
|
|
2810
2901
|
return [];
|
|
2811
2902
|
};
|
|
2812
2903
|
const padding = "md";
|
|
2813
|
-
const gap = props.items ? props.gap ??
|
|
2904
|
+
const gap = props.items ? props.gap ?? 4 : "xs";
|
|
2814
2905
|
const menu = useMemo(() => getSidebarNodes(), [props.items, props.autoPopulateMenu]);
|
|
2815
2906
|
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
2816
2907
|
flex: 1,
|
|
@@ -2873,14 +2964,16 @@ const SidebarItem = (props) => {
|
|
|
2873
2964
|
direction: "column",
|
|
2874
2965
|
ps: level === 0 ? 0 : 32,
|
|
2875
2966
|
pos: "relative",
|
|
2876
|
-
children: [/* @__PURE__ */ jsx(
|
|
2967
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2877
2968
|
w: "100%",
|
|
2878
2969
|
justify: "space-between",
|
|
2879
2970
|
href: props.item.href,
|
|
2880
2971
|
target: props.item.target,
|
|
2881
2972
|
size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
|
|
2882
|
-
tooltip: item.description
|
|
2883
|
-
|
|
2973
|
+
tooltip: item.description ? {
|
|
2974
|
+
label: item.description,
|
|
2975
|
+
position: "right"
|
|
2976
|
+
} : void 0,
|
|
2884
2977
|
color: "gray",
|
|
2885
2978
|
variant: "subtle",
|
|
2886
2979
|
variantActive: "default",
|
|
@@ -2890,7 +2983,7 @@ const SidebarItem = (props) => {
|
|
|
2890
2983
|
w: "100%",
|
|
2891
2984
|
align: "center",
|
|
2892
2985
|
gap: "sm",
|
|
2893
|
-
children: [renderIcon(item.icon), /* @__PURE__ */ jsx(Flex$1, {
|
|
2986
|
+
children: [renderIcon(item.icon, ui.sizes.icon.sm), /* @__PURE__ */ jsx(Flex$1, {
|
|
2894
2987
|
direction: "column",
|
|
2895
2988
|
children: /* @__PURE__ */ jsx(Flex$1, { children: item.label })
|
|
2896
2989
|
})]
|
|
@@ -2903,7 +2996,7 @@ const SidebarItem = (props) => {
|
|
|
2903
2996
|
children: [/* @__PURE__ */ jsx(Flex$1, { style: {
|
|
2904
2997
|
position: "absolute",
|
|
2905
2998
|
width: 1,
|
|
2906
|
-
background: "linear-gradient(to bottom, transparent, var(--
|
|
2999
|
+
background: "linear-gradient(to bottom, transparent, var(--mantine-color-default-border), transparent)",
|
|
2907
3000
|
top: 48,
|
|
2908
3001
|
left: 20 + 32 * level,
|
|
2909
3002
|
bottom: 16
|
|
@@ -2922,7 +3015,7 @@ const SidebarCollapsedItem = (props) => {
|
|
|
2922
3015
|
props.onItemClick?.(item);
|
|
2923
3016
|
item.onClick?.();
|
|
2924
3017
|
};
|
|
2925
|
-
return /* @__PURE__ */ jsx(
|
|
3018
|
+
return /* @__PURE__ */ jsx(ActionButton, {
|
|
2926
3019
|
size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
|
|
2927
3020
|
variant: "subtle",
|
|
2928
3021
|
variantActive: "default",
|
|
@@ -2932,7 +3025,7 @@ const SidebarCollapsedItem = (props) => {
|
|
|
2932
3025
|
},
|
|
2933
3026
|
radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
|
|
2934
3027
|
onClick: handleItemClick,
|
|
2935
|
-
icon: renderIcon(item.icon) ?? /* @__PURE__ */ jsx(IconSquareRounded, {}),
|
|
3028
|
+
icon: renderIcon(item.icon, ui.sizes.icon.sm) ?? /* @__PURE__ */ jsx(IconSquareRounded, { size: ui.sizes.icon.sm }),
|
|
2936
3029
|
href: props.item.href,
|
|
2937
3030
|
target: props.item.target,
|
|
2938
3031
|
...props.item.actionProps
|
|
@@ -2940,17 +3033,12 @@ const SidebarCollapsedItem = (props) => {
|
|
|
2940
3033
|
};
|
|
2941
3034
|
|
|
2942
3035
|
//#endregion
|
|
2943
|
-
//#region ../../src/core/components/layout/
|
|
2944
|
-
const
|
|
3036
|
+
//#region ../../src/core/components/layout/DashboardShell.tsx
|
|
3037
|
+
const DashboardShell = (props) => {
|
|
2945
3038
|
const router = useRouter();
|
|
2946
3039
|
const [sidebar, setSidebar] = useStore(alephaSidebarAtom);
|
|
2947
|
-
const { opened
|
|
2948
|
-
|
|
2949
|
-
if (props.sidebarProps?.collapsed !== void 0) setSidebar({
|
|
2950
|
-
...sidebar,
|
|
2951
|
-
collapsed: props.sidebarProps.collapsed
|
|
2952
|
-
});
|
|
2953
|
-
}, []);
|
|
3040
|
+
const { opened } = sidebar;
|
|
3041
|
+
const collapsed = props.sidebarProps?.collapsed !== void 0 ? props.sidebarProps.collapsed : sidebar.collapsed;
|
|
2954
3042
|
const [isResizing, setIsResizing] = useState(false);
|
|
2955
3043
|
const [isHovering, setIsHovering] = useState(false);
|
|
2956
3044
|
const [collapseEffect, setCollapseEffect] = useState({
|
|
@@ -3045,11 +3133,16 @@ const AdminShell = (props) => {
|
|
|
3045
3133
|
collapseEffect.offset
|
|
3046
3134
|
]);
|
|
3047
3135
|
const hoverTimeoutRef = useRef(null);
|
|
3136
|
+
const expandOnHover = props.sidebarProps?.expandOnHover !== false;
|
|
3048
3137
|
const handleNavbarMouseEnter = useCallback(() => {
|
|
3049
|
-
if (collapsed) hoverTimeoutRef.current = setTimeout(() => {
|
|
3138
|
+
if (collapsed && expandOnHover) hoverTimeoutRef.current = setTimeout(() => {
|
|
3050
3139
|
setIsHovering(true);
|
|
3051
3140
|
}, hoverDelay);
|
|
3052
|
-
}, [
|
|
3141
|
+
}, [
|
|
3142
|
+
collapsed,
|
|
3143
|
+
expandOnHover,
|
|
3144
|
+
hoverDelay
|
|
3145
|
+
]);
|
|
3053
3146
|
const handleNavbarMouseLeave = useCallback(() => {
|
|
3054
3147
|
if (hoverTimeoutRef.current) {
|
|
3055
3148
|
clearTimeout(hoverTimeoutRef.current);
|
|
@@ -3091,9 +3184,11 @@ const AdminShell = (props) => {
|
|
|
3091
3184
|
const appBarProps = { ...props.appBarProps };
|
|
3092
3185
|
appBarProps.container ??= props.container;
|
|
3093
3186
|
const hasSidebar = showSidebar && props.sidebarProps !== void 0;
|
|
3094
|
-
const hasAppBar =
|
|
3095
|
-
const
|
|
3096
|
-
const
|
|
3187
|
+
const hasAppBar = props.appBarProps || props.header;
|
|
3188
|
+
const hHeight = props.headerHeight ?? 60;
|
|
3189
|
+
const fHeight = props.footerHeight ?? 24;
|
|
3190
|
+
const headerHeight = hasAppBar ? hHeight : 0;
|
|
3191
|
+
const footerHeight = props.footer ? fHeight : 0;
|
|
3097
3192
|
const expandedWidth = Math.max(sidebar.width, collapsedWidth);
|
|
3098
3193
|
const isExpandedByHover = collapsed && isHovering;
|
|
3099
3194
|
const effectiveCollapsed = collapsed && !isHovering;
|
|
@@ -3102,31 +3197,28 @@ const AdminShell = (props) => {
|
|
|
3102
3197
|
props.sidebarProps?.onItemClick?.(item);
|
|
3103
3198
|
}, [isExpandedByHover, props.sidebarProps?.onItemClick]);
|
|
3104
3199
|
const hoverWidth = Math.max(defaultWidth, collapsedWidth);
|
|
3105
|
-
const sidebarWidth = hasSidebar ? effectiveCollapsed || isExpandedByHover ? collapsedWidth : expandedWidth : 0;
|
|
3106
3200
|
const canResize = props.sidebarResizable && !collapsed;
|
|
3107
3201
|
return /* @__PURE__ */ jsxs(AppShell, {
|
|
3202
|
+
layout: props.layout,
|
|
3108
3203
|
w: "100%",
|
|
3109
3204
|
flex: 1,
|
|
3110
|
-
|
|
3111
|
-
header: hasAppBar ? { height: 60 } : void 0,
|
|
3205
|
+
header: hasAppBar ? { height: hHeight } : void 0,
|
|
3112
3206
|
navbar: hasSidebar ? {
|
|
3113
3207
|
width: effectiveCollapsed || isExpandedByHover ? { base: collapsedWidth } : { base: expandedWidth },
|
|
3114
3208
|
breakpoint: "sm",
|
|
3115
3209
|
collapsed: { mobile: !opened }
|
|
3116
3210
|
} : void 0,
|
|
3117
|
-
footer: props.footer ? { height:
|
|
3211
|
+
footer: props.footer ? { height: fHeight } : void 0,
|
|
3118
3212
|
...props.appShellProps,
|
|
3119
3213
|
children: [
|
|
3120
|
-
/* @__PURE__ */ jsx(AppShell.Header, {
|
|
3121
|
-
bg: ui.colors.surface,
|
|
3214
|
+
hasAppBar && /* @__PURE__ */ jsx(AppShell.Header, {
|
|
3122
3215
|
...props.appShellHeaderProps,
|
|
3123
|
-
children: props.header ?? /* @__PURE__ */ jsx(
|
|
3216
|
+
children: props.header ?? /* @__PURE__ */ jsx(AppBar, {
|
|
3124
3217
|
items: defaultAppBarItems,
|
|
3125
3218
|
...appBarProps
|
|
3126
3219
|
})
|
|
3127
3220
|
}),
|
|
3128
3221
|
hasSidebar && /* @__PURE__ */ jsxs(AppShell.Navbar, {
|
|
3129
|
-
bg: ui.colors.surface,
|
|
3130
3222
|
className: "alepha-sidebar-navbar",
|
|
3131
3223
|
"data-resizing": isResizing,
|
|
3132
3224
|
"data-hover-expanded": isExpandedByHover,
|
|
@@ -3142,31 +3234,37 @@ const AdminShell = (props) => {
|
|
|
3142
3234
|
}
|
|
3143
3235
|
},
|
|
3144
3236
|
...props.appShellNavbarProps,
|
|
3145
|
-
children: [
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3237
|
+
children: [
|
|
3238
|
+
props.navbarHeader ? /* @__PURE__ */ jsx(Flex$1, {
|
|
3239
|
+
style: { borderBottom: "1px solid var(--mantine-color-default-border)" },
|
|
3240
|
+
h: headerHeight,
|
|
3241
|
+
children: props.navbarHeader
|
|
3242
|
+
}) : null,
|
|
3243
|
+
/* @__PURE__ */ jsx(Sidebar, {
|
|
3244
|
+
...props.sidebarProps ?? {},
|
|
3245
|
+
collapsed: effectiveCollapsed,
|
|
3246
|
+
onItemClick: handleSidebarItemClick
|
|
3247
|
+
}),
|
|
3248
|
+
props.navbarFooter ? /* @__PURE__ */ jsx(Flex$1, {
|
|
3249
|
+
style: { borderTop: "1px solid var(--mantine-color-default-border)" },
|
|
3250
|
+
h: footerHeight,
|
|
3251
|
+
children: props.navbarFooter
|
|
3252
|
+
}) : null,
|
|
3253
|
+
(canResize || isExpandedByHover) && /* @__PURE__ */ jsx(Flex$1, {
|
|
3254
|
+
pos: "absolute",
|
|
3255
|
+
right: -6,
|
|
3256
|
+
top: 0,
|
|
3257
|
+
bottom: 0,
|
|
3258
|
+
w: 12,
|
|
3259
|
+
style: {
|
|
3260
|
+
cursor: "col-resize",
|
|
3261
|
+
userSelect: "none"
|
|
3262
|
+
},
|
|
3263
|
+
onMouseDown: handleResizeStart
|
|
3264
|
+
})
|
|
3265
|
+
]
|
|
3161
3266
|
}),
|
|
3162
3267
|
/* @__PURE__ */ jsx(AppShell.Main, {
|
|
3163
|
-
pl: sidebarWidth,
|
|
3164
|
-
pt: headerHeight,
|
|
3165
|
-
pb: footerHeight,
|
|
3166
|
-
pr: 0,
|
|
3167
|
-
display: "flex",
|
|
3168
|
-
flex: 1,
|
|
3169
|
-
style: { flexDirection: "column" },
|
|
3170
3268
|
className: "alepha-sidebar-main",
|
|
3171
3269
|
"data-resizing": isResizing,
|
|
3172
3270
|
...props.appShellMainProps,
|
|
@@ -3180,14 +3278,12 @@ const AdminShell = (props) => {
|
|
|
3180
3278
|
}) : props.children ?? /* @__PURE__ */ jsx(NestedView, {})
|
|
3181
3279
|
}),
|
|
3182
3280
|
props.footer && /* @__PURE__ */ jsx(AppShell.Footer, {
|
|
3183
|
-
bg: ui.colors.surface,
|
|
3184
3281
|
...props.appShellFooterProps,
|
|
3185
3282
|
children: props.footer
|
|
3186
3283
|
})
|
|
3187
3284
|
]
|
|
3188
3285
|
});
|
|
3189
3286
|
};
|
|
3190
|
-
var AdminShell_default = AdminShell;
|
|
3191
3287
|
|
|
3192
3288
|
//#endregion
|
|
3193
3289
|
//#region ../../src/core/components/table/DataTableFilters.tsx
|
|
@@ -3207,16 +3303,23 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
|
|
|
3207
3303
|
p: "xs",
|
|
3208
3304
|
bg: ui.colors.surface,
|
|
3209
3305
|
style: { borderBottom: "1px solid var(--alepha-border)" },
|
|
3210
|
-
children: /* @__PURE__ */ jsx(
|
|
3306
|
+
children: /* @__PURE__ */ jsx(TypeForm, {
|
|
3307
|
+
size: "xs",
|
|
3211
3308
|
...typeFormProps,
|
|
3212
3309
|
skipSubmitButton: true,
|
|
3213
3310
|
fill: true,
|
|
3214
3311
|
form,
|
|
3215
|
-
schema: visibleSchema
|
|
3312
|
+
schema: visibleSchema,
|
|
3313
|
+
columns: {
|
|
3314
|
+
base: 1,
|
|
3315
|
+
sm: 2,
|
|
3316
|
+
md: 3,
|
|
3317
|
+
lg: 4,
|
|
3318
|
+
xl: 6
|
|
3319
|
+
}
|
|
3216
3320
|
})
|
|
3217
3321
|
});
|
|
3218
3322
|
};
|
|
3219
|
-
var DataTableFilters_default = DataTableFilters;
|
|
3220
3323
|
|
|
3221
3324
|
//#endregion
|
|
3222
3325
|
//#region ../../src/core/components/table/DataTablePagination.tsx
|
|
@@ -3264,7 +3367,10 @@ const DataTablePagination = ({ page, size, totalPages, onPageChange, onSizeChang
|
|
|
3264
3367
|
}) })]
|
|
3265
3368
|
});
|
|
3266
3369
|
};
|
|
3267
|
-
|
|
3370
|
+
|
|
3371
|
+
//#endregion
|
|
3372
|
+
//#region ../../src/core/components/table/types.ts
|
|
3373
|
+
const DEFAULT_MAX_VISIBLE_COLUMNS = 8;
|
|
3268
3374
|
|
|
3269
3375
|
//#endregion
|
|
3270
3376
|
//#region ../../src/core/components/table/ColumnPicker.tsx
|
|
@@ -3277,11 +3383,16 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
3277
3383
|
[key]: true
|
|
3278
3384
|
}), {}));
|
|
3279
3385
|
};
|
|
3280
|
-
const
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
[key]
|
|
3284
|
-
|
|
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
|
+
}, {}));
|
|
3285
3396
|
};
|
|
3286
3397
|
const handleToggle = (key, checked) => {
|
|
3287
3398
|
onVisibilityChange({
|
|
@@ -3303,20 +3414,22 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
3303
3414
|
duration: 200,
|
|
3304
3415
|
timingFunction: "ease"
|
|
3305
3416
|
},
|
|
3306
|
-
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(
|
|
3417
|
+
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ActionButton, {
|
|
3307
3418
|
variant: "subtle",
|
|
3308
|
-
icon: IconColumns
|
|
3309
|
-
|
|
3419
|
+
icon: IconColumns,
|
|
3420
|
+
onClick: () => setOpened((o) => !o)
|
|
3421
|
+
}) }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
3310
3422
|
bg: "transparent",
|
|
3311
3423
|
p: "xs",
|
|
3312
3424
|
bd: `1px solid ${ui.colors.border}`,
|
|
3313
3425
|
style: { backdropFilter: "blur(20px)" },
|
|
3314
|
-
children: /* @__PURE__ */ jsxs(
|
|
3426
|
+
children: /* @__PURE__ */ jsxs(Flex$1, {
|
|
3427
|
+
direction: "column",
|
|
3315
3428
|
gap: "xs",
|
|
3316
3429
|
bg: ui.colors.surface,
|
|
3317
3430
|
p: "sm",
|
|
3318
3431
|
bdrs: "sm",
|
|
3319
|
-
children: [/* @__PURE__ */ jsxs(
|
|
3432
|
+
children: [/* @__PURE__ */ jsxs(Flex$1, {
|
|
3320
3433
|
justify: "space-between",
|
|
3321
3434
|
children: [/* @__PURE__ */ jsxs(Text$1, {
|
|
3322
3435
|
size: "sm",
|
|
@@ -3328,26 +3441,27 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
3328
3441
|
columnEntries.length,
|
|
3329
3442
|
")"
|
|
3330
3443
|
]
|
|
3331
|
-
}), /* @__PURE__ */ jsxs(
|
|
3444
|
+
}), /* @__PURE__ */ jsxs(Flex$1, {
|
|
3332
3445
|
gap: 4,
|
|
3333
|
-
children: [/* @__PURE__ */ jsx(
|
|
3446
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
3334
3447
|
size: "compact-xs",
|
|
3335
3448
|
variant: "subtle",
|
|
3336
3449
|
onClick: handleShowAll,
|
|
3337
3450
|
children: "All"
|
|
3338
|
-
}), /* @__PURE__ */ jsx(
|
|
3451
|
+
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
3339
3452
|
size: "compact-xs",
|
|
3340
3453
|
variant: "subtle",
|
|
3341
|
-
onClick:
|
|
3342
|
-
children: "
|
|
3454
|
+
onClick: handleDefault,
|
|
3455
|
+
children: "Default"
|
|
3343
3456
|
})]
|
|
3344
3457
|
})]
|
|
3345
3458
|
}), /* @__PURE__ */ jsx(ScrollArea.Autosize, {
|
|
3346
3459
|
mah: 300,
|
|
3347
|
-
children: /* @__PURE__ */ jsx(
|
|
3460
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
3461
|
+
direction: "column",
|
|
3348
3462
|
gap: 4,
|
|
3349
3463
|
children: columnEntries.map(([key, col]) => /* @__PURE__ */ jsx(Checkbox, {
|
|
3350
|
-
label: col.label,
|
|
3464
|
+
label: col.label || key,
|
|
3351
3465
|
checked: visibility[key] !== false,
|
|
3352
3466
|
onChange: (e) => handleToggle(key, e.currentTarget.checked),
|
|
3353
3467
|
size: "sm"
|
|
@@ -3358,7 +3472,6 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
3358
3472
|
})]
|
|
3359
3473
|
});
|
|
3360
3474
|
};
|
|
3361
|
-
var ColumnPicker_default = ColumnPicker;
|
|
3362
3475
|
|
|
3363
3476
|
//#endregion
|
|
3364
3477
|
//#region ../../src/core/components/table/FilterPicker.tsx
|
|
@@ -3388,7 +3501,7 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
3388
3501
|
[key]: checked
|
|
3389
3502
|
});
|
|
3390
3503
|
};
|
|
3391
|
-
const visibleCount = filterKeys.filter((key) => visibility[key]
|
|
3504
|
+
const visibleCount = filterKeys.filter((key) => visibility[key]).length;
|
|
3392
3505
|
return /* @__PURE__ */ jsxs(Popover, {
|
|
3393
3506
|
width: 280,
|
|
3394
3507
|
position: "bottom-start",
|
|
@@ -3402,20 +3515,22 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
3402
3515
|
duration: 200,
|
|
3403
3516
|
timingFunction: "ease"
|
|
3404
3517
|
},
|
|
3405
|
-
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(
|
|
3518
|
+
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ActionButton, {
|
|
3406
3519
|
variant: "subtle",
|
|
3407
|
-
icon: IconFilter
|
|
3408
|
-
|
|
3520
|
+
icon: IconFilter,
|
|
3521
|
+
onClick: () => setOpened((o) => !o)
|
|
3522
|
+
}) }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
3409
3523
|
bg: "transparent",
|
|
3410
3524
|
p: "xs",
|
|
3411
3525
|
bd: `1px solid ${ui.colors.border}`,
|
|
3412
3526
|
style: { backdropFilter: "blur(20px)" },
|
|
3413
|
-
children: /* @__PURE__ */ jsxs(
|
|
3527
|
+
children: /* @__PURE__ */ jsxs(Flex$1, {
|
|
3528
|
+
direction: "column",
|
|
3414
3529
|
gap: "xs",
|
|
3415
3530
|
bg: ui.colors.surface,
|
|
3416
3531
|
p: "sm",
|
|
3417
3532
|
bdrs: "sm",
|
|
3418
|
-
children: [/* @__PURE__ */ jsxs(
|
|
3533
|
+
children: [/* @__PURE__ */ jsxs(Flex$1, {
|
|
3419
3534
|
justify: "space-between",
|
|
3420
3535
|
children: [/* @__PURE__ */ jsxs(Text$1, {
|
|
3421
3536
|
size: "sm",
|
|
@@ -3427,14 +3542,14 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
3427
3542
|
filterKeys.length,
|
|
3428
3543
|
")"
|
|
3429
3544
|
]
|
|
3430
|
-
}), /* @__PURE__ */ jsxs(
|
|
3545
|
+
}), /* @__PURE__ */ jsxs(Flex$1, {
|
|
3431
3546
|
gap: 4,
|
|
3432
|
-
children: [/* @__PURE__ */ jsx(
|
|
3547
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
3433
3548
|
size: "compact-xs",
|
|
3434
3549
|
variant: "subtle",
|
|
3435
3550
|
onClick: handleShowAll,
|
|
3436
3551
|
children: "All"
|
|
3437
|
-
}), /* @__PURE__ */ jsx(
|
|
3552
|
+
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
3438
3553
|
size: "compact-xs",
|
|
3439
3554
|
variant: "subtle",
|
|
3440
3555
|
onClick: handleHideAll,
|
|
@@ -3443,11 +3558,12 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
3443
3558
|
})]
|
|
3444
3559
|
}), /* @__PURE__ */ jsx(ScrollArea.Autosize, {
|
|
3445
3560
|
mah: 300,
|
|
3446
|
-
children: /* @__PURE__ */ jsx(
|
|
3561
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
3562
|
+
direction: "column",
|
|
3447
3563
|
gap: 4,
|
|
3448
3564
|
children: filterKeys.map((key) => /* @__PURE__ */ jsx(Checkbox, {
|
|
3449
3565
|
label: getFieldLabel(schema, key),
|
|
3450
|
-
checked: visibility[key]
|
|
3566
|
+
checked: visibility[key] === true,
|
|
3451
3567
|
onChange: (e) => handleToggle(key, e.currentTarget.checked),
|
|
3452
3568
|
size: "sm"
|
|
3453
3569
|
}, key))
|
|
@@ -3457,12 +3573,53 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
3457
3573
|
})]
|
|
3458
3574
|
});
|
|
3459
3575
|
};
|
|
3460
|
-
var FilterPicker_default = FilterPicker;
|
|
3461
3576
|
|
|
3462
3577
|
//#endregion
|
|
3463
3578
|
//#region ../../src/core/components/table/DataTableToolbar.tsx
|
|
3464
|
-
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 }) => {
|
|
3465
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]);
|
|
3466
3623
|
const handleCheckboxAction = async (action) => {
|
|
3467
3624
|
const ctx = {
|
|
3468
3625
|
selectedItems,
|
|
@@ -3478,17 +3635,30 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
3478
3635
|
gap: 4,
|
|
3479
3636
|
align: "center",
|
|
3480
3637
|
children: [
|
|
3481
|
-
filters && /* @__PURE__ */ jsx(
|
|
3638
|
+
filters && /* @__PURE__ */ jsx(FilterPicker, {
|
|
3482
3639
|
schema: filters,
|
|
3483
3640
|
visibility: filterVisibility,
|
|
3484
3641
|
onVisibilityChange: onFilterVisibilityChange
|
|
3485
3642
|
}),
|
|
3486
|
-
/* @__PURE__ */ jsx(
|
|
3643
|
+
/* @__PURE__ */ jsx(ColumnPicker, {
|
|
3487
3644
|
columns,
|
|
3488
3645
|
visibility: columnVisibility,
|
|
3489
3646
|
onVisibilityChange: onColumnVisibilityChange
|
|
3490
3647
|
}),
|
|
3491
|
-
|
|
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
|
+
}),
|
|
3661
|
+
hasSelection && /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
3492
3662
|
/* @__PURE__ */ jsx(Divider, {
|
|
3493
3663
|
orientation: "vertical",
|
|
3494
3664
|
mx: "xs"
|
|
@@ -3498,14 +3668,14 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
3498
3668
|
size: "lg",
|
|
3499
3669
|
children: [selectedItems.length, " selected"]
|
|
3500
3670
|
}),
|
|
3501
|
-
/* @__PURE__ */ jsx(
|
|
3671
|
+
/* @__PURE__ */ jsx(ActionButton, {
|
|
3502
3672
|
variant: "subtle",
|
|
3503
3673
|
size: "compact-sm",
|
|
3504
3674
|
icon: IconX,
|
|
3505
3675
|
onClick: onClearSelection,
|
|
3506
3676
|
children: "Clear"
|
|
3507
3677
|
}),
|
|
3508
|
-
checkboxActions?.map((action, index) => /* @__PURE__ */ jsx(
|
|
3678
|
+
checkboxActions?.map((action, index) => /* @__PURE__ */ jsx(ActionButton, {
|
|
3509
3679
|
variant: "light",
|
|
3510
3680
|
size: "compact-sm",
|
|
3511
3681
|
intent: action.intent,
|
|
@@ -3519,23 +3689,84 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
3519
3689
|
/* @__PURE__ */ jsx(Flex$1, { flex: 1 }),
|
|
3520
3690
|
/* @__PURE__ */ jsxs(Flex$1, {
|
|
3521
3691
|
gap: "xs",
|
|
3522
|
-
children: [actions?.map((props, index) => !isValidElement(props) ? /* @__PURE__ */ jsx(
|
|
3692
|
+
children: [actions?.map((props, index) => !isValidElement(props) ? /* @__PURE__ */ jsx(ActionButton, {
|
|
3523
3693
|
...props,
|
|
3524
3694
|
children: props.label
|
|
3525
|
-
}, index) : props), /* @__PURE__ */ jsx(
|
|
3695
|
+
}, index) : props), /* @__PURE__ */ jsx(ActionButton, {
|
|
3696
|
+
variant: "subtle",
|
|
3526
3697
|
icon: IconRefresh,
|
|
3527
|
-
onClick: onRefresh
|
|
3528
|
-
children: "Refresh"
|
|
3698
|
+
onClick: onRefresh
|
|
3529
3699
|
})]
|
|
3530
3700
|
})
|
|
3531
3701
|
]
|
|
3532
3702
|
});
|
|
3533
3703
|
};
|
|
3534
|
-
|
|
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
|
+
};
|
|
3535
3767
|
|
|
3536
3768
|
//#endregion
|
|
3537
3769
|
//#region ../../src/core/components/table/DataTable.tsx
|
|
3538
|
-
const DEFAULT_VISIBLE_COLUMN_COUNT = 10;
|
|
3539
3770
|
/**
|
|
3540
3771
|
* Parse the sort string to get direction for a specific field.
|
|
3541
3772
|
* Alepha convention: 'field' = ASC, '-field' = DESC
|
|
@@ -3560,6 +3791,15 @@ const toggleSort = (sortString, field) => {
|
|
|
3560
3791
|
else if (current === "asc") parts.unshift(`-${field}`);
|
|
3561
3792
|
return parts.length > 0 ? parts.join(",") : void 0;
|
|
3562
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
|
+
};
|
|
3563
3803
|
const DataTable = (props) => {
|
|
3564
3804
|
const [items, setItems] = useState(typeof props.items === "function" ? { content: [] } : props.items);
|
|
3565
3805
|
const defaultSize = props.infinityScroll ? 100 : props.defaultSize || 10;
|
|
@@ -3567,31 +3807,27 @@ const DataTable = (props) => {
|
|
|
3567
3807
|
const [size, setSize] = useState(String(defaultSize));
|
|
3568
3808
|
const [currentPage, setCurrentPage] = useState(0);
|
|
3569
3809
|
const alepha = useInject(Alepha);
|
|
3810
|
+
const sentinelRef = useRef(null);
|
|
3570
3811
|
const [columnVisibility, setColumnVisibility] = useState(() => {
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
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
|
+
}, {});
|
|
3578
3822
|
});
|
|
3579
3823
|
const [filterVisibility, setFilterVisibility] = useState(() => {
|
|
3580
|
-
if (props.defaultFilterVisibility) return props.defaultFilterVisibility;
|
|
3581
3824
|
if (!props.filters?.properties) return {};
|
|
3825
|
+
const defaults = new Set(props.defaultFilters ?? []);
|
|
3582
3826
|
return Object.keys(props.filters.properties).reduce((acc, key) => ({
|
|
3583
3827
|
...acc,
|
|
3584
|
-
[key]:
|
|
3828
|
+
[key]: defaults.has(key)
|
|
3585
3829
|
}), {});
|
|
3586
3830
|
});
|
|
3587
|
-
const handleColumnVisibilityChange = (visibility) => {
|
|
3588
|
-
setColumnVisibility(visibility);
|
|
3589
|
-
props.onColumnVisibilityChange?.(visibility);
|
|
3590
|
-
};
|
|
3591
|
-
const handleFilterVisibilityChange = (visibility) => {
|
|
3592
|
-
setFilterVisibility(visibility);
|
|
3593
|
-
props.onFilterVisibilityChange?.(visibility);
|
|
3594
|
-
};
|
|
3595
3831
|
const visibleColumns = useMemo(() => {
|
|
3596
3832
|
return Object.entries(props.columns).filter(([key]) => columnVisibility[key] !== false);
|
|
3597
3833
|
}, [props.columns, columnVisibility]);
|
|
@@ -3602,64 +3838,38 @@ const DataTable = (props) => {
|
|
|
3602
3838
|
form.input.sort.set(newSort);
|
|
3603
3839
|
form.input.page.set(0);
|
|
3604
3840
|
};
|
|
3605
|
-
const [selectedKeys, setSelectedKeys] = useState(/* @__PURE__ */ new Set());
|
|
3606
3841
|
const getItemKey = useCallback((item) => {
|
|
3607
3842
|
if (props.getItemKey) return props.getItemKey(item);
|
|
3843
|
+
if ("id" in item) return String(item.id);
|
|
3608
3844
|
return JSON.stringify(item);
|
|
3609
3845
|
}, [props.getItemKey]);
|
|
3610
|
-
const
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
props.
|
|
3618
|
-
]);
|
|
3619
|
-
const
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
items.content,
|
|
3633
|
-
selectedKeys,
|
|
3634
|
-
getItemKey
|
|
3635
|
-
]);
|
|
3636
|
-
const toggleItemSelection = useCallback((item) => {
|
|
3637
|
-
const key = getItemKey(item);
|
|
3638
|
-
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) => {
|
|
3639
3868
|
const next = new Set(prev);
|
|
3640
3869
|
if (next.has(key)) next.delete(key);
|
|
3641
3870
|
else next.add(key);
|
|
3642
3871
|
return next;
|
|
3643
3872
|
});
|
|
3644
|
-
}, [getItemKey]);
|
|
3645
|
-
const toggleAllSelection = useCallback(() => {
|
|
3646
|
-
if (allSelected) setSelectedKeys((prev) => {
|
|
3647
|
-
const next = new Set(prev);
|
|
3648
|
-
for (const item of items.content) next.delete(getItemKey(item));
|
|
3649
|
-
return next;
|
|
3650
|
-
});
|
|
3651
|
-
else setSelectedKeys((prev) => {
|
|
3652
|
-
const next = new Set(prev);
|
|
3653
|
-
for (const item of items.content) next.add(getItemKey(item));
|
|
3654
|
-
return next;
|
|
3655
|
-
});
|
|
3656
|
-
}, [
|
|
3657
|
-
allSelected,
|
|
3658
|
-
items.content,
|
|
3659
|
-
getItemKey
|
|
3660
|
-
]);
|
|
3661
|
-
const clearSelection = useCallback(() => {
|
|
3662
|
-
setSelectedKeys(/* @__PURE__ */ new Set());
|
|
3663
3873
|
}, []);
|
|
3664
3874
|
const form = useForm({
|
|
3665
3875
|
schema: t.object({
|
|
@@ -3681,7 +3891,7 @@ const DataTable = (props) => {
|
|
|
3681
3891
|
},
|
|
3682
3892
|
onReset: async () => {
|
|
3683
3893
|
setPage(1);
|
|
3684
|
-
setSize(
|
|
3894
|
+
setSize(String(defaultSize));
|
|
3685
3895
|
await form.submit();
|
|
3686
3896
|
},
|
|
3687
3897
|
onChange: async (key, value) => {
|
|
@@ -3698,7 +3908,6 @@ const DataTable = (props) => {
|
|
|
3698
3908
|
props.onFilterChange?.(key, value, form);
|
|
3699
3909
|
}
|
|
3700
3910
|
}, [items]);
|
|
3701
|
-
useDebouncedCallback(() => form.submit(), { delay: 800 });
|
|
3702
3911
|
const dt = useInject(DateTimeProvider);
|
|
3703
3912
|
useEffect(() => {
|
|
3704
3913
|
if (props.submitOnInit) form.submit();
|
|
@@ -3714,18 +3923,15 @@ const DataTable = (props) => {
|
|
|
3714
3923
|
}, [props.items]);
|
|
3715
3924
|
useEffect(() => {
|
|
3716
3925
|
if (!props.infinityScroll || typeof props.items !== "function") return;
|
|
3717
|
-
const
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
const
|
|
3722
|
-
if (
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
};
|
|
3727
|
-
window.addEventListener("scroll", handleScroll);
|
|
3728
|
-
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();
|
|
3729
3935
|
}, [
|
|
3730
3936
|
props.infinityScroll,
|
|
3731
3937
|
form.submitting,
|
|
@@ -3733,63 +3939,134 @@ const DataTable = (props) => {
|
|
|
3733
3939
|
currentPage,
|
|
3734
3940
|
form
|
|
3735
3941
|
]);
|
|
3942
|
+
const totalColumns = visibleColumns.length + (panelConfig ? 1 : 0) + (props.withCheckbox ? 1 : 0);
|
|
3736
3943
|
const checkboxHeader = props.withCheckbox ? /* @__PURE__ */ jsx(Table.Th, {
|
|
3737
3944
|
style: { width: 40 },
|
|
3738
3945
|
children: /* @__PURE__ */ jsx(Checkbox, {
|
|
3739
|
-
checked: allSelected,
|
|
3740
|
-
indeterminate: someSelected,
|
|
3741
|
-
onChange:
|
|
3946
|
+
checked: selection.allSelected,
|
|
3947
|
+
indeterminate: selection.someSelected,
|
|
3948
|
+
onChange: selection.toggleAll,
|
|
3742
3949
|
"aria-label": "Select all"
|
|
3743
3950
|
})
|
|
3744
3951
|
}) : null;
|
|
3745
3952
|
const head = visibleColumns.map(([key, col]) => {
|
|
3746
3953
|
const sortField = col.sortKey || key;
|
|
3747
3954
|
const sortDir = col.sortable ? getSortDirection(sortString, sortField) : null;
|
|
3748
|
-
const headerContent = /* @__PURE__ */ jsxs(Flex$1, {
|
|
3749
|
-
align: "center",
|
|
3750
|
-
gap: 4,
|
|
3751
|
-
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
3752
|
-
size: "xs",
|
|
3753
|
-
children: col.label
|
|
3754
|
-
}), col.sortable && /* @__PURE__ */ jsxs(Flex$1, {
|
|
3755
|
-
c: "dimmed",
|
|
3756
|
-
children: [
|
|
3757
|
-
sortDir === "asc" && /* @__PURE__ */ jsx(IconArrowUp, { size: ui.sizes.icon.sm }),
|
|
3758
|
-
sortDir === "desc" && /* @__PURE__ */ jsx(IconArrowDown, { size: ui.sizes.icon.sm }),
|
|
3759
|
-
sortDir === null && /* @__PURE__ */ jsx(IconArrowsSort, { size: ui.sizes.icon.sm })
|
|
3760
|
-
]
|
|
3761
|
-
})]
|
|
3762
|
-
});
|
|
3763
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,
|
|
3764
3958
|
style: {
|
|
3765
|
-
...col.fit ?
|
|
3766
|
-
...col.sortable ? {
|
|
3959
|
+
...col.fit ? FIT_STYLE : {},
|
|
3960
|
+
...col.sortable ? {
|
|
3961
|
+
cursor: "pointer",
|
|
3962
|
+
userSelect: "none"
|
|
3963
|
+
} : {}
|
|
3767
3964
|
},
|
|
3768
|
-
children:
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
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
|
+
})
|
|
3772
3980
|
}, key);
|
|
3773
3981
|
});
|
|
3774
|
-
const rows = items.content.
|
|
3982
|
+
const rows = items.content.flatMap((item, index) => {
|
|
3775
3983
|
const trProps = props.tableTrProps ? props.tableTrProps(item) : {};
|
|
3776
3984
|
const itemKey = getItemKey(item);
|
|
3777
|
-
const isSelected =
|
|
3778
|
-
|
|
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, {
|
|
3779
3990
|
...trProps,
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
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);
|
|
3786
4061
|
})
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
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;
|
|
3793
4070
|
});
|
|
3794
4071
|
const filterSchema = useMemo(() => {
|
|
3795
4072
|
if (!props.filters) return null;
|
|
@@ -3802,25 +4079,25 @@ const DataTable = (props) => {
|
|
|
3802
4079
|
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
3803
4080
|
flex: 1,
|
|
3804
4081
|
p: 0,
|
|
3805
|
-
bg: "var(--alepha-elevated)",
|
|
3806
4082
|
bdrs: "sm",
|
|
3807
|
-
bd: "1px solid var(--alepha-border)",
|
|
3808
4083
|
direction: "column",
|
|
3809
4084
|
children: [
|
|
3810
|
-
/* @__PURE__ */ jsx(
|
|
4085
|
+
/* @__PURE__ */ jsx(DataTableToolbar, {
|
|
3811
4086
|
columns: props.columns,
|
|
3812
4087
|
filters: props.filters,
|
|
3813
4088
|
columnVisibility,
|
|
3814
4089
|
filterVisibility,
|
|
3815
|
-
onColumnVisibilityChange:
|
|
3816
|
-
onFilterVisibilityChange:
|
|
4090
|
+
onColumnVisibilityChange: setColumnVisibility,
|
|
4091
|
+
onFilterVisibilityChange: setFilterVisibility,
|
|
3817
4092
|
actions: props.actions,
|
|
3818
4093
|
onRefresh: () => form.submit(),
|
|
3819
|
-
|
|
4094
|
+
items: items.content,
|
|
4095
|
+
withExport: props.withExport,
|
|
4096
|
+
selectedItems: selection.selectedItems,
|
|
3820
4097
|
checkboxActions: props.checkboxActions,
|
|
3821
|
-
onClearSelection:
|
|
4098
|
+
onClearSelection: selection.clear
|
|
3822
4099
|
}),
|
|
3823
|
-
filterSchema && props.filters && /* @__PURE__ */ jsx(
|
|
4100
|
+
filterSchema && props.filters && /* @__PURE__ */ jsx(DataTableFilters, {
|
|
3824
4101
|
schema: filterSchema,
|
|
3825
4102
|
form,
|
|
3826
4103
|
typeFormProps: props.typeFormProps,
|
|
@@ -3829,13 +4106,42 @@ const DataTable = (props) => {
|
|
|
3829
4106
|
/* @__PURE__ */ jsx(Flex$1, {
|
|
3830
4107
|
className: "overflow-auto",
|
|
3831
4108
|
children: /* @__PURE__ */ jsxs(Table, {
|
|
4109
|
+
"aria-label": "Data table",
|
|
3832
4110
|
withColumnBorders: true,
|
|
3833
4111
|
withRowBorders: true,
|
|
3834
4112
|
...props.tableProps,
|
|
3835
|
-
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
|
+
})]
|
|
3836
4141
|
})
|
|
3837
4142
|
}),
|
|
3838
|
-
|
|
4143
|
+
props.infinityScroll && /* @__PURE__ */ jsx("div", { ref: sentinelRef }),
|
|
4144
|
+
!props.infinityScroll && /* @__PURE__ */ jsx(DataTablePagination, {
|
|
3839
4145
|
page,
|
|
3840
4146
|
size,
|
|
3841
4147
|
totalPages: items.page?.totalPages ?? 1,
|
|
@@ -3845,11 +4151,18 @@ const DataTable = (props) => {
|
|
|
3845
4151
|
onSizeChange: (value) => {
|
|
3846
4152
|
form.input.size.set(value);
|
|
3847
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)
|
|
3848
4162
|
})
|
|
3849
4163
|
]
|
|
3850
4164
|
});
|
|
3851
4165
|
};
|
|
3852
|
-
var DataTable_default = DataTable;
|
|
3853
4166
|
|
|
3854
4167
|
//#endregion
|
|
3855
4168
|
//#region ../../src/core/hooks/useDialog.ts
|
|
@@ -3883,7 +4196,7 @@ const useDialog = () => {
|
|
|
3883
4196
|
* - AlertDialog, ConfirmDialog, PromptDialog
|
|
3884
4197
|
* - Form controls: Control, ControlArray, ControlDate, ControlNumber, ControlObject, ControlSelect, ControlQueryBuilder
|
|
3885
4198
|
* - TypeForm for automatic form generation from TypeBox schemas
|
|
3886
|
-
* -
|
|
4199
|
+
* - DashboardShell layout component
|
|
3887
4200
|
* - AppBar with configurable elements
|
|
3888
4201
|
* - Sidebar navigation with sections and menu items
|
|
3889
4202
|
* - Omnibar for command palette / search
|
|
@@ -3920,5 +4233,5 @@ const $ui = (options = {}) => {
|
|
|
3920
4233
|
};
|
|
3921
4234
|
|
|
3922
4235
|
//#endregion
|
|
3923
|
-
export { $ui,
|
|
4236
|
+
export { $ui, ActionButton, DashboardShell as AdminShell, DashboardShell, AlephaMantineProvider, AlephaUI, AlertDialog, AppBar, Breadcrumb, BurgerButton, ClipboardButton, ConfirmDialog, Control, ControlArray, ControlDate, ControlNumber, ControlObject, ControlQueryBuilder, ControlSelect, DarkModeButton, DataTable, DialogService, Flex, LanguageButton, OPERATOR_INFO, Omnibar, OmnibarButton, PromptDialog, Sidebar, Text, ThemeButton, ThemeProvider, ToastService, ToggleSidebarButton, TypeForm, UiRouter, alephaSidebarAtom, alephaThemeAtom, alephaThemeListAtom, capitalize, defaultTheme, extractSchemaFields, getDefaultIcon, getOperatorsForField, midnightTheme, prettyName, toTitleCase, ui, useDialog, useToast };
|
|
3924
4237
|
//# sourceMappingURL=index.js.map
|