diff --git a/comps/form/field/Field.tsx b/comps/form/field/Field.tsx index b824c56..ade3a15 100755 --- a/comps/form/field/Field.tsx +++ b/comps/form/field/Field.tsx @@ -45,6 +45,8 @@ export const Field: FC = (arg) => { props.className.split(" ").find((e: string) => e.startsWith("s-")) || ""; } + if (field.hidden) return <>; + return ( { - if (isEditor) return; + const reload = () => { if (typeof arg.on_load === "function") { + local.loaded = false; + local.render(); const options = arg.on_load({ field }); if (options instanceof Promise) { options.then((res) => { @@ -67,7 +58,7 @@ export const TypeDropdown: FC<{ options: local.options, selected: [local.options[0]?.value], }); - } else if ( value) { + } else if (value) { arg.opt_set_value({ fm, name: field.name, @@ -87,7 +78,35 @@ export const TypeDropdown: FC<{ local.render(); } } - }, []); + }; + + if ((arg.load_trigger?.deps || []).length > 0 && !isEditor) { + useEffect( + () => { + reload(); + }, + arg.load_trigger?.deps.map((e) => fm.data[e]) + ); + } else { + useEffect(() => { + if (isEditor) { + local.loaded = true; + local.render(); + return; + } + reload(); + }, []); + } + + let value = + typeof arg.opt_get_value === "function" + ? arg.opt_get_value({ + fm, + name: field.name, + options: local.options, + type: field.type, + }) + : fm.data[field.name]; let popupClassName = ""; @@ -120,6 +139,7 @@ export const TypeDropdown: FC<{ typeof field.disabled === "function" ? field.disabled() : field.disabled; if (!local.loaded) return ; + if (field.type === "single-option") { if (value === null) { fm.data[field.name] = undefined; diff --git a/comps/form/gen/gen-form.ts b/comps/form/gen/gen-form.ts index 1a46f30..3ab9fdd 100755 --- a/comps/form/gen/gen-form.ts +++ b/comps/form/gen/gen-form.ts @@ -177,13 +177,15 @@ export const generateForm = async ( copyProps(old_item, new_item, [ "placeholder", "label", + "link__url", "ext__width", + "opt__load_trigger", "ext__on_change", "ext__description", "ext__show_label", "ext__disabled", "ext__prefix", - "ext__suffxi", + "ext__suffix", ]); } diff --git a/comps/form/gen/on_load_rel.ts b/comps/form/gen/on_load_rel.ts index dcfdb1a..be919ce 100755 --- a/comps/form/gen/on_load_rel.ts +++ b/comps/form/gen/on_load_rel.ts @@ -28,7 +28,7 @@ export const on_load_rel = ({ const skip_select = !isEmptyString(type) && ["checkbox", "typeahead", "button"].includes(type as any); - + return `\ async (arg: { field: any; @@ -56,7 +56,30 @@ async (arg: { ext_select[rel__id_parent] = true; } - const where = (await call_prasi_events("field", "relation_load", [fm, arg.field]) || {}) as Prisma.${table}WhereInput; + let where = + (await call_prasi_events("field", "relation_load", [fm, arg.field]) || {}) as Prisma.${table}WhereInput; + + if (typeof opt__load_trigger === "object" && typeof opt__load_trigger?.on_change === "function") { + const trigger = await opt__load_trigger.on_change({ md, fm, where }); + if (trigger.hidden) { + done([]); + arg.field.hidden = true; + arg.field.render(); + return; + } else { + if (arg.field.hidden) { + arg.field.hidden = false; + arg.field.render(); + } + } + + if (trigger.result) { + done(trigger.result); + return; + } else if (trigger.where) { + where = trigger.where; + } + } let items = await db.${table}.findMany({ select: { diff --git a/comps/form/typings.ts b/comps/form/typings.ts index e505763..b5bb11d 100755 --- a/comps/form/typings.ts +++ b/comps/form/typings.ts @@ -48,6 +48,13 @@ export type FieldProp = { label: string; desc?: string; props?: any; + load_trigger?: { + deps: any[]; + on_change: (arg: { + fm: FMLocal; + where: any; + }) => Promise<{ where?: any; result?: any[] }>; + }; link: { text: | string @@ -117,7 +124,7 @@ export type FieldProp = { model_upload?: "upload" | "import"; max_date?: any; min_date?: any; - upload_style?: "inline" | "full" + upload_style?: "inline" | "full"; }; export type FMInternal = { @@ -176,6 +183,7 @@ export type FieldInternal = { width: FieldProp["width"]; required: boolean; focused: boolean; + hidden: boolean; disabled: boolean | (() => boolean); required_msg: FieldProp["required_msg"]; col?: GFCol;