{md.actions.map((e, idx) => {
if (isValidElement(e)) {
return
;
}
- if (typeof e === "object" && e.label) {
+ if (typeof e === "object" && (e.action || e.label)) {
return
;
}
})}
diff --git a/comps/md/MDTab.tsx b/comps/md/MDTab.tsx
index 456d44d..12cc540 100755
--- a/comps/md/MDTab.tsx
+++ b/comps/md/MDTab.tsx
@@ -16,7 +16,6 @@ export const MDTab: FC<{ md: MDLocal; mdr: MDRef }> = ({ md, mdr }) => {
return null;
}
-
return (
<>
{md.props.show_head === "only-child" &&
}
@@ -41,7 +40,7 @@ export const MDNavTab: FC<{ md: MDLocal; mdr: MDRef }> = ({ md, mdr }) => {
diff --git a/comps/md/MasterDetail.tsx b/comps/md/MasterDetail.tsx
index 0ee78b8..012b5c2 100755
--- a/comps/md/MasterDetail.tsx
+++ b/comps/md/MasterDetail.tsx
@@ -44,7 +44,7 @@ export const MasterDetail: FC<{
active: "",
list: [],
},
- internal: { action_should_refresh: false },
+ internal: { action_should_refresh: true },
childs: {},
props: {
mode,
@@ -65,7 +65,7 @@ export const MasterDetail: FC<{
masterDetailApplyParams(md);
},
},
- master: { internal: null, render() {}, pk: null },
+ master: { internal: null, render() {} },
});
const local = useLocal({ init: false });
if (isEditor) {
diff --git a/comps/md/utils/md-hash.ts b/comps/md/utils/md-hash.ts
index 73e6a5a..345c86b 100755
--- a/comps/md/utils/md-hash.ts
+++ b/comps/md/utils/md-hash.ts
@@ -36,7 +36,7 @@ export const masterDetailApplyParams = (md: MDLocal) => {
}
}
- const pk = md.master.pk;
+ const pk = md.pk;
if (pk && row[pk.name]) {
md.params.hash[md.name] = row[pk.name];
}
diff --git a/comps/md/utils/md-init.ts b/comps/md/utils/md-init.ts
index fff5467..736df07 100755
--- a/comps/md/utils/md-init.ts
+++ b/comps/md/utils/md-init.ts
@@ -30,7 +30,7 @@ export const masterDetailInit = (
md.master.internal = child;
const pk = parseGenField(md.props.gen_fields).find((e) => e.is_pk);
if (pk) {
- md.master.pk = pk;
+ md.pk = pk;
}
}
if (cid === "cb52075a-14ab-455a-9847-6f1d929a2a73") {
@@ -62,7 +62,7 @@ export const masterDetailInit = (
export const masterDetailSelected = (md: MDLocal) => {
md.params.parse();
- const pk = md.master.pk;
+ const pk = md.pk;
if (pk) {
const value = md.params.hash[md.name];
if (value) {
diff --git a/comps/md/utils/typings.ts b/comps/md/utils/typings.ts
index 9a99d61..ad3182a 100755
--- a/comps/md/utils/typings.ts
+++ b/comps/md/utils/typings.ts
@@ -18,13 +18,14 @@ export type MDLocalInternal = {
list: string[];
};
internal: { action_should_refresh: boolean };
- master: { internal: any; render: () => void; pk: null | GFCol };
+ master: { internal: any; render: () => void };
params: {
hash: any;
tabs: any;
parse: () => void;
apply: () => void;
};
+ pk?: GFCol;
props: {
mode: "full" | "h-split" | "v-split";
show_head: "always" | "only-master" | "only-child" | "hidden";
@@ -75,19 +76,28 @@ export const MasterDetailType = `const md = {
parse: () => void;
apply: () => void;
};
+ props: {
+ mode: "full" | "h-split" | "v-split";
+ show_head: "always" | "only-master" | "only-child" | "hidden";
+ tab_mode: "h-tab" | "v-tab" | "hidden";
+ editor_tab: string;
+ gen_fields: any;
+ gen_table: string;
+ on_init: (md: any) => void;
+ };
internal: { action_should_refresh: boolean };
render: () => void;
- master: { internal: any; render: () => void; pk: null | {
- name: string;
- type: string;
- is_pk: boolean;
- optional: boolean;
- relation?: {
- from: { table: string; fields: string[] };
- to: { table: string; fields: string[] };
- fields: GFCol[];
- };
- }
+ master: { internal: any; render: () => void; };
+ pk?: {
+ name: string;
+ type: string;
+ is_pk: boolean;
+ optional: boolean;
+ relation?: {
+ from: { table: string; fields: string[] };
+ to: { table: string; fields: string[] };
+ fields: GFCol[];
+ };
};
childs: Record<
string,
diff --git a/gen/gen_form/gen_form.ts b/gen/gen_form/gen_form.ts
index bf12ba0..501e231 100755
--- a/gen/gen_form/gen_form.ts
+++ b/gen/gen_form/gen_form.ts
@@ -60,7 +60,6 @@ export const gen_form = async (modify: (data: any) => void, data: any) => {
result["body"] = data["body"];
result.body.content.childs = [];
- console.log(fields);
for (const item of fields.filter((e) => !e.is_pk)) {
result.body.content.childs.push(await newField(item));
}
diff --git a/gen/gen_form/on_load.ts b/gen/gen_form/on_load.ts
index 1738405..9e085c2 100755
--- a/gen/gen_form/on_load.ts
+++ b/gen/gen_form/on_load.ts
@@ -34,8 +34,8 @@ async (opt) => {
if (isEditor) return ${JSON.stringify(sample)};
let raw_id = params.id;
- if (typeof md === 'object' && md.selected && md.master?.pk) {
- const pk = md.master?.pk?.name;
+ if (typeof md === 'object' && md.selected && md.pk) {
+ const pk = md.pk?.name;
if (md.selected[pk]) {
raw_id = md.selected[pk];
}
diff --git a/gen/gen_form/on_submit.ts b/gen/gen_form/on_submit.ts
index f8e9e58..7db5090 100755
--- a/gen/gen_form/on_submit.ts
+++ b/gen/gen_form/on_submit.ts
@@ -34,6 +34,11 @@ async ({ form, error }: IForm) => {
const pks = ${JSON.stringify(pks)};
for (const [k, v] of Object.entries(pks)) {
if (typeof data[k] === 'object') {
+ if (data[k] === null) {
+ data[k] = {
+ disconnect: true
+ }
+ }
if (data[k][v]) {
data[k] = {
connect: {
diff --git a/gen/gen_relation/gen_relation.ts b/gen/gen_relation/gen_relation.ts
index 58768ce..55e73cb 100755
--- a/gen/gen_relation/gen_relation.ts
+++ b/gen/gen_relation/gen_relation.ts
@@ -3,7 +3,11 @@ import { GFCol, parseGenField } from "../utils";
import { newField } from "./new_field";
import { on_load } from "./on_load";
-export const gen_relation = async (modify: (data: any) => void, data: any) => {
+export const gen_relation = async (
+ modify: (data: any) => void,
+ data: any,
+ arg: { id_parent: string }
+) => {
const table = JSON.parse(data.gen_table.value);
const raw_fields = JSON.parse(data.gen_fields.value) as (
| string
@@ -31,6 +35,10 @@ export const gen_relation = async (modify: (data: any) => void, data: any) => {
}
}
+ if (arg.id_parent) {
+ select[arg.id_parent] = true;
+ }
+
if (!pk) {
alert("Failed to generate! Primary Key not found. ");
return;
@@ -40,7 +48,13 @@ export const gen_relation = async (modify: (data: any) => void, data: any) => {
const code = {} as any;
if (data["on_load"]) {
result["on_load"] = data["on_load"];
- result["on_load"].value = on_load({ pk, pks, select, table });
+ result["on_load"].value = on_load({
+ pk,
+ pks,
+ select,
+ table,
+ id_parent: arg.id_parent,
+ });
code.on_load = result["on_load"].value;
}
@@ -50,7 +64,7 @@ export const gen_relation = async (modify: (data: any) => void, data: any) => {
(item:any, pk:string) => {
return \`${Object.entries(select)
.filter(([k, v]) => {
- if (typeof v !== "object" && k !== pk?.name) {
+ if (typeof v !== "object" && k !== pk?.name && k !== arg.id_parent) {
return true;
}
})
diff --git a/gen/gen_relation/new_field.ts b/gen/gen_relation/new_field.ts
index 149f0bc..ebb3f9d 100755
--- a/gen/gen_relation/new_field.ts
+++ b/gen/gen_relation/new_field.ts
@@ -28,15 +28,22 @@ export type NewFieldArg = {
};
};
-export const newField = (arg: GFCol) => {
+export const newField = (arg: GFCol, idx: number) => {
+ let result = `{item["${arg.name}"]}`;
+ let result_built = `render(React.createElement("div", Object.assign({}, props, { className: cx(props.className, "") }), item["${arg.name}"]));`;
+ if (idx === 0) {
+ result = `
`;
+ result_built = `render(React.createElement("div", Object.assign({}, props, { className: cx(props.className, "") }),
+ React.createElement(FormatValue, { value: item["${arg.name}"], tree_depth: item.__depth })));`;
+ }
return createItem({
name: arg.name,
adv: {
js: `\
- {item["${arg.name}"]}
+ ${result}
`,
- jsBuilt: `render(React.createElement("div", Object.assign({}, props, { className: cx(props.className, "") }), item["${arg.name}"]));`,
+ jsBuilt: result_built,
},
dim: {
h: "full",
diff --git a/gen/gen_relation/on_load.ts b/gen/gen_relation/on_load.ts
index cde8ca2..9c497ae 100755
--- a/gen/gen_relation/on_load.ts
+++ b/gen/gen_relation/on_load.ts
@@ -6,6 +6,7 @@ export const on_load = ({
select,
pks,
opt,
+ id_parent,
}: {
pk: GFCol;
table: string;
@@ -15,6 +16,7 @@ export const on_load = ({
before_load: string;
after_load: string;
};
+ id_parent: string;
}) => {
const sample: any = {};
for (const [k, v] of Object.entries(select) as any) {
@@ -41,11 +43,6 @@ async (opt: { value: any }) => {
}
let items = await db.${table}.findMany({
- where: !!id
- ? {
- ${pk.name}: id,
- }
- : undefined,
select: ${JSON.stringify(select, null, 2).split("\n").join("\n ")},
});
diff --git a/gen/gen_table_list/gen_table_list.tsx b/gen/gen_table_list/gen_table_list.tsx
index ae206d3..490efb2 100755
--- a/gen/gen_table_list/gen_table_list.tsx
+++ b/gen/gen_table_list/gen_table_list.tsx
@@ -6,7 +6,7 @@ import { codeBuild } from "../master_detail/utils";
export const gen_table_list = async (
modify: (data: any) => void,
data: any,
- arg: { mode: "table" | "list" | "grid" }
+ arg: { mode: "table" | "list" | "grid"; id_parent: string }
) => {
const table = JSON.parse(data.gen_table.value) as string;
const raw_fields = JSON.parse(data.gen_fields.value) as (
@@ -35,6 +35,10 @@ export const gen_table_list = async (
}
}
+ if (arg.id_parent) {
+ select[arg.id_parent] = true;
+ }
+
if (!pk) {
alert("Failed to generate! Primary Key not found. ");
return;
@@ -60,11 +64,19 @@ export const gen_table_list = async (
}
);
+ let first = true;
const child = createItem({
name: sub_name,
childs: fields
.map((e) => {
if (e.is_pk) return;
+ let tree_depth = "";
+ let tree_depth_built = "";
+ if (first) {
+ tree_depth = `tree_depth={col.depth}`;
+ tree_depth_built = `tree_depth:col.depth`;
+ first = false;
+ }
return {
component: {
id: "297023a4-d552-464a-971d-f40dcd940b77",
@@ -84,10 +96,10 @@ export const gen_table_list = async (
adv: {
js: `\
-
+
`,
jsBuilt: `\
-render(React.createElement("div", Object.assign({}, props, { className: cx(props.className, "") }),React.createElement(FormatValue, { value: col.value, name: col.name, gen_fields: gen_fields })));
+render(React.createElement("div", Object.assign({}, props, { className: cx(props.className, "") }),React.createElement(FormatValue, { value: col.value, name: col.name, gen_fields: gen_fields, ${tree_depth_built} })));
`,
},
}),
diff --git a/gen/master_detail/gen-form.ts b/gen/master_detail/gen-form.ts
index 0a4b37c..0d5413e 100755
--- a/gen/master_detail/gen-form.ts
+++ b/gen/master_detail/gen-form.ts
@@ -48,6 +48,9 @@ type BreadItem = {
actions: `\
async () => {
return [
+ {
+ action: "delete",
+ },
{
label: "Save",
action: "save",
@@ -68,7 +71,9 @@ async ({ submit, reload }: Init) => {
if (tab) {
const actions = await getProp(tab.internal, "actions", { md });
if (Array.isArray(actions)) {
- const save_btn = actions.find((e) => e.action === "save");
+ const save_btn = actions
+ .filter((e) => e)
+ .find((e) => e.action === "save");
if (save_btn) {
save_btn.onClick = async () => {
await submit();
diff --git a/gen/prop/gen_prop_fields.ts b/gen/prop/gen_prop_fields.ts
index 7eafe4f..bf34a14 100755
--- a/gen/prop/gen_prop_fields.ts
+++ b/gen/prop/gen_prop_fields.ts
@@ -1,4 +1,8 @@
+const cache = {} as Record
;
+
export const gen_prop_fields = async (gen_table: string) => {
+ if (cache[gen_table]) return cache[gen_table];
+
const result: {
label: string;
value: string;
@@ -48,5 +52,10 @@ export const gen_prop_fields = async (gen_table: string) => {
options,
});
}
+
+ if (!cache[gen_table]) {
+ cache[gen_table] = result;
+ }
+
return result;
};
diff --git a/gen/prop/gen_prop_table.ts b/gen/prop/gen_prop_table.ts
index f72a54e..b803bc0 100755
--- a/gen/prop/gen_prop_table.ts
+++ b/gen/prop/gen_prop_table.ts
@@ -1,6 +1,10 @@
+const cache: any = [];
+
export const gen_props_table = async () => {
+ if (cache.length > 0) return cache;
+
const result = [{ value: "", label: "" }];
- return [
+ const final = [
...result,
...(await db._schema.tables()).map((e) => ({
value: e,
@@ -8,4 +12,10 @@ export const gen_props_table = async () => {
reload: ["gen_fields", "gen_label"],
})),
];
+
+ for (const f of final) {
+ cache.push(f);
+ }
+
+ return cache;
};
diff --git a/utils/format-value.tsx b/utils/format-value.tsx
index 237574f..44b54bf 100755
--- a/utils/format-value.tsx
+++ b/utils/format-value.tsx
@@ -7,47 +7,76 @@ export const FormatValue: FC<{
value: any;
name: string;
gen_fields: string[];
+ tree_depth?: number;
}> = (prop) => {
- const { value, gen_fields, name } = prop;
+ const { value, gen_fields, name, tree_depth } = prop;
- const gf = JSON.stringify(gen_fields);
- if (!fields_map.has(gf)) {
- fields_map.set(
- gf,
- gen_fields.map((e: any) => {
- if (typeof e === "string") {
- return JSON.parse(e);
- } else {
- return {
- ...JSON.parse(e.value),
- checked: e.checked.map(JSON.parse),
- };
+ if (gen_fields) {
+ const gf = JSON.stringify(gen_fields);
+ if (!fields_map.has(gf)) {
+ fields_map.set(
+ gf,
+ gen_fields.map((e: any) => {
+ if (typeof e === "string") {
+ return JSON.parse(e);
+ } else {
+ return {
+ ...JSON.parse(e.value),
+ checked: e.checked.map(JSON.parse),
+ };
+ }
+ })
+ );
+ }
+
+ const fields = fields_map.get(gf);
+
+ if (typeof value === "object" && value) {
+ const rel = fields?.find((e) => e.name === name);
+ if (rel && rel.checked) {
+ const result = rel.checked
+ .filter((e) => !e.is_pk)
+ .map((e) => {
+ return value[e.name];
+ })
+ .join(" - ");
+
+ if (Array.isArray(value)) {
+ const len = value.length;
+ if (len === 0) return ` - `;
+ return `${len} item${len > 1 ? "s" : ""}`;
}
- })
+ return result;
+ }
+
+ return JSON.stringify(value);
+ }
+ }
+
+ let prefix = <>>;
+ if (typeof tree_depth === "number" && tree_depth > 0) {
+ prefix = (
+
);
}
- const fields = fields_map.get(gf);
-
- if (typeof value === "object" && value) {
- const rel = fields?.find((e) => e.name === name);
- if (rel && rel.checked) {
- const result = rel.checked
- .filter((e) => !e.is_pk)
- .map((e) => {
- return value[e.name];
- })
- .join(" - ");
-
- if (Array.isArray(value)) {
- const len = value.length;
- if (len === 0) return ` - `;
- return `${len} item${len > 1 ? "s" : ""}`;
- }
- return result;
- }
-
- return JSON.stringify(value);
- }
- return <>{value}>;
+ return (
+
+ );
};