@alepha/ui 0.18.2 → 0.18.3
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-BJhIwfD6.js → AdminApiKeys-Dy_k-4Vd.js} +2 -2
- package/dist/admin/{AdminApiKeys-BJhIwfD6.js.map → AdminApiKeys-Dy_k-4Vd.js.map} +1 -1
- package/dist/admin/{AdminAudits-DzD_4cDt.js → AdminAudits-CKiFMSSU.js} +2 -2
- package/dist/admin/{AdminAudits-DzD_4cDt.js.map → AdminAudits-CKiFMSSU.js.map} +1 -1
- package/dist/admin/{AdminDashboard-C92tIc6x.js → AdminDashboard-PhC_dZqo.js} +2 -2
- package/dist/admin/{AdminDashboard-C92tIc6x.js.map → AdminDashboard-PhC_dZqo.js.map} +1 -1
- package/dist/admin/{AdminFiles-DLpfhBkf.js → AdminFiles-DFTjijGp.js} +2 -2
- package/dist/admin/{AdminFiles-DLpfhBkf.js.map → AdminFiles-DFTjijGp.js.map} +1 -1
- package/dist/admin/{AdminJobDashboard-KIOkeMgE.js → AdminJobDashboard-BL8gGPDp.js} +2 -2
- package/dist/admin/{AdminJobDashboard-KIOkeMgE.js.map → AdminJobDashboard-BL8gGPDp.js.map} +1 -1
- package/dist/admin/{AdminJobExecutions-D0Yo_PU0.js → AdminJobExecutions-D9E-CS-U.js} +2 -2
- package/dist/admin/{AdminJobExecutions-D0Yo_PU0.js.map → AdminJobExecutions-D9E-CS-U.js.map} +1 -1
- package/dist/admin/{AdminJobRegistry-PFajqaGK.js → AdminJobRegistry-Ci9ue1zC.js} +2 -2
- package/dist/admin/{AdminJobRegistry-PFajqaGK.js.map → AdminJobRegistry-Ci9ue1zC.js.map} +1 -1
- package/dist/admin/{AdminLayout-B1DXZHDn.js → AdminLayout-I6TlUMPc.js} +2 -2
- package/dist/admin/{AdminLayout-B1DXZHDn.js.map → AdminLayout-I6TlUMPc.js.map} +1 -1
- package/dist/admin/AdminNotifications-ZPHCYrv7.js +542 -0
- package/dist/admin/AdminNotifications-ZPHCYrv7.js.map +1 -0
- package/dist/admin/{AdminParameters-BspPeqp_.js → AdminParameters-CqgvhRsb.js} +120 -105
- package/dist/admin/AdminParameters-CqgvhRsb.js.map +1 -0
- package/dist/admin/{AdminSessions-BnH5CZQl.js → AdminSessions-Bz5NRuoW.js} +2 -2
- package/dist/admin/{AdminSessions-BnH5CZQl.js.map → AdminSessions-Bz5NRuoW.js.map} +1 -1
- package/dist/admin/{AdminUserLayout-DUbC6-BI.js → AdminUserLayout-lXT6I0Qq.js} +14 -8
- package/dist/admin/AdminUserLayout-lXT6I0Qq.js.map +1 -0
- package/dist/admin/{AdminUserProfile-DuTUnjdG.js → AdminUserProfile-vFBLoJ3h.js} +3 -3
- package/dist/admin/{AdminUserProfile-DuTUnjdG.js.map → AdminUserProfile-vFBLoJ3h.js.map} +1 -1
- package/dist/admin/{AdminUserSessions-DvZdAGpL.js → AdminUserSessions-CT_YDim0.js} +2 -2
- package/dist/admin/{AdminUserSessions-DvZdAGpL.js.map → AdminUserSessions-CT_YDim0.js.map} +1 -1
- package/dist/admin/{AdminUsers-CR9z0g_5.js → AdminUsers-D1UfGya9.js} +2 -2
- package/dist/admin/{AdminUsers-CR9z0g_5.js.map → AdminUsers-D1UfGya9.js.map} +1 -1
- package/dist/admin/{AuthLayout-DsUfp9RG.js → AuthLayout-_frhdgOO.js} +2 -2
- package/dist/admin/{AuthLayout-DsUfp9RG.js.map → AuthLayout-_frhdgOO.js.map} +1 -1
- package/dist/admin/Login-xtNmQtGh.js +275 -0
- package/dist/admin/Login-xtNmQtGh.js.map +1 -0
- package/dist/admin/{Profile-B2EcIDB9.js → Profile-_AtPUwAP.js} +31 -27
- package/dist/admin/Profile-_AtPUwAP.js.map +1 -0
- package/dist/admin/{Register-Z3fxRbUF.js → Register-JcCjHUUn.js} +198 -142
- package/dist/admin/Register-JcCjHUUn.js.map +1 -0
- package/dist/admin/{ResetPassword-_Y1qTTKh.js → ResetPassword-CwGBPLJO.js} +7 -7
- package/dist/admin/ResetPassword-CwGBPLJO.js.map +1 -0
- package/dist/admin/{VerifyEmail-Bg22bwcC.js → VerifyEmail-hNxWejWf.js} +23 -8
- package/dist/admin/VerifyEmail-hNxWejWf.js.map +1 -0
- package/dist/admin/{core-BVO_TQxb.js → core-CYaRQ8O-.js} +709 -556
- package/dist/admin/core-CYaRQ8O-.js.map +1 -0
- package/dist/admin/index.d.ts +83 -44
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +58 -39
- package/dist/admin/index.js.map +1 -1
- package/dist/auth/{AuthLayout-C161NeF6.js → AuthLayout-AvLlcLjS.js} +2 -2
- package/dist/auth/{AuthLayout-C161NeF6.js.map → AuthLayout-AvLlcLjS.js.map} +1 -1
- package/dist/auth/Login-BA1E8IZl.js +275 -0
- package/dist/auth/Login-BA1E8IZl.js.map +1 -0
- package/dist/auth/{Profile-BMpXJ0oi.js → Profile-YcWdeuFz.js} +31 -27
- package/dist/auth/Profile-YcWdeuFz.js.map +1 -0
- package/dist/auth/{Register-2gx8qll-.js → Register-CPhEO5MG.js} +198 -142
- package/dist/auth/Register-CPhEO5MG.js.map +1 -0
- package/dist/{demo/ResetPassword-CAPj8MO3.js → auth/ResetPassword-DCtGcneA.js} +7 -7
- package/dist/auth/ResetPassword-DCtGcneA.js.map +1 -0
- package/dist/{demo/VerifyEmail-DFmdCdYs.js → auth/VerifyEmail-DkH7NBfn.js} +23 -8
- package/dist/auth/VerifyEmail-DkH7NBfn.js.map +1 -0
- package/dist/auth/{core-DyfeVr5c.js → core-D5jIAVF2.js} +386 -294
- package/dist/auth/core-D5jIAVF2.js.map +1 -0
- package/dist/auth/index.d.ts +93 -48
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +28 -24
- package/dist/auth/index.js.map +1 -1
- package/dist/core/index.d.ts +116 -61
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +873 -701
- package/dist/core/index.js.map +1 -1
- package/dist/demo/{AuthLayout-DN-ClJQk.js → AuthLayout-Brri4A-L.js} +2 -2
- package/dist/demo/{AuthLayout-DN-ClJQk.js.map → AuthLayout-Brri4A-L.js.map} +1 -1
- package/dist/demo/DemoButton-wiCxZZ_L.js +182 -0
- package/dist/demo/DemoButton-wiCxZZ_L.js.map +1 -0
- package/dist/demo/DemoControlSelect-D7ILObVg.js +305 -0
- package/dist/demo/DemoControlSelect-D7ILObVg.js.map +1 -0
- package/dist/demo/DemoDataTable-DZ5Y8pFX.js +362 -0
- package/dist/demo/DemoDataTable-DZ5Y8pFX.js.map +1 -0
- package/dist/demo/{DemoDialog-DW8QEvD1.js → DemoDialog-CUWdLHim.js} +2 -2
- package/dist/demo/{DemoDialog-DW8QEvD1.js.map → DemoDialog-CUWdLHim.js.map} +1 -1
- package/dist/demo/{DemoFlex-CAhLUanT.js → DemoFlex-a8OhMMvq.js} +3 -3
- package/dist/demo/{DemoFlex-CAhLUanT.js.map → DemoFlex-a8OhMMvq.js.map} +1 -1
- package/dist/demo/{DemoHeading-yIFmNjHB.js → DemoHeading-C13OVDfS.js} +3 -3
- package/dist/demo/{DemoHeading-yIFmNjHB.js.map → DemoHeading-C13OVDfS.js.map} +1 -1
- package/dist/demo/{DemoHome-BSGuBHus.js → DemoHome-D_De3UiT.js} +2 -2
- package/dist/demo/{DemoHome-BSGuBHus.js.map → DemoHome-D_De3UiT.js.map} +1 -1
- package/dist/demo/{DemoJsonViewer-DsA2IpgV.js → DemoJsonViewer-B50s9aGM.js} +3 -3
- package/dist/demo/{DemoJsonViewer-DsA2IpgV.js.map → DemoJsonViewer-B50s9aGM.js.map} +1 -1
- package/dist/demo/{DemoLayout-Cy6xjn6P.js → DemoLayout-CHU8WTwO.js} +14 -5
- package/dist/demo/DemoLayout-CHU8WTwO.js.map +1 -0
- package/dist/demo/{DemoLogin-vqxgTu4P.js → DemoLogin-BBlrWpml.js} +49 -32
- package/dist/demo/DemoLogin-BBlrWpml.js.map +1 -0
- package/dist/demo/{DemoRegister-YHPvPg77.js → DemoRegister-BuNE3_-f.js} +49 -50
- package/dist/demo/DemoRegister-BuNE3_-f.js.map +1 -0
- package/dist/demo/{DemoResetPassword-mOW18Zlm.js → DemoResetPassword-D_IjjjOJ.js} +12 -16
- package/dist/demo/DemoResetPassword-D_IjjjOJ.js.map +1 -0
- package/dist/demo/{DemoSidebar-od7aLjP_.js → DemoSidebar-Giy2HRBD.js} +3 -3
- package/dist/demo/{DemoSidebar-od7aLjP_.js.map → DemoSidebar-Giy2HRBD.js.map} +1 -1
- package/dist/demo/{DemoText-DU3JeRS0.js → DemoText-ubcw-vog.js} +3 -3
- package/dist/demo/{DemoText-DU3JeRS0.js.map → DemoText-ubcw-vog.js.map} +1 -1
- package/dist/demo/{DemoToast-CUJEiPRa.js → DemoToast-9die_dYT.js} +2 -2
- package/dist/demo/{DemoToast-CUJEiPRa.js.map → DemoToast-9die_dYT.js.map} +1 -1
- package/dist/demo/{DemoTypeForm-C1dNkahD.js → DemoTypeForm-D_d6OVKL.js} +8 -4
- package/dist/demo/DemoTypeForm-D_d6OVKL.js.map +1 -0
- package/dist/demo/DemoVerifyEmail-B43KlF4F.js +34 -0
- package/dist/demo/DemoVerifyEmail-B43KlF4F.js.map +1 -0
- package/dist/demo/Login-C12N4oGs.js +275 -0
- package/dist/demo/Login-C12N4oGs.js.map +1 -0
- package/dist/demo/{Profile-BE_Y3co2.js → Profile-DS5q4vOh.js} +31 -27
- package/dist/demo/Profile-DS5q4vOh.js.map +1 -0
- package/dist/demo/{Register-fXHmBpr3.js → Register-B4hLBeEv.js} +198 -142
- package/dist/demo/Register-B4hLBeEv.js.map +1 -0
- package/dist/{auth/ResetPassword-DBxt9hKk.js → demo/ResetPassword-D8g9ha1N.js} +7 -7
- package/dist/demo/ResetPassword-D8g9ha1N.js.map +1 -0
- package/dist/demo/{Showcase-BtEU0pY9.js → Showcase-D6Fxt4X4.js} +64 -65
- package/dist/demo/Showcase-D6Fxt4X4.js.map +1 -0
- package/dist/{auth/VerifyEmail-Z80Ubajk.js → demo/VerifyEmail-BjDo0cZA.js} +23 -8
- package/dist/demo/VerifyEmail-BjDo0cZA.js.map +1 -0
- package/dist/demo/{auth-Djd7SKiw.js → auth-ByVTreDl.js} +8 -8
- package/dist/demo/{auth-Djd7SKiw.js.map → auth-ByVTreDl.js.map} +1 -1
- package/dist/demo/{core-B7LNjM78.js → core-DFgB3yU4.js} +741 -573
- package/dist/demo/core-DFgB3yU4.js.map +1 -0
- package/dist/demo/index.d.ts +1 -0
- package/dist/demo/index.d.ts.map +1 -1
- package/dist/demo/index.js +24 -18
- package/dist/demo/index.js.map +1 -1
- package/package.json +7 -7
- package/src/admin/AdminRouter.tsx +24 -1
- package/src/admin/components/notifications/AdminNotifications.tsx +519 -0
- package/src/admin/components/parameters/ParameterDetails.tsx +12 -270
- package/src/admin/components/parameters/ParameterDetailsConfigForm.tsx +238 -0
- package/src/admin/components/parameters/ParameterDetailsLoading.tsx +24 -0
- package/src/admin/components/parameters/ParameterHistory.tsx +10 -11
- package/src/admin/components/parameters/ParameterTree.tsx +28 -184
- package/src/admin/components/parameters/ParameterTreeNode.tsx +151 -0
- package/src/admin/components/shared/AdminResourceHeader.tsx +2 -25
- package/src/admin/components/shared/AdminResourceHeaderMenuItem.tsx +37 -0
- package/src/admin/components/shared/AdminResourceTabs.tsx +2 -26
- package/src/admin/components/shared/AdminResourceTabsItem.tsx +36 -0
- package/src/auth/components/Login.tsx +188 -121
- package/src/auth/components/Profile.tsx +1 -22
- package/src/auth/components/ProfileField.tsx +39 -0
- package/src/auth/components/Register.tsx +215 -158
- package/src/auth/components/ResetPassword.tsx +7 -11
- package/src/auth/components/VerifyEmail.tsx +35 -10
- package/src/auth/components/buttons/UserButton.tsx +19 -21
- package/src/auth/index.ts +1 -0
- package/src/core/components/Flex.tsx +10 -0
- package/src/core/components/buttons/ActionButton.tsx +104 -78
- package/src/core/components/data/DetailDrawer.tsx +102 -96
- package/src/core/components/data/DetailList.tsx +2 -1
- package/src/core/components/layout/Breadcrumb.tsx +3 -6
- package/src/core/components/layout/DashboardShell.tsx +18 -4
- package/src/core/components/layout/Sidebar.tsx +16 -241
- package/src/core/components/layout/SidebarCollapsedItem.tsx +91 -0
- package/src/core/components/layout/SidebarItem.tsx +146 -0
- package/src/core/components/layout/index.ts +3 -1
- package/src/core/form/components/Control.tsx +31 -29
- package/src/core/form/components/ControlArray.tsx +13 -39
- package/src/core/form/components/ControlDate.tsx +10 -21
- package/src/core/form/components/ControlNumber.tsx +4 -33
- package/src/core/form/components/ControlQueryBuilder.tsx +12 -175
- package/src/core/form/components/ControlQueryBuilderHelp.tsx +165 -0
- package/src/core/form/components/ControlSelect.browser.spec.tsx +343 -0
- package/src/core/form/components/ControlSelect.tsx +294 -92
- package/src/core/form/components/TypeForm.browser.spec.tsx +3 -3
- package/src/core/form/components/TypeForm.tsx +5 -2
- package/src/core/form/index.ts +8 -1
- package/src/core/form/utils/parseInput.ts +7 -3
- package/src/core/index.ts +3 -1
- package/src/core/json/components/JsonViewer.tsx +103 -319
- package/src/core/json/components/JsonViewerCopyButton.tsx +46 -0
- package/src/core/json/components/JsonViewerRowNode.tsx +120 -0
- package/src/core/json/components/JsonViewerShared.ts +76 -0
- package/src/core/styles.css +12 -2
- package/src/core/table/components/ColumnPicker.tsx +3 -3
- package/src/core/table/components/DataTable.tsx +89 -29
- package/src/core/table/components/DataTableFilters.tsx +6 -11
- package/src/core/table/components/DataTablePagination.tsx +9 -3
- package/src/core/table/components/DataTableToolbar.tsx +7 -3
- package/src/core/table/components/FilterPicker.tsx +3 -3
- package/src/core/table/interfaces/types.ts +29 -0
- package/src/core/utils/icons.tsx +2 -2
- package/src/demo/DemoRouter.ts +8 -1
- package/src/demo/components/DemoLayout.tsx +12 -2
- package/src/demo/components/auth/DemoLogin.tsx +35 -28
- package/src/demo/components/auth/DemoRegister.tsx +35 -49
- package/src/demo/components/auth/DemoResetPassword.tsx +5 -9
- package/src/demo/components/auth/DemoVerifyEmail.tsx +7 -6
- package/src/demo/components/core/DemoButton.tsx +123 -103
- package/src/demo/components/core/DemoControlSelect.tsx +325 -0
- package/src/demo/components/core/DemoDataTable.tsx +255 -237
- package/src/demo/components/core/DemoTypeForm.tsx +7 -2
- package/src/demo/components/shared/MacWindow.tsx +5 -11
- package/src/demo/components/shared/Showcase.tsx +28 -42
- package/dist/admin/AdminParameters-BspPeqp_.js.map +0 -1
- package/dist/admin/AdminUserLayout-DUbC6-BI.js.map +0 -1
- package/dist/admin/Login-DHbYJKwg.js +0 -219
- package/dist/admin/Login-DHbYJKwg.js.map +0 -1
- package/dist/admin/Profile-B2EcIDB9.js.map +0 -1
- package/dist/admin/Register-Z3fxRbUF.js.map +0 -1
- package/dist/admin/ResetPassword-_Y1qTTKh.js.map +0 -1
- package/dist/admin/VerifyEmail-Bg22bwcC.js.map +0 -1
- package/dist/admin/core-BVO_TQxb.js.map +0 -1
- package/dist/auth/Login-C7jIqf00.js +0 -219
- package/dist/auth/Login-C7jIqf00.js.map +0 -1
- package/dist/auth/Profile-BMpXJ0oi.js.map +0 -1
- package/dist/auth/Register-2gx8qll-.js.map +0 -1
- package/dist/auth/ResetPassword-DBxt9hKk.js.map +0 -1
- package/dist/auth/VerifyEmail-Z80Ubajk.js.map +0 -1
- package/dist/auth/core-DyfeVr5c.js.map +0 -1
- package/dist/demo/DemoButton-CGUyR9eM.js +0 -178
- package/dist/demo/DemoButton-CGUyR9eM.js.map +0 -1
- package/dist/demo/DemoDataTable-QFG-xXSx.js +0 -358
- package/dist/demo/DemoDataTable-QFG-xXSx.js.map +0 -1
- package/dist/demo/DemoLayout-Cy6xjn6P.js.map +0 -1
- package/dist/demo/DemoLogin-vqxgTu4P.js.map +0 -1
- package/dist/demo/DemoRegister-YHPvPg77.js.map +0 -1
- package/dist/demo/DemoResetPassword-mOW18Zlm.js.map +0 -1
- package/dist/demo/DemoTypeForm-C1dNkahD.js.map +0 -1
- package/dist/demo/DemoVerifyEmail-D9EcXZ38.js +0 -30
- package/dist/demo/DemoVerifyEmail-D9EcXZ38.js.map +0 -1
- package/dist/demo/Login-CoYf_P_F.js +0 -219
- package/dist/demo/Login-CoYf_P_F.js.map +0 -1
- package/dist/demo/Profile-BE_Y3co2.js.map +0 -1
- package/dist/demo/Register-fXHmBpr3.js.map +0 -1
- package/dist/demo/ResetPassword-CAPj8MO3.js.map +0 -1
- package/dist/demo/Showcase-BtEU0pY9.js.map +0 -1
- package/dist/demo/VerifyEmail-DFmdCdYs.js.map +0 -1
- package/dist/demo/core-B7LNjM78.js.map +0 -1
- package/src/demo/styles.css +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { $atom, $context, $inject, $module, Alepha, AlephaError, TypeBoxError, t } from "alepha";
|
|
2
|
-
import { AlephaReactForm, FormValidationError, useForm, useFormState } from "alepha/react/form";
|
|
2
|
+
import { AlephaReactForm, FormValidationError, useFieldValue, useForm, useFormState } from "alepha/react/form";
|
|
3
3
|
import { $head, AlephaReactHead, BrowserHeadProvider } from "alepha/react/head";
|
|
4
4
|
import { AlephaReactI18n, useI18n } from "alepha/react/i18n";
|
|
5
5
|
import { $cookie } from "alepha/server/cookies";
|
|
@@ -1548,41 +1548,10 @@ function isComponentType(param) {
|
|
|
1548
1548
|
|
|
1549
1549
|
//#endregion
|
|
1550
1550
|
//#region ../../src/core/components/buttons/ActionButton.tsx
|
|
1551
|
-
const ActionMenuItem = (props) => {
|
|
1552
|
-
const { item, index } = props;
|
|
1553
|
-
const router = useRouter();
|
|
1554
|
-
const action = useAction({ handler: async (e) => {
|
|
1555
|
-
await item.onClick?.();
|
|
1556
|
-
} }, [item.onClick]);
|
|
1557
|
-
if (item.type === "divider") return /* @__PURE__ */ jsx(Menu.Divider, {}, index);
|
|
1558
|
-
if (item.type === "label") return /* @__PURE__ */ jsx(Menu.Label, { children: item.label }, index);
|
|
1559
|
-
if (item.children && item.children.length > 0) return /* @__PURE__ */ jsxs(Menu, {
|
|
1560
|
-
trigger: "hover",
|
|
1561
|
-
position: "right-start",
|
|
1562
|
-
offset: 2,
|
|
1563
|
-
children: [/* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Menu.Item, {
|
|
1564
|
-
leftSection: item.icon,
|
|
1565
|
-
rightSection: /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }),
|
|
1566
|
-
children: item.label
|
|
1567
|
-
}) }), /* @__PURE__ */ jsx(Menu.Dropdown, { children: item.children.map((child, childIndex) => /* @__PURE__ */ jsx(ActionMenuItem, {
|
|
1568
|
-
item: child,
|
|
1569
|
-
index: childIndex
|
|
1570
|
-
}, childIndex)) })]
|
|
1571
|
-
}, index);
|
|
1572
|
-
const menuItemProps = {};
|
|
1573
|
-
if (props.item.onClick) menuItemProps.onClick = action.run;
|
|
1574
|
-
else if (props.item.href) Object.assign(menuItemProps, router.anchor(props.item.href));
|
|
1575
|
-
return /* @__PURE__ */ jsx(Menu.Item, {
|
|
1576
|
-
leftSection: item.icon ?? (item.active ? /* @__PURE__ */ jsx(IconCheck, { size: ui.sizes.icon.sm }) : /* @__PURE__ */ jsx(Flex, { w: ui.sizes.icon.sm })),
|
|
1577
|
-
onClick: item.onClick,
|
|
1578
|
-
color: item.color,
|
|
1579
|
-
...menuItemProps,
|
|
1580
|
-
children: item.label
|
|
1581
|
-
}, index);
|
|
1582
|
-
};
|
|
1583
1551
|
const ActionButton = (_props) => {
|
|
1584
1552
|
const theme = useMantineTheme();
|
|
1585
1553
|
const props = { ..._props };
|
|
1554
|
+
if (props.variant === "minimal") {}
|
|
1586
1555
|
const { tooltip, menu, icon, iconSize, ...restProps } = props;
|
|
1587
1556
|
if (props.intent) {
|
|
1588
1557
|
if (props.intent === "primary") restProps.color ??= theme.primaryColor;
|
|
@@ -1627,6 +1596,7 @@ const ActionButton = (_props) => {
|
|
|
1627
1596
|
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
1628
1597
|
px: "xs",
|
|
1629
1598
|
...rest,
|
|
1599
|
+
"aria-label": typeof children === "string" ? children : void 0,
|
|
1630
1600
|
tooltip,
|
|
1631
1601
|
menu,
|
|
1632
1602
|
children: leftSection
|
|
@@ -1783,7 +1753,7 @@ const ActionClickButton = ({ preventDefault, ...props }) => {
|
|
|
1783
1753
|
* Action for navigation with active state support.
|
|
1784
1754
|
*/
|
|
1785
1755
|
const ActionNavigationButton = (props) => {
|
|
1786
|
-
const { active: options, classNameActive, variantActive, propsActive, routerGoOptions, onClick: propsOnClick, anchor, ...buttonProps } = props;
|
|
1756
|
+
const { active: options, classNameActive, variantActive, propsActive, routerGoOptions, onClick: propsOnClick, anchorProps: buttonAnchorProps, anchor, ...buttonProps } = props;
|
|
1787
1757
|
const router = useRouter();
|
|
1788
1758
|
const { isPending, isActive } = useActive(options ? {
|
|
1789
1759
|
href: props.href,
|
|
@@ -1797,11 +1767,11 @@ const ActionNavigationButton = (props) => {
|
|
|
1797
1767
|
};
|
|
1798
1768
|
const className = buttonProps.className || "";
|
|
1799
1769
|
if (isActive && options !== false && classNameActive) buttonProps.className = `${className} ${classNameActive}`.trim();
|
|
1800
|
-
if (
|
|
1770
|
+
if (buttonAnchorProps || anchor) return /* @__PURE__ */ jsx(Anchor, {
|
|
1801
1771
|
component: "a",
|
|
1802
1772
|
...anchorProps,
|
|
1803
1773
|
...buttonProps,
|
|
1804
|
-
...
|
|
1774
|
+
...buttonAnchorProps,
|
|
1805
1775
|
onClick: combinedOnClick,
|
|
1806
1776
|
children: props.children
|
|
1807
1777
|
});
|
|
@@ -1824,6 +1794,38 @@ const ActionHrefButton = (props) => {
|
|
|
1824
1794
|
children: props.children
|
|
1825
1795
|
});
|
|
1826
1796
|
};
|
|
1797
|
+
const ActionMenuItem = (props) => {
|
|
1798
|
+
const { item, index } = props;
|
|
1799
|
+
const router = useRouter();
|
|
1800
|
+
const action = useAction({ handler: async (e) => {
|
|
1801
|
+
await item.onClick?.();
|
|
1802
|
+
} }, [item.onClick]);
|
|
1803
|
+
if (item.type === "divider") return /* @__PURE__ */ jsx(Menu.Divider, {}, index);
|
|
1804
|
+
if (item.type === "label") return /* @__PURE__ */ jsx(Menu.Label, { children: item.label }, index);
|
|
1805
|
+
if (item.children && item.children.length > 0) return /* @__PURE__ */ jsxs(Menu, {
|
|
1806
|
+
trigger: "hover",
|
|
1807
|
+
position: "right-start",
|
|
1808
|
+
offset: 2,
|
|
1809
|
+
children: [/* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Menu.Item, {
|
|
1810
|
+
leftSection: item.icon,
|
|
1811
|
+
rightSection: /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }),
|
|
1812
|
+
children: item.label
|
|
1813
|
+
}) }), /* @__PURE__ */ jsx(Menu.Dropdown, { children: item.children.map((child, childIndex) => /* @__PURE__ */ jsx(ActionMenuItem, {
|
|
1814
|
+
item: child,
|
|
1815
|
+
index: childIndex
|
|
1816
|
+
}, childIndex)) })]
|
|
1817
|
+
}, index);
|
|
1818
|
+
const menuItemProps = {};
|
|
1819
|
+
if (props.item.onClick) menuItemProps.onClick = action.run;
|
|
1820
|
+
else if (props.item.href) Object.assign(menuItemProps, router.anchor(props.item.href));
|
|
1821
|
+
return /* @__PURE__ */ jsx(Menu.Item, {
|
|
1822
|
+
leftSection: item.icon ?? (item.active ? /* @__PURE__ */ jsx(IconCheck, { size: ui.sizes.icon.sm }) : /* @__PURE__ */ jsx(Flex, { w: ui.sizes.icon.sm })),
|
|
1823
|
+
onClick: item.onClick,
|
|
1824
|
+
color: item.color,
|
|
1825
|
+
...menuItemProps,
|
|
1826
|
+
children: item.label
|
|
1827
|
+
}, index);
|
|
1828
|
+
};
|
|
1827
1829
|
|
|
1828
1830
|
//#endregion
|
|
1829
1831
|
//#region ../../src/core/components/buttons/BurgerButton.tsx
|
|
@@ -2234,7 +2236,8 @@ const ToggleSidebarButton = (props) => {
|
|
|
2234
2236
|
|
|
2235
2237
|
//#endregion
|
|
2236
2238
|
//#region ../../src/core/components/data/DetailList.tsx
|
|
2237
|
-
const DetailList = (
|
|
2239
|
+
const DetailList = (props) => {
|
|
2240
|
+
const { items, columns = 1 } = props;
|
|
2238
2241
|
return /* @__PURE__ */ jsx(Grid, {
|
|
2239
2242
|
gutter: "xs",
|
|
2240
2243
|
children: items.filter((item) => !item.hidden).map((item) => /* @__PURE__ */ jsx(Grid.Col, {
|
|
@@ -2313,7 +2316,7 @@ const StatCards = ({ items }) => /* @__PURE__ */ jsx(Flex, {
|
|
|
2313
2316
|
//#endregion
|
|
2314
2317
|
//#region ../../src/core/components/Flex.tsx
|
|
2315
2318
|
const Flex$1 = forwardRef((props, ref) => {
|
|
2316
|
-
const { fill, center, centerX, centerY, col, ground, surface, elevated, rounded, bordered, borderedTop, borderedBottom, shadowed, ...rest } = props;
|
|
2319
|
+
const { fill, center, centerX, centerY, col, ground, surface, elevated, rounded, bordered, borderedTop, borderedBottom, shadowed, overflow, ...rest } = props;
|
|
2317
2320
|
if (fill) rest.flex ??= 1;
|
|
2318
2321
|
if (col) rest.direction ??= "column";
|
|
2319
2322
|
if (center) {
|
|
@@ -2336,6 +2339,7 @@ const Flex$1 = forwardRef((props, ref) => {
|
|
|
2336
2339
|
...rest.style ?? {}
|
|
2337
2340
|
};
|
|
2338
2341
|
if (shadowed) rest.className = `${rest.className ?? ""} shadow-${shadowed === true ? "md" : shadowed}`.trim();
|
|
2342
|
+
if (overflow) rest.className = `${rest.className ?? ""} overflow-auto`.trim();
|
|
2339
2343
|
return /* @__PURE__ */ jsx(Flex, {
|
|
2340
2344
|
ref,
|
|
2341
2345
|
...rest
|
|
@@ -2467,7 +2471,8 @@ const AppBar = (props) => {
|
|
|
2467
2471
|
* Pages should define a `label` in their `$page()` options for best results.
|
|
2468
2472
|
* Falls back to the page name converted to Title Case.
|
|
2469
2473
|
*/
|
|
2470
|
-
const Breadcrumb = (
|
|
2474
|
+
const Breadcrumb = (props) => {
|
|
2475
|
+
const { home = "Home", separator, size = "sm", ...groupProps } = props;
|
|
2471
2476
|
const state = useRouterState();
|
|
2472
2477
|
const router = useRouter();
|
|
2473
2478
|
const crumbs = [];
|
|
@@ -2522,11 +2527,175 @@ const Container$1 = forwardRef((props, ref) => {
|
|
|
2522
2527
|
});
|
|
2523
2528
|
Container$1.displayName = "Container";
|
|
2524
2529
|
|
|
2530
|
+
//#endregion
|
|
2531
|
+
//#region ../../src/core/helpers/renderIcon.tsx
|
|
2532
|
+
const renderIcon = (icon, size) => {
|
|
2533
|
+
if (!icon) return null;
|
|
2534
|
+
if (isValidElement(icon)) return icon;
|
|
2535
|
+
if (isComponentType(icon)) return /* @__PURE__ */ jsx(icon, { size: size ?? ui.sizes.icon.md });
|
|
2536
|
+
return icon;
|
|
2537
|
+
};
|
|
2538
|
+
|
|
2539
|
+
//#endregion
|
|
2540
|
+
//#region ../../src/core/components/Text.tsx
|
|
2541
|
+
const INTENT_COLORS = {
|
|
2542
|
+
primary: "blue",
|
|
2543
|
+
info: "cyan",
|
|
2544
|
+
success: "green",
|
|
2545
|
+
warning: "yellow",
|
|
2546
|
+
danger: "red"
|
|
2547
|
+
};
|
|
2548
|
+
const Text$1 = forwardRef((props, ref) => {
|
|
2549
|
+
const { intent, bold, italic, light, muted, small, uppercase, capitalize, center, monospace, title, ...rest } = props;
|
|
2550
|
+
if (intent) rest.c ??= INTENT_COLORS[intent];
|
|
2551
|
+
if (bold) rest.fw ??= 700;
|
|
2552
|
+
if (light) rest.fw ??= 300;
|
|
2553
|
+
if (italic) rest.fs ??= "italic";
|
|
2554
|
+
if (muted) rest.c ??= "dimmed";
|
|
2555
|
+
if (small) rest.size ??= "xs";
|
|
2556
|
+
if (uppercase) rest.tt ??= "uppercase";
|
|
2557
|
+
if (capitalize) rest.tt ??= "capitalize";
|
|
2558
|
+
if (center) rest.ta ??= "center";
|
|
2559
|
+
if (monospace) rest.ff ??= "monospace";
|
|
2560
|
+
if (title) rest.size ??= "xl";
|
|
2561
|
+
return /* @__PURE__ */ jsx(Text, {
|
|
2562
|
+
ref,
|
|
2563
|
+
...rest
|
|
2564
|
+
});
|
|
2565
|
+
});
|
|
2566
|
+
Text$1.displayName = "Text";
|
|
2567
|
+
|
|
2568
|
+
//#endregion
|
|
2569
|
+
//#region ../../src/core/components/layout/SidebarCollapsedItem.tsx
|
|
2570
|
+
const SidebarCollapsedItem = (props) => {
|
|
2571
|
+
const router = useRouter();
|
|
2572
|
+
const handleItemClick = () => {
|
|
2573
|
+
props.onItemClick?.(props.item);
|
|
2574
|
+
props.item.onClick?.();
|
|
2575
|
+
};
|
|
2576
|
+
const hasChildren = props.item.children && props.item.children.length > 0;
|
|
2577
|
+
const menu = hasChildren ? {
|
|
2578
|
+
on: "hover",
|
|
2579
|
+
position: "right",
|
|
2580
|
+
menuProps: {
|
|
2581
|
+
arrowPosition: "center",
|
|
2582
|
+
arrowSize: 10,
|
|
2583
|
+
withArrow: true
|
|
2584
|
+
},
|
|
2585
|
+
items: [{
|
|
2586
|
+
type: "label",
|
|
2587
|
+
label: props.item.label
|
|
2588
|
+
}, ...props.item.children.filter((child) => !child.can || child.can()).map((child) => ({
|
|
2589
|
+
label: child.label,
|
|
2590
|
+
icon: renderIcon(child.icon, ui.sizes.icon.sm),
|
|
2591
|
+
href: child.href,
|
|
2592
|
+
active: child.href ? router.isActive(child.href, { startWith: child.activeStartsWith }) : void 0
|
|
2593
|
+
}))]
|
|
2594
|
+
} : void 0;
|
|
2595
|
+
return /* @__PURE__ */ jsx(Flex$1, {
|
|
2596
|
+
w: "100%",
|
|
2597
|
+
justify: "center",
|
|
2598
|
+
pos: "relative",
|
|
2599
|
+
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
2600
|
+
size: props.item.theme?.size ?? props.theme.button?.size ?? (props.level === 0 ? "sm" : "xs"),
|
|
2601
|
+
bd: 0,
|
|
2602
|
+
variant: "default",
|
|
2603
|
+
propsActive: { variant: "outline" },
|
|
2604
|
+
tooltip: hasChildren ? void 0 : {
|
|
2605
|
+
label: props.item.label,
|
|
2606
|
+
position: "right"
|
|
2607
|
+
},
|
|
2608
|
+
onClick: hasChildren ? void 0 : handleItemClick,
|
|
2609
|
+
icon: renderIcon(props.item.icon, ui.sizes.icon.sm) ?? /* @__PURE__ */ jsx(IconSquareRounded, { size: ui.sizes.icon.sm }),
|
|
2610
|
+
href: hasChildren ? void 0 : props.item.href,
|
|
2611
|
+
target: hasChildren ? void 0 : props.item.target,
|
|
2612
|
+
menu,
|
|
2613
|
+
...props.item.actionProps
|
|
2614
|
+
})
|
|
2615
|
+
});
|
|
2616
|
+
};
|
|
2617
|
+
|
|
2618
|
+
//#endregion
|
|
2619
|
+
//#region ../../src/core/components/layout/SidebarItem.tsx
|
|
2620
|
+
const SidebarItem = (props) => {
|
|
2621
|
+
const maxLevel = 2;
|
|
2622
|
+
const router = useRouter();
|
|
2623
|
+
const isActive = useCallback((item) => {
|
|
2624
|
+
if (!item.children) return false;
|
|
2625
|
+
for (const child of item.children) {
|
|
2626
|
+
if (child.href) {
|
|
2627
|
+
if (router.isActive(child.href)) return true;
|
|
2628
|
+
}
|
|
2629
|
+
if (isActive(child)) return true;
|
|
2630
|
+
}
|
|
2631
|
+
return false;
|
|
2632
|
+
}, []);
|
|
2633
|
+
const [isOpen, setIsOpen] = useState(isActive(props.item));
|
|
2634
|
+
useEvents({ "react:transition:end": () => {
|
|
2635
|
+
if (isActive(props.item)) setIsOpen(true);
|
|
2636
|
+
} }, []);
|
|
2637
|
+
if (props.level > maxLevel) return null;
|
|
2638
|
+
const handleItemClick = (e) => {
|
|
2639
|
+
if (!props.item.target) e.preventDefault();
|
|
2640
|
+
if (props.item.children && props.item.children.length > 0) setIsOpen(!isOpen);
|
|
2641
|
+
else {
|
|
2642
|
+
props.onItemClick?.(props.item);
|
|
2643
|
+
props.item.onClick?.();
|
|
2644
|
+
}
|
|
2645
|
+
};
|
|
2646
|
+
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
2647
|
+
direction: "column",
|
|
2648
|
+
ps: props.level === 0 ? 0 : 32,
|
|
2649
|
+
pos: "relative",
|
|
2650
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2651
|
+
w: "100%",
|
|
2652
|
+
justify: "space-between",
|
|
2653
|
+
href: props.item.href,
|
|
2654
|
+
target: props.item.target,
|
|
2655
|
+
size: props.item.theme?.size ?? props.theme.button?.size ?? (props.level === 0 ? "sm" : "xs"),
|
|
2656
|
+
bd: 0,
|
|
2657
|
+
fw: "normal",
|
|
2658
|
+
variant: "default",
|
|
2659
|
+
propsActive: { variant: "outline" },
|
|
2660
|
+
radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
|
|
2661
|
+
onClick: handleItemClick,
|
|
2662
|
+
leftSection: /* @__PURE__ */ jsxs(Flex$1, {
|
|
2663
|
+
w: "100%",
|
|
2664
|
+
align: "center",
|
|
2665
|
+
gap: "sm",
|
|
2666
|
+
children: [renderIcon(props.item.icon, ui.sizes.icon.sm), /* @__PURE__ */ jsx(Flex$1, {
|
|
2667
|
+
direction: "column",
|
|
2668
|
+
children: /* @__PURE__ */ jsx(Flex$1, { children: props.item.label })
|
|
2669
|
+
})]
|
|
2670
|
+
}),
|
|
2671
|
+
rightSection: props.item.children ? /* @__PURE__ */ jsx(Flex$1, { children: isOpen ? /* @__PURE__ */ jsx(IconChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }) }) : props.item.rightSection,
|
|
2672
|
+
...props.item.actionProps
|
|
2673
|
+
}), props.item.children && isOpen && /* @__PURE__ */ jsxs(Flex$1, {
|
|
2674
|
+
direction: "column",
|
|
2675
|
+
"data-parent-level": props.level,
|
|
2676
|
+
gap: 2,
|
|
2677
|
+
py: 2,
|
|
2678
|
+
children: [/* @__PURE__ */ jsx(Flex$1, { style: {
|
|
2679
|
+
position: "absolute",
|
|
2680
|
+
width: 1,
|
|
2681
|
+
background: "linear-gradient(to bottom, transparent, var(--mantine-color-default-border), transparent)",
|
|
2682
|
+
top: 48,
|
|
2683
|
+
left: 20 + 32 * props.level,
|
|
2684
|
+
bottom: 16
|
|
2685
|
+
} }), props.item.children.filter((child) => !child.can || child.can()).map((child, index) => /* @__PURE__ */ jsx(SidebarItem, {
|
|
2686
|
+
item: child,
|
|
2687
|
+
level: props.level + 1,
|
|
2688
|
+
onItemClick: props.onItemClick,
|
|
2689
|
+
theme: props.theme
|
|
2690
|
+
}, index))]
|
|
2691
|
+
})]
|
|
2692
|
+
});
|
|
2693
|
+
};
|
|
2694
|
+
|
|
2525
2695
|
//#endregion
|
|
2526
2696
|
//#region ../../src/core/components/layout/Sidebar.tsx
|
|
2527
2697
|
const Sidebar = (props) => {
|
|
2528
2698
|
const router = useRouter();
|
|
2529
|
-
const { onItemClick } = props;
|
|
2530
2699
|
const divider = (key, fill, collapsed) => {
|
|
2531
2700
|
return /* @__PURE__ */ jsx(Flex$1, {
|
|
2532
2701
|
h: 1,
|
|
@@ -2577,13 +2746,13 @@ const Sidebar = (props) => {
|
|
|
2577
2746
|
if (collapsed) return /* @__PURE__ */ jsx(SidebarCollapsedItem, {
|
|
2578
2747
|
item,
|
|
2579
2748
|
level: 0,
|
|
2580
|
-
onItemClick,
|
|
2749
|
+
onItemClick: props.onItemClick,
|
|
2581
2750
|
theme: props.theme ?? {}
|
|
2582
2751
|
}, key);
|
|
2583
2752
|
return /* @__PURE__ */ jsx(SidebarItem, {
|
|
2584
2753
|
item,
|
|
2585
2754
|
level: 0,
|
|
2586
|
-
onItemClick,
|
|
2755
|
+
onItemClick: props.onItemClick,
|
|
2587
2756
|
theme: props.theme ?? {}
|
|
2588
2757
|
}, key);
|
|
2589
2758
|
};
|
|
@@ -2646,129 +2815,6 @@ const Sidebar = (props) => {
|
|
|
2646
2815
|
})] });
|
|
2647
2816
|
return renderSidebar(false);
|
|
2648
2817
|
};
|
|
2649
|
-
const SidebarItem = (props) => {
|
|
2650
|
-
const { item, level } = props;
|
|
2651
|
-
const maxLevel = 2;
|
|
2652
|
-
const router = useRouter();
|
|
2653
|
-
const isActive = useCallback((item) => {
|
|
2654
|
-
if (!item.children) return false;
|
|
2655
|
-
for (const child of item.children) {
|
|
2656
|
-
if (child.href) {
|
|
2657
|
-
if (router.isActive(child.href)) return true;
|
|
2658
|
-
}
|
|
2659
|
-
if (isActive(child)) return true;
|
|
2660
|
-
}
|
|
2661
|
-
return false;
|
|
2662
|
-
}, []);
|
|
2663
|
-
const [isOpen, setIsOpen] = useState(isActive(item));
|
|
2664
|
-
useEvents({ "react:transition:end": () => {
|
|
2665
|
-
if (isActive(item)) setIsOpen(true);
|
|
2666
|
-
} }, []);
|
|
2667
|
-
if (level > maxLevel) return null;
|
|
2668
|
-
const handleItemClick = (e) => {
|
|
2669
|
-
if (!props.item.target) e.preventDefault();
|
|
2670
|
-
if (item.children && item.children.length > 0) setIsOpen(!isOpen);
|
|
2671
|
-
else {
|
|
2672
|
-
props.onItemClick?.(item);
|
|
2673
|
-
item.onClick?.();
|
|
2674
|
-
}
|
|
2675
|
-
};
|
|
2676
|
-
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
2677
|
-
direction: "column",
|
|
2678
|
-
ps: level === 0 ? 0 : 32,
|
|
2679
|
-
pos: "relative",
|
|
2680
|
-
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2681
|
-
w: "100%",
|
|
2682
|
-
justify: "space-between",
|
|
2683
|
-
href: props.item.href,
|
|
2684
|
-
target: props.item.target,
|
|
2685
|
-
size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
|
|
2686
|
-
bd: 0,
|
|
2687
|
-
fw: "normal",
|
|
2688
|
-
variant: "default",
|
|
2689
|
-
propsActive: { variant: "outline" },
|
|
2690
|
-
radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
|
|
2691
|
-
onClick: handleItemClick,
|
|
2692
|
-
leftSection: /* @__PURE__ */ jsxs(Flex$1, {
|
|
2693
|
-
w: "100%",
|
|
2694
|
-
align: "center",
|
|
2695
|
-
gap: "sm",
|
|
2696
|
-
children: [renderIcon(item.icon, ui.sizes.icon.sm), /* @__PURE__ */ jsx(Flex$1, {
|
|
2697
|
-
direction: "column",
|
|
2698
|
-
children: /* @__PURE__ */ jsx(Flex$1, { children: item.label })
|
|
2699
|
-
})]
|
|
2700
|
-
}),
|
|
2701
|
-
rightSection: item.children ? /* @__PURE__ */ jsx(Flex$1, { children: isOpen ? /* @__PURE__ */ jsx(IconChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }) }) : props.item.rightSection,
|
|
2702
|
-
...props.item.actionProps
|
|
2703
|
-
}), item.children && isOpen && /* @__PURE__ */ jsxs(Flex$1, {
|
|
2704
|
-
direction: "column",
|
|
2705
|
-
"data-parent-level": level,
|
|
2706
|
-
gap: 2,
|
|
2707
|
-
py: 2,
|
|
2708
|
-
children: [/* @__PURE__ */ jsx(Flex$1, { style: {
|
|
2709
|
-
position: "absolute",
|
|
2710
|
-
width: 1,
|
|
2711
|
-
background: "linear-gradient(to bottom, transparent, var(--mantine-color-default-border), transparent)",
|
|
2712
|
-
top: 48,
|
|
2713
|
-
left: 20 + 32 * level,
|
|
2714
|
-
bottom: 16
|
|
2715
|
-
} }), item.children.filter((child) => !child.can || child.can()).map((child, index) => /* @__PURE__ */ jsx(SidebarItem, {
|
|
2716
|
-
item: child,
|
|
2717
|
-
level: level + 1,
|
|
2718
|
-
onItemClick: props.onItemClick,
|
|
2719
|
-
theme: props.theme
|
|
2720
|
-
}, index))]
|
|
2721
|
-
})]
|
|
2722
|
-
});
|
|
2723
|
-
};
|
|
2724
|
-
const SidebarCollapsedItem = (props) => {
|
|
2725
|
-
const { item, level } = props;
|
|
2726
|
-
const router = useRouter();
|
|
2727
|
-
const handleItemClick = () => {
|
|
2728
|
-
props.onItemClick?.(item);
|
|
2729
|
-
item.onClick?.();
|
|
2730
|
-
};
|
|
2731
|
-
const hasChildren = item.children && item.children.length > 0;
|
|
2732
|
-
const menu = hasChildren ? {
|
|
2733
|
-
on: "hover",
|
|
2734
|
-
position: "right",
|
|
2735
|
-
menuProps: {
|
|
2736
|
-
arrowPosition: "center",
|
|
2737
|
-
arrowSize: 10,
|
|
2738
|
-
withArrow: true
|
|
2739
|
-
},
|
|
2740
|
-
items: [{
|
|
2741
|
-
type: "label",
|
|
2742
|
-
label: item.label
|
|
2743
|
-
}, ...item.children.filter((child) => !child.can || child.can()).map((child) => ({
|
|
2744
|
-
label: child.label,
|
|
2745
|
-
icon: renderIcon(child.icon, ui.sizes.icon.sm),
|
|
2746
|
-
href: child.href,
|
|
2747
|
-
active: child.href ? router.isActive(child.href, { startWith: child.activeStartsWith }) : void 0
|
|
2748
|
-
}))]
|
|
2749
|
-
} : void 0;
|
|
2750
|
-
return /* @__PURE__ */ jsx(Flex$1, {
|
|
2751
|
-
w: "100%",
|
|
2752
|
-
justify: "center",
|
|
2753
|
-
pos: "relative",
|
|
2754
|
-
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
2755
|
-
size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
|
|
2756
|
-
bd: 0,
|
|
2757
|
-
variant: "default",
|
|
2758
|
-
propsActive: { variant: "outline" },
|
|
2759
|
-
tooltip: hasChildren ? void 0 : {
|
|
2760
|
-
label: item.label,
|
|
2761
|
-
position: "right"
|
|
2762
|
-
},
|
|
2763
|
-
onClick: hasChildren ? void 0 : handleItemClick,
|
|
2764
|
-
icon: renderIcon(item.icon, ui.sizes.icon.sm) ?? /* @__PURE__ */ jsx(IconSquareRounded, { size: ui.sizes.icon.sm }),
|
|
2765
|
-
href: hasChildren ? void 0 : props.item.href,
|
|
2766
|
-
target: hasChildren ? void 0 : props.item.target,
|
|
2767
|
-
menu,
|
|
2768
|
-
...props.item.actionProps
|
|
2769
|
-
})
|
|
2770
|
-
});
|
|
2771
|
-
};
|
|
2772
2818
|
|
|
2773
2819
|
//#endregion
|
|
2774
2820
|
//#region ../../src/core/components/layout/DashboardShell.tsx
|
|
@@ -2809,6 +2855,8 @@ const DashboardShell = (props) => {
|
|
|
2809
2855
|
const fHeight = props.footerHeight ?? 24;
|
|
2810
2856
|
const headerHeight = hasAppBar ? hHeight : 0;
|
|
2811
2857
|
const footerHeight = footerElement ? fHeight : 0;
|
|
2858
|
+
const navbarWidth = collapsed ? collapsedWidth : expandedWidth;
|
|
2859
|
+
const mainContent = props.children ?? /* @__PURE__ */ jsx(NestedView, {});
|
|
2812
2860
|
return /* @__PURE__ */ jsxs(AppShell, {
|
|
2813
2861
|
layout: "alt",
|
|
2814
2862
|
w: "100%",
|
|
@@ -2816,7 +2864,7 @@ const DashboardShell = (props) => {
|
|
|
2816
2864
|
flex: 1,
|
|
2817
2865
|
header: hasAppBar ? { height: hHeight } : void 0,
|
|
2818
2866
|
navbar: hasSidebar ? {
|
|
2819
|
-
width: { base:
|
|
2867
|
+
width: { base: navbarWidth },
|
|
2820
2868
|
breakpoint: "md",
|
|
2821
2869
|
collapsed: { mobile: sidebar.closed }
|
|
2822
2870
|
} : void 0,
|
|
@@ -2853,8 +2901,12 @@ const DashboardShell = (props) => {
|
|
|
2853
2901
|
display: "flex",
|
|
2854
2902
|
bg: "var(--alepha-ground)",
|
|
2855
2903
|
pos: "relative",
|
|
2904
|
+
h: props.fill ? "100%" : "inherit",
|
|
2856
2905
|
...props.appShellMainProps,
|
|
2857
|
-
children: props.
|
|
2906
|
+
children: props.container ? /* @__PURE__ */ jsx(Container$1, {
|
|
2907
|
+
...typeof props.container === "boolean" ? {} : props.container,
|
|
2908
|
+
children: mainContent
|
|
2909
|
+
}) : mainContent
|
|
2858
2910
|
}),
|
|
2859
2911
|
footerElement && /* @__PURE__ */ jsx(AppShell.Footer, {
|
|
2860
2912
|
...props.appShellFooterProps,
|
|
@@ -2864,41 +2916,12 @@ const DashboardShell = (props) => {
|
|
|
2864
2916
|
});
|
|
2865
2917
|
};
|
|
2866
2918
|
|
|
2867
|
-
//#endregion
|
|
2868
|
-
//#region ../../src/core/components/Text.tsx
|
|
2869
|
-
const INTENT_COLORS = {
|
|
2870
|
-
primary: "blue",
|
|
2871
|
-
info: "cyan",
|
|
2872
|
-
success: "green",
|
|
2873
|
-
warning: "yellow",
|
|
2874
|
-
danger: "red"
|
|
2875
|
-
};
|
|
2876
|
-
const Text$1 = forwardRef((props, ref) => {
|
|
2877
|
-
const { intent, bold, italic, light, muted, small, uppercase, capitalize, center, monospace, title, ...rest } = props;
|
|
2878
|
-
if (intent) rest.c ??= INTENT_COLORS[intent];
|
|
2879
|
-
if (bold) rest.fw ??= 700;
|
|
2880
|
-
if (light) rest.fw ??= 300;
|
|
2881
|
-
if (italic) rest.fs ??= "italic";
|
|
2882
|
-
if (muted) rest.c ??= "dimmed";
|
|
2883
|
-
if (small) rest.size ??= "xs";
|
|
2884
|
-
if (uppercase) rest.tt ??= "uppercase";
|
|
2885
|
-
if (capitalize) rest.tt ??= "capitalize";
|
|
2886
|
-
if (center) rest.ta ??= "center";
|
|
2887
|
-
if (monospace) rest.ff ??= "monospace";
|
|
2888
|
-
if (title) rest.size ??= "xl";
|
|
2889
|
-
return /* @__PURE__ */ jsx(Text, {
|
|
2890
|
-
ref,
|
|
2891
|
-
...rest
|
|
2892
|
-
});
|
|
2893
|
-
});
|
|
2894
|
-
Text$1.displayName = "Text";
|
|
2895
|
-
|
|
2896
2919
|
//#endregion
|
|
2897
2920
|
//#region ../../src/core/form/utils/parseInput.ts
|
|
2898
2921
|
const parseInput = (props, form) => {
|
|
2899
2922
|
const disabled = false;
|
|
2900
2923
|
const id = props.input.props.id;
|
|
2901
|
-
const label = props.
|
|
2924
|
+
const label = props.label ?? ("title" in props.input.schema && typeof props.input.schema.title === "string" ? props.input.schema.title : void 0) ?? prettyName(props.input.path);
|
|
2902
2925
|
const description = props.description ?? ("description" in props.input.schema && typeof props.input.schema.description === "string" ? props.input.schema.description : void 0);
|
|
2903
2926
|
const error = form.error && form.error instanceof TypeBoxError ? form.error.value.message : void 0;
|
|
2904
2927
|
const icon = !props.icon ? getDefaultIcon({
|
|
@@ -2906,17 +2929,20 @@ const parseInput = (props, form) => {
|
|
|
2906
2929
|
format: props.input.schema && "format" in props.input.schema && typeof props.input.schema.format === "string" ? props.input.schema.format : void 0,
|
|
2907
2930
|
name: props.input.props.name,
|
|
2908
2931
|
isEnum: props.input.schema && "enum" in props.input.schema && Boolean(props.input.schema.enum),
|
|
2909
|
-
isArray: props.input.schema && "type" in props.input.schema && props.input.schema.type === "array"
|
|
2910
|
-
|
|
2932
|
+
isArray: props.input.schema && "type" in props.input.schema && props.input.schema.type === "array",
|
|
2933
|
+
size: props.size
|
|
2934
|
+
}) : isValidElement(props.icon) ? props.icon : createElement(props.icon, { size: ui.sizes.icon.sm });
|
|
2911
2935
|
const format = props.input.schema && "format" in props.input.schema && typeof props.input.schema.format === "string" ? props.input.schema.format : void 0;
|
|
2912
2936
|
const required = props.input.required;
|
|
2913
2937
|
const schema = props.input.schema;
|
|
2938
|
+
const testId = props.input.props?.["data-testid"];
|
|
2914
2939
|
const inputProps = {
|
|
2915
2940
|
label,
|
|
2916
2941
|
description,
|
|
2917
2942
|
error,
|
|
2918
2943
|
required,
|
|
2919
|
-
disabled
|
|
2944
|
+
disabled,
|
|
2945
|
+
...testId ? { "data-testid": testId } : {}
|
|
2920
2946
|
};
|
|
2921
2947
|
if ("minLength" in schema && typeof schema.minLength === "number") inputProps.minLength = schema.minLength;
|
|
2922
2948
|
if ("maxLength" in schema && typeof schema.maxLength === "number") inputProps.maxLength = schema.maxLength;
|
|
@@ -2941,8 +2967,8 @@ const useArrayItems = (input) => {
|
|
|
2941
2967
|
const alepha = useAlepha();
|
|
2942
2968
|
const keyCounter = useRef(0);
|
|
2943
2969
|
const [items, setItemsState] = useState(() => {
|
|
2944
|
-
const
|
|
2945
|
-
if (Array.isArray(
|
|
2970
|
+
const initial = input?.initialValue;
|
|
2971
|
+
if (Array.isArray(initial)) return initial.map((value) => ({
|
|
2946
2972
|
key: keyCounter.current++,
|
|
2947
2973
|
value
|
|
2948
2974
|
}));
|
|
@@ -2968,22 +2994,9 @@ const useArrayItems = (input) => {
|
|
|
2968
2994
|
if (!input?.form) return;
|
|
2969
2995
|
const formId = input.form.id;
|
|
2970
2996
|
const fieldPath = input.path;
|
|
2971
|
-
|
|
2972
|
-
if (event.id === formId) {
|
|
2973
|
-
const defaultValue = input.props?.defaultValue;
|
|
2974
|
-
keyCounter.current = 0;
|
|
2975
|
-
if (Array.isArray(defaultValue)) setItemsState(defaultValue.map((value) => ({
|
|
2976
|
-
key: keyCounter.current++,
|
|
2977
|
-
value
|
|
2978
|
-
})));
|
|
2979
|
-
else setItemsState([]);
|
|
2980
|
-
}
|
|
2981
|
-
}), alepha.events.on("form:change", (event) => {
|
|
2997
|
+
return alepha.events.on("form:change", (event) => {
|
|
2982
2998
|
if (event.id === formId && event.path === fieldPath) syncFromFormValue(event.value);
|
|
2983
|
-
})
|
|
2984
|
-
return () => {
|
|
2985
|
-
for (const unsub of listeners) unsub();
|
|
2986
|
-
};
|
|
2999
|
+
});
|
|
2987
3000
|
}, [
|
|
2988
3001
|
alepha,
|
|
2989
3002
|
input,
|
|
@@ -3008,10 +3021,10 @@ const createArrayItemInput = (parentInput, itemSchema, index, _itemKey, value, o
|
|
|
3008
3021
|
path: `${parentInput.path}/${index}`,
|
|
3009
3022
|
required: false,
|
|
3010
3023
|
form: parentInput.form,
|
|
3024
|
+
initialValue: value,
|
|
3011
3025
|
props: {
|
|
3012
3026
|
id: `${parentInput.props.id}-${index}`,
|
|
3013
|
-
name: `${parentInput.props.name}[${index}]
|
|
3014
|
-
defaultValue: value
|
|
3027
|
+
name: `${parentInput.props.name}[${index}]`
|
|
3015
3028
|
},
|
|
3016
3029
|
set: onValueChange
|
|
3017
3030
|
};
|
|
@@ -3026,10 +3039,10 @@ const createArrayItemFieldInput = (parentInput, itemSchema, fieldName, index, _i
|
|
|
3026
3039
|
path: `${parentInput.path}/${index}/${fieldName}`,
|
|
3027
3040
|
required: itemSchema.required?.includes(fieldName) ?? false,
|
|
3028
3041
|
form: parentInput.form,
|
|
3042
|
+
initialValue: itemValue?.[fieldName],
|
|
3029
3043
|
props: {
|
|
3030
3044
|
id: `${parentInput.props.id}-${index}-${fieldName}`,
|
|
3031
|
-
name: `${parentInput.props.name}[${index}].${fieldName}
|
|
3032
|
-
defaultValue: itemValue?.[fieldName]
|
|
3045
|
+
name: `${parentInput.props.name}[${index}].${fieldName}`
|
|
3033
3046
|
},
|
|
3034
3047
|
set: (value) => onFieldChange(fieldName, value)
|
|
3035
3048
|
};
|
|
@@ -3247,7 +3260,9 @@ const ControlArray = (props) => {
|
|
|
3247
3260
|
* Automatically detects date formats from schema and renders appropriate picker.
|
|
3248
3261
|
*/
|
|
3249
3262
|
const ControlDate = (props) => {
|
|
3250
|
-
const
|
|
3263
|
+
const form = useFormState(props.input);
|
|
3264
|
+
const [value, setValue] = useFieldValue(props.input);
|
|
3265
|
+
const { inputProps, id, icon, format } = parseInput(props, form);
|
|
3251
3266
|
if (!props.input?.props) return null;
|
|
3252
3267
|
if (props.datetime || format === "date-time") {
|
|
3253
3268
|
const dateTimePickerProps = typeof props.datetime === "object" ? props.datetime : {};
|
|
@@ -3255,10 +3270,8 @@ const ControlDate = (props) => {
|
|
|
3255
3270
|
...inputProps,
|
|
3256
3271
|
id,
|
|
3257
3272
|
leftSection: icon,
|
|
3258
|
-
|
|
3259
|
-
onChange: (
|
|
3260
|
-
props.input.set(value ? new Date(value).toISOString() : void 0);
|
|
3261
|
-
},
|
|
3273
|
+
value: value ? new Date(value) : null,
|
|
3274
|
+
onChange: (val) => setValue(val ? new Date(val).toISOString() : void 0),
|
|
3262
3275
|
...dateTimePickerProps
|
|
3263
3276
|
});
|
|
3264
3277
|
}
|
|
@@ -3268,10 +3281,8 @@ const ControlDate = (props) => {
|
|
|
3268
3281
|
...inputProps,
|
|
3269
3282
|
id,
|
|
3270
3283
|
leftSection: icon,
|
|
3271
|
-
|
|
3272
|
-
onChange: (
|
|
3273
|
-
props.input.set(value ? new Date(value).toISOString().slice(0, 10) : void 0);
|
|
3274
|
-
},
|
|
3284
|
+
value: value ? new Date(value) : null,
|
|
3285
|
+
onChange: (val) => setValue(val ? new Date(val).toISOString().slice(0, 10) : void 0),
|
|
3275
3286
|
...dateInputProps
|
|
3276
3287
|
});
|
|
3277
3288
|
}
|
|
@@ -3281,10 +3292,8 @@ const ControlDate = (props) => {
|
|
|
3281
3292
|
...inputProps,
|
|
3282
3293
|
id,
|
|
3283
3294
|
leftSection: icon,
|
|
3284
|
-
|
|
3285
|
-
onChange: (event) =>
|
|
3286
|
-
props.input.set(event.currentTarget.value);
|
|
3287
|
-
},
|
|
3295
|
+
value: value ?? "",
|
|
3296
|
+
onChange: (event) => setValue(event.currentTarget.value),
|
|
3288
3297
|
...timeInputProps
|
|
3289
3298
|
});
|
|
3290
3299
|
}
|
|
@@ -3297,14 +3306,10 @@ const ControlDate = (props) => {
|
|
|
3297
3306
|
*
|
|
3298
3307
|
*/
|
|
3299
3308
|
const ControlNumber = (props) => {
|
|
3300
|
-
const
|
|
3301
|
-
const
|
|
3302
|
-
const
|
|
3303
|
-
useEvents({ "form:reset": (event) => {
|
|
3304
|
-
if (event.id === props.input?.form.id && ref.current) setValue(props.input.props.defaultValue);
|
|
3305
|
-
} }, [props.input]);
|
|
3309
|
+
const form = useFormState(props.input);
|
|
3310
|
+
const [value, setValue] = useFieldValue(props.input);
|
|
3311
|
+
const { inputProps, id, icon } = parseInput(props, form);
|
|
3306
3312
|
if (!props.input?.props) return null;
|
|
3307
|
-
const { type, ...inputPropsWithoutType } = props.input.props;
|
|
3308
3313
|
if (props.sliderProps) {
|
|
3309
3314
|
const min = props.sliderProps.min ?? inputProps.minimum ?? 0;
|
|
3310
3315
|
const max = props.sliderProps.max ?? inputProps.maximum ?? 100;
|
|
@@ -3317,34 +3322,25 @@ const ControlNumber = (props) => {
|
|
|
3317
3322
|
},
|
|
3318
3323
|
children: /* @__PURE__ */ jsx(Slider, {
|
|
3319
3324
|
...inputProps,
|
|
3320
|
-
ref,
|
|
3321
3325
|
id,
|
|
3322
|
-
...inputPropsWithoutType,
|
|
3323
3326
|
...props.sliderProps,
|
|
3324
|
-
value,
|
|
3327
|
+
value: value ?? 0,
|
|
3325
3328
|
min,
|
|
3326
3329
|
max,
|
|
3327
3330
|
label: () => value,
|
|
3328
|
-
onChange: (val) =>
|
|
3329
|
-
setValue(val);
|
|
3330
|
-
props.input.set(val);
|
|
3331
|
-
}
|
|
3331
|
+
onChange: (val) => setValue(val)
|
|
3332
3332
|
})
|
|
3333
3333
|
})
|
|
3334
3334
|
});
|
|
3335
3335
|
}
|
|
3336
3336
|
return /* @__PURE__ */ jsx(NumberInput, {
|
|
3337
3337
|
...inputProps,
|
|
3338
|
-
ref,
|
|
3339
3338
|
id,
|
|
3340
3339
|
leftSection: icon,
|
|
3341
|
-
...inputPropsWithoutType,
|
|
3342
3340
|
...props.numberInputProps,
|
|
3343
3341
|
value: value ?? "",
|
|
3344
3342
|
onChange: (val) => {
|
|
3345
|
-
|
|
3346
|
-
setValue(newValue);
|
|
3347
|
-
props.input.set(newValue);
|
|
3343
|
+
setValue(val !== null ? Number(val) : void 0);
|
|
3348
3344
|
}
|
|
3349
3345
|
});
|
|
3350
3346
|
};
|
|
@@ -3363,156 +3359,73 @@ const ControlNumber = (props) => {
|
|
|
3363
3359
|
* The form system provides nested InputFields under the `.items` property.
|
|
3364
3360
|
* For example: form.input.address.items.street
|
|
3365
3361
|
*
|
|
3366
|
-
* @example
|
|
3367
|
-
* ```tsx
|
|
3368
|
-
* // For a schema like:
|
|
3369
|
-
* // t.object({
|
|
3370
|
-
* // address: t.object({
|
|
3371
|
-
* // street: t.text(),
|
|
3372
|
-
* // city: t.text(),
|
|
3373
|
-
* // zip: t.text(),
|
|
3374
|
-
* // })
|
|
3375
|
-
* // })
|
|
3376
|
-
*
|
|
3377
|
-
* <ControlObject
|
|
3378
|
-
* input={form.input.address}
|
|
3379
|
-
* columns={2}
|
|
3380
|
-
* controlProps={{
|
|
3381
|
-
* zip: { text: { maxLength: 10 } }
|
|
3382
|
-
* }}
|
|
3383
|
-
* />
|
|
3384
|
-
* ```
|
|
3385
|
-
*/
|
|
3386
|
-
const ControlObject = (props) => {
|
|
3387
|
-
const { inputProps } = parseInput(props, {});
|
|
3388
|
-
if (!props.input?.props) return null;
|
|
3389
|
-
const schema = props.input.schema;
|
|
3390
|
-
if (!schema?.properties) return null;
|
|
3391
|
-
const fieldNames = Object.keys(schema.properties);
|
|
3392
|
-
const colSpan = 12 / (props.columns ?? 1);
|
|
3393
|
-
const nestedItems = props.input.items;
|
|
3394
|
-
const renderFields = () => /* @__PURE__ */ jsx(Grid, { children: fieldNames.map((fieldName) => {
|
|
3395
|
-
const fieldControlProps = props.controlProps?.[fieldName] ?? {};
|
|
3396
|
-
const field = nestedItems?.[fieldName];
|
|
3397
|
-
if (!field) return null;
|
|
3398
|
-
return /* @__PURE__ */ jsx(Grid.Col, {
|
|
3399
|
-
span: colSpan,
|
|
3400
|
-
children: /* @__PURE__ */ jsx(Control, {
|
|
3401
|
-
input: field,
|
|
3402
|
-
...fieldControlProps
|
|
3403
|
-
})
|
|
3404
|
-
}, fieldName);
|
|
3405
|
-
}) });
|
|
3406
|
-
if (props.variant === "plain") return renderFields();
|
|
3407
|
-
return /* @__PURE__ */ jsx(Fieldset, {
|
|
3408
|
-
legend: inputProps.label,
|
|
3409
|
-
children: /* @__PURE__ */ jsxs(Flex, {
|
|
3410
|
-
direction: "column",
|
|
3411
|
-
gap: "xs",
|
|
3412
|
-
children: [
|
|
3413
|
-
inputProps.description && /* @__PURE__ */ jsx(Text, {
|
|
3414
|
-
size: "sm",
|
|
3415
|
-
c: "dimmed",
|
|
3416
|
-
children: inputProps.description
|
|
3417
|
-
}),
|
|
3418
|
-
renderFields(),
|
|
3419
|
-
inputProps.error && /* @__PURE__ */ jsx(Text, {
|
|
3420
|
-
size: "sm",
|
|
3421
|
-
c: "red",
|
|
3422
|
-
children: inputProps.error
|
|
3423
|
-
})
|
|
3424
|
-
]
|
|
3425
|
-
})
|
|
3426
|
-
});
|
|
3427
|
-
};
|
|
3428
|
-
|
|
3429
|
-
//#endregion
|
|
3430
|
-
//#region ../../src/core/form/components/ControlQueryBuilder.tsx
|
|
3431
|
-
/**
|
|
3432
|
-
* Query builder with text input and help popover.
|
|
3433
|
-
* Generates query strings for parseQueryString syntax.
|
|
3434
|
-
*/
|
|
3435
|
-
const ControlQueryBuilder = ({ schema, value = "", onChange, placeholder = "Enter query or click for assistance...", ...textInputProps }) => {
|
|
3436
|
-
const [helpOpened, setHelpOpened] = useState(false);
|
|
3437
|
-
const [textValue, setTextValue] = useState(value);
|
|
3438
|
-
const inputRef = useRef(null);
|
|
3439
|
-
const fields = schema ? extractSchemaFields(schema) : [];
|
|
3440
|
-
const [error, setError] = useState(null);
|
|
3441
|
-
const isValid = (value) => {
|
|
3442
|
-
try {
|
|
3443
|
-
parseQueryString(value.trim());
|
|
3444
|
-
} catch (e) {
|
|
3445
|
-
setError(e.message);
|
|
3446
|
-
return false;
|
|
3447
|
-
}
|
|
3448
|
-
setError(null);
|
|
3449
|
-
return true;
|
|
3450
|
-
};
|
|
3451
|
-
const handleTextChange = (newValue) => {
|
|
3452
|
-
setTextValue(newValue);
|
|
3453
|
-
if (isValid(newValue)) onChange?.(newValue);
|
|
3454
|
-
};
|
|
3455
|
-
const handleClear = () => {
|
|
3456
|
-
setTextValue("");
|
|
3457
|
-
onChange?.("");
|
|
3458
|
-
isValid("");
|
|
3459
|
-
};
|
|
3460
|
-
const handleInsert = (text) => {
|
|
3461
|
-
const newValue = textValue ? `${textValue}${text} ` : `${text} `;
|
|
3462
|
-
setTextValue(newValue);
|
|
3463
|
-
if (isValid(newValue)) onChange?.(newValue);
|
|
3464
|
-
setTimeout(() => {
|
|
3465
|
-
inputRef.current?.focus();
|
|
3466
|
-
const length = inputRef.current?.value.length || 0;
|
|
3467
|
-
inputRef.current?.setSelectionRange(length, length);
|
|
3468
|
-
}, 0);
|
|
3469
|
-
};
|
|
3470
|
-
useEvents({ "form:change": (event) => {
|
|
3471
|
-
if (event.id === inputRef.current?.form?.id) {
|
|
3472
|
-
if (event.path === textInputProps["data-path"]) setTextValue(event.value ?? "");
|
|
3473
|
-
}
|
|
3474
|
-
} }, []);
|
|
3475
|
-
return /* @__PURE__ */ jsxs(Popover, {
|
|
3476
|
-
width: 800,
|
|
3477
|
-
position: "bottom-start",
|
|
3478
|
-
shadow: "md",
|
|
3479
|
-
opened: helpOpened,
|
|
3480
|
-
onChange: setHelpOpened,
|
|
3481
|
-
closeOnClickOutside: true,
|
|
3482
|
-
closeOnEscape: true,
|
|
3483
|
-
transitionProps: {
|
|
3484
|
-
transition: "fade-up",
|
|
3485
|
-
duration: 200,
|
|
3486
|
-
timingFunction: "ease"
|
|
3487
|
-
},
|
|
3488
|
-
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(TextInput, {
|
|
3489
|
-
ref: inputRef,
|
|
3490
|
-
placeholder,
|
|
3491
|
-
value: textValue,
|
|
3492
|
-
onChange: (e) => handleTextChange(e.currentTarget.value),
|
|
3493
|
-
onFocus: () => setHelpOpened(true),
|
|
3494
|
-
leftSection: error ? /* @__PURE__ */ jsx(IconInfoTriangle, { size: 16 }) : /* @__PURE__ */ jsx(IconFilter, { size: 16 }),
|
|
3495
|
-
rightSection: textValue && /* @__PURE__ */ jsx(ActionIcon, {
|
|
3496
|
-
size: "sm",
|
|
3497
|
-
variant: "subtle",
|
|
3498
|
-
color: "gray",
|
|
3499
|
-
onClick: handleClear,
|
|
3500
|
-
children: /* @__PURE__ */ jsx(IconX, { size: 14 })
|
|
3501
|
-
}),
|
|
3502
|
-
...textInputProps
|
|
3503
|
-
}) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
3504
|
-
bg: "transparent",
|
|
3505
|
-
p: "xs",
|
|
3506
|
-
bd: `1px solid ${ui.colors.border}`,
|
|
3507
|
-
style: { backdropFilter: "blur(20px)" },
|
|
3508
|
-
children: /* @__PURE__ */ jsx(QueryHelp, {
|
|
3509
|
-
fields,
|
|
3510
|
-
onInsert: handleInsert
|
|
3362
|
+
* @example
|
|
3363
|
+
* ```tsx
|
|
3364
|
+
* // For a schema like:
|
|
3365
|
+
* // t.object({
|
|
3366
|
+
* // address: t.object({
|
|
3367
|
+
* // street: t.text(),
|
|
3368
|
+
* // city: t.text(),
|
|
3369
|
+
* // zip: t.text(),
|
|
3370
|
+
* // })
|
|
3371
|
+
* // })
|
|
3372
|
+
*
|
|
3373
|
+
* <ControlObject
|
|
3374
|
+
* input={form.input.address}
|
|
3375
|
+
* columns={2}
|
|
3376
|
+
* controlProps={{
|
|
3377
|
+
* zip: { text: { maxLength: 10 } }
|
|
3378
|
+
* }}
|
|
3379
|
+
* />
|
|
3380
|
+
* ```
|
|
3381
|
+
*/
|
|
3382
|
+
const ControlObject = (props) => {
|
|
3383
|
+
const { inputProps } = parseInput(props, {});
|
|
3384
|
+
if (!props.input?.props) return null;
|
|
3385
|
+
const schema = props.input.schema;
|
|
3386
|
+
if (!schema?.properties) return null;
|
|
3387
|
+
const fieldNames = Object.keys(schema.properties);
|
|
3388
|
+
const colSpan = 12 / (props.columns ?? 1);
|
|
3389
|
+
const nestedItems = props.input.items;
|
|
3390
|
+
const renderFields = () => /* @__PURE__ */ jsx(Grid, { children: fieldNames.map((fieldName) => {
|
|
3391
|
+
const fieldControlProps = props.controlProps?.[fieldName] ?? {};
|
|
3392
|
+
const field = nestedItems?.[fieldName];
|
|
3393
|
+
if (!field) return null;
|
|
3394
|
+
return /* @__PURE__ */ jsx(Grid.Col, {
|
|
3395
|
+
span: colSpan,
|
|
3396
|
+
children: /* @__PURE__ */ jsx(Control, {
|
|
3397
|
+
input: field,
|
|
3398
|
+
...fieldControlProps
|
|
3511
3399
|
})
|
|
3512
|
-
})
|
|
3400
|
+
}, fieldName);
|
|
3401
|
+
}) });
|
|
3402
|
+
if (props.variant === "plain") return renderFields();
|
|
3403
|
+
return /* @__PURE__ */ jsx(Fieldset, {
|
|
3404
|
+
legend: inputProps.label,
|
|
3405
|
+
children: /* @__PURE__ */ jsxs(Flex, {
|
|
3406
|
+
direction: "column",
|
|
3407
|
+
gap: "xs",
|
|
3408
|
+
children: [
|
|
3409
|
+
inputProps.description && /* @__PURE__ */ jsx(Text, {
|
|
3410
|
+
size: "sm",
|
|
3411
|
+
c: "dimmed",
|
|
3412
|
+
children: inputProps.description
|
|
3413
|
+
}),
|
|
3414
|
+
renderFields(),
|
|
3415
|
+
inputProps.error && /* @__PURE__ */ jsx(Text, {
|
|
3416
|
+
size: "sm",
|
|
3417
|
+
c: "red",
|
|
3418
|
+
children: inputProps.error
|
|
3419
|
+
})
|
|
3420
|
+
]
|
|
3421
|
+
})
|
|
3513
3422
|
});
|
|
3514
3423
|
};
|
|
3515
|
-
|
|
3424
|
+
|
|
3425
|
+
//#endregion
|
|
3426
|
+
//#region ../../src/core/form/components/ControlQueryBuilderHelp.tsx
|
|
3427
|
+
const ControlQueryBuilderHelp = (props) => {
|
|
3428
|
+
const { fields, onInsert } = props;
|
|
3516
3429
|
return /* @__PURE__ */ jsxs(Flex, {
|
|
3517
3430
|
gap: "md",
|
|
3518
3431
|
align: "flex-start",
|
|
@@ -3675,111 +3588,314 @@ function QueryHelp({ fields, onInsert }) {
|
|
|
3675
3588
|
})
|
|
3676
3589
|
]
|
|
3677
3590
|
});
|
|
3678
|
-
}
|
|
3591
|
+
};
|
|
3592
|
+
|
|
3593
|
+
//#endregion
|
|
3594
|
+
//#region ../../src/core/form/components/ControlQueryBuilder.tsx
|
|
3595
|
+
/**
|
|
3596
|
+
* Query builder with text input and help popover.
|
|
3597
|
+
* Generates query strings for parseQueryString syntax.
|
|
3598
|
+
*/
|
|
3599
|
+
const ControlQueryBuilder = (props) => {
|
|
3600
|
+
const { schema, value = "", onChange, placeholder = "Enter query or click for assistance...", ...textInputProps } = props;
|
|
3601
|
+
const [helpOpened, setHelpOpened] = useState(false);
|
|
3602
|
+
const [textValue, setTextValue] = useState(value);
|
|
3603
|
+
const inputRef = useRef(null);
|
|
3604
|
+
const fields = schema ? extractSchemaFields(schema) : [];
|
|
3605
|
+
const [error, setError] = useState(null);
|
|
3606
|
+
const isValid = (value) => {
|
|
3607
|
+
try {
|
|
3608
|
+
parseQueryString(value.trim());
|
|
3609
|
+
} catch (e) {
|
|
3610
|
+
setError(e.message);
|
|
3611
|
+
return false;
|
|
3612
|
+
}
|
|
3613
|
+
setError(null);
|
|
3614
|
+
return true;
|
|
3615
|
+
};
|
|
3616
|
+
const handleTextChange = (newValue) => {
|
|
3617
|
+
setTextValue(newValue);
|
|
3618
|
+
if (isValid(newValue)) onChange?.(newValue);
|
|
3619
|
+
};
|
|
3620
|
+
const handleClear = () => {
|
|
3621
|
+
setTextValue("");
|
|
3622
|
+
onChange?.("");
|
|
3623
|
+
isValid("");
|
|
3624
|
+
};
|
|
3625
|
+
const handleInsert = (text) => {
|
|
3626
|
+
const newValue = textValue ? `${textValue}${text} ` : `${text} `;
|
|
3627
|
+
setTextValue(newValue);
|
|
3628
|
+
if (isValid(newValue)) onChange?.(newValue);
|
|
3629
|
+
setTimeout(() => {
|
|
3630
|
+
inputRef.current?.focus();
|
|
3631
|
+
const length = inputRef.current?.value.length || 0;
|
|
3632
|
+
inputRef.current?.setSelectionRange(length, length);
|
|
3633
|
+
}, 0);
|
|
3634
|
+
};
|
|
3635
|
+
useEvents({ "form:change": (event) => {
|
|
3636
|
+
if (event.id === inputRef.current?.form?.id) {
|
|
3637
|
+
if (event.path === textInputProps["data-path"]) setTextValue(event.value ?? "");
|
|
3638
|
+
}
|
|
3639
|
+
} }, []);
|
|
3640
|
+
return /* @__PURE__ */ jsxs(Popover, {
|
|
3641
|
+
width: 800,
|
|
3642
|
+
position: "bottom-start",
|
|
3643
|
+
shadow: "md",
|
|
3644
|
+
opened: helpOpened,
|
|
3645
|
+
onChange: setHelpOpened,
|
|
3646
|
+
closeOnClickOutside: true,
|
|
3647
|
+
closeOnEscape: true,
|
|
3648
|
+
transitionProps: {
|
|
3649
|
+
transition: "fade-up",
|
|
3650
|
+
duration: 200,
|
|
3651
|
+
timingFunction: "ease"
|
|
3652
|
+
},
|
|
3653
|
+
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(TextInput, {
|
|
3654
|
+
ref: inputRef,
|
|
3655
|
+
placeholder,
|
|
3656
|
+
value: textValue,
|
|
3657
|
+
onChange: (e) => handleTextChange(e.currentTarget.value),
|
|
3658
|
+
onFocus: () => setHelpOpened(true),
|
|
3659
|
+
leftSection: error ? /* @__PURE__ */ jsx(IconInfoTriangle, { size: 16 }) : /* @__PURE__ */ jsx(IconFilter, { size: 16 }),
|
|
3660
|
+
rightSection: textValue && /* @__PURE__ */ jsx(ActionIcon, {
|
|
3661
|
+
size: "sm",
|
|
3662
|
+
variant: "subtle",
|
|
3663
|
+
color: "gray",
|
|
3664
|
+
onClick: handleClear,
|
|
3665
|
+
children: /* @__PURE__ */ jsx(IconX, { size: 14 })
|
|
3666
|
+
}),
|
|
3667
|
+
...textInputProps
|
|
3668
|
+
}) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
3669
|
+
bg: "transparent",
|
|
3670
|
+
p: "xs",
|
|
3671
|
+
bd: `1px solid ${ui.colors.border}`,
|
|
3672
|
+
style: { backdropFilter: "blur(20px)" },
|
|
3673
|
+
children: /* @__PURE__ */ jsx(ControlQueryBuilderHelp, {
|
|
3674
|
+
fields,
|
|
3675
|
+
onInsert: handleInsert
|
|
3676
|
+
})
|
|
3677
|
+
})]
|
|
3678
|
+
});
|
|
3679
|
+
};
|
|
3679
3680
|
|
|
3680
3681
|
//#endregion
|
|
3681
3682
|
//#region ../../src/core/form/components/ControlSelect.tsx
|
|
3682
3683
|
/**
|
|
3683
|
-
* ControlSelect component for handling Select, MultiSelect, and TagsInput.
|
|
3684
|
+
* ControlSelect component for handling Select, MultiSelect, Autocomplete, and TagsInput.
|
|
3684
3685
|
*
|
|
3685
3686
|
* Features:
|
|
3686
3687
|
* - Basic Select with enum support
|
|
3687
3688
|
* - MultiSelect for array of enums
|
|
3688
|
-
* -
|
|
3689
|
-
* -
|
|
3690
|
-
* -
|
|
3691
|
-
* -
|
|
3689
|
+
* - Autocomplete for creatable single values
|
|
3690
|
+
* - TagsInput for creatable array values
|
|
3691
|
+
* - Async lazy loading with auto short/long mode detection
|
|
3692
|
+
* - Short mode: client-side filtering with cached data
|
|
3693
|
+
* - Long mode: debounced server search
|
|
3692
3694
|
*
|
|
3693
3695
|
* Automatically detects enum values and array types from schema.
|
|
3694
3696
|
*/
|
|
3695
3697
|
const ControlSelect = (props) => {
|
|
3696
|
-
const
|
|
3698
|
+
const form = useFormState(props.input);
|
|
3699
|
+
const [value, setValue] = useFieldValue(props.input);
|
|
3700
|
+
const { inputProps, id, icon } = parseInput(props, form);
|
|
3697
3701
|
const isArray = props.input.schema && "type" in props.input.schema && props.input.schema.type === "array";
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
const items = props.input.schema.items;
|
|
3701
|
-
if ("enum" in items && Array.isArray(items.enum)) itemsEnum = items.enum;
|
|
3702
|
-
}
|
|
3702
|
+
const isNumeric = props.input.schema && "type" in props.input.schema && (props.input.schema.type === "integer" || props.input.schema.type === "number");
|
|
3703
|
+
const isBoolean = props.input.schema && "type" in props.input.schema && props.input.schema.type === "boolean";
|
|
3703
3704
|
const enumValues = props.input.schema && "enum" in props.input.schema && Array.isArray(props.input.schema.enum) ? props.input.schema.enum : [];
|
|
3704
|
-
const
|
|
3705
|
+
const { data: asyncData, loading, mode, search } = useAsyncLoader(props.loader, props.loaderThreshold ?? 100, props.loaderDebounce ?? 300, props.input.initialValue);
|
|
3706
|
+
const [staticData, setStaticData] = useState([]);
|
|
3707
|
+
const enumKey = JSON.stringify(enumValues);
|
|
3705
3708
|
useEffect(() => {
|
|
3706
|
-
if (!props.input?.props) return;
|
|
3707
|
-
if (
|
|
3708
|
-
|
|
3709
|
-
|
|
3709
|
+
if (!props.input?.props || props.loader) return;
|
|
3710
|
+
if (isBoolean && enumValues.length === 0) setStaticData([{
|
|
3711
|
+
value: "true",
|
|
3712
|
+
label: "True"
|
|
3713
|
+
}, {
|
|
3714
|
+
value: "false",
|
|
3715
|
+
label: "False"
|
|
3716
|
+
}]);
|
|
3717
|
+
else setStaticData(enumValues);
|
|
3718
|
+
}, [
|
|
3719
|
+
props.input,
|
|
3720
|
+
props.loader,
|
|
3721
|
+
enumKey,
|
|
3722
|
+
isBoolean
|
|
3723
|
+
]);
|
|
3724
|
+
const data = props.loader ? asyncData : staticData;
|
|
3710
3725
|
if (!props.input?.props) return null;
|
|
3711
|
-
|
|
3712
|
-
|
|
3726
|
+
/**
|
|
3727
|
+
* Coerce value for numeric schemas — Select values are always strings.
|
|
3728
|
+
*/
|
|
3729
|
+
const coerceValue = (val) => {
|
|
3730
|
+
if (val == null) return val;
|
|
3731
|
+
if (isNumeric) return Number(val);
|
|
3732
|
+
if (isBoolean) return val === "true";
|
|
3733
|
+
return val;
|
|
3734
|
+
};
|
|
3735
|
+
if (props.segmentedProps) {
|
|
3736
|
+
const segmentedControlProps = typeof props.segmentedProps === "object" ? props.segmentedProps : {};
|
|
3737
|
+
const segmentedData = segmentedControlProps.data ?? data.slice(0, 10);
|
|
3713
3738
|
return /* @__PURE__ */ jsx(Input.Wrapper, {
|
|
3714
3739
|
...inputProps,
|
|
3715
|
-
children: /* @__PURE__ */ jsx(Flex, {
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3740
|
+
children: /* @__PURE__ */ jsx(Flex, {
|
|
3741
|
+
my: "calc(var(--mantine-spacing-xs) / 2)",
|
|
3742
|
+
children: /* @__PURE__ */ jsx(SegmentedControl, {
|
|
3743
|
+
disabled: inputProps.disabled,
|
|
3744
|
+
value: value != null ? String(value) : "",
|
|
3745
|
+
...segmentedControlProps,
|
|
3746
|
+
onChange: (val) => {
|
|
3747
|
+
setValue(coerceValue(val));
|
|
3748
|
+
},
|
|
3749
|
+
data: segmentedData
|
|
3750
|
+
})
|
|
3751
|
+
})
|
|
3724
3752
|
});
|
|
3725
3753
|
}
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3754
|
+
const sharedProps = {
|
|
3755
|
+
size: props.size,
|
|
3756
|
+
id,
|
|
3757
|
+
leftSection: loading ? /* @__PURE__ */ jsx(Loader, {
|
|
3758
|
+
color: "gray",
|
|
3759
|
+
size: 10
|
|
3760
|
+
}) : icon,
|
|
3761
|
+
data
|
|
3762
|
+
};
|
|
3763
|
+
const selectableProps = {
|
|
3764
|
+
...sharedProps,
|
|
3765
|
+
searchable: true,
|
|
3766
|
+
rightSection: /* @__PURE__ */ jsx("span", {})
|
|
3767
|
+
};
|
|
3768
|
+
const longModeProps = mode === "long" ? {
|
|
3769
|
+
filter: ({ options }) => options,
|
|
3770
|
+
onSearchChange: search.run
|
|
3771
|
+
} : {};
|
|
3772
|
+
if (props.creatable && (isArray || props.tagsInputProps)) {
|
|
3773
|
+
const tagsInputExtraProps = props.tagsInputProps ?? {};
|
|
3774
|
+
return /* @__PURE__ */ jsx(TagsInput, {
|
|
3729
3775
|
...inputProps,
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3776
|
+
...sharedProps,
|
|
3777
|
+
...longModeProps,
|
|
3778
|
+
value: Array.isArray(value) ? value : [],
|
|
3779
|
+
onChange: (val) => {
|
|
3780
|
+
setValue(val);
|
|
3781
|
+
},
|
|
3782
|
+
...tagsInputExtraProps
|
|
3736
3783
|
});
|
|
3737
3784
|
}
|
|
3738
|
-
if (
|
|
3739
|
-
const
|
|
3740
|
-
return /* @__PURE__ */ jsx(
|
|
3785
|
+
if (props.creatable) {
|
|
3786
|
+
const autocompleteExtraProps = props.autocompleteProps ?? {};
|
|
3787
|
+
return /* @__PURE__ */ jsx(Autocomplete, {
|
|
3741
3788
|
...inputProps,
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
props.input.set(value);
|
|
3789
|
+
...sharedProps,
|
|
3790
|
+
...longModeProps,
|
|
3791
|
+
value: value != null ? String(value) : "",
|
|
3792
|
+
onChange: (val) => {
|
|
3793
|
+
setValue(coerceValue(val));
|
|
3748
3794
|
},
|
|
3749
|
-
...
|
|
3795
|
+
...autocompleteExtraProps
|
|
3750
3796
|
});
|
|
3751
3797
|
}
|
|
3752
|
-
if (isArray
|
|
3753
|
-
const
|
|
3754
|
-
value,
|
|
3755
|
-
label: value
|
|
3756
|
-
})) || [];
|
|
3757
|
-
const multiSelectProps = typeof props.multi === "object" ? props.multi : {};
|
|
3798
|
+
if (isArray || props.multiSelectProps) {
|
|
3799
|
+
const multiSelectExtraProps = typeof props.multiSelectProps === "object" ? props.multiSelectProps : {};
|
|
3758
3800
|
return /* @__PURE__ */ jsx(MultiSelect, {
|
|
3759
3801
|
...inputProps,
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
onChange: (value) => {
|
|
3766
|
-
props.input.set(value);
|
|
3802
|
+
...selectableProps,
|
|
3803
|
+
...longModeProps,
|
|
3804
|
+
value: Array.isArray(value) ? value : [],
|
|
3805
|
+
onChange: (val) => {
|
|
3806
|
+
setValue(val);
|
|
3767
3807
|
},
|
|
3768
|
-
...
|
|
3808
|
+
...multiSelectExtraProps
|
|
3769
3809
|
});
|
|
3770
3810
|
}
|
|
3771
|
-
const
|
|
3811
|
+
const selectExtraProps = typeof props.selectProps === "object" ? props.selectProps : {};
|
|
3812
|
+
if (mode === "static") return /* @__PURE__ */ jsx(Select, {
|
|
3813
|
+
...inputProps,
|
|
3814
|
+
...selectableProps,
|
|
3815
|
+
value: value != null ? String(value) : null,
|
|
3816
|
+
onChange: (val) => {
|
|
3817
|
+
setValue(coerceValue(val));
|
|
3818
|
+
},
|
|
3819
|
+
...selectExtraProps
|
|
3820
|
+
});
|
|
3772
3821
|
return /* @__PURE__ */ jsx(Select, {
|
|
3773
3822
|
...inputProps,
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
...
|
|
3823
|
+
...selectableProps,
|
|
3824
|
+
...longModeProps,
|
|
3825
|
+
value: value != null ? String(value) : null,
|
|
3826
|
+
onChange: (val) => {
|
|
3827
|
+
setValue(coerceValue(val));
|
|
3828
|
+
},
|
|
3829
|
+
...selectExtraProps
|
|
3781
3830
|
});
|
|
3782
3831
|
};
|
|
3832
|
+
/**
|
|
3833
|
+
* Hook for async select data loading with auto short/long mode detection.
|
|
3834
|
+
*/
|
|
3835
|
+
const useAsyncLoader = (loader, threshold, debounceMs, defaultValue) => {
|
|
3836
|
+
const [data, setData] = useState([]);
|
|
3837
|
+
const [loading, setLoading] = useState(false);
|
|
3838
|
+
const [mode, setMode] = useState("static");
|
|
3839
|
+
const cache = useRef(/* @__PURE__ */ new Map());
|
|
3840
|
+
useAction({
|
|
3841
|
+
name: "select:loader:init",
|
|
3842
|
+
runOnInit: true,
|
|
3843
|
+
handler: async () => {
|
|
3844
|
+
if (!loader) {
|
|
3845
|
+
setMode("static");
|
|
3846
|
+
return;
|
|
3847
|
+
}
|
|
3848
|
+
setLoading(true);
|
|
3849
|
+
try {
|
|
3850
|
+
const result = await loader("");
|
|
3851
|
+
const isShort = result.length <= threshold;
|
|
3852
|
+
setMode(isShort ? "short" : "long");
|
|
3853
|
+
cache.current.set("", result);
|
|
3854
|
+
setData(result);
|
|
3855
|
+
if (!isShort && defaultValue != null && String(defaultValue) !== "") {
|
|
3856
|
+
const resolved = await loader("", [String(defaultValue)]);
|
|
3857
|
+
if (resolved.length > 0) setData((prev) => {
|
|
3858
|
+
const existing = new Set(prev.map((d) => typeof d === "string" ? d : d.value));
|
|
3859
|
+
const newItems = resolved.filter((r) => {
|
|
3860
|
+
const val = typeof r === "string" ? r : r.value;
|
|
3861
|
+
return !existing.has(val);
|
|
3862
|
+
});
|
|
3863
|
+
return [...prev, ...newItems];
|
|
3864
|
+
});
|
|
3865
|
+
}
|
|
3866
|
+
} finally {
|
|
3867
|
+
setLoading(false);
|
|
3868
|
+
}
|
|
3869
|
+
}
|
|
3870
|
+
}, [loader, threshold]);
|
|
3871
|
+
return {
|
|
3872
|
+
data,
|
|
3873
|
+
loading,
|
|
3874
|
+
mode,
|
|
3875
|
+
search: useAction({
|
|
3876
|
+
debounce: debounceMs,
|
|
3877
|
+
handler: async (text) => {
|
|
3878
|
+
if (!loader || mode !== "long") return;
|
|
3879
|
+
if (cache.current.has(text)) {
|
|
3880
|
+
setData(cache.current.get(text));
|
|
3881
|
+
return;
|
|
3882
|
+
}
|
|
3883
|
+
setLoading(true);
|
|
3884
|
+
try {
|
|
3885
|
+
const result = await loader(text);
|
|
3886
|
+
cache.current.set(text, result);
|
|
3887
|
+
setData(result);
|
|
3888
|
+
} finally {
|
|
3889
|
+
setLoading(false);
|
|
3890
|
+
}
|
|
3891
|
+
}
|
|
3892
|
+
}, [
|
|
3893
|
+
loader,
|
|
3894
|
+
mode,
|
|
3895
|
+
debounceMs
|
|
3896
|
+
])
|
|
3897
|
+
};
|
|
3898
|
+
};
|
|
3783
3899
|
|
|
3784
3900
|
//#endregion
|
|
3785
3901
|
//#region ../../src/core/form/components/Control.tsx
|
|
@@ -3809,6 +3925,7 @@ const ControlSelect = (props) => {
|
|
|
3809
3925
|
*/
|
|
3810
3926
|
const Control = (_props) => {
|
|
3811
3927
|
const form = useFormState(_props.input, ["error"]);
|
|
3928
|
+
const [value, setValue] = useFieldValue(_props.input);
|
|
3812
3929
|
if (!_props.input?.props) return null;
|
|
3813
3930
|
const { inputProps, id, icon, format, schema } = parseInput(_props, form);
|
|
3814
3931
|
const props = {
|
|
@@ -3816,12 +3933,11 @@ const Control = (_props) => {
|
|
|
3816
3933
|
...schema.$control
|
|
3817
3934
|
};
|
|
3818
3935
|
if (props.query) return /* @__PURE__ */ jsx(ControlQueryBuilder, {
|
|
3819
|
-
...props.input.props,
|
|
3820
3936
|
...inputProps,
|
|
3821
3937
|
schema: props.query,
|
|
3822
|
-
value
|
|
3823
|
-
onChange: (
|
|
3824
|
-
|
|
3938
|
+
value,
|
|
3939
|
+
onChange: (val) => {
|
|
3940
|
+
setValue(val);
|
|
3825
3941
|
}
|
|
3826
3942
|
});
|
|
3827
3943
|
if (props.custom) {
|
|
@@ -3832,9 +3948,9 @@ const Control = (_props) => {
|
|
|
3832
3948
|
flex: 1,
|
|
3833
3949
|
mt: "calc(var(--mantine-spacing-xs) / 2)",
|
|
3834
3950
|
children: /* @__PURE__ */ jsx(Custom, {
|
|
3835
|
-
|
|
3836
|
-
onChange: (
|
|
3837
|
-
|
|
3951
|
+
value,
|
|
3952
|
+
onChange: (val) => {
|
|
3953
|
+
setValue(val);
|
|
3838
3954
|
}
|
|
3839
3955
|
})
|
|
3840
3956
|
})
|
|
@@ -3845,7 +3961,7 @@ const Control = (_props) => {
|
|
|
3845
3961
|
const controlObjectProps = typeof props.object === "object" ? props.object : {};
|
|
3846
3962
|
return /* @__PURE__ */ jsx(ControlObject, {
|
|
3847
3963
|
input: props.input,
|
|
3848
|
-
|
|
3964
|
+
label: props.label,
|
|
3849
3965
|
description: props.description,
|
|
3850
3966
|
...controlObjectProps
|
|
3851
3967
|
});
|
|
@@ -3856,18 +3972,18 @@ const Control = (_props) => {
|
|
|
3856
3972
|
const controlArrayProps = typeof props.array === "object" ? props.array : {};
|
|
3857
3973
|
return /* @__PURE__ */ jsx(ControlArray, {
|
|
3858
3974
|
input: props.input,
|
|
3859
|
-
|
|
3975
|
+
label: props.label,
|
|
3860
3976
|
description: props.description,
|
|
3861
3977
|
...controlArrayProps
|
|
3862
3978
|
});
|
|
3863
3979
|
}
|
|
3864
|
-
if (props.number || props.input.schema && "type" in props.input.schema && (props.input.schema.type === "number" || props.input.schema.type === "integer")) {
|
|
3980
|
+
if (props.number || !props.select && props.input.schema && "type" in props.input.schema && (props.input.schema.type === "number" || props.input.schema.type === "integer")) {
|
|
3865
3981
|
const controlNumberProps = typeof props.number === "object" ? props.number : {};
|
|
3866
3982
|
if (props.slider) controlNumberProps.sliderProps ??= {};
|
|
3867
3983
|
return /* @__PURE__ */ jsx(ControlNumber, {
|
|
3868
3984
|
size: props.size,
|
|
3869
3985
|
input: props.input,
|
|
3870
|
-
|
|
3986
|
+
label: props.label,
|
|
3871
3987
|
description: props.description,
|
|
3872
3988
|
icon,
|
|
3873
3989
|
...controlNumberProps
|
|
@@ -3880,9 +3996,7 @@ const Control = (_props) => {
|
|
|
3880
3996
|
size: props.size,
|
|
3881
3997
|
id,
|
|
3882
3998
|
leftSection: icon,
|
|
3883
|
-
onChange: (file) =>
|
|
3884
|
-
props.input.set(file);
|
|
3885
|
-
},
|
|
3999
|
+
onChange: (file) => setValue(file),
|
|
3886
4000
|
...fileInputProps
|
|
3887
4001
|
});
|
|
3888
4002
|
}
|
|
@@ -3893,17 +4007,18 @@ const Control = (_props) => {
|
|
|
3893
4007
|
size: props.size,
|
|
3894
4008
|
id,
|
|
3895
4009
|
leftSection: icon,
|
|
3896
|
-
|
|
4010
|
+
value: value ?? "",
|
|
4011
|
+
onChange: (val) => setValue(val),
|
|
3897
4012
|
...colorInputProps
|
|
3898
4013
|
});
|
|
3899
4014
|
}
|
|
3900
4015
|
if (props.input.schema && "enum" in props.input.schema && props.input.schema.enum || isArray && !isArrayOfObjects || props.select) {
|
|
3901
4016
|
const opts = typeof props.select === "object" ? props.select : {};
|
|
3902
|
-
if (props.segmented) opts.
|
|
4017
|
+
if (props.segmented) opts.segmentedProps ??= {};
|
|
3903
4018
|
return /* @__PURE__ */ jsx(ControlSelect, {
|
|
3904
4019
|
size: props.size,
|
|
3905
4020
|
input: props.input,
|
|
3906
|
-
|
|
4021
|
+
label: props.label,
|
|
3907
4022
|
description: props.description,
|
|
3908
4023
|
icon,
|
|
3909
4024
|
...opts
|
|
@@ -3917,16 +4032,16 @@ const Control = (_props) => {
|
|
|
3917
4032
|
size: props.size,
|
|
3918
4033
|
id,
|
|
3919
4034
|
color: "blue",
|
|
3920
|
-
|
|
4035
|
+
checked: Boolean(value),
|
|
3921
4036
|
onChange: (event) => {
|
|
3922
|
-
|
|
4037
|
+
setValue(event.currentTarget.checked);
|
|
3923
4038
|
},
|
|
3924
4039
|
...switchProps
|
|
3925
4040
|
});
|
|
3926
4041
|
}
|
|
3927
4042
|
const opts = {
|
|
3928
4043
|
input: props.input,
|
|
3929
|
-
|
|
4044
|
+
selectProps: { data: [{
|
|
3930
4045
|
value: "true",
|
|
3931
4046
|
label: "Yes"
|
|
3932
4047
|
}, {
|
|
@@ -3936,7 +4051,7 @@ const Control = (_props) => {
|
|
|
3936
4051
|
};
|
|
3937
4052
|
return /* @__PURE__ */ jsx(ControlSelect, {
|
|
3938
4053
|
size: props.size,
|
|
3939
|
-
|
|
4054
|
+
label: props.label,
|
|
3940
4055
|
description: props.description,
|
|
3941
4056
|
icon,
|
|
3942
4057
|
...opts
|
|
@@ -3949,7 +4064,8 @@ const Control = (_props) => {
|
|
|
3949
4064
|
size: props.size,
|
|
3950
4065
|
id,
|
|
3951
4066
|
leftSection: icon,
|
|
3952
|
-
|
|
4067
|
+
value: value ?? "",
|
|
4068
|
+
onChange: (ev) => setValue(ev.target.value),
|
|
3953
4069
|
...passwordInputProps
|
|
3954
4070
|
});
|
|
3955
4071
|
}
|
|
@@ -3960,14 +4076,15 @@ const Control = (_props) => {
|
|
|
3960
4076
|
size: props.size,
|
|
3961
4077
|
id,
|
|
3962
4078
|
leftSection: icon,
|
|
3963
|
-
|
|
4079
|
+
value: value ?? "",
|
|
4080
|
+
onChange: (ev) => setValue(ev.target.value),
|
|
3964
4081
|
...textAreaProps
|
|
3965
4082
|
});
|
|
3966
4083
|
}
|
|
3967
4084
|
if (props.date || props.datetime || props.time || format === "date" || format === "date-time" || format === "time") return /* @__PURE__ */ jsx(ControlDate, {
|
|
3968
4085
|
size: props.size,
|
|
3969
4086
|
input: props.input,
|
|
3970
|
-
|
|
4087
|
+
label: props.label,
|
|
3971
4088
|
description: props.description,
|
|
3972
4089
|
icon,
|
|
3973
4090
|
date: props.date,
|
|
@@ -3982,7 +4099,7 @@ const Control = (_props) => {
|
|
|
3982
4099
|
case "uri": return "url";
|
|
3983
4100
|
case "tel":
|
|
3984
4101
|
case "phone": return "tel";
|
|
3985
|
-
default: return;
|
|
4102
|
+
default: return props.input.props.type ?? "text";
|
|
3986
4103
|
}
|
|
3987
4104
|
};
|
|
3988
4105
|
return /* @__PURE__ */ jsx(TextInput, {
|
|
@@ -3991,14 +4108,9 @@ const Control = (_props) => {
|
|
|
3991
4108
|
id,
|
|
3992
4109
|
leftSection: icon,
|
|
3993
4110
|
type: getInputType(),
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
"label",
|
|
3998
|
-
"input",
|
|
3999
|
-
"description",
|
|
4000
|
-
"error"
|
|
4001
|
-
]
|
|
4111
|
+
value: value ?? "",
|
|
4112
|
+
onChange: (ev) => setValue(ev.target.value),
|
|
4113
|
+
...textInputProps
|
|
4002
4114
|
});
|
|
4003
4115
|
};
|
|
4004
4116
|
|
|
@@ -4047,6 +4159,7 @@ const Control = (_props) => {
|
|
|
4047
4159
|
*/
|
|
4048
4160
|
const TypeForm = (props) => {
|
|
4049
4161
|
const { form, columns = 3, children, controlProps, fieldControlProps, skipFormElement = false, skipSubmitButton = false, submitButtonProps, fill = true, size } = props;
|
|
4162
|
+
const { dirty } = useFormState(form, ["dirty"]);
|
|
4050
4163
|
const schema = props.schema || form.options.schema;
|
|
4051
4164
|
if (!schema?.properties) return null;
|
|
4052
4165
|
const supportedFields = Object.keys(schema.properties);
|
|
@@ -4109,10 +4222,12 @@ const TypeForm = (props) => {
|
|
|
4109
4222
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
4110
4223
|
variant: "subtle",
|
|
4111
4224
|
type: "reset",
|
|
4225
|
+
disabled: !dirty,
|
|
4112
4226
|
children: "Reset"
|
|
4113
4227
|
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
4114
4228
|
intent: "primary",
|
|
4115
4229
|
form,
|
|
4230
|
+
disabled: !dirty,
|
|
4116
4231
|
...submitButtonProps,
|
|
4117
4232
|
children: submitButtonProps?.children ?? "Submit"
|
|
4118
4233
|
})]
|
|
@@ -4131,22 +4246,14 @@ const TypeForm = (props) => {
|
|
|
4131
4246
|
});
|
|
4132
4247
|
};
|
|
4133
4248
|
|
|
4134
|
-
//#endregion
|
|
4135
|
-
//#region ../../src/core/helpers/renderIcon.tsx
|
|
4136
|
-
const renderIcon = (icon, size) => {
|
|
4137
|
-
if (!icon) return null;
|
|
4138
|
-
if (isValidElement(icon)) return icon;
|
|
4139
|
-
if (isComponentType(icon)) return /* @__PURE__ */ jsx(icon, { size: size ?? ui.sizes.icon.md });
|
|
4140
|
-
return icon;
|
|
4141
|
-
};
|
|
4142
|
-
|
|
4143
4249
|
//#endregion
|
|
4144
4250
|
//#region ../../src/core/table/interfaces/types.ts
|
|
4145
4251
|
const DEFAULT_MAX_VISIBLE_COLUMNS = 8;
|
|
4146
4252
|
|
|
4147
4253
|
//#endregion
|
|
4148
4254
|
//#region ../../src/core/table/components/DataTableFilters.tsx
|
|
4149
|
-
const DataTableFilters = (
|
|
4255
|
+
const DataTableFilters = (props) => {
|
|
4256
|
+
const { schema, form, typeFormProps, filterVisibility } = props;
|
|
4150
4257
|
const visibleSchema = useMemo(() => {
|
|
4151
4258
|
const visibleKeys = Object.keys(schema.properties).filter((key) => filterVisibility[key] !== false);
|
|
4152
4259
|
if (visibleKeys.length === 0) return null;
|
|
@@ -4157,14 +4264,14 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
|
|
|
4157
4264
|
return t.object(visibleProps);
|
|
4158
4265
|
}, [schema, filterVisibility]);
|
|
4159
4266
|
if (!visibleSchema) return null;
|
|
4160
|
-
return /* @__PURE__ */ jsx(Flex, {
|
|
4161
|
-
|
|
4267
|
+
return /* @__PURE__ */ jsx(Flex$1, {
|
|
4268
|
+
surface: true,
|
|
4269
|
+
flex: 1,
|
|
4270
|
+
mt: -4,
|
|
4162
4271
|
p: "xs",
|
|
4163
4272
|
m: "xs",
|
|
4164
4273
|
bdrs: "md",
|
|
4165
|
-
bg: ui.colors.surface,
|
|
4166
4274
|
children: /* @__PURE__ */ jsx(TypeForm, {
|
|
4167
|
-
size: "xs",
|
|
4168
4275
|
...typeFormProps,
|
|
4169
4276
|
skipSubmitButton: true,
|
|
4170
4277
|
fill: true,
|
|
@@ -4175,7 +4282,7 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
|
|
|
4175
4282
|
sm: 2,
|
|
4176
4283
|
md: 3,
|
|
4177
4284
|
lg: 4,
|
|
4178
|
-
xl:
|
|
4285
|
+
xl: 5
|
|
4179
4286
|
}
|
|
4180
4287
|
})
|
|
4181
4288
|
});
|
|
@@ -4183,9 +4290,10 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
|
|
|
4183
4290
|
|
|
4184
4291
|
//#endregion
|
|
4185
4292
|
//#region ../../src/core/table/components/DataTablePagination.tsx
|
|
4186
|
-
const DataTablePagination = ({ page, size, totalPages, totalElements, offset, numberOfElements, onPageChange, onSizeChange }) => {
|
|
4293
|
+
const DataTablePagination = ({ page, size, totalPages, totalElements, isFirst, isLast, offset, numberOfElements, onPageChange, onSizeChange }) => {
|
|
4187
4294
|
const from = numberOfElements > 0 ? offset + 1 : 0;
|
|
4188
4295
|
const to = offset + numberOfElements;
|
|
4296
|
+
const hasTotal = totalPages != null;
|
|
4189
4297
|
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
4190
4298
|
align: "center",
|
|
4191
4299
|
justify: "space-between",
|
|
@@ -4233,8 +4341,9 @@ const DataTablePagination = ({ page, size, totalPages, totalElements, offset, nu
|
|
|
4233
4341
|
]
|
|
4234
4342
|
}) }), /* @__PURE__ */ jsx(Flex$1, { children: /* @__PURE__ */ jsx(Pagination, {
|
|
4235
4343
|
size: "sm",
|
|
4236
|
-
withEdges:
|
|
4237
|
-
|
|
4344
|
+
withEdges: hasTotal,
|
|
4345
|
+
withPages: hasTotal,
|
|
4346
|
+
total: hasTotal ? totalPages : isLast !== false ? page : page + 1,
|
|
4238
4347
|
value: page,
|
|
4239
4348
|
onChange: onPageChange
|
|
4240
4349
|
}) })]
|
|
@@ -4285,7 +4394,7 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
4285
4394
|
timingFunction: "ease"
|
|
4286
4395
|
},
|
|
4287
4396
|
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ActionButton, {
|
|
4288
|
-
variant: "
|
|
4397
|
+
variant: "minimal",
|
|
4289
4398
|
icon: IconColumns,
|
|
4290
4399
|
onClick: () => setOpened((o) => !o)
|
|
4291
4400
|
}) }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
@@ -4315,12 +4424,12 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
4315
4424
|
gap: 4,
|
|
4316
4425
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
4317
4426
|
size: "compact-xs",
|
|
4318
|
-
variant: "
|
|
4427
|
+
variant: "minimal",
|
|
4319
4428
|
onClick: handleShowAll,
|
|
4320
4429
|
children: "All"
|
|
4321
4430
|
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
4322
4431
|
size: "compact-xs",
|
|
4323
|
-
variant: "
|
|
4432
|
+
variant: "minimal",
|
|
4324
4433
|
onClick: handleDefault,
|
|
4325
4434
|
children: "Default"
|
|
4326
4435
|
})]
|
|
@@ -4386,7 +4495,7 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
4386
4495
|
timingFunction: "ease"
|
|
4387
4496
|
},
|
|
4388
4497
|
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ActionButton, {
|
|
4389
|
-
variant: "
|
|
4498
|
+
variant: "minimal",
|
|
4390
4499
|
icon: IconFilter,
|
|
4391
4500
|
onClick: () => setOpened((o) => !o)
|
|
4392
4501
|
}) }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
@@ -4416,12 +4525,12 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
4416
4525
|
gap: 4,
|
|
4417
4526
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
4418
4527
|
size: "compact-xs",
|
|
4419
|
-
variant: "
|
|
4528
|
+
variant: "minimal",
|
|
4420
4529
|
onClick: handleShowAll,
|
|
4421
4530
|
children: "All"
|
|
4422
4531
|
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
4423
4532
|
size: "compact-xs",
|
|
4424
|
-
variant: "
|
|
4533
|
+
variant: "minimal",
|
|
4425
4534
|
onClick: handleHideAll,
|
|
4426
4535
|
children: "None"
|
|
4427
4536
|
})]
|
|
@@ -4515,7 +4624,7 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
4515
4624
|
onVisibilityChange: onColumnVisibilityChange
|
|
4516
4625
|
}),
|
|
4517
4626
|
withExport && /* @__PURE__ */ jsx(ActionButton, {
|
|
4518
|
-
variant: "
|
|
4627
|
+
variant: "minimal",
|
|
4519
4628
|
icon: IconDownload,
|
|
4520
4629
|
menu: { items: [{
|
|
4521
4630
|
label: "Export as CSV",
|
|
@@ -4538,7 +4647,7 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
4538
4647
|
children: [selectedItems.length, " selected"]
|
|
4539
4648
|
}),
|
|
4540
4649
|
/* @__PURE__ */ jsx(ActionButton, {
|
|
4541
|
-
variant: "
|
|
4650
|
+
variant: "minimal",
|
|
4542
4651
|
size: "compact-sm",
|
|
4543
4652
|
icon: IconX,
|
|
4544
4653
|
onClick: onClearSelection,
|
|
@@ -4562,7 +4671,7 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
4562
4671
|
...props,
|
|
4563
4672
|
children: props.label
|
|
4564
4673
|
}, index) : props), /* @__PURE__ */ jsx(ActionButton, {
|
|
4565
|
-
variant: "
|
|
4674
|
+
variant: "minimal",
|
|
4566
4675
|
icon: IconRefresh,
|
|
4567
4676
|
onClick: onRefresh
|
|
4568
4677
|
})]
|
|
@@ -4671,12 +4780,16 @@ const FIT_STYLE = {
|
|
|
4671
4780
|
};
|
|
4672
4781
|
const DataTable = (props) => {
|
|
4673
4782
|
const [items, setItems] = useState(typeof props.items === "function" ? { content: [] } : props.items);
|
|
4674
|
-
const
|
|
4783
|
+
const itemsRef = useRef(items);
|
|
4784
|
+
const [loaded, setLoaded] = useState(typeof props.items !== "function" || !props.submitOnInit);
|
|
4785
|
+
const defaultSize = props.defaultSize || (props.infinityScroll ? 100 : 10);
|
|
4675
4786
|
const [page, setPage] = useState(1);
|
|
4676
4787
|
const [size, setSize] = useState(String(defaultSize));
|
|
4677
4788
|
const [currentPage, setCurrentPage] = useState(0);
|
|
4678
4789
|
const alepha = useInject(Alepha);
|
|
4790
|
+
itemsRef.current = items;
|
|
4679
4791
|
const sentinelRef = useRef(null);
|
|
4792
|
+
const debounceRef = useRef(null);
|
|
4680
4793
|
const [columnVisibility, setColumnVisibility] = useState(() => {
|
|
4681
4794
|
const entries = Object.entries(props.columns);
|
|
4682
4795
|
let visibleCount = 0;
|
|
@@ -4749,13 +4862,14 @@ const DataTable = (props) => {
|
|
|
4749
4862
|
}),
|
|
4750
4863
|
handler: async (values) => {
|
|
4751
4864
|
if (typeof props.items === "function") {
|
|
4752
|
-
const response = await props.items(values, { items:
|
|
4865
|
+
const response = await props.items(values, { items: itemsRef.current.content });
|
|
4753
4866
|
if (props.infinityScroll && values.page > 0) setItems((prev) => ({
|
|
4754
4867
|
...response,
|
|
4755
4868
|
content: [...prev.content, ...response.content]
|
|
4756
4869
|
}));
|
|
4757
4870
|
else setItems(response);
|
|
4758
4871
|
setCurrentPage(values.page);
|
|
4872
|
+
if (!loaded) setLoaded(true);
|
|
4759
4873
|
}
|
|
4760
4874
|
},
|
|
4761
4875
|
onReset: async () => {
|
|
@@ -4775,9 +4889,23 @@ const DataTable = (props) => {
|
|
|
4775
4889
|
return;
|
|
4776
4890
|
}
|
|
4777
4891
|
props.onFilterChange?.(key, value, form);
|
|
4892
|
+
if (props.skipSubmitOnChange) return;
|
|
4893
|
+
form.input.page.set(0);
|
|
4894
|
+
const delay = props.debounce ?? 300;
|
|
4895
|
+
if (delay > 0) {
|
|
4896
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
4897
|
+
debounceRef.current = setTimeout(() => {
|
|
4898
|
+
form.submit();
|
|
4899
|
+
}, delay);
|
|
4900
|
+
} else await form.submit();
|
|
4778
4901
|
}
|
|
4779
|
-
}, [
|
|
4902
|
+
}, []);
|
|
4780
4903
|
const dt = useInject(DateTimeProvider);
|
|
4904
|
+
useEffect(() => {
|
|
4905
|
+
return () => {
|
|
4906
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
4907
|
+
};
|
|
4908
|
+
}, []);
|
|
4781
4909
|
useEffect(() => {
|
|
4782
4910
|
if (props.submitOnInit) form.submit();
|
|
4783
4911
|
if (props.submitEvery) {
|
|
@@ -4842,9 +4970,9 @@ const DataTable = (props) => {
|
|
|
4842
4970
|
}), col.sortable && /* @__PURE__ */ jsxs(Flex$1, {
|
|
4843
4971
|
c: "dimmed",
|
|
4844
4972
|
children: [
|
|
4845
|
-
sortDir === "asc" && /* @__PURE__ */ jsx(IconArrowUp, { size: ui.sizes.icon.
|
|
4846
|
-
sortDir === "desc" && /* @__PURE__ */ jsx(IconArrowDown, { size: ui.sizes.icon.
|
|
4847
|
-
sortDir === null && /* @__PURE__ */ jsx(IconArrowsSort, { size: ui.sizes.icon.
|
|
4973
|
+
sortDir === "asc" && /* @__PURE__ */ jsx(IconArrowUp, { size: ui.sizes.icon.xs }),
|
|
4974
|
+
sortDir === "desc" && /* @__PURE__ */ jsx(IconArrowDown, { size: ui.sizes.icon.xs }),
|
|
4975
|
+
sortDir === null && /* @__PURE__ */ jsx(IconArrowsSort, { size: ui.sizes.icon.xs })
|
|
4848
4976
|
]
|
|
4849
4977
|
})]
|
|
4850
4978
|
})
|
|
@@ -4904,9 +5032,15 @@ const DataTable = (props) => {
|
|
|
4904
5032
|
form,
|
|
4905
5033
|
alepha
|
|
4906
5034
|
};
|
|
5035
|
+
const content = col.value?.(item, ctx);
|
|
4907
5036
|
return /* @__PURE__ */ jsx(Table.Td, {
|
|
4908
5037
|
style: col.fit ? FIT_STYLE : void 0,
|
|
4909
|
-
children: col.
|
|
5038
|
+
children: col.action ? /* @__PURE__ */ jsx(ActionButton, {
|
|
5039
|
+
td: "inherit",
|
|
5040
|
+
unstyled: true,
|
|
5041
|
+
...col.action(item),
|
|
5042
|
+
children: content
|
|
5043
|
+
}) : content
|
|
4910
5044
|
}, key);
|
|
4911
5045
|
}),
|
|
4912
5046
|
props.rowActions && (() => {
|
|
@@ -4923,7 +5057,7 @@ const DataTable = (props) => {
|
|
|
4923
5057
|
style: FIT_STYLE,
|
|
4924
5058
|
onClick: (e) => e.stopPropagation(),
|
|
4925
5059
|
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
4926
|
-
variant: "
|
|
5060
|
+
variant: "minimal",
|
|
4927
5061
|
size: "xs",
|
|
4928
5062
|
icon: IconDotsVertical,
|
|
4929
5063
|
menu: { items: actions.map((action) => {
|
|
@@ -4931,7 +5065,10 @@ const DataTable = (props) => {
|
|
|
4931
5065
|
return {
|
|
4932
5066
|
label: action.label ?? (typeof action.tooltip === "string" ? action.tooltip : void 0),
|
|
4933
5067
|
icon: Icon && isComponentType(Icon) ? /* @__PURE__ */ jsx(Icon, { size: 14 }) : Icon,
|
|
4934
|
-
onClick: action.onClick
|
|
5068
|
+
onClick: action.onClick ? async () => {
|
|
5069
|
+
await action.onClick();
|
|
5070
|
+
if (!action.skipRefresh) await form.submit();
|
|
5071
|
+
} : void 0,
|
|
4935
5072
|
color: action.color
|
|
4936
5073
|
};
|
|
4937
5074
|
}) }
|
|
@@ -4993,19 +5130,26 @@ const DataTable = (props) => {
|
|
|
4993
5130
|
bordered: true,
|
|
4994
5131
|
elevated: true,
|
|
4995
5132
|
shadowed: "xs",
|
|
5133
|
+
flex: 1,
|
|
5134
|
+
style: { minHeight: 0 },
|
|
4996
5135
|
children: [
|
|
4997
5136
|
/* @__PURE__ */ jsx(Flex$1, {
|
|
4998
5137
|
className: "overflow-auto",
|
|
5138
|
+
flex: 1,
|
|
5139
|
+
style: { minHeight: 0 },
|
|
5140
|
+
col: true,
|
|
4999
5141
|
children: /* @__PURE__ */ jsxs(Table, {
|
|
5000
5142
|
"aria-label": "Data table",
|
|
5001
5143
|
withRowBorders: true,
|
|
5002
5144
|
highlightOnHover: true,
|
|
5003
5145
|
...props.tableProps,
|
|
5004
5146
|
children: [/* @__PURE__ */ jsx(Table.Thead, {
|
|
5147
|
+
bdrs: "md",
|
|
5005
5148
|
style: {
|
|
5006
5149
|
position: "sticky",
|
|
5007
5150
|
top: 0,
|
|
5008
|
-
zIndex: 1
|
|
5151
|
+
zIndex: 1,
|
|
5152
|
+
backgroundColor: "var(--alepha-elevated)"
|
|
5009
5153
|
},
|
|
5010
5154
|
children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
5011
5155
|
panelConfig && /* @__PURE__ */ jsx(Table.Th, { style: { width: 36 } }),
|
|
@@ -5013,30 +5157,39 @@ const DataTable = (props) => {
|
|
|
5013
5157
|
head,
|
|
5014
5158
|
props.rowActions && /* @__PURE__ */ jsx(Table.Th, { style: FIT_STYLE })
|
|
5015
5159
|
] })
|
|
5016
|
-
}), /* @__PURE__ */
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5160
|
+
}), /* @__PURE__ */ jsx(Table.Tbody, { children: !loaded || form.submitting ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
|
|
5161
|
+
colSpan: totalColumns || 1,
|
|
5162
|
+
py: "sm",
|
|
5163
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
5164
|
+
justify: "center",
|
|
5165
|
+
p: "md",
|
|
5166
|
+
children: /* @__PURE__ */ jsx(Loader, {
|
|
5167
|
+
size: "sm",
|
|
5168
|
+
type: "dots"
|
|
5169
|
+
})
|
|
5170
|
+
})
|
|
5171
|
+
}) }) : rows.length === 0 ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
|
|
5172
|
+
colSpan: totalColumns || 1,
|
|
5173
|
+
py: "xl",
|
|
5174
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
5175
|
+
justify: "center",
|
|
5025
5176
|
children: /* @__PURE__ */ jsx(Text$1, {
|
|
5026
5177
|
c: "dimmed",
|
|
5027
5178
|
size: "sm",
|
|
5028
|
-
children:
|
|
5179
|
+
children: props.emptyLabel ?? "No results"
|
|
5029
5180
|
})
|
|
5030
|
-
})
|
|
5031
|
-
})]
|
|
5181
|
+
})
|
|
5182
|
+
}) }) : rows })]
|
|
5032
5183
|
})
|
|
5033
5184
|
}),
|
|
5034
5185
|
props.infinityScroll && /* @__PURE__ */ jsx("div", { ref: sentinelRef }),
|
|
5035
5186
|
!props.infinityScroll && /* @__PURE__ */ jsx(DataTablePagination, {
|
|
5036
5187
|
page,
|
|
5037
5188
|
size,
|
|
5038
|
-
totalPages: items.page?.totalPages
|
|
5189
|
+
totalPages: items.page?.totalPages,
|
|
5039
5190
|
totalElements: items.page?.totalElements,
|
|
5191
|
+
isFirst: items.page?.isFirst,
|
|
5192
|
+
isLast: items.page?.isLast,
|
|
5040
5193
|
offset: items.page?.offset ?? 0,
|
|
5041
5194
|
numberOfElements: items.content.length,
|
|
5042
5195
|
onPageChange: (value) => {
|
|
@@ -5154,8 +5307,8 @@ const OPERATOR_INFO = {
|
|
|
5154
5307
|
* Get the default icon for an input based on its type, format, or name.
|
|
5155
5308
|
*/
|
|
5156
5309
|
const getDefaultIcon = (params) => {
|
|
5157
|
-
const { type, format, name, isEnum, isArray, size = "
|
|
5158
|
-
const iconSize = ui.sizes.icon[size];
|
|
5310
|
+
const { type, format, name, isEnum, isArray, size = "xs" } = params;
|
|
5311
|
+
const iconSize = ui.sizes.icon[size] - 4;
|
|
5159
5312
|
if (format) switch (format) {
|
|
5160
5313
|
case "email": return /* @__PURE__ */ jsx(IconMail, { size: iconSize });
|
|
5161
5314
|
case "url":
|
|
@@ -5268,5 +5421,5 @@ const AlephaUI = $module({
|
|
|
5268
5421
|
});
|
|
5269
5422
|
|
|
5270
5423
|
//#endregion
|
|
5271
|
-
export { ActionButton as _, Control as a, useToast as b, Breadcrumb as c, DetailList as d, ToggleSidebarButton as f, ClipboardButton as g, LanguageButton as h, TypeForm as i, Flex$1 as l, useDialog as m, capitalize as n,
|
|
5272
|
-
//# sourceMappingURL=core-
|
|
5424
|
+
export { ActionButton as _, Control as a, useToast as b, Breadcrumb as c, DetailList as d, ToggleSidebarButton as f, ClipboardButton as g, LanguageButton as h, TypeForm as i, Flex$1 as l, useDialog as m, capitalize as n, DashboardShell as o, ThemeButton as p, DataTable as r, Text$1 as s, AlephaUI as t, StatCards as u, ui as v, alephaSidebarAtom as x, AlephaMantineProvider as y };
|
|
5425
|
+
//# sourceMappingURL=core-CYaRQ8O-.js.map
|