From 8001a395a76c823062105cfb28f9ff62afacec8b Mon Sep 17 00:00:00 2001 From: faisolavolut Date: Thu, 13 Feb 2025 14:43:48 +0700 Subject: [PATCH 1/6] fix: improve event handling in DropdownHamburgerBetter for better alert management --- components/ui/dropdown-menu.tsx | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/components/ui/dropdown-menu.tsx b/components/ui/dropdown-menu.tsx index e6ca75f..153e483 100644 --- a/components/ui/dropdown-menu.tsx +++ b/components/ui/dropdown-menu.tsx @@ -205,10 +205,13 @@ const DropdownHamburgerBetter: React.FC<{ { + onClick={async (e) => { + e.preventDefault(); + e.stopPropagation(); if (typeof local.onClick === "function") { await local.onClick(); } + setOpenAlert(false); }} mode="manual" open={openAlert} @@ -263,19 +266,20 @@ const DropdownHamburgerBetter: React.FC<{ event.stopPropagation(); event.preventDefault(); } - if (typeof e?.onClick === "function") { - local.onClick = e?.onClick; - e?.onClick({ - close: () => { - setOpen(false); - }, - }); - } const data = { alert: e?.alert ? true : false, onClick: e?.onClick, msg: e?.msg, }; + if (typeof e?.onClick === "function") { + local.onClick = e?.onClick; + if (!data?.alert) + e?.onClick({ + close: () => { + setOpen(false); + }, + }); + } if (data?.alert) { setOpen(false); setOpenAlert(e); From e253feba588a88fc3a60731607a565cc4fb134ed Mon Sep 17 00:00:00 2001 From: faisolavolut Date: Fri, 14 Feb 2025 11:34:12 +0700 Subject: [PATCH 2/6] feat: add afterLoad callback to Form and FormBetter components for enhanced data handling --- components/form/Form.tsx | 23 +++++++---------------- components/form/FormBetter.tsx | 2 ++ 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/components/form/Form.tsx b/components/form/Form.tsx index 5d28f0f..eb2c9aa 100644 --- a/components/form/Form.tsx +++ b/components/form/Form.tsx @@ -27,6 +27,7 @@ export const Form: React.FC = ({ mode, className, onInit, + afterLoad, }) => { const local = useLocal({ ready: false, @@ -121,6 +122,9 @@ export const Form: React.FC = ({ local.ready = true; local.data = res; local.render(); + if (typeof afterLoad === "function") { + afterLoad(local); + } setTimeout(() => { toast.dismiss(); }, 100); @@ -183,25 +187,12 @@ export const Form: React.FC = ({ local.ready = true; local.data = res; local.render(); // Panggil render setelah data diperbarui - + if (typeof afterLoad === "function") { + afterLoad(local); + } setTimeout(() => { toast.dismiss(); }, 100); - // if (res instanceof Promise) { - // res.then((data) => { - // local.ready = true; - // local.data = data; - // local.render(); // Panggil render setelah data diperbarui - // toast.dismiss(); - // // toast.success("Data Loaded Successfully!"); - // }); - // } else { - // local.ready = true; - // local.data = res; - // local.render(); // Panggil render untuk memicu re-render - // toast.dismiss(); - // toast.success("Data Loaded Successfully!"); - // } }; run(); }, []); diff --git a/components/form/FormBetter.tsx b/components/form/FormBetter.tsx index 8d245a2..64488df 100644 --- a/components/form/FormBetter.tsx +++ b/components/form/FormBetter.tsx @@ -14,6 +14,7 @@ export const FormBetter: React.FC = ({ mode, className, onInit, + afterLoad, }) => { const [fm, setFM] = useState({ data: null as any, @@ -42,6 +43,7 @@ export const FormBetter: React.FC = ({ showResize, mode, className: cx(className, "top-0 left-0 w-full"), + afterLoad, onInit: (form: any) => { setFM(form); From 822f50595ae40301b81a97a0ed252ef19616e36c Mon Sep 17 00:00:00 2001 From: faisolavolut Date: Fri, 14 Feb 2025 13:07:40 +0700 Subject: [PATCH 3/6] feat: make afterLoad callback in Form component asynchronous for improved data handling --- components/form/Form.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/form/Form.tsx b/components/form/Form.tsx index eb2c9aa..c59d60f 100644 --- a/components/form/Form.tsx +++ b/components/form/Form.tsx @@ -188,7 +188,7 @@ export const Form: React.FC = ({ local.data = res; local.render(); // Panggil render setelah data diperbarui if (typeof afterLoad === "function") { - afterLoad(local); + await afterLoad(local); } setTimeout(() => { toast.dismiss(); From f329480d60b1728a00ecec4f372da5cb25855107 Mon Sep 17 00:00:00 2001 From: faisolavolut Date: Mon, 17 Feb 2025 05:51:08 +0700 Subject: [PATCH 4/6] fix: update HeaderComponent assignment in Form component for improved reactivity --- components/form/Form.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/form/Form.tsx b/components/form/Form.tsx index c59d60f..c1751b4 100644 --- a/components/form/Form.tsx +++ b/components/form/Form.tsx @@ -198,7 +198,7 @@ export const Form: React.FC = ({ }, []); // Tambahkan dependency ke header agar reaktif - const HeaderComponent = header(local); + const HeaderComponent = typeof header === "function" ? header(local) : <>; if (!local.ready) return (
@@ -210,7 +210,7 @@ export const Form: React.FC = ({ ); return (
-
{header(local)}
+
{HeaderComponent}
{showResize ? ( // Resize panels... From 0518f3b03357005137c59b8cdd5a771a0f13625a Mon Sep 17 00:00:00 2001 From: faisolavolut Date: Mon, 17 Feb 2025 14:30:02 +0700 Subject: [PATCH 5/6] refactor: update import paths for consistency and improve code organization --- components/comp/500.tsx | 3 +- components/tablelist/TableBetter.tsx | 2 +- components/tablelist/TableList.tsx | 17 ++++--- components/tablelist/TableListBetter.tsx | 2 +- components/tablelist/TableUI.tsx | 61 ++++++++++++++++++------ utils/getAccess.ts | 1 - 6 files changed, 60 insertions(+), 26 deletions(-) diff --git a/components/comp/500.tsx b/components/comp/500.tsx index 875c01a..062f283 100644 --- a/components/comp/500.tsx +++ b/components/comp/500.tsx @@ -1,7 +1,6 @@ -import { Button } from "flowbite-react"; import type { FC } from "react"; import { HiChevronLeft } from "react-icons/hi"; -import { ButtonLink } from "../ui/button-link"; +import { ButtonLink } from "@/lib/components/ui/button-link"; import { siteurl } from "@/lib/utils/siteurl"; const ServerErrorPage: FC = function () { diff --git a/components/tablelist/TableBetter.tsx b/components/tablelist/TableBetter.tsx index 9fcdccb..b1bc3f3 100644 --- a/components/tablelist/TableBetter.tsx +++ b/components/tablelist/TableBetter.tsx @@ -7,7 +7,7 @@ import { init_column } from "./lib/column"; import { toast } from "sonner"; import { Loader2, Sticker } from "lucide-react"; import { getNumber } from "@/lib/utils/getNumber"; -import { formatMoney } from "../form/field/TypeInput"; +import { formatMoney } from "@/lib/components/form/field/TypeInput"; export const TableEditBetter: React.FC = ({ name, column, diff --git a/components/tablelist/TableList.tsx b/components/tablelist/TableList.tsx index 1c3846b..39b2e67 100644 --- a/components/tablelist/TableList.tsx +++ b/components/tablelist/TableList.tsx @@ -24,7 +24,7 @@ import { InputSearch } from "../ui/input-search"; import get from "lodash.get"; import { Checkbox } from "../ui/checkbox"; import { getNumber } from "@/lib/utils/getNumber"; -import { formatMoney } from "../form/field/TypeInput"; +import { formatMoney } from "@/lib/components/form/field/TypeInput"; export const TableList: React.FC = ({ autoPagination = true, @@ -116,6 +116,12 @@ export const TableList: React.FC = ({ {"Loading..."} ); + + if (typeof onCount === "function") { + const res = await onCount(); + local.count = res; + local.render(); + } if (Array.isArray(onLoad)) { let res = onLoad; if (!autoPagination) { @@ -282,7 +288,8 @@ export const TableList: React.FC = ({ } run(); }, []); - const defaultColumns: ColumnDef[] = init_column(column); + const cols = typeof column === "function" ? column() : column; + const defaultColumns: ColumnDef[] = init_column(cols); const [sorting, setSorting] = React.useState([]); const [columns] = React.useState(() => checkbox @@ -548,9 +555,7 @@ export const TableList: React.FC = ({ > {headerGroup.headers.map((header, index) => { const name = header.column.id; - const col = column.find( - (e: any) => e?.name === name - ); + const col = cols.find((e: any) => e?.name === name); const isSort = name === "select" ? false @@ -751,7 +756,7 @@ export const TableList: React.FC = ({ setData(local.data); }, }; - const head = column.find( + const head = cols.find( (e: any) => e?.name === get(ctx, "column.columnDef.accessorKey") diff --git a/components/tablelist/TableListBetter.tsx b/components/tablelist/TableListBetter.tsx index 58d77b0..13ac9c6 100644 --- a/components/tablelist/TableListBetter.tsx +++ b/components/tablelist/TableListBetter.tsx @@ -24,7 +24,7 @@ import { InputSearch } from "../ui/input-search"; import get from "lodash.get"; import { Checkbox } from "../ui/checkbox"; import { getNumber } from "@/lib/utils/getNumber"; -import { formatMoney } from "../form/field/TypeInput"; +import { formatMoney } from "@/lib/components/form/field/TypeInput"; import { cloneFM } from "@/lib/utils/cloneFm"; export const TableListBetter: React.FC = ({ diff --git a/components/tablelist/TableUI.tsx b/components/tablelist/TableUI.tsx index 368041e..a061553 100644 --- a/components/tablelist/TableUI.tsx +++ b/components/tablelist/TableUI.tsx @@ -7,6 +7,7 @@ import { TabHeaderBetter } from "../tablist/TabHeaderBetter"; import { getNumber } from "@/lib/utils/getNumber"; import { BreadcrumbBetterLink } from "../ui/breadcrumb-link"; export const TableUI: React.FC = ({ + tabHeader, name, modeTab, column, @@ -30,12 +31,20 @@ export const TableUI: React.FC = ({ tab, onTab, breadcrumb, + ready = true, }) => { const local = useLocal({ tab: get(tab, "[0].id"), table: null as any, + show: true as boolean, }); - + if (!ready) { + return ( +
+
+
+ ); + } return (
@@ -88,6 +97,12 @@ export const TableUI: React.FC = ({ if (typeof onTab === "function") { onTab(local.tab); } + local.show = false; + local.render(); + setTimeout(() => { + local.show = true; + local.render(); + }, 100); if (typeof local?.table?.refresh === "function") { { local.table.refresh(); @@ -103,21 +118,37 @@ export const TableUI: React.FC = ({ )}
+
+ {tab?.length ? ( + typeof tabHeader === "function" ? ( + tabHeader(local) + ) : ( + tabHeader + ) + ) : ( + <> + )} +
+
- { - local.table = e; - local.render(); - if (typeof onInit === "function") { - onInit(e); - } - }} - /> + {local.show ? ( + { + local.table = e; + local.render(); + if (typeof onInit === "function") { + onInit(e); + } + }} + /> + ) : ( + <> + )}
diff --git a/utils/getAccess.ts b/utils/getAccess.ts index 2d99adf..3543cc8 100644 --- a/utils/getAccess.ts +++ b/utils/getAccess.ts @@ -49,7 +49,6 @@ export const accessMe = async (keys: string) => { ); const data = user?.data.data; const roles = data.roles; - if (!Array.isArray(roles) || !roles?.length) return false; for (const role of roles) { const permissionExists = role.permissions.some( From cc0a9d8651ad8a33fab0bead01f30c56064ba6de Mon Sep 17 00:00:00 2001 From: faisolavolut Date: Tue, 18 Feb 2025 01:01:02 +0700 Subject: [PATCH 6/6] feat: enhance actionToast utility with failed callback and make on_change asynchronous --- components/form/field/TypeUploadSingle.tsx | 2 +- utils/action.tsx | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/components/form/field/TypeUploadSingle.tsx b/components/form/field/TypeUploadSingle.tsx index 532ad37..bccf6cb 100644 --- a/components/form/field/TypeUploadSingle.tsx +++ b/components/form/field/TypeUploadSingle.tsx @@ -85,7 +85,7 @@ export const FieldUploadSingle: FC<{ input.isLocal = true; input.render(); if (typeof on_change === "function") { - on_change({}); + await on_change({}); } return; const formData = new FormData(); diff --git a/utils/action.tsx b/utils/action.tsx index aa6ade0..04ebcf0 100644 --- a/utils/action.tsx +++ b/utils/action.tsx @@ -7,12 +7,21 @@ export const actionToast = async (data: { before?: () => any; success?: () => any; after?: () => any; + failed?: () => any; msg_succes?: string; msg_error?: string; msg_load?: string; }) => { - const { task, before, after, success, msg_succes, msg_error, msg_load } = - data; + const { + task, + before, + after, + success, + msg_succes, + msg_error, + msg_load, + failed, + } = data; try { if (typeof before === "function") before(); @@ -61,6 +70,7 @@ export const actionToast = async (data: { }, 100); } catch (ex: any) { setTimeout(() => { + if (typeof failed === "function") failed(); toast.dismiss(); toast.error(