fix data input
This commit is contained in:
parent
771a342f80
commit
69753fe0e0
|
|
@ -29,27 +29,33 @@ export const Breadcrumb: FC<BreadcrumbProps> = (_arg) => {
|
|||
|
||||
if (_arg.value) {
|
||||
local.list = _arg.value;
|
||||
local.status = "ready";
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
if (_arg.value) {
|
||||
local.status = "ready";
|
||||
local.render();
|
||||
return;
|
||||
}
|
||||
if (local.status === "init" && typeof on_load === "function") {
|
||||
local.status = "loading";
|
||||
local.render();
|
||||
if (local.status === "init") {
|
||||
let should_load = true;
|
||||
|
||||
local.list = await on_load();
|
||||
if (isEditor) breadcrumbData[_arg.item.id] = local.list;
|
||||
if (isEditor && breadcrumbData[_arg.item.id]) {
|
||||
local.list = breadcrumbData[_arg.item.id];
|
||||
local.status = "ready";
|
||||
should_load = false;
|
||||
}
|
||||
|
||||
if (should_load && typeof on_load === "function") {
|
||||
const callback = (res: any) => {
|
||||
local.list = res;
|
||||
breadcrumbData[_arg.item.id] = res;
|
||||
local.status = "ready";
|
||||
local.render();
|
||||
}
|
||||
})();
|
||||
}, [on_load]);
|
||||
};
|
||||
const res = on_load();
|
||||
if (res instanceof Promise) {
|
||||
res.then((res) => {
|
||||
callback(res);
|
||||
local.render();
|
||||
});
|
||||
} else callback(res);
|
||||
}
|
||||
}
|
||||
|
||||
if (isEditor && local.status !== "ready" && breadcrumbData[_arg.item.id]) {
|
||||
local.list = breadcrumbData[_arg.item.id];
|
||||
|
|
|
|||
|
|
@ -127,14 +127,10 @@ export const Form: FC<FMProps> = (props) => {
|
|||
{fm.status !== "init" &&
|
||||
fm.size.width > 0 &&
|
||||
childs.map((child, idx) => {
|
||||
const props = {} as any;
|
||||
for (const [k, v] of Object.entries(child.component.props)) {
|
||||
props[k] = getProp(child, k);
|
||||
}
|
||||
return (
|
||||
<Fragment key={idx}>
|
||||
<Field {...props} fm={fm} />
|
||||
</Fragment>
|
||||
<PassProp fm={fm} key={idx}>
|
||||
{child}
|
||||
</PassProp>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { FC, useEffect } from "react";
|
|||
import { FieldProp } from "../typings";
|
||||
import { useField } from "../utils/use-field";
|
||||
import { validate } from "../utils/validate";
|
||||
import { FieldInput } from "./Input";
|
||||
import { FieldInput } from "./FieldInput";
|
||||
import { Label } from "./Label";
|
||||
|
||||
export const Field: FC<FieldProp> = (arg) => {
|
||||
|
|
@ -15,10 +15,16 @@ export const Field: FC<FieldProp> = (arg) => {
|
|||
useEffect(() => {
|
||||
validate(field, fm);
|
||||
fm.events.on_change(field.name, fm.data[field.name]);
|
||||
fm.render();
|
||||
}, [fm.data[field.name]]);
|
||||
|
||||
if (field.status === "init" && !isEditor) return null;
|
||||
|
||||
const errors = fm.error.get(field.name);
|
||||
|
||||
const props = { ...arg.props };
|
||||
delete props.className;
|
||||
|
||||
return (
|
||||
<label
|
||||
className={cx(
|
||||
|
|
@ -36,9 +42,36 @@ export const Field: FC<FieldProp> = (arg) => {
|
|||
mode === "horizontal" && "c-flex-row c-items-center",
|
||||
mode === "vertical" && "c-flex-col c-space-y-1"
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{mode !== "hidden" && <Label field={field} fm={fm} />}
|
||||
<FieldInput field={field} fm={fm} />
|
||||
<div className="field-inner c-flex c-flex-1 c-flex-col">
|
||||
<FieldInput
|
||||
field={field}
|
||||
fm={fm}
|
||||
PassProp={arg.PassProp}
|
||||
child={arg.child}
|
||||
_meta={arg._meta}
|
||||
_item={arg._item}
|
||||
/>
|
||||
{field.desc && (
|
||||
<div className={cx("c-p-2 c-text-xs", errors.length > 0 && "c-pb-1")}>
|
||||
{field.desc}
|
||||
</div>
|
||||
)}
|
||||
{errors.length > 0 && (
|
||||
<div
|
||||
className={cx(
|
||||
"c-p-2 c-text-xs c-text-red-600",
|
||||
field.desc && "c-pt-0"
|
||||
)}
|
||||
>
|
||||
{errors.map((err) => {
|
||||
return <div>{err}</div>;
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</label>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
import { Skeleton } from "@/comps/ui/skeleton";
|
||||
import get from "lodash.get";
|
||||
import { FC, useEffect } from "react";
|
||||
import { FMLocal, FieldLocal } from "../typings";
|
||||
import { fieldMapping } from "./mapping";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { genFieldMitem } from "../utils/gen-mitem";
|
||||
|
||||
const modify = {
|
||||
timeout: null as any,
|
||||
};
|
||||
|
||||
export const FieldInput: FC<{
|
||||
field: FieldLocal;
|
||||
fm: FMLocal;
|
||||
PassProp: any;
|
||||
child: any;
|
||||
_item: any;
|
||||
_meta: any;
|
||||
}> = ({ field, fm, PassProp, child, _meta, _item }) => {
|
||||
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);
|
||||
const childs = get(
|
||||
child,
|
||||
"props.meta.item.component.props.child.content.childs"
|
||||
);
|
||||
|
||||
let found = null as any;
|
||||
if (childs && childs.length > 0) {
|
||||
for (const child of childs) {
|
||||
if (child.component?.id === fieldMapping[field.type].id) {
|
||||
found = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isEditor && !found) {
|
||||
genFieldMitem({ _meta, _item, field, fm });
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx(
|
||||
"field-inner c-flex c-flex-1 c-flex-row c-rounded c-border c-text-sm",
|
||||
fm.status === "loading"
|
||||
? css`
|
||||
border-color: transparent;
|
||||
`
|
||||
: field.disabled
|
||||
? "c-border-gray-100"
|
||||
: errors.length > 0
|
||||
? field.focused
|
||||
? "c-border-red-600 c-bg-red-50 c-outline c-outline-red-700"
|
||||
: "c-border-red-600 c-bg-red-50"
|
||||
: field.focused &&
|
||||
"c-border-blue-700 c-outline c-outline-blue-700",
|
||||
css`
|
||||
> div {
|
||||
min-height: 35px;
|
||||
line-height: 35px;
|
||||
}
|
||||
`
|
||||
)}
|
||||
>
|
||||
{prefix && <></>}
|
||||
{fm.status === "loading" ? (
|
||||
<div className="c-flex c-flex-col c-space-y-1 c-p-1 c-justify-center">
|
||||
<div className="c-flex c-space-x-1">
|
||||
<Skeleton
|
||||
className={css`
|
||||
width: 50px;
|
||||
height: 10px;
|
||||
`}
|
||||
/>
|
||||
<Skeleton
|
||||
className={css`
|
||||
width: 50px;
|
||||
height: 10px;
|
||||
`}
|
||||
/>
|
||||
</div>
|
||||
<Skeleton
|
||||
className={css`
|
||||
width: 80px;
|
||||
height: 10px;
|
||||
`}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className={cx(
|
||||
"field-inner c-flex-1 c-flex c-items-center c-justify-center",
|
||||
field.disabled && "c-pointer-events-none"
|
||||
)}
|
||||
>
|
||||
{!found && <Loader2 className="c-h-4 c-w-4 c-animate-spin" />}
|
||||
{found && (
|
||||
<PassProp field={field} fm={fm}>
|
||||
{found}
|
||||
</PassProp>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{suffix && <></>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
import { FC } from "react";
|
||||
import { FMLocal, FieldLocal, FieldProp } from "../typings";
|
||||
import { InputText } from "./input/InputText";
|
||||
import { Skeleton } from "@/comps/ui/skeleton";
|
||||
|
||||
export const FieldInput: FC<{ field: FieldLocal; fm: FMLocal }> = ({
|
||||
field,
|
||||
fm,
|
||||
}) => {
|
||||
const prefix = typeof field.prefix === "function" ? field.prefix() : null;
|
||||
const suffix = typeof field.suffix === "function" ? field.suffix() : null;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx(
|
||||
"field-outer c-flex c-flex-1 c-flex-row c-rounded c-border c-text-sm",
|
||||
fm.status === "loading"
|
||||
? css`
|
||||
border-color: transparent;
|
||||
`
|
||||
: field.disabled
|
||||
? "c-border-gray-100"
|
||||
: field.focused && "c-border-blue-700 c-outline c-outline-blue-700",
|
||||
css`
|
||||
> div {
|
||||
min-height: 35px;
|
||||
line-height: 35px;
|
||||
}
|
||||
`
|
||||
)}
|
||||
>
|
||||
{prefix && <></>}
|
||||
{fm.status === "loading" ? (
|
||||
<div className="c-flex c-flex-col c-space-y-1 c-p-1 c-justify-center">
|
||||
<div className="c-flex c-space-x-1">
|
||||
<Skeleton
|
||||
className={css`
|
||||
width: 50px;
|
||||
height: 10px;
|
||||
`}
|
||||
/>
|
||||
<Skeleton
|
||||
className={css`
|
||||
width: 50px;
|
||||
height: 10px;
|
||||
`}
|
||||
/>
|
||||
</div>
|
||||
<Skeleton
|
||||
className={css`
|
||||
width: 80px;
|
||||
height: 10px;
|
||||
`}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className={cx(
|
||||
"field-inner c-flex-1 c-flex",
|
||||
field.disabled && "c-pointer-events-none"
|
||||
)}
|
||||
>
|
||||
{(["text", "password", "number"] as FieldProp["type"][]).includes(
|
||||
field.type
|
||||
) && <InputText field={field} fm={fm} />}
|
||||
</div>
|
||||
)}
|
||||
{suffix && <></>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
@ -5,18 +5,41 @@ export const Label: FC<{ field: FieldLocal; fm: FMLocal }> = ({
|
|||
field,
|
||||
fm,
|
||||
}) => {
|
||||
const errors = fm.error.get(field.name);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx(
|
||||
"label",
|
||||
"label c-text-sm c-flex c-items-center",
|
||||
fm.props.label_mode === "horizontal" &&
|
||||
css`
|
||||
font-size: 14px;
|
||||
width: ${fm.props.label_width}px;
|
||||
`
|
||||
`,
|
||||
fm.props.label_mode === "vertical" && "c-mt-3"
|
||||
)}
|
||||
>
|
||||
{field.label}
|
||||
<span className={cx(errors.length > 0 && `c-text-red-600`)}>
|
||||
{field.label}
|
||||
</span>
|
||||
{field.required && (
|
||||
<span className="c-text-red-600 c-mb-2 c-ml-1">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M12 6v12" />
|
||||
<path d="M17.196 9 6.804 15" />
|
||||
<path d="m6.804 9 10.392 6" />
|
||||
</svg>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
import { FieldProp } from "../typings";
|
||||
|
||||
export const fieldMapping: Record<FieldProp["type"], { id: string }> = {
|
||||
text: { id: "ca7ac237-8f22-4492-bb9d-4b715b1f5c25" },
|
||||
} as any;
|
||||
|
|
@ -1,19 +1,22 @@
|
|||
import { FC } from "react";
|
||||
import { FMLocal, FieldLocal } from "../../typings";
|
||||
|
||||
export const InputText: FC<{ field: FieldLocal; fm: FMLocal }> = ({
|
||||
field,
|
||||
fm,
|
||||
}) => {
|
||||
export const FieldTypeText: FC<{
|
||||
field: FieldLocal;
|
||||
fm: FMLocal;
|
||||
prop: {
|
||||
type: "text" | "password" | "number";
|
||||
};
|
||||
}> = ({ field, fm, prop }) => {
|
||||
const value = fm.data[field.name];
|
||||
return (
|
||||
<input
|
||||
type="text"
|
||||
type={prop.type}
|
||||
onChange={(ev) => {
|
||||
fm.data[field.name] = ev.currentTarget.value;
|
||||
fm.render();
|
||||
}}
|
||||
value={value || ''}
|
||||
value={value || ""}
|
||||
disabled={field.disabled}
|
||||
className="c-flex-1 c-rounded c-bg-transparent c-outline-none c-px-2 c-text-sm"
|
||||
spellCheck={false}
|
||||
|
|
@ -24,6 +24,7 @@ export type FieldProp = {
|
|||
name: string;
|
||||
label: string;
|
||||
desc?: string;
|
||||
props?: any;
|
||||
fm: FMLocal;
|
||||
type:
|
||||
| "text"
|
||||
|
|
@ -44,17 +45,14 @@ export type FieldProp = {
|
|||
options: FieldOptions;
|
||||
on_change: (arg: { value: any }) => void | Promise<void>;
|
||||
PassProp: any;
|
||||
custom: "y" | "n";
|
||||
disabled: "y" | "n";
|
||||
child: any;
|
||||
selection: "single" | "multi";
|
||||
prefix: any;
|
||||
suffix: any;
|
||||
placeholder?: any;
|
||||
rel_table: string;
|
||||
rel_fields: string[];
|
||||
rel_query: () => any;
|
||||
width: "auto" | "full" | "½" | "⅓" | "¼";
|
||||
_meta: any;
|
||||
_item: any;
|
||||
};
|
||||
|
||||
export type FMInternal = {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ export const formError = (fm: FMLocal) => {
|
|||
const error = {
|
||||
_internal: {},
|
||||
get list() {
|
||||
if (fm.status !== "ready") return [];
|
||||
|
||||
const res = Object.entries(this._internal).map(([name, error]) => {
|
||||
return { name, error };
|
||||
});
|
||||
|
|
@ -15,6 +17,7 @@ export const formError = (fm: FMLocal) => {
|
|||
else this._internal = {};
|
||||
},
|
||||
get(name) {
|
||||
if (fm.status !== "ready") return [];
|
||||
return this._internal[name] || [];
|
||||
},
|
||||
set(name, error) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
import { FMLocal, FieldLocal } from "../typings";
|
||||
|
||||
export const genFieldMitem = (arg: {
|
||||
_meta: any;
|
||||
_item: any;
|
||||
fm: FMLocal;
|
||||
field: FieldLocal;
|
||||
}) => {
|
||||
const { _meta, _item, fm, field } = arg;
|
||||
const m = _meta[_item.id];
|
||||
if (m) {
|
||||
const mitem = m.mitem;
|
||||
if (mitem) {
|
||||
const childs = mitem
|
||||
.get("component")
|
||||
?.get("props")
|
||||
?.get("child")
|
||||
?.get("content")
|
||||
?.get("childs");
|
||||
|
||||
// console.log(field.name, childs);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -20,11 +20,12 @@ export const useField = (arg: FieldProp) => {
|
|||
width: arg.width,
|
||||
required: arg.required === "y",
|
||||
required_msg: arg.required_msg,
|
||||
focused: false,
|
||||
disabled: arg.disabled === "y",
|
||||
};
|
||||
for (const [k, v] of Object.entries(update_field)) {
|
||||
(field as any)[k] = v;
|
||||
if (field.status === "init" || isEditor) {
|
||||
for (const [k, v] of Object.entries(update_field)) {
|
||||
(field as any)[k] = v;
|
||||
}
|
||||
}
|
||||
|
||||
const fm = arg.fm;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,18 @@
|
|||
import { FMLocal, FieldLocal } from "../typings";
|
||||
|
||||
export const validate = (field: FieldLocal, fm: FMLocal) => {
|
||||
if (field.required && typeof field.required_msg === "function") {
|
||||
const error_msg = field.required_msg(field.name);
|
||||
if (fm.status !== "ready") return;
|
||||
|
||||
let msg = (name: string) => {
|
||||
return `${name} harus diisi`;
|
||||
};
|
||||
if (typeof field.required_msg === "function") {
|
||||
msg = field.required_msg;
|
||||
}
|
||||
if (field.required) {
|
||||
const error_msg = msg(field.name);
|
||||
const error_list = fm.error.get(field.name).filter((e) => e !== error_msg);
|
||||
if (fm.data[field.name]) {
|
||||
if (!fm.data[field.name]) {
|
||||
fm.error.set(field.name, [error_msg, ...error_list]);
|
||||
} else {
|
||||
fm.error.set(field.name, error_list);
|
||||
|
|
|
|||
1
data.ts
1
data.ts
|
|
@ -1,3 +1,4 @@
|
|||
export { FieldTypeText } from "./comps/form/field/type/TypeText";
|
||||
export { Form } from "@/comps/form/Form";
|
||||
export { Field } from "@/comps/form/field/Field";
|
||||
export { formType } from "@/comps/form/typings";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import get from "lodash.get";
|
||||
import { GFCol as Col, formatName } from "../utils";
|
||||
import { GFCol as Col, GFCol, formatName, parseGenField } from "../utils";
|
||||
import { NewFieldArg, newField } from "./new_field";
|
||||
import { on_load } from "./on_load";
|
||||
import { on_submit } from "./on_submit";
|
||||
|
|
@ -7,57 +7,32 @@ 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);
|
||||
const fields = JSON.parse(data.gen_fields.value);
|
||||
const raw_fields = JSON.parse(data.gen_fields.value) as (
|
||||
| string
|
||||
| { value: string; checked: string[] }
|
||||
)[];
|
||||
const select = {} as any;
|
||||
const new_fields: NewFieldArg[] = [];
|
||||
|
||||
let pk: Col | null = null;
|
||||
let pk: null | GFCol = null;
|
||||
let pks: Record<string, string> = {};
|
||||
|
||||
for (let sel of fields) {
|
||||
if (typeof sel === "object") {
|
||||
const col = JSON.parse(sel.value) as Col;
|
||||
select[col.name] = {};
|
||||
const fields: string[] = [];
|
||||
for (let s of sel.checked) {
|
||||
const c = JSON.parse(s) as Col;
|
||||
if (c.is_pk) {
|
||||
pks[col.name] = c.name;
|
||||
fields.push(`::${c.name}`);
|
||||
select[col.name] = { select: { [c.name]: true } };
|
||||
} else {
|
||||
fields.push(c.name);
|
||||
}
|
||||
const fields = parseGenField(raw_fields);
|
||||
const result = {} as any;
|
||||
for (const f of fields) {
|
||||
select[f.name] = true;
|
||||
if (f.relation) {
|
||||
select[f.name] = {
|
||||
select: {},
|
||||
};
|
||||
for (const r of f.relation.fields) {
|
||||
select[f.name].select[r.name] = true;
|
||||
}
|
||||
}
|
||||
|
||||
new_fields.push({
|
||||
name: col.name,
|
||||
label: formatName(col.name),
|
||||
required: false,
|
||||
type: "relation",
|
||||
relation: {
|
||||
table: col.name,
|
||||
fields,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const col = JSON.parse(sel) as Col;
|
||||
if (col.is_pk) {
|
||||
pk = col;
|
||||
} else {
|
||||
new_fields.push({
|
||||
name: col.name,
|
||||
label: formatName(col.name),
|
||||
required: !col.optional,
|
||||
type: "text",
|
||||
});
|
||||
}
|
||||
select[col.name] = true;
|
||||
if (f.is_pk) {
|
||||
pk = f;
|
||||
}
|
||||
}
|
||||
|
||||
const result: any = {};
|
||||
|
||||
if (!pk) {
|
||||
alert("Failed to generate! Primary Key not found. ");
|
||||
return;
|
||||
|
|
@ -82,7 +57,7 @@ export const gen_form = async (modify: (data: any) => void, data: any) => {
|
|||
}
|
||||
|
||||
result["body"] = data["body"];
|
||||
result.body.content.childs = new_fields.map(newField);
|
||||
result.body.content.childs = fields.map(newField);
|
||||
}
|
||||
modify(result);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { GFCol, createItem, formatName } from "../utils";
|
||||
export const newItem = (component: {
|
||||
id: string;
|
||||
props: Record<string, string>;
|
||||
|
|
@ -27,296 +28,25 @@ export type NewFieldArg = {
|
|||
};
|
||||
};
|
||||
|
||||
export const newField = (arg: NewFieldArg) => {
|
||||
return {
|
||||
id: createId(),
|
||||
adv: {
|
||||
js: '<div\n {...props}\n className={cx(\n "field",\n css`\n width:100%;\n border-bottom:1px solid white;\n padding: 10px;`,\n )}\n>\n <Field\n label={label}\n name={name}\n type={type}\n selection={selection}\n label_alt={label_alt}\n options={options}\n on_change={on_change}\n form={form}\n custom={custom}\n PassProp={PassProp}\n required={required}\n child={child}\n slider={slider}\n placeholder={placeholder}\n suffix={suffix}\n ></Field>\n</div>',
|
||||
css: "",
|
||||
jsBuilt:
|
||||
'render(/* @__PURE__ */ React.createElement(\n "div",\n {\n ...props,\n className: cx(\n "field",\n css`\n width:100%;\n border-bottom:1px solid white;\n padding: 10px;`\n )\n },\n /* @__PURE__ */ React.createElement(\n Field,\n {\n label,\n name,\n type,\n selection,\n label_alt,\n options,\n on_change,\n form,\n custom,\n PassProp,\n required,\n child,\n slider,\n placeholder,\n suffix\n }\n )\n));\n',
|
||||
},
|
||||
dim: {
|
||||
h: "full",
|
||||
w: "full",
|
||||
},
|
||||
name: "field",
|
||||
type: "item",
|
||||
childs: [],
|
||||
mobile: {
|
||||
dim: {
|
||||
h: "full",
|
||||
w: "full",
|
||||
hUnit: "px",
|
||||
},
|
||||
border: {
|
||||
color: "#ba2f2f",
|
||||
style: "solid",
|
||||
stroke: {
|
||||
b: 1,
|
||||
},
|
||||
},
|
||||
padding: {
|
||||
b: 5,
|
||||
l: 15,
|
||||
r: 15,
|
||||
t: 5,
|
||||
},
|
||||
},
|
||||
script: {},
|
||||
export const newField = (arg: GFCol) => {
|
||||
const item = createItem({
|
||||
component: {
|
||||
id: "32550d01-42a3-4b15-a04a-2c2d5c3c8e67",
|
||||
props: {
|
||||
name: {
|
||||
idx: 0,
|
||||
meta: {
|
||||
type: "text",
|
||||
},
|
||||
name: "prop_1",
|
||||
type: "string",
|
||||
value: "`" + arg.name + "`",
|
||||
is_name: true,
|
||||
valueBuilt: "`" + arg.name + "`",
|
||||
},
|
||||
type: {
|
||||
idx: 4,
|
||||
meta: {
|
||||
type: "option",
|
||||
options:
|
||||
'[\n "text",\n "number",\n "textarea",\n "slider",\n "dropdown",\n "password",\n "radio",\n "date",\n "datetime",\n "money",\n "sub-link",\n]',
|
||||
option_mode: "dropdown",
|
||||
optionsBuilt:
|
||||
' [\n "text",\n "number",\n "textarea",\n "slider",\n "dropdown",\n "password",\n "radio",\n "date",\n "datetime",\n "money",\n "sub-link"\n];\n',
|
||||
},
|
||||
name: "prop_3",
|
||||
type: "string",
|
||||
value: '"' + arg.type + '"',
|
||||
content: {
|
||||
id: "vmic2917cg7j005xd1p54h71",
|
||||
adv: {
|
||||
css: "",
|
||||
},
|
||||
dim: {
|
||||
h: "full",
|
||||
w: "full",
|
||||
},
|
||||
name: "type",
|
||||
type: "item",
|
||||
childs: [],
|
||||
},
|
||||
is_name: false,
|
||||
valueBuilt: '"' + arg.type + '"',
|
||||
},
|
||||
name: arg.name,
|
||||
label: formatName(arg.name),
|
||||
child: {
|
||||
idx: 11,
|
||||
meta: {
|
||||
type: "content-element",
|
||||
},
|
||||
name: "prop_11",
|
||||
type: "string",
|
||||
value: '"hello"',
|
||||
content: {
|
||||
id: "jzr2ns0pgqhkuo5yfvqenpkc",
|
||||
adv: {
|
||||
css: "",
|
||||
},
|
||||
dim: {
|
||||
h: "full",
|
||||
w: "full",
|
||||
},
|
||||
name: "child",
|
||||
type: "item",
|
||||
childs: [],
|
||||
},
|
||||
is_name: false,
|
||||
typings:
|
||||
'const typings = {\n data: "any",\n is_active: "boolean",\n item_click: "() => void",\n current_name: "string",\n option_item: "{value: string, label: string}",\n modify: `(field_name: string, opt: {\n value?: any,\n }) => void`,\n}',
|
||||
visible: 'type === "radio"',
|
||||
valueBuilt: '"hello"',
|
||||
},
|
||||
label: {
|
||||
idx: 1,
|
||||
meta: {
|
||||
type: "text",
|
||||
},
|
||||
name: "prop_1",
|
||||
type: "string",
|
||||
value: "`" + arg.label + "`",
|
||||
is_name: false,
|
||||
valueBuilt: "`" + arg.label + "`",
|
||||
},
|
||||
custom: {
|
||||
idx: 8,
|
||||
meta: {
|
||||
type: "option",
|
||||
options:
|
||||
'[\n {\n label: "yes",\n value: "y"\n },\n {\n label: "no",\n value: "n"\n },\n]\n',
|
||||
option_mode: "button",
|
||||
optionsBuilt:
|
||||
' [\n {\n label: "yes",\n value: "y"\n },\n {\n label: "no",\n value: "n"\n }\n];\n',
|
||||
},
|
||||
name: "prop_11",
|
||||
type: "string",
|
||||
value: '"n"',
|
||||
is_name: false,
|
||||
valueBuilt: ' "n";\n',
|
||||
},
|
||||
slider: {
|
||||
idx: 9,
|
||||
meta: {
|
||||
type: "text",
|
||||
},
|
||||
name: "prop_9",
|
||||
type: "string",
|
||||
value:
|
||||
'async () => {\n return {\n step: 1,\n min: { value: 0, label: "Start" },\n max: { value: 100, label: "End" },\n };\n}',
|
||||
is_name: false,
|
||||
visible: "type === 'slider'",
|
||||
valueBuilt:
|
||||
' async () => {\n return {\n step: 1,\n min: { value: 0, label: "Start" },\n max: { value: 100, label: "End" }\n };\n};\n',
|
||||
},
|
||||
suffix: {
|
||||
idx: 12,
|
||||
meta: {
|
||||
type: "text",
|
||||
},
|
||||
name: "prop_11",
|
||||
type: "string",
|
||||
value: '""',
|
||||
visible: '["number", "text", "password"].includes(type)',
|
||||
valueBuilt: ' "";\n',
|
||||
},
|
||||
options: {
|
||||
idx: 6,
|
||||
meta: {
|
||||
type: "text",
|
||||
},
|
||||
name: "prop_5",
|
||||
type: "string",
|
||||
value:
|
||||
'async () => {\r\n return [\r\n {\r\n value: "sample1",\r\n label: "sample1",\r\n },\r\n {\r\n value: "sample2",\r\n label: "sample2",\r\n },\r\n ];\r\n}',
|
||||
is_name: false,
|
||||
visible: "['button-options', 'dropdown', 'radio'].includes(type)",
|
||||
valueBuilt:
|
||||
' async () => {\n return [\n {\n value: "sample1",\n label: "sample1"\n },\n {\n value: "sample2",\n label: "sample2"\n }\n ];\n};\n',
|
||||
},
|
||||
required: {
|
||||
idx: 7,
|
||||
meta: {
|
||||
type: "option",
|
||||
options:
|
||||
'[\n {\n label: "yes",\n value: "y"\n },\n {\n label: "no",\n value: "n"\n },\n]',
|
||||
optionsBuilt:
|
||||
' [\n {\n label: "yes",\n value: "y"\n },\n {\n label: "no",\n value: "n"\n }\n];\n',
|
||||
},
|
||||
name: "prop_7",
|
||||
type: "string",
|
||||
value: "`" + (arg.required ? "y" : "n") + "`",
|
||||
is_name: false,
|
||||
valueBuilt: "`" + (arg.required ? "y" : "n") + "`",
|
||||
},
|
||||
label_alt: {
|
||||
idx: 2,
|
||||
meta: {
|
||||
type: "text",
|
||||
},
|
||||
name: "prop_10",
|
||||
type: "string",
|
||||
value: '""',
|
||||
is_name: false,
|
||||
valueBuilt: ' "";\n',
|
||||
},
|
||||
on_change: {
|
||||
idx: 10,
|
||||
meta: {
|
||||
type: "text",
|
||||
},
|
||||
name: "prop_11",
|
||||
type: "string",
|
||||
value: "({ value }) => {}",
|
||||
is_name: false,
|
||||
valueBuilt: " ({ value }) => {\n};\n",
|
||||
},
|
||||
selection: {
|
||||
idx: 5,
|
||||
meta: {
|
||||
type: "option",
|
||||
options: '["single", "multi"]',
|
||||
optionsBuilt: ' ["single", "multi"];\n',
|
||||
},
|
||||
name: "prop_11",
|
||||
type: "string",
|
||||
value: '"single"',
|
||||
visible: 'type === "radio"',
|
||||
valueBuilt: ' "single";\n',
|
||||
},
|
||||
placeholder: {
|
||||
idx: 3,
|
||||
meta: {
|
||||
type: "text",
|
||||
},
|
||||
name: "prop_11",
|
||||
type: "string",
|
||||
value: '""',
|
||||
visible: '["text", "number", "password"].includes(type)',
|
||||
valueBuilt: ' "";\n',
|
||||
},
|
||||
rel_query: {
|
||||
idx: 11,
|
||||
name: "prop_11",
|
||||
type: "string",
|
||||
value: "async () => {\n return {\n };\n}",
|
||||
valueBuilt: " async () => {\n return {\n };\n};\n",
|
||||
meta: {
|
||||
type: "text",
|
||||
},
|
||||
},
|
||||
prop_11: {
|
||||
idx: 11,
|
||||
name: "prop_11",
|
||||
type: "string",
|
||||
value: '"hello"',
|
||||
valueBuilt: '"hello"',
|
||||
meta: {
|
||||
type: "text",
|
||||
},
|
||||
},
|
||||
rel_table: {
|
||||
idx: 11,
|
||||
name: "prop_11",
|
||||
type: "string",
|
||||
value: '"' + (arg.relation?.table || "") + '"',
|
||||
valueBuilt: '"' + (arg.relation?.table || "") + '"',
|
||||
meta: {
|
||||
type: "text",
|
||||
},
|
||||
content: {
|
||||
id: "id7ai9balb0k60kduqrkmyzr",
|
||||
name: "rel_table",
|
||||
type: "item",
|
||||
dim: {
|
||||
w: "full",
|
||||
h: "full",
|
||||
},
|
||||
childs: [],
|
||||
adv: {
|
||||
css: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
rel_fields: {
|
||||
idx: 11,
|
||||
name: "prop_11",
|
||||
type: "string",
|
||||
value: JSON.stringify(arg.relation?.fields || []),
|
||||
valueBuilt: JSON.stringify(arg.relation?.fields || []),
|
||||
meta: {
|
||||
type: "option",
|
||||
},
|
||||
childs: [
|
||||
createItem({
|
||||
component: {
|
||||
id: "ca7ac237-8f22-4492-bb9d-4b715b1f5c25",
|
||||
props: {},
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
},
|
||||
ref_ids: {},
|
||||
instances: {},
|
||||
},
|
||||
};
|
||||
});
|
||||
return item;
|
||||
};
|
||||
|
|
|
|||
14
gen/utils.ts
14
gen/utils.ts
|
|
@ -92,21 +92,13 @@ export const createItem = (arg: SimplifiedItem): any => {
|
|||
valueBuilt: v[1],
|
||||
};
|
||||
} else {
|
||||
let newItem = createItem(v);
|
||||
|
||||
component.props[k] = {
|
||||
meta: {
|
||||
type: "content-element",
|
||||
},
|
||||
content: {
|
||||
id: createId(),
|
||||
dim: {
|
||||
h: "full",
|
||||
w: "full",
|
||||
},
|
||||
padding: arg.padding,
|
||||
type: "item",
|
||||
name: k,
|
||||
...v,
|
||||
},
|
||||
content: newItem,
|
||||
value: "",
|
||||
valueBuilt: "",
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue