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 { 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 () {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ export const Form: React.FC<any> = ({
|
|||
mode,
|
||||
className,
|
||||
onInit,
|
||||
afterLoad,
|
||||
}) => {
|
||||
const local = useLocal({
|
||||
ready: false,
|
||||
|
|
@ -121,6 +122,9 @@ export const Form: React.FC<any> = ({
|
|||
local.ready = true;
|
||||
local.data = res;
|
||||
local.render();
|
||||
if (typeof afterLoad === "function") {
|
||||
afterLoad(local);
|
||||
}
|
||||
setTimeout(() => {
|
||||
toast.dismiss();
|
||||
}, 100);
|
||||
|
|
@ -183,31 +187,18 @@ export const Form: React.FC<any> = ({
|
|||
local.ready = true;
|
||||
local.data = res;
|
||||
local.render(); // Panggil render setelah data diperbarui
|
||||
|
||||
if (typeof afterLoad === "function") {
|
||||
await 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();
|
||||
}, []);
|
||||
|
||||
// Tambahkan dependency ke header agar reaktif
|
||||
const HeaderComponent = header(local);
|
||||
const HeaderComponent = typeof header === "function" ? header(local) : <></>;
|
||||
if (!local.ready)
|
||||
return (
|
||||
<div className="flex flex-grow flex-row items-center justify-center">
|
||||
|
|
@ -219,7 +210,7 @@ export const Form: React.FC<any> = ({
|
|||
);
|
||||
return (
|
||||
<div className={`flex-grow flex-col flex ${className}`}>
|
||||
<div className="flex flex-row">{header(local)}</div>
|
||||
<div className="flex flex-row">{HeaderComponent}</div>
|
||||
{showResize ? (
|
||||
// Resize panels...
|
||||
<ResizablePanelGroup direction="vertical" className="rounded-lg border">
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ export const FormBetter: React.FC<any> = ({
|
|||
mode,
|
||||
className,
|
||||
onInit,
|
||||
afterLoad,
|
||||
}) => {
|
||||
const [fm, setFM] = useState<any>({
|
||||
data: null as any,
|
||||
|
|
@ -42,6 +43,7 @@ export const FormBetter: React.FC<any> = ({
|
|||
showResize,
|
||||
mode,
|
||||
className: cx(className, "top-0 left-0 w-full"),
|
||||
afterLoad,
|
||||
onInit: (form: any) => {
|
||||
setFM(form);
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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<any> = ({
|
||||
name,
|
||||
column,
|
||||
|
|
|
|||
|
|
@ -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<any> = ({
|
||||
autoPagination = true,
|
||||
|
|
@ -116,6 +116,12 @@ export const TableList: React.FC<any> = ({
|
|||
{"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<any> = ({
|
|||
}
|
||||
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 [columns] = React.useState<typeof defaultColumns>(() =>
|
||||
checkbox
|
||||
|
|
@ -548,9 +555,7 @@ export const TableList: React.FC<any> = ({
|
|||
>
|
||||
{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<any> = ({
|
|||
setData(local.data);
|
||||
},
|
||||
};
|
||||
const head = column.find(
|
||||
const head = cols.find(
|
||||
(e: any) =>
|
||||
e?.name ===
|
||||
get(ctx, "column.columnDef.accessorKey")
|
||||
|
|
|
|||
|
|
@ -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<any> = ({
|
||||
|
|
|
|||
|
|
@ -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<any> = ({
|
||||
tabHeader,
|
||||
name,
|
||||
modeTab,
|
||||
column,
|
||||
|
|
@ -30,12 +31,20 @@ export const TableUI: React.FC<any> = ({
|
|||
tab,
|
||||
onTab,
|
||||
breadcrumb,
|
||||
ready = true,
|
||||
}) => {
|
||||
const local = useLocal({
|
||||
tab: get(tab, "[0].id"),
|
||||
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 (
|
||||
<div className="flex flex-col flex-grow">
|
||||
<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") {
|
||||
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<any> = ({
|
|||
)}
|
||||
|
||||
<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 ">
|
||||
<TableList
|
||||
name={name}
|
||||
header={header}
|
||||
column={column}
|
||||
onLoad={onLoad}
|
||||
onCount={onCount}
|
||||
onInit={(e: any) => {
|
||||
local.table = e;
|
||||
local.render();
|
||||
if (typeof onInit === "function") {
|
||||
onInit(e);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{local.show ? (
|
||||
<TableList
|
||||
name={name}
|
||||
header={header}
|
||||
column={column}
|
||||
onLoad={onLoad}
|
||||
onCount={onCount}
|
||||
onInit={(e: any) => {
|
||||
local.table = e;
|
||||
local.render();
|
||||
if (typeof onInit === "function") {
|
||||
onInit(e);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -205,10 +205,13 @@ const DropdownHamburgerBetter: React.FC<{
|
|||
<Alert
|
||||
type={"delete"}
|
||||
msg={local?.msg}
|
||||
onClick={async () => {
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
<div className="flex flex-col w-full">
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Reference in New Issue