wip fix
This commit is contained in:
parent
4559a90ca1
commit
9957e9d626
|
|
@ -93,7 +93,6 @@ export const Field: FC<{
|
|||
},
|
||||
modify: null as any,
|
||||
});
|
||||
|
||||
const textAreaRef = useRef<any>();
|
||||
useEffect(() => {
|
||||
autosize(textAreaRef.current);
|
||||
|
|
|
|||
|
|
@ -1,30 +1,54 @@
|
|||
import { useLocal } from "@/utils/use-local";
|
||||
import get from "lodash.get";
|
||||
import { FC, useEffect } from "react";
|
||||
import { Tabs, TabsList, TabsTrigger } from "../ui/tabs";
|
||||
import {
|
||||
MasterDetailConfig,
|
||||
MasterDetailLocal,
|
||||
MasterDetailProp,
|
||||
} from "./type";
|
||||
import { Tab } from "../custom/Tab";
|
||||
import { Tabs, TabsList, TabsTrigger } from "../ui/tabs";
|
||||
import { GFCol } from "@/gen/utils";
|
||||
import { master_detail_gen_hash, master_detail_params } from "./utils";
|
||||
|
||||
export const MasterDetail: FC<MasterDetailProp> = (props) => {
|
||||
const { header, PassProp, master, detail, mode, title, actions } = props;
|
||||
const md = useLocal<MasterDetailLocal & { cache_internal: any }>({
|
||||
mode,
|
||||
selected: null,
|
||||
active_tab: "",
|
||||
ui: {
|
||||
back: false,
|
||||
title: title,
|
||||
breadcrumb: [],
|
||||
default_actions: null as any,
|
||||
actions: null as any,
|
||||
const { header, name, mode, title, actions, gen_fields } = props;
|
||||
const md = useLocal<MasterDetailLocal & { cache_internal: any }>(
|
||||
{
|
||||
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,
|
||||
},
|
||||
cache_internal: {},
|
||||
cache: null as any,
|
||||
});
|
||||
() => {
|
||||
if (!isEditor) {
|
||||
const hash = master_detail_params(md);
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
if (!md.pk && gen_fields) {
|
||||
for (const str of gen_fields) {
|
||||
const f = JSON.parse(str) as GFCol;
|
||||
if (f.is_pk) md.pk = f;
|
||||
}
|
||||
}
|
||||
|
||||
if (!md.ui.actions) {
|
||||
md.ui.actions = actions(md);
|
||||
|
|
@ -72,6 +96,24 @@ const BreadcrumbMode: FC<{
|
|||
props: MasterDetailProp;
|
||||
md: MasterDetailConfig;
|
||||
}> = ({ props, md }) => {
|
||||
const local = useLocal({ init: false }, () => {
|
||||
local.init = true;
|
||||
local.render();
|
||||
});
|
||||
|
||||
if (local.init) {
|
||||
const hash = master_detail_params(md);
|
||||
delete hash.parent_id;
|
||||
|
||||
if (!md.selected) {
|
||||
delete hash[md.name];
|
||||
location.hash = master_detail_gen_hash(hash);
|
||||
} else if (md.pk) {
|
||||
hash[md.name] = md.selected[md.pk.name];
|
||||
location.hash = master_detail_gen_hash(hash);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cx("c-flex-1 c-flex-col c-flex")}>
|
||||
<div
|
||||
|
|
@ -80,6 +122,11 @@ const BreadcrumbMode: FC<{
|
|||
<props.PassProp md={md}>{props.master}</props.PassProp>
|
||||
</div>
|
||||
{md.selected && <Detail props={props} md={md} />}
|
||||
{isEditor && !local.init && (
|
||||
<div className="c-hidden">
|
||||
<Detail props={props} md={md} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { GFCol } from "@/gen/utils";
|
||||
import { ReactElement, ReactNode } from "react";
|
||||
|
||||
export type MasterDetailProp = {
|
||||
|
|
@ -8,6 +9,8 @@ export type MasterDetailProp = {
|
|||
mode: "breadcrumb" | "vertical" | "horizontal";
|
||||
title: string;
|
||||
actions: (md: any) => MasterDetailAction[];
|
||||
gen_fields: any;
|
||||
name: string;
|
||||
};
|
||||
|
||||
type MasterDetailAction = {
|
||||
|
|
@ -18,6 +21,7 @@ type MasterDetailAction = {
|
|||
};
|
||||
|
||||
export type MasterDetailLocal = {
|
||||
name: string;
|
||||
mode: MasterDetailProp["mode"];
|
||||
selected: null | Record<string, any>;
|
||||
active_tab: string;
|
||||
|
|
@ -29,6 +33,7 @@ export type MasterDetailLocal = {
|
|||
actions: MasterDetailAction[];
|
||||
};
|
||||
cache: (name: string, opt?: { reset: boolean }) => any;
|
||||
pk: null | GFCol;
|
||||
};
|
||||
|
||||
export type MasterDetailConfig = MasterDetailLocal & { render: () => void };
|
||||
|
|
@ -54,6 +59,7 @@ export const master_detail_typings = {
|
|||
actions: ${action_type}[];
|
||||
};
|
||||
cache: (name: string, opt?: { reset: boolean }) => any;
|
||||
pk: null | any
|
||||
}`,
|
||||
action_type,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
import { MasterDetailConfig } from "./type";
|
||||
|
||||
export const master_detail_params = (md: MasterDetailConfig) => {
|
||||
let parent_id =
|
||||
md.pk?.type === "int"
|
||||
? parseInt(md.selected?.[md.pk?.name || ""])
|
||||
: md.selected?.[md.pk?.name || ""];
|
||||
|
||||
const hash: any = {};
|
||||
for (const h of location.hash.split("#")) {
|
||||
if (h) {
|
||||
const [tab_name, tab_val] = h.split("=");
|
||||
if (tab_name && tab_val) {
|
||||
hash[tab_name] = tab_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parent_id) {
|
||||
return { ...hash, parent_id };
|
||||
}
|
||||
return hash;
|
||||
};
|
||||
|
||||
export const master_detail_gen_hash = (
|
||||
obj: Record<string, number | string>
|
||||
) => {
|
||||
let hash = "";
|
||||
for (const [k, v] of Object.entries(obj)) {
|
||||
hash += `#${k}=${v}`;
|
||||
}
|
||||
return hash;
|
||||
};
|
||||
|
|
@ -20,8 +20,13 @@ export const on_load = ({
|
|||
async (opt) => {
|
||||
if (isEditor) return {};
|
||||
|
||||
${
|
||||
opt?.before_load
|
||||
? opt.before_load
|
||||
: `
|
||||
let id = ${pk.type === "int" ? "parseInt(params.id)" : "params.id"};
|
||||
${opt?.before_load}
|
||||
`
|
||||
}
|
||||
|
||||
let item = {};
|
||||
if (id){
|
||||
|
|
@ -32,16 +37,19 @@ async (opt) => {
|
|||
select: ${JSON.stringify(select, null, 2).split("\n").join("\n ")},
|
||||
});
|
||||
|
||||
for (const [k, v] of Object.entries(item)) {
|
||||
${Object.entries(pks)
|
||||
.map(([k, v]) => {
|
||||
return `\
|
||||
if (k === "${k}") {
|
||||
if (v?.["${v}"]) item[k] = { connect: { ${v}: v?.["${v}"] } } as any;
|
||||
else delete item[k];
|
||||
}`;
|
||||
})
|
||||
.join("\n")}
|
||||
if (item){
|
||||
for (const [k, v] of Object.entries(item)) {
|
||||
${Object.entries(pks)
|
||||
.map(([k, v]) => {
|
||||
return `\
|
||||
if (k === "${k}") {
|
||||
if (v?.["${v}"]) item[k] = { connect: { ${v}: v?.["${v}"] } } as any;
|
||||
else delete item[k];
|
||||
}`;
|
||||
})
|
||||
.join("\n")}
|
||||
}
|
||||
}
|
||||
|
||||
${opt?.after_load}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
import { GFCol } from "../utils";
|
||||
|
||||
export const form_before_load = (
|
||||
table: string,
|
||||
pk: string,
|
||||
pk: GFCol,
|
||||
title: string,
|
||||
label: string
|
||||
) => {
|
||||
return `
|
||||
|
||||
const id = master_detail_params(md).parent_id;
|
||||
|
||||
const after_load = (item: any) => {
|
||||
const set_actions = () =>
|
||||
(md.ui.actions = [
|
||||
|
|
@ -16,7 +21,9 @@ export const form_before_load = (
|
|||
md.ui.actions = [{ label: "Deleting...", type: "ghost" }];
|
||||
md.render();
|
||||
|
||||
await db.${table}.delete({ where: { ${pk}: item.${pk} } });
|
||||
await db.${table}.delete({ where: { ${pk.name}: item.${
|
||||
pk.name
|
||||
} } });
|
||||
|
||||
setTimeout(() => {
|
||||
md.ui.actions = [...md.ui.default_actions];
|
||||
|
|
@ -44,10 +51,12 @@ export const form_before_load = (
|
|||
},
|
||||
]);
|
||||
set_actions();
|
||||
md.ui.breadcrumb = [["${title}", ""]${label ? `, item?.["${label}"]` : ""}];
|
||||
md.ui.breadcrumb = [[md.ui.title, ""]${
|
||||
label ? `, item?.["${label}"]` : ""
|
||||
}];
|
||||
md.render();
|
||||
};
|
||||
md.ui.breadcrumb = [["${title}", ""], "..."];
|
||||
md.ui.breadcrumb = [[md.ui.title, ""], "..."];
|
||||
md.render();
|
||||
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import { gen_columns } from "../gen_table/columns";
|
|||
import { newField as table_new_field } from "../gen_table/new_field";
|
||||
import { gen_detail } from "./gen_detail";
|
||||
import { form_before_load } from "./form_before_load";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
|
||||
export const gen_md = (modify: (data: any) => void, data: any) => {
|
||||
const table = JSON.parse(data.gen_table.value);
|
||||
|
|
@ -86,7 +87,7 @@ export const gen_md = (modify: (data: any) => void, data: any) => {
|
|||
const detail = gen_detail();
|
||||
const title = parse(get(data, "title.value"));
|
||||
const label = parse(get(data, "gen_label.value"));
|
||||
const before_load = form_before_load(table, pk.name, title, label);
|
||||
const before_load = form_before_load(table, pk, title, label);
|
||||
|
||||
detail.props["on_load"].value = form_on_load({
|
||||
pk,
|
||||
|
|
@ -105,9 +106,17 @@ export const gen_md = (modify: (data: any) => void, data: any) => {
|
|||
const childs = get(detail.props, "body.content.childs");
|
||||
if (Array.isArray(childs)) {
|
||||
detail.props.body.content.childs = new_fields.map(form_new_field) as any;
|
||||
console.log(detail.props.body.content.childs);
|
||||
}
|
||||
result["detail"].content = detail.content;
|
||||
result["detail"].content = {
|
||||
id: createId(),
|
||||
name: "Detail",
|
||||
type: "item",
|
||||
dim: {
|
||||
w: "full",
|
||||
h: "full",
|
||||
},
|
||||
childs: [detail.content],
|
||||
};
|
||||
}
|
||||
modify(result);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue