fix
This commit is contained in:
parent
72bcba5bb5
commit
26c1402bd1
|
|
@ -1,14 +1,12 @@
|
|||
import { useLocal } from "@/utils/use-local";
|
||||
import { FC, Fragment, useEffect, useRef } from "react";
|
||||
import { FMInternal, FMProps } from "./typings";
|
||||
import { formReload } from "./utils/reload";
|
||||
import { formInit } from "./utils/init";
|
||||
import get from "lodash.get";
|
||||
import { FC, useRef } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { Toaster } from "sonner";
|
||||
import get from "lodash.get";
|
||||
import { Field } from "./field/Field";
|
||||
import { getProp } from "../../..";
|
||||
import { FMInternal, FMProps } from "./typings";
|
||||
import { editorFormData } from "./utils/ed-data";
|
||||
import { formInit } from "./utils/init";
|
||||
import { formReload } from "./utils/reload";
|
||||
|
||||
const editorFormWidth = {} as Record<string, { w: number; f: any }>;
|
||||
|
||||
|
|
@ -35,6 +33,7 @@ export const Form: FC<FMProps> = (props) => {
|
|||
done: [],
|
||||
},
|
||||
},
|
||||
field_def: {},
|
||||
props: {} as any,
|
||||
size: {
|
||||
width: editorFormWidth[props.item.id]
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ export const Field: FC<FieldProp> = (arg) => {
|
|||
w === "auto" && fm.size.field === "full" && "c-w-full",
|
||||
w === "auto" && fm.size.field === "half" && "c-w-1/2",
|
||||
w === "full" && "c-w-full",
|
||||
w === "¾" && "c-w-3/4",
|
||||
w === "½" && "c-w-1/2",
|
||||
w === "⅓" && "c-w-1/3",
|
||||
w === "¼" && "c-w-1/4",
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export const FieldInput: FC<{
|
|||
_item: any;
|
||||
_meta: any;
|
||||
_sync: (mitem: any, item: any) => void;
|
||||
}> = ({ field, fm, PassProp, child, _meta, _item }) => {
|
||||
}> = ({ field, fm, PassProp, child, _meta, _item, _sync }) => {
|
||||
const prefix = typeof field.prefix === "function" ? field.prefix() : null;
|
||||
const suffix = typeof field.suffix === "function" ? field.suffix() : null;
|
||||
const errors = fm.error.get(field.name);
|
||||
|
|
@ -31,26 +31,35 @@ export const FieldInput: FC<{
|
|||
let found = null as any;
|
||||
if (childs && childs.length > 0) {
|
||||
for (const child of childs) {
|
||||
if (child.component?.id === fieldMapping[field.type].id) {
|
||||
const mp = (fieldMapping as any)[field.type];
|
||||
if (child.component?.id === mp.id) {
|
||||
found = child;
|
||||
|
||||
const item = createItem({
|
||||
component: { id: "--", props: fieldMapping[field.type].props },
|
||||
});
|
||||
if (mp.props) {
|
||||
const item = createItem({
|
||||
component: {
|
||||
id: "--",
|
||||
props:
|
||||
typeof mp.props === "function" ? mp.props(fm, field) : mp.props,
|
||||
},
|
||||
});
|
||||
|
||||
const props = found.component.props;
|
||||
let should_update = false;
|
||||
for (const [k, v] of Object.entries(item.component.props) as any) {
|
||||
if (props[k] && props[k].valueBuilt === v.valueBuilt) {
|
||||
continue;
|
||||
} else {
|
||||
props[k] = v;
|
||||
should_update = true;
|
||||
const props = found.component.props;
|
||||
let should_update = false;
|
||||
for (const [k, v] of Object.entries(item.component.props) as any) {
|
||||
if (props[k] && props[k].valueBuilt === v.valueBuilt) {
|
||||
continue;
|
||||
} else {
|
||||
if (field.prop && !field.prop[k]) {
|
||||
props[k] = v;
|
||||
should_update = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (should_update) {
|
||||
updateFieldMItem(_meta, found);
|
||||
if (should_update) {
|
||||
updateFieldMItem(_meta, found, _sync);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -58,14 +67,14 @@ export const FieldInput: FC<{
|
|||
|
||||
useEffect(() => {
|
||||
if (isEditor && !found) {
|
||||
genFieldMitem({ _meta, _item, field, fm });
|
||||
genFieldMitem({ _meta, _item, _sync, field, fm });
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx(
|
||||
"field-inner c-flex c-flex-1 c-flex-row c-rounded c-border c-text-sm",
|
||||
"field-outer c-flex c-flex-1 c-flex-row c-rounded c-border c-text-sm",
|
||||
fm.status === "loading"
|
||||
? css`
|
||||
border-color: transparent;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,29 @@
|
|||
import { FieldProp } from "../typings";
|
||||
import { FMLocal, FieldInternal, FieldLocal, FieldProp } from "../typings";
|
||||
|
||||
export const fieldMapping: Record<
|
||||
FieldProp["type"],
|
||||
{ id: string; props: any }
|
||||
> = {
|
||||
export const fieldMapping: {
|
||||
[K in FieldProp["type"]]: {
|
||||
id: string;
|
||||
props?:
|
||||
| Record<string, any>
|
||||
| ((
|
||||
fm: FMLocal,
|
||||
field: FieldInternal<K> & {
|
||||
render: () => void;
|
||||
}
|
||||
) => Record<string, any>);
|
||||
};
|
||||
} = {
|
||||
text: { id: "ca7ac237-8f22-4492-bb9d-4b715b1f5c25", props: { type: "text" } },
|
||||
number: {
|
||||
id: "ca7ac237-8f22-4492-bb9d-4b715b1f5c25",
|
||||
props: { type: "number" },
|
||||
relation: {
|
||||
id: "69263ca0-61a1-4899-ad5f-059ac12b94d1",
|
||||
props: (fm, field) => {
|
||||
const rel = fm.field_def[field.name];
|
||||
if (rel) {
|
||||
if (field.prop && !field.prop.type) {
|
||||
return { type: rel.type };
|
||||
}
|
||||
}
|
||||
return {};
|
||||
},
|
||||
},
|
||||
} as any;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,150 @@
|
|||
import { Popover } from "@/comps/custom/Popover";
|
||||
import { useLocal } from "@/utils/use-local";
|
||||
import { ChevronDown } from "lucide-react";
|
||||
import { FC, ReactNode } from "react";
|
||||
|
||||
type OptionItem = { value: string; label: string; el?: ReactNode };
|
||||
|
||||
export const RawDropdown: FC<{
|
||||
options: OptionItem[];
|
||||
className?: string;
|
||||
value: string;
|
||||
onFocus?: () => void;
|
||||
onBlur?: () => void;
|
||||
onChange?: (value: string) => void;
|
||||
}> = ({ value, options, className, onFocus, onBlur, onChange }) => {
|
||||
const local = useLocal({
|
||||
open: false,
|
||||
input: {
|
||||
value: "",
|
||||
el: null as any,
|
||||
},
|
||||
filter: "",
|
||||
width: 0,
|
||||
selected: undefined as undefined | OptionItem,
|
||||
});
|
||||
|
||||
let filtered = options;
|
||||
|
||||
if (local.filter) {
|
||||
filtered = options.filter((e) => {
|
||||
if (e.label.toLowerCase().includes(local.filter)) return true;
|
||||
return false;
|
||||
});
|
||||
}
|
||||
local.selected = options.find((e) => e.value === value);
|
||||
|
||||
return (
|
||||
<Popover
|
||||
open={local.open}
|
||||
onOpenChange={() => {
|
||||
local.open = false;
|
||||
local.render();
|
||||
}}
|
||||
arrow={false}
|
||||
className={cx("c-rounded-sm c-bg-white")}
|
||||
content={
|
||||
<div
|
||||
className={cx(
|
||||
"c-text-sm",
|
||||
css`
|
||||
width: ${local.width || 100}px;
|
||||
`
|
||||
)}
|
||||
>
|
||||
<>
|
||||
{filtered.map((item, idx) => {
|
||||
return (
|
||||
<div
|
||||
tabIndex={0}
|
||||
key={item.value + "_" + idx}
|
||||
className={cx(
|
||||
"c-px-3 c-py-1 cursor-pointer option-item",
|
||||
item.value === value
|
||||
? "c-bg-blue-600 c-text-white"
|
||||
: "hover:c-bg-blue-50",
|
||||
idx > 0 && "c-border-t",
|
||||
idx === 0 && "c-rounded-t-sm",
|
||||
idx === filtered.length - 1 && "c-rounded-b-sm"
|
||||
)}
|
||||
onClick={() => {
|
||||
if (onChange) onChange(item.value);
|
||||
}}
|
||||
>
|
||||
{item.label}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
"c-relative",
|
||||
className,
|
||||
css`
|
||||
cursor: pointer !important;
|
||||
`
|
||||
)}
|
||||
tabIndex={0}
|
||||
onFocus={() => {
|
||||
local.open = true;
|
||||
if (local.selected) local.input.value = local.selected.label;
|
||||
local.filter = "";
|
||||
local.render();
|
||||
setTimeout(() => {
|
||||
local.input.el?.focus();
|
||||
});
|
||||
}}
|
||||
ref={(el) => {
|
||||
if (local.width === 0 && el) {
|
||||
const box = el.getBoundingClientRect();
|
||||
if (box && box.width) {
|
||||
local.width = box.width;
|
||||
local.render();
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="c-w-full c-h-full c-relative">
|
||||
<input
|
||||
spellCheck={false}
|
||||
value={local.open ? local.input.value : "Halo"}
|
||||
className={cx(
|
||||
"c-absolute c-inset-0 c-w-full c-h-full c-outline-none c-p-0",
|
||||
local.open
|
||||
? "c-cursor-pointer"
|
||||
: "c-pointer-events-none c-invisible"
|
||||
)}
|
||||
onChange={(e) => {
|
||||
local.input.value = e.currentTarget.value;
|
||||
local.filter = local.input.value.toLowerCase();
|
||||
local.render();
|
||||
}}
|
||||
ref={(el) => {
|
||||
local.input.el = el;
|
||||
}}
|
||||
type="text"
|
||||
onFocus={onFocus}
|
||||
onBlur={onBlur}
|
||||
/>
|
||||
|
||||
{!local.open && local.selected && (
|
||||
<div className="c-absolute c-inset-0 c-z-10 c-w-full c-h-full c-text-sm c-flex c-items-center">
|
||||
{local.selected.el || local.selected.label}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={cx(
|
||||
"c-absolute c-pointer-events-none c-z-10 c-inset-0 c-left-auto c-flex c-items-center ",
|
||||
"c-bg-white c-justify-center c-w-6 c-mr-1 c-my-2"
|
||||
)}
|
||||
>
|
||||
<ChevronDown size={14} />
|
||||
</div>
|
||||
</div>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import { useLocal } from "@/utils/use-local";
|
||||
import { FC } from "react";
|
||||
import { FMLocal, FieldLocal } from "../../typings";
|
||||
import { RawDropdown } from "../raw/Dropdown";
|
||||
|
||||
export type PropTypeRelation = {
|
||||
type: "has-one" | "has-many";
|
||||
};
|
||||
export const FieldTypeRelation: FC<{
|
||||
field: FieldLocal;
|
||||
fm: FMLocal;
|
||||
prop: PropTypeRelation;
|
||||
}> = ({ field, fm, prop }) => {
|
||||
const input = useLocal({});
|
||||
const value = fm.data[field.name];
|
||||
field.input = input;
|
||||
field.prop = prop;
|
||||
|
||||
return (
|
||||
<>
|
||||
<RawDropdown
|
||||
options={[{ label: "Halo", value: "halo" }]}
|
||||
value={"halo"}
|
||||
className="c-flex-1 c-bg-transparent c-outline-none c-px-2 c-text-sm c-w-full c-h-full"
|
||||
onFocus={() => {
|
||||
field.focused = true;
|
||||
field.render();
|
||||
}}
|
||||
onBlur={() => {
|
||||
field.focused = false;
|
||||
field.render();
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,14 +1,21 @@
|
|||
import { FC } from "react";
|
||||
import { FMLocal, FieldLocal } from "../../typings";
|
||||
import { useLocal } from "@/utils/use-local";
|
||||
|
||||
export type PropTypeText = {
|
||||
type: "text" | "password" | "number";
|
||||
};
|
||||
|
||||
export const FieldTypeText: FC<{
|
||||
field: FieldLocal;
|
||||
fm: FMLocal;
|
||||
prop: {
|
||||
type: "text" | "password" | "number";
|
||||
};
|
||||
prop: PropTypeText;
|
||||
}> = ({ field, fm, prop }) => {
|
||||
const input = useLocal({});
|
||||
const value = fm.data[field.name];
|
||||
field.input = input;
|
||||
field.prop = prop;
|
||||
|
||||
return (
|
||||
<input
|
||||
type={prop.type}
|
||||
|
|
@ -18,7 +25,7 @@ export const FieldTypeText: FC<{
|
|||
}}
|
||||
value={value || ""}
|
||||
disabled={field.disabled}
|
||||
className="c-flex-1 c-rounded c-bg-transparent c-outline-none c-px-2 c-text-sm"
|
||||
className="c-flex-1 c-bg-transparent c-outline-none c-px-2 c-text-sm"
|
||||
spellCheck={false}
|
||||
onFocus={() => {
|
||||
field.focused = true;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import { GFCol } from "@/gen/utils";
|
||||
import { ReactNode } from "react";
|
||||
import { SliderOptions } from "../form-old/Slider/types";
|
||||
import { FieldOptions } from "../form-old/type";
|
||||
import { FormHook } from "../form-old/utils/utils";
|
||||
import { editorFormData } from "./utils/ed-data";
|
||||
import { PropTypeText } from "./field/type/TypeText";
|
||||
import { PropTypeRelation } from "./field/type/TypeRelation";
|
||||
|
||||
export type FMProps = {
|
||||
on_init: (arg: { fm: FMLocal; submit: any; reload: any }) => any;
|
||||
|
|
@ -18,6 +20,7 @@ export type FMProps = {
|
|||
item: any;
|
||||
label_mode: "vertical" | "horizontal" | "hidden";
|
||||
label_width: number;
|
||||
gen_fields: any;
|
||||
};
|
||||
|
||||
export type FieldProp = {
|
||||
|
|
@ -26,20 +29,18 @@ export type FieldProp = {
|
|||
desc?: string;
|
||||
props?: any;
|
||||
fm: FMLocal;
|
||||
type:
|
||||
| "text"
|
||||
| "number"
|
||||
| "textarea"
|
||||
| "dropdown"
|
||||
| "relation"
|
||||
| "password"
|
||||
| "radio"
|
||||
| "date"
|
||||
| "datetime"
|
||||
| "money"
|
||||
| "slider"
|
||||
| "master-link"
|
||||
| "custom";
|
||||
type: "text" | "relation";
|
||||
// | "number"
|
||||
// | "textarea"
|
||||
// | "dropdown"
|
||||
// | "password"
|
||||
// | "radio"
|
||||
// | "date"
|
||||
// | "datetime"
|
||||
// | "money"
|
||||
// | "slider"
|
||||
// | "master-link"
|
||||
// | "custom";
|
||||
required: "y" | "n";
|
||||
required_msg: (name: string) => string;
|
||||
options: FieldOptions;
|
||||
|
|
@ -50,7 +51,7 @@ export type FieldProp = {
|
|||
selection: "single" | "multi";
|
||||
prefix: any;
|
||||
suffix: any;
|
||||
width: "auto" | "full" | "½" | "⅓" | "¼";
|
||||
width: "auto" | "full" | "¾" | "½" | "⅓" | "¼";
|
||||
_meta: any;
|
||||
_item: any;
|
||||
_sync: any;
|
||||
|
|
@ -65,6 +66,7 @@ export type FMInternal = {
|
|||
on_change: (name: string, new_value: any) => void;
|
||||
};
|
||||
fields: Record<string, FieldLocal>;
|
||||
field_def: Record<string, GFCol>;
|
||||
error: {
|
||||
readonly list: { name: string; error: string[] }[];
|
||||
set: (name: string, error: string[]) => void;
|
||||
|
|
@ -87,10 +89,16 @@ export type FMInternal = {
|
|||
};
|
||||
export type FMLocal = FMInternal & { render: () => void };
|
||||
|
||||
export type FieldInternal = {
|
||||
type FieldInternalProp = {
|
||||
text: PropTypeText;
|
||||
number: PropTypeText;
|
||||
relation: PropTypeRelation;
|
||||
};
|
||||
|
||||
export type FieldInternal<T extends FieldProp["type"]> = {
|
||||
status: "init" | "loading" | "ready";
|
||||
name: FieldProp["name"];
|
||||
type: FieldProp["type"];
|
||||
type: T;
|
||||
label: FieldProp["label"];
|
||||
desc: FieldProp["desc"];
|
||||
prefix: FieldProp["prefix"];
|
||||
|
|
@ -100,9 +108,16 @@ export type FieldInternal = {
|
|||
focused: boolean;
|
||||
disabled: boolean;
|
||||
required_msg: FieldProp["required_msg"];
|
||||
col?: GFCol;
|
||||
Child: () => ReactNode;
|
||||
input: Record<string, any> & {
|
||||
render: () => void;
|
||||
};
|
||||
prop?: FieldInternalProp[T];
|
||||
};
|
||||
export type FieldLocal = FieldInternal<any> & {
|
||||
render: () => void;
|
||||
};
|
||||
export type FieldLocal = FieldInternal & { render: () => void };
|
||||
|
||||
export const formType = (active: { item_id: string }, meta: any) => {
|
||||
let data = "null as any";
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
import { newField } from "@/gen/gen_form/new_field";
|
||||
import { FMLocal, FieldLocal } from "../typings";
|
||||
import get from "lodash.get";
|
||||
import { fieldMapping } from "../field/mapping";
|
||||
import { createItem } from "@/gen/utils";
|
||||
|
||||
export const genFieldMitem = (arg: {
|
||||
_meta: any;
|
||||
_item: any;
|
||||
_sync: any;
|
||||
fm: FMLocal;
|
||||
field: FieldLocal;
|
||||
}) => {
|
||||
const { _meta, _item, fm, field } = arg;
|
||||
const { _meta, _item, _sync, fm, field } = arg;
|
||||
const m = _meta[_item.id];
|
||||
if (m) {
|
||||
const mitem = m.mitem;
|
||||
|
|
@ -18,16 +23,27 @@ export const genFieldMitem = (arg: {
|
|||
?.get("content")
|
||||
?.get("childs");
|
||||
|
||||
// console.log(field.name, childs);
|
||||
const col = fm.field_def[field.name];
|
||||
if (col) {
|
||||
const component = fieldMapping[field.type as "text"];
|
||||
if (component) {
|
||||
const item = createItem({
|
||||
component: component as any,
|
||||
});
|
||||
|
||||
_sync(childs, [...childs.toJSON(), item]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
export const updateFieldMItem = (_meta: any, _item: any) => {
|
||||
|
||||
export const updateFieldMItem = (_meta: any, _item: any, _sync: any) => {
|
||||
const m = _meta[_item.id];
|
||||
if (m) {
|
||||
const mitem = m.mitem;
|
||||
if (mitem) {
|
||||
|
||||
_sync(mitem, _item);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { parseGenField } from "@/gen/utils";
|
||||
import get from "lodash.get";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { FMLocal, FMProps } from "../typings";
|
||||
import { formError } from "./error";
|
||||
import { editorFormData } from "./ed-data";
|
||||
import get from "lodash.get";
|
||||
import { formError } from "./error";
|
||||
|
||||
export const formInit = (fm: FMLocal, props: FMProps) => {
|
||||
for (const [k, v] of Object.entries(props)) {
|
||||
|
|
@ -13,6 +14,14 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
|
|||
const { on_load, sonar } = fm.props;
|
||||
fm.error = formError(fm);
|
||||
|
||||
if (isEditor) {
|
||||
fm.field_def = {};
|
||||
const defs = parseGenField(fm.props.gen_fields);
|
||||
for (const d of defs) {
|
||||
fm.field_def[d.name] = d;
|
||||
}
|
||||
}
|
||||
|
||||
fm.reload = () => {
|
||||
fm.status = isEditor ? "ready" : "loading";
|
||||
fm.render();
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@ import { FMLocal, FieldInternal, FieldProp } from "../typings";
|
|||
import { useEffect } from "react";
|
||||
|
||||
export const useField = (arg: FieldProp) => {
|
||||
const field = useLocal<FieldInternal>({
|
||||
const field = useLocal<FieldInternal<typeof arg.type>>({
|
||||
status: "init",
|
||||
Child: () => {
|
||||
return <arg.PassProp>{arg.child}</arg.PassProp>;
|
||||
},
|
||||
input: {},
|
||||
} as any);
|
||||
|
||||
const update_field = {
|
||||
|
|
|
|||
1
data.ts
1
data.ts
|
|
@ -1,4 +1,5 @@
|
|||
export { FieldTypeText } from "./comps/form/field/type/TypeText";
|
||||
export { FieldTypeRelation } from "./comps/form/field/type/TypeRelation";
|
||||
export { Form } from "@/comps/form/Form";
|
||||
export { Field } from "@/comps/form/field/Field";
|
||||
export { formType } from "@/comps/form/typings";
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import get from "lodash.get";
|
||||
import { GFCol as Col, GFCol, formatName, parseGenField } from "../utils";
|
||||
import { NewFieldArg, newField } from "./new_field";
|
||||
import { codeBuild } from "../master_detail/utils";
|
||||
import { GFCol, parseGenField } from "../utils";
|
||||
import { newField } from "./new_field";
|
||||
import { on_load } from "./on_load";
|
||||
import { on_submit } from "./on_submit";
|
||||
import { codeBuild } from "../master_detail/utils";
|
||||
|
||||
export const gen_form = async (modify: (data: any) => void, data: any) => {
|
||||
const table = JSON.parse(data.gen_table.value);
|
||||
|
|
@ -57,7 +56,7 @@ export const gen_form = async (modify: (data: any) => void, data: any) => {
|
|||
}
|
||||
|
||||
result["body"] = data["body"];
|
||||
result.body.content.childs = fields.map(newField);
|
||||
result.body.content.childs = fields.filter((e) => !e.is_pk).map(newField);
|
||||
}
|
||||
modify(result);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,23 +29,43 @@ export type NewFieldArg = {
|
|||
};
|
||||
|
||||
export const newField = (arg: GFCol) => {
|
||||
const childs = [];
|
||||
|
||||
let type = "text";
|
||||
if (["int", "string"].includes(arg.type)) {
|
||||
childs.push(
|
||||
createItem({
|
||||
component: {
|
||||
id: "ca7ac237-8f22-4492-bb9d-4b715b1f5c25",
|
||||
props: {
|
||||
type: arg.type === "int" ? "number" : "text",
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
} else if (["has-many", "has-one"].includes(arg.type)) {
|
||||
type = "relation";
|
||||
childs.push(
|
||||
createItem({
|
||||
component: {
|
||||
id: "69263ca0-61a1-4899-ad5f-059ac12b94d1",
|
||||
props: {
|
||||
type: arg.type,
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const item = createItem({
|
||||
component: {
|
||||
id: "32550d01-42a3-4b15-a04a-2c2d5c3c8e67",
|
||||
props: {
|
||||
name: arg.name,
|
||||
label: formatName(arg.name),
|
||||
type,
|
||||
child: {
|
||||
childs: [
|
||||
createItem({
|
||||
component: {
|
||||
id: "ca7ac237-8f22-4492-bb9d-4b715b1f5c25",
|
||||
props: {
|
||||
type: "text",
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
childs,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue