import { GFCol } from "@/gen/utils"; import { useLocal } from "@/utils/use-local"; import get from "lodash.get"; import { FC, useEffect } from "react"; import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels"; import { Tabs, TabsList, TabsTrigger } from "../ui/tabs"; import { MasterDetailConfig, MasterDetailLocal, MasterDetailProp, } from "./type"; import { master_detail_gen_hash, master_detail_params } from "./utils"; export const MasterDetail: FC = (props) => { const { header, name, mode, title, actions, gen_fields, md_parent } = props; const md = useLocal( { name, mode, selected: null, active_tab: "", ui: { back: false, title: title, breadcrumb: [], default_actions: null as any, actions: null as any, }, cache_internal: {}, cache: null as any, pk: null as null | GFCol, parent: md_parent, }, () => { const params = master_detail_params(md); const hash = params.hash; if (params.tabs && params.tabs[md.name]) { md.active_tab = params.tabs[md.name]; } if (md.mode === "breadcrumb") { if (hash && hash[name] && md.pk) { if (md.pk.type === "int") { md.selected = { [md.pk.name]: parseInt(hash[name]) }; } else { md.selected = { [md.pk.name]: hash[name] }; } } } md.render(); } ); const local = useLocal({ init: false }, () => { local.init = true; local.render(); }); if (local.init) { const params = master_detail_params(md); const hash = params.hash; delete hash.parent_id; if (!md.selected) { delete hash[md.name]; master_detail_gen_hash(params); } else if (md.pk) { hash[md.name] = md.selected[md.pk.name]; master_detail_gen_hash(params); } } if (!md.pk && gen_fields) { for (const str of gen_fields) { try { const f = JSON.parse(str) as GFCol; if (f.is_pk) md.pk = f; } catch (e) {} } } if (!md.ui.actions) { md.ui.actions = actions(md); md.ui.default_actions = actions(md); } if (!md.cache) { md.cache = (name: string, opt?: { reset: boolean }) => { if (!md.cache_internal[name] || opt?.reset) md.cache_internal[name] = {}; return md.cache_internal[name]; }; } if (isEditor) { useEffect(() => { md.ui.title = title; md.render(); }, [title]); useEffect(() => { md.mode = mode; md.render(); }, [mode]); } useEffect(() => { let back = false; if (md.selected && md.mode === "breadcrumb") { back = true; } if (back !== md.ui.back) { md.ui.back = back; md.render(); } }, [md.selected]); return (
{md.mode === "breadcrumb" && ( )} {md.mode === "vertical" && ( )} {md.mode === "horizontal" && ( )} {isEditor && (
{props.detail}
)}
); }; const VerticalMode: FC<{ props: MasterDetailProp; md: MasterDetailConfig; header: any; }> = ({ props, md, header }) => { return (
{props.master} <> { if (e < 80) { localStorage.setItem(`prasi-md-h-${md.name}`, e.toString()); } }} > {header}
); }; const HorizontalMode: FC<{ props: MasterDetailProp; md: MasterDetailConfig; header: any; }> = ({ props, md, header }) => { return (
{props.master} <> { if (e < 80) { localStorage.setItem(`prasi-md-h-${md.name}`, e.toString()); } }} > {header}
); }; const BreadcrumbMode: FC<{ props: MasterDetailProp; md: MasterDetailConfig; header: any; }> = ({ props, md, header }) => { return ( <> {header}
{props.master}
{md.selected && }
); }; const Detail: FC<{ props: MasterDetailProp; md: MasterDetailConfig; }> = ({ props, md }) => { const childs = get( props.detail, "props.meta.item.component.props.detail.content.childs" ); let idx = childs.findIndex( (e: any) => e.name.toLowerCase() === md.active_tab.toLowerCase() ); if (idx < 0) { idx = 0; if (childs[idx]) { md.active_tab = childs[idx].name; } setTimeout(md.render); } const content = childs[idx]; return ( <> {childs.length > 1 && ( {childs.map((e: { name: string }) => { return ( { const params = master_detail_params(md); const hash = params.hash; delete hash.parent_id; params.tabs[md.name] = e.name; master_detail_gen_hash(params); md.active_tab = e.name; md.render(); }} overrideClassName >
{e.name}
); })}
)} {content} ); };