Merge branch 'main' of https://github.com/faisolavolut/julong-lib
This commit is contained in:
commit
000fae36c1
|
|
@ -1,7 +1,6 @@
|
||||||
import { Button } from "flowbite-react";
|
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
import { HiChevronLeft } from "react-icons/hi";
|
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";
|
import { siteurl } from "@/lib/utils/siteurl";
|
||||||
|
|
||||||
const ServerErrorPage: FC = function () {
|
const ServerErrorPage: FC = function () {
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ export const Form: React.FC<any> = ({
|
||||||
mode,
|
mode,
|
||||||
className,
|
className,
|
||||||
onInit,
|
onInit,
|
||||||
|
afterLoad,
|
||||||
}) => {
|
}) => {
|
||||||
const local = useLocal({
|
const local = useLocal({
|
||||||
ready: false,
|
ready: false,
|
||||||
|
|
@ -121,6 +122,9 @@ export const Form: React.FC<any> = ({
|
||||||
local.ready = true;
|
local.ready = true;
|
||||||
local.data = res;
|
local.data = res;
|
||||||
local.render();
|
local.render();
|
||||||
|
if (typeof afterLoad === "function") {
|
||||||
|
afterLoad(local);
|
||||||
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
toast.dismiss();
|
toast.dismiss();
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
@ -183,31 +187,18 @@ export const Form: React.FC<any> = ({
|
||||||
local.ready = true;
|
local.ready = true;
|
||||||
local.data = res;
|
local.data = res;
|
||||||
local.render(); // Panggil render setelah data diperbarui
|
local.render(); // Panggil render setelah data diperbarui
|
||||||
|
if (typeof afterLoad === "function") {
|
||||||
|
await afterLoad(local);
|
||||||
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
toast.dismiss();
|
toast.dismiss();
|
||||||
}, 100);
|
}, 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();
|
run();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Tambahkan dependency ke header agar reaktif
|
// Tambahkan dependency ke header agar reaktif
|
||||||
const HeaderComponent = header(local);
|
const HeaderComponent = typeof header === "function" ? header(local) : <></>;
|
||||||
if (!local.ready)
|
if (!local.ready)
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-grow flex-row items-center justify-center">
|
<div className="flex flex-grow flex-row items-center justify-center">
|
||||||
|
|
@ -219,7 +210,7 @@ export const Form: React.FC<any> = ({
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div className={`flex-grow flex-col flex ${className}`}>
|
<div className={`flex-grow flex-col flex ${className}`}>
|
||||||
<div className="flex flex-row">{header(local)}</div>
|
<div className="flex flex-row">{HeaderComponent}</div>
|
||||||
{showResize ? (
|
{showResize ? (
|
||||||
// Resize panels...
|
// Resize panels...
|
||||||
<ResizablePanelGroup direction="vertical" className="rounded-lg border">
|
<ResizablePanelGroup direction="vertical" className="rounded-lg border">
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ export const FormBetter: React.FC<any> = ({
|
||||||
mode,
|
mode,
|
||||||
className,
|
className,
|
||||||
onInit,
|
onInit,
|
||||||
|
afterLoad,
|
||||||
}) => {
|
}) => {
|
||||||
const [fm, setFM] = useState<any>({
|
const [fm, setFM] = useState<any>({
|
||||||
data: null as any,
|
data: null as any,
|
||||||
|
|
@ -42,6 +43,7 @@ export const FormBetter: React.FC<any> = ({
|
||||||
showResize,
|
showResize,
|
||||||
mode,
|
mode,
|
||||||
className: cx(className, "top-0 left-0 w-full"),
|
className: cx(className, "top-0 left-0 w-full"),
|
||||||
|
afterLoad,
|
||||||
onInit: (form: any) => {
|
onInit: (form: any) => {
|
||||||
setFM(form);
|
setFM(form);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ export const FieldUploadSingle: FC<{
|
||||||
input.isLocal = true;
|
input.isLocal = true;
|
||||||
input.render();
|
input.render();
|
||||||
if (typeof on_change === "function") {
|
if (typeof on_change === "function") {
|
||||||
on_change({});
|
await on_change({});
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { init_column } from "./lib/column";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { Loader2, Sticker } from "lucide-react";
|
import { Loader2, Sticker } from "lucide-react";
|
||||||
import { getNumber } from "@/lib/utils/getNumber";
|
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<any> = ({
|
export const TableEditBetter: React.FC<any> = ({
|
||||||
name,
|
name,
|
||||||
column,
|
column,
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import { InputSearch } from "../ui/input-search";
|
||||||
import get from "lodash.get";
|
import get from "lodash.get";
|
||||||
import { Checkbox } from "../ui/checkbox";
|
import { Checkbox } from "../ui/checkbox";
|
||||||
import { getNumber } from "@/lib/utils/getNumber";
|
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<any> = ({
|
export const TableList: React.FC<any> = ({
|
||||||
autoPagination = true,
|
autoPagination = true,
|
||||||
|
|
@ -116,6 +116,12 @@ export const TableList: React.FC<any> = ({
|
||||||
{"Loading..."}
|
{"Loading..."}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (typeof onCount === "function") {
|
||||||
|
const res = await onCount();
|
||||||
|
local.count = res;
|
||||||
|
local.render();
|
||||||
|
}
|
||||||
if (Array.isArray(onLoad)) {
|
if (Array.isArray(onLoad)) {
|
||||||
let res = onLoad;
|
let res = onLoad;
|
||||||
if (!autoPagination) {
|
if (!autoPagination) {
|
||||||
|
|
@ -282,7 +288,8 @@ export const TableList: React.FC<any> = ({
|
||||||
}
|
}
|
||||||
run();
|
run();
|
||||||
}, []);
|
}, []);
|
||||||
const defaultColumns: ColumnDef<Person>[] = init_column(column);
|
const cols = typeof column === "function" ? column() : column;
|
||||||
|
const defaultColumns: ColumnDef<Person>[] = init_column(cols);
|
||||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||||
const [columns] = React.useState<typeof defaultColumns>(() =>
|
const [columns] = React.useState<typeof defaultColumns>(() =>
|
||||||
checkbox
|
checkbox
|
||||||
|
|
@ -548,9 +555,7 @@ export const TableList: React.FC<any> = ({
|
||||||
>
|
>
|
||||||
{headerGroup.headers.map((header, index) => {
|
{headerGroup.headers.map((header, index) => {
|
||||||
const name = header.column.id;
|
const name = header.column.id;
|
||||||
const col = column.find(
|
const col = cols.find((e: any) => e?.name === name);
|
||||||
(e: any) => e?.name === name
|
|
||||||
);
|
|
||||||
const isSort =
|
const isSort =
|
||||||
name === "select"
|
name === "select"
|
||||||
? false
|
? false
|
||||||
|
|
@ -751,7 +756,7 @@ export const TableList: React.FC<any> = ({
|
||||||
setData(local.data);
|
setData(local.data);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const head = column.find(
|
const head = cols.find(
|
||||||
(e: any) =>
|
(e: any) =>
|
||||||
e?.name ===
|
e?.name ===
|
||||||
get(ctx, "column.columnDef.accessorKey")
|
get(ctx, "column.columnDef.accessorKey")
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import { InputSearch } from "../ui/input-search";
|
||||||
import get from "lodash.get";
|
import get from "lodash.get";
|
||||||
import { Checkbox } from "../ui/checkbox";
|
import { Checkbox } from "../ui/checkbox";
|
||||||
import { getNumber } from "@/lib/utils/getNumber";
|
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";
|
import { cloneFM } from "@/lib/utils/cloneFm";
|
||||||
|
|
||||||
export const TableListBetter: React.FC<any> = ({
|
export const TableListBetter: React.FC<any> = ({
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { TabHeaderBetter } from "../tablist/TabHeaderBetter";
|
||||||
import { getNumber } from "@/lib/utils/getNumber";
|
import { getNumber } from "@/lib/utils/getNumber";
|
||||||
import { BreadcrumbBetterLink } from "../ui/breadcrumb-link";
|
import { BreadcrumbBetterLink } from "../ui/breadcrumb-link";
|
||||||
export const TableUI: React.FC<any> = ({
|
export const TableUI: React.FC<any> = ({
|
||||||
|
tabHeader,
|
||||||
name,
|
name,
|
||||||
modeTab,
|
modeTab,
|
||||||
column,
|
column,
|
||||||
|
|
@ -30,12 +31,20 @@ export const TableUI: React.FC<any> = ({
|
||||||
tab,
|
tab,
|
||||||
onTab,
|
onTab,
|
||||||
breadcrumb,
|
breadcrumb,
|
||||||
|
ready = true,
|
||||||
}) => {
|
}) => {
|
||||||
const local = useLocal({
|
const local = useLocal({
|
||||||
tab: get(tab, "[0].id"),
|
tab: get(tab, "[0].id"),
|
||||||
table: null as any,
|
table: null as any,
|
||||||
|
show: true as boolean,
|
||||||
});
|
});
|
||||||
|
if (!ready) {
|
||||||
|
return (
|
||||||
|
<div className="flex-grow flex-grow flex flex-row items-center justify-center">
|
||||||
|
<div className="spinner-better"></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col flex-grow">
|
<div className="flex flex-col flex-grow">
|
||||||
<div className="w-full p-4 py-6 pr-6 pl-3 ">
|
<div className="w-full p-4 py-6 pr-6 pl-3 ">
|
||||||
|
|
@ -88,6 +97,12 @@ export const TableUI: React.FC<any> = ({
|
||||||
if (typeof onTab === "function") {
|
if (typeof onTab === "function") {
|
||||||
onTab(local.tab);
|
onTab(local.tab);
|
||||||
}
|
}
|
||||||
|
local.show = false;
|
||||||
|
local.render();
|
||||||
|
setTimeout(() => {
|
||||||
|
local.show = true;
|
||||||
|
local.render();
|
||||||
|
}, 100);
|
||||||
if (typeof local?.table?.refresh === "function") {
|
if (typeof local?.table?.refresh === "function") {
|
||||||
{
|
{
|
||||||
local.table.refresh();
|
local.table.refresh();
|
||||||
|
|
@ -103,21 +118,37 @@ export const TableUI: React.FC<any> = ({
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="flex flex-col bg-white mt-[-1px] flex-grow">
|
<div className="flex flex-col bg-white mt-[-1px] flex-grow">
|
||||||
|
<div className="flex flex-col w-full">
|
||||||
|
{tab?.length ? (
|
||||||
|
typeof tabHeader === "function" ? (
|
||||||
|
tabHeader(local)
|
||||||
|
) : (
|
||||||
|
tabHeader
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="w-full flex flex-row flex-grow overflow-hidden ">
|
<div className="w-full flex flex-row flex-grow overflow-hidden ">
|
||||||
<TableList
|
{local.show ? (
|
||||||
name={name}
|
<TableList
|
||||||
header={header}
|
name={name}
|
||||||
column={column}
|
header={header}
|
||||||
onLoad={onLoad}
|
column={column}
|
||||||
onCount={onCount}
|
onLoad={onLoad}
|
||||||
onInit={(e: any) => {
|
onCount={onCount}
|
||||||
local.table = e;
|
onInit={(e: any) => {
|
||||||
local.render();
|
local.table = e;
|
||||||
if (typeof onInit === "function") {
|
local.render();
|
||||||
onInit(e);
|
if (typeof onInit === "function") {
|
||||||
}
|
onInit(e);
|
||||||
}}
|
}
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -205,10 +205,13 @@ const DropdownHamburgerBetter: React.FC<{
|
||||||
<Alert
|
<Alert
|
||||||
type={"delete"}
|
type={"delete"}
|
||||||
msg={local?.msg}
|
msg={local?.msg}
|
||||||
onClick={async () => {
|
onClick={async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
if (typeof local.onClick === "function") {
|
if (typeof local.onClick === "function") {
|
||||||
await local.onClick();
|
await local.onClick();
|
||||||
}
|
}
|
||||||
|
setOpenAlert(false);
|
||||||
}}
|
}}
|
||||||
mode="manual"
|
mode="manual"
|
||||||
open={openAlert}
|
open={openAlert}
|
||||||
|
|
@ -263,19 +266,20 @@ const DropdownHamburgerBetter: React.FC<{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
if (typeof e?.onClick === "function") {
|
|
||||||
local.onClick = e?.onClick;
|
|
||||||
e?.onClick({
|
|
||||||
close: () => {
|
|
||||||
setOpen(false);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const data = {
|
const data = {
|
||||||
alert: e?.alert ? true : false,
|
alert: e?.alert ? true : false,
|
||||||
onClick: e?.onClick,
|
onClick: e?.onClick,
|
||||||
msg: e?.msg,
|
msg: e?.msg,
|
||||||
};
|
};
|
||||||
|
if (typeof e?.onClick === "function") {
|
||||||
|
local.onClick = e?.onClick;
|
||||||
|
if (!data?.alert)
|
||||||
|
e?.onClick({
|
||||||
|
close: () => {
|
||||||
|
setOpen(false);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
if (data?.alert) {
|
if (data?.alert) {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
setOpenAlert(e);
|
setOpenAlert(e);
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,21 @@ export const actionToast = async (data: {
|
||||||
before?: () => any;
|
before?: () => any;
|
||||||
success?: () => any;
|
success?: () => any;
|
||||||
after?: () => any;
|
after?: () => any;
|
||||||
|
failed?: () => any;
|
||||||
msg_succes?: string;
|
msg_succes?: string;
|
||||||
msg_error?: string;
|
msg_error?: string;
|
||||||
msg_load?: string;
|
msg_load?: string;
|
||||||
}) => {
|
}) => {
|
||||||
const { task, before, after, success, msg_succes, msg_error, msg_load } =
|
const {
|
||||||
data;
|
task,
|
||||||
|
before,
|
||||||
|
after,
|
||||||
|
success,
|
||||||
|
msg_succes,
|
||||||
|
msg_error,
|
||||||
|
msg_load,
|
||||||
|
failed,
|
||||||
|
} = data;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (typeof before === "function") before();
|
if (typeof before === "function") before();
|
||||||
|
|
@ -61,6 +70,7 @@ export const actionToast = async (data: {
|
||||||
}, 100);
|
}, 100);
|
||||||
} catch (ex: any) {
|
} catch (ex: any) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
if (typeof failed === "function") failed();
|
||||||
toast.dismiss();
|
toast.dismiss();
|
||||||
toast.error(
|
toast.error(
|
||||||
<div className="flex flex-col w-full">
|
<div className="flex flex-col w-full">
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,6 @@ export const accessMe = async (keys: string) => {
|
||||||
);
|
);
|
||||||
const data = user?.data.data;
|
const data = user?.data.data;
|
||||||
const roles = data.roles;
|
const roles = data.roles;
|
||||||
|
|
||||||
if (!Array.isArray(roles) || !roles?.length) return false;
|
if (!Array.isArray(roles) || !roles?.length) return false;
|
||||||
for (const role of roles) {
|
for (const role of roles) {
|
||||||
const permissionExists = role.permissions.some(
|
const permissionExists = role.permissions.some(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue