wip fix
This commit is contained in:
parent
ec2c0d55e5
commit
99e6c1c530
|
|
@ -32,7 +32,7 @@ export const Relation: FC<RelationProps> = ({
|
||||||
input: "",
|
input: "",
|
||||||
label: "",
|
label: "",
|
||||||
filter: "",
|
filter: "",
|
||||||
pk: "",
|
pk_field: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -42,11 +42,11 @@ export const Relation: FC<RelationProps> = ({
|
||||||
local.render();
|
local.render();
|
||||||
const table_fn = (db as any)[relation.table];
|
const table_fn = (db as any)[relation.table];
|
||||||
const select = {} as any;
|
const select = {} as any;
|
||||||
local.pk = "";
|
local.pk_field = "";
|
||||||
for (const f of relation.fields) {
|
for (const f of relation.fields) {
|
||||||
if (f.startsWith("::")) {
|
if (f.startsWith("::")) {
|
||||||
select[f.substring(2)] = true;
|
select[f.substring(2)] = true;
|
||||||
local.pk = f.substring(2);
|
local.pk_field = f.substring(2);
|
||||||
} else {
|
} else {
|
||||||
select[f] = true;
|
select[f] = true;
|
||||||
}
|
}
|
||||||
|
|
@ -62,13 +62,22 @@ export const Relation: FC<RelationProps> = ({
|
||||||
local.list = list.map((item: any) => {
|
local.list = list.map((item: any) => {
|
||||||
let label = [];
|
let label = [];
|
||||||
for (const [k, v] of Object.entries(item)) {
|
for (const [k, v] of Object.entries(item)) {
|
||||||
if (k !== local.pk) label.push(v);
|
if (k !== local.pk_field) label.push(v);
|
||||||
}
|
}
|
||||||
return { value: item[local.pk], label: label.join(" - ") };
|
return { value: item[local.pk_field], label: label.join(" - ") };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const found = local.list.find((e) => e.value === value);
|
const found = local.list.find((e) => {
|
||||||
|
if (typeof value === "object") {
|
||||||
|
if (value["connect"]) {
|
||||||
|
return e.value === value["connect"][local.pk_field];
|
||||||
|
}
|
||||||
|
return e.value === value[local.pk_field];
|
||||||
|
} else {
|
||||||
|
return e.value === value;
|
||||||
|
}
|
||||||
|
});
|
||||||
if (found) {
|
if (found) {
|
||||||
local.label = found.label;
|
local.label = found.label;
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +142,9 @@ export const Relation: FC<RelationProps> = ({
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (form) {
|
if (form) {
|
||||||
local.open = false;
|
local.open = false;
|
||||||
form.hook.setValue(name, item.value);
|
form.hook.setValue(name, {
|
||||||
|
connect: { [local.pk_field]: item.value },
|
||||||
|
});
|
||||||
form.render();
|
form.render();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,13 @@ import { Input } from "../ui/input";
|
||||||
import { Textarea } from "../ui/textarea";
|
import { Textarea } from "../ui/textarea";
|
||||||
import { Date } from "./Date";
|
import { Date } from "./Date";
|
||||||
import { Datetime } from "./Datetime";
|
import { Datetime } from "./Datetime";
|
||||||
|
import { Dropdown } from "./Dropdown";
|
||||||
|
import { Relation } from "./Dropdown/relation";
|
||||||
import { InputMoney } from "./InputMoney";
|
import { InputMoney } from "./InputMoney";
|
||||||
import { Radio } from "./Radio";
|
import { Radio } from "./Radio";
|
||||||
import { SliderOptions } from "./Slider/types";
|
import { SliderOptions } from "./Slider/types";
|
||||||
import { FormHook, modify } from "./utils/utils";
|
|
||||||
import { Dropdown } from "./Dropdown";
|
|
||||||
import { FieldOptions } from "./type";
|
import { FieldOptions } from "./type";
|
||||||
import { Relation } from "./Dropdown/relation";
|
import { FormHook, modify } from "./utils/utils";
|
||||||
|
|
||||||
export const Field: FC<{
|
export const Field: FC<{
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -123,6 +123,30 @@ export const Field: FC<{
|
||||||
}
|
}
|
||||||
}, [value]);
|
}, [value]);
|
||||||
|
|
||||||
|
const inputKeyDown = (e: any) => {
|
||||||
|
if (e.key === "Enter" && form?.ref) {
|
||||||
|
form.submit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChange = (e: any) => {
|
||||||
|
form?.hook.setValue(name, e.currentTarget.value);
|
||||||
|
form?.render();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (form) {
|
||||||
|
form.label[name] = label;
|
||||||
|
if (required === "y") {
|
||||||
|
form.validation[name] = "required";
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
delete form.hook.formState.errors[name];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
delete form.validation[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FormField
|
<FormField
|
||||||
|
|
@ -131,7 +155,7 @@ export const Field: FC<{
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="c-flex c-flex-1 c-flex-col">
|
<FormItem className="c-flex c-flex-1 c-flex-col">
|
||||||
<FormLabel className="c-flex c-justify-between">
|
<FormLabel className="c-flex c-justify-between">
|
||||||
<div>
|
<div className="c-flex c-items-center">
|
||||||
{label}
|
{label}
|
||||||
{required === "y" && (
|
{required === "y" && (
|
||||||
<h1 className="c-ml-1 c-text-red-500">*</h1>
|
<h1 className="c-ml-1 c-text-red-500">*</h1>
|
||||||
|
|
@ -196,15 +220,11 @@ export const Field: FC<{
|
||||||
<Input
|
<Input
|
||||||
{...field}
|
{...field}
|
||||||
type={type}
|
type={type}
|
||||||
|
spellCheck={false}
|
||||||
className="c-flex-1 c-rounded-r-none focus:c-rounded-r-none c-pr-1 c-border-r-0"
|
className="c-flex-1 c-rounded-r-none focus:c-rounded-r-none c-pr-1 c-border-r-0"
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
onChangeCapture={
|
onChange={onChange}
|
||||||
typeof on_change === "function"
|
onKeyDown={inputKeyDown}
|
||||||
? (e) => {
|
|
||||||
on_change({ value: e.currentTarget.value });
|
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
></Input>
|
></Input>
|
||||||
<span className="c-p-[7px] c-rounded-r c-bg-[#D3D3D5]">
|
<span className="c-p-[7px] c-rounded-r c-bg-[#D3D3D5]">
|
||||||
{suffix || "-"}
|
{suffix || "-"}
|
||||||
|
|
@ -214,18 +234,20 @@ export const Field: FC<{
|
||||||
<Input
|
<Input
|
||||||
{...field}
|
{...field}
|
||||||
type={type}
|
type={type}
|
||||||
onChangeCapture={
|
spellCheck={false}
|
||||||
typeof on_change === "function"
|
placeholder={placeholder}
|
||||||
? (e) => {
|
onKeyDown={inputKeyDown}
|
||||||
on_change({ value: e.currentTarget.value });
|
onChange={onChange}
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{type === "textarea" && (
|
{type === "textarea" && (
|
||||||
<Textarea {...field} ref={textAreaRef} />
|
<Textarea
|
||||||
|
{...field}
|
||||||
|
ref={textAreaRef}
|
||||||
|
spellCheck={false}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{type === "dropdown" && (
|
{type === "dropdown" && (
|
||||||
|
|
@ -296,7 +318,7 @@ export const Field: FC<{
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormDescription>{desc}</FormDescription>
|
{/* <FormDescription>{desc}</FormDescription> */}
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,14 @@ import { Form as FForm } from "@/comps/ui/form";
|
||||||
import { useLocal } from "@/utils/use-local";
|
import { useLocal } from "@/utils/use-local";
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
|
import { FormHook } from "./utils/utils";
|
||||||
|
|
||||||
export const Form: FC<{
|
export const Form: FC<{
|
||||||
on_init: (arg: { submit: any }) => any;
|
on_init: (arg: { submit: any }) => any;
|
||||||
on_load: () => any;
|
on_load: () => any;
|
||||||
on_submit: (arg: { form: any; error: any }) => any;
|
on_submit: (arg: { form: any; error: any }) => any;
|
||||||
body: any;
|
body: any;
|
||||||
form: { hook: any; render: () => void };
|
form: FormHook;
|
||||||
PassProp: any;
|
PassProp: any;
|
||||||
layout: "auto" | "1-col" | "2-col";
|
layout: "auto" | "1-col" | "2-col";
|
||||||
}> = ({
|
}> = ({
|
||||||
|
|
@ -32,6 +33,12 @@ export const Form: FC<{
|
||||||
});
|
});
|
||||||
|
|
||||||
form.hook = form_hook;
|
form.hook = form_hook;
|
||||||
|
if (!form.validation) {
|
||||||
|
form.validation = {};
|
||||||
|
}
|
||||||
|
if (!form.label) {
|
||||||
|
form.label = {};
|
||||||
|
}
|
||||||
|
|
||||||
let layout = _layout || "auto";
|
let layout = _layout || "auto";
|
||||||
if (layout !== "auto") local.layout = layout;
|
if (layout !== "auto") local.layout = layout;
|
||||||
|
|
@ -39,9 +46,24 @@ export const Form: FC<{
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
clearTimeout(local.submit_timeout);
|
clearTimeout(local.submit_timeout);
|
||||||
local.submit_timeout = setTimeout(() => {
|
local.submit_timeout = setTimeout(() => {
|
||||||
|
const data = form.hook.getValues();
|
||||||
|
form.hook.clearErrors();
|
||||||
|
for (const [k, v] of Object.entries(form.validation)) {
|
||||||
|
if (v === "required") {
|
||||||
|
if (!data[k]) {
|
||||||
|
const error = {
|
||||||
|
type: "required",
|
||||||
|
message: `${form.label[k] || k} is required.`,
|
||||||
|
};
|
||||||
|
form.hook.formState.errors[k] = error;
|
||||||
|
form.hook.setError(k, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
on_submit({
|
on_submit({
|
||||||
form: form.hook.getValues(),
|
form: data,
|
||||||
error: {},
|
error: form.hook.formState.errors,
|
||||||
});
|
});
|
||||||
}, 300);
|
}, 300);
|
||||||
};
|
};
|
||||||
|
|
@ -51,13 +73,19 @@ export const Form: FC<{
|
||||||
on_init({ submit });
|
on_init({ submit });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
form.submit = submit;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FForm {...form_hook}>
|
<FForm {...form_hook}>
|
||||||
<form
|
<form
|
||||||
className={
|
className={
|
||||||
"flex-1 flex flex-col w-full items-stretch relative overflow-auto"
|
"flex-1 flex flex-col w-full items-stretch relative overflow-auto"
|
||||||
}
|
}
|
||||||
|
ref={(el) => {
|
||||||
|
if (el) form.ref = el;
|
||||||
|
}}
|
||||||
onSubmit={(e) => {
|
onSubmit={(e) => {
|
||||||
|
console.log("on submit");
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
submit();
|
submit();
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ export const Radio: FC<{
|
||||||
{!!local.list &&
|
{!!local.list &&
|
||||||
local.list
|
local.list
|
||||||
.filter((e) => e)
|
.filter((e) => e)
|
||||||
.map((item, index) => {
|
.map((item, index:number) => {
|
||||||
if (custom === "y" && form)
|
if (custom === "y" && form)
|
||||||
return (
|
return (
|
||||||
<PassProp
|
<PassProp
|
||||||
|
|
@ -102,15 +102,20 @@ export const Radio: FC<{
|
||||||
option_item={item}
|
option_item={item}
|
||||||
current_name={name}
|
current_name={name}
|
||||||
item_click={() => {
|
item_click={() => {
|
||||||
console.log(value, "====single", name);
|
|
||||||
if (selection === "single") {
|
if (selection === "single") {
|
||||||
|
console.log(value, "====single", name);
|
||||||
local.mod(name, { value: item.value });
|
local.mod(name, { value: item.value });
|
||||||
local.render();
|
local.render();
|
||||||
} else if (selection === "multi") {
|
} else if (selection === "multi") {
|
||||||
const val = [];
|
const val = [];
|
||||||
val.push();
|
console.log();
|
||||||
local.mod(name, { value: item.value });
|
|
||||||
|
val.push( ...value, item.value);
|
||||||
|
|
||||||
|
local.mod(name, { value: val });
|
||||||
local.render();
|
local.render();
|
||||||
|
console.log(item.value, "value", form.hook.getValues());
|
||||||
|
return;
|
||||||
console.log(value, "====multi", name);
|
console.log(value, "====multi", name);
|
||||||
} else {
|
} else {
|
||||||
null;
|
null;
|
||||||
|
|
|
||||||
|
|
@ -21,5 +21,9 @@ export const modify = function (
|
||||||
|
|
||||||
export type FormHook = {
|
export type FormHook = {
|
||||||
hook: UseFormReturn<any, any, undefined>;
|
hook: UseFormReturn<any, any, undefined>;
|
||||||
|
ref: HTMLFormElement;
|
||||||
|
submit: any;
|
||||||
|
label: Record<string, string>;
|
||||||
|
validation: Record<string, "required">;
|
||||||
render: () => void;
|
render: () => void;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
import get from "lodash.get";
|
||||||
|
import { on_load } from "./gen_form/on_load";
|
||||||
|
import { on_submit } from "./gen_form/on_submit";
|
||||||
|
import { GFCol as Col } from "./gen_form/type";
|
||||||
|
import { NewFieldArg, newField } from "./gen_form/new_field";
|
||||||
|
import capitalize from "lodash.capitalize";
|
||||||
|
|
||||||
|
export const gen_form = (modify: (data: any) => void, data: any) => {
|
||||||
|
const mode = JSON.parse(data.gen_mode.value) as (
|
||||||
|
| string
|
||||||
|
| { value: string; checked: string[] }
|
||||||
|
)[];
|
||||||
|
const table = JSON.parse(data.gen_table.value);
|
||||||
|
const fields = JSON.parse(data.gen_fields.value);
|
||||||
|
const select = {} as any;
|
||||||
|
const new_fields: NewFieldArg[] = [];
|
||||||
|
|
||||||
|
let pk: Col | null = 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(new_fields);
|
||||||
|
|
||||||
|
const result: any = {};
|
||||||
|
if (pk) {
|
||||||
|
if (mode.includes("on_load")) {
|
||||||
|
result["on_load"] = data["on_load"];
|
||||||
|
result["on_load"].value = on_load({ pk, pks, select, table });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.includes("on_submit")) {
|
||||||
|
result["on_submit"] = data["on_submit"];
|
||||||
|
result["on_submit"].value = on_submit({ pk, table, select, pks });
|
||||||
|
}
|
||||||
|
|
||||||
|
result["body"] = data["body"];
|
||||||
|
const childs = get(result, "body.content.childs");
|
||||||
|
if (Array.isArray(childs)) {
|
||||||
|
|
||||||
|
result.body.content.childs = new_fields.map(newField);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
modify(result);
|
||||||
|
|
||||||
|
alert("Prop Generated!");
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatName = (name: string) => {
|
||||||
|
return name
|
||||||
|
.split("_")
|
||||||
|
.filter((e) => e.length > 1)
|
||||||
|
.map((e) => capitalize(e))
|
||||||
|
.join(" ");
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,324 @@
|
||||||
|
import { createId } from "@paralleldrive/cuid2";
|
||||||
|
export const newItem = (component: {
|
||||||
|
id: string;
|
||||||
|
props: Record<string, string>;
|
||||||
|
}) => {
|
||||||
|
return {
|
||||||
|
id: createId(),
|
||||||
|
name: "new_item",
|
||||||
|
type: "item",
|
||||||
|
dim: { w: "full", h: "full" },
|
||||||
|
childs: [],
|
||||||
|
adv: {
|
||||||
|
css: "",
|
||||||
|
},
|
||||||
|
component: component,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type NewFieldArg = {
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
type: "relation" | "text";
|
||||||
|
required: boolean;
|
||||||
|
relation?: {
|
||||||
|
table: string;
|
||||||
|
fields: string[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
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: {},
|
||||||
|
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 + '"',
|
||||||
|
},
|
||||||
|
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 orderBy: {\n regional: "asc",\n },\n };\n}',
|
||||||
|
valueBuilt:
|
||||||
|
' async () => {\n return {\n orderBy: {\n regional: "asc"\n }\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",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ref_ids: {},
|
||||||
|
instances: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { GFCol } from "./type";
|
||||||
|
|
||||||
|
export const on_load = ({
|
||||||
|
pk,
|
||||||
|
table,
|
||||||
|
select,
|
||||||
|
pks,
|
||||||
|
}: {
|
||||||
|
pk: GFCol;
|
||||||
|
table: string;
|
||||||
|
select: any;
|
||||||
|
pks: Record<string, string>;
|
||||||
|
}) => {
|
||||||
|
return `\
|
||||||
|
async (opt) => {
|
||||||
|
if (isEditor) return {};
|
||||||
|
|
||||||
|
let id = ${pk.type === "int" ? "parseInt(params.id)" : "params.id"};
|
||||||
|
|
||||||
|
if (id){
|
||||||
|
const item = await db.${table}.findFirst({
|
||||||
|
where: {
|
||||||
|
${pk.name}: id,
|
||||||
|
},
|
||||||
|
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}") {
|
||||||
|
item[k] = { connect: { ${v}: v["${v}"] } } as any;
|
||||||
|
}`;
|
||||||
|
})
|
||||||
|
.join("\n")}
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
import { GFCol } from "./type";
|
||||||
|
|
||||||
|
export const on_submit = ({
|
||||||
|
pk,
|
||||||
|
table,
|
||||||
|
select,
|
||||||
|
pks,
|
||||||
|
}: {
|
||||||
|
pk: GFCol;
|
||||||
|
table: string;
|
||||||
|
select: any;
|
||||||
|
pks: Record<string, string>;
|
||||||
|
}) => {
|
||||||
|
const id = pk.name;
|
||||||
|
|
||||||
|
return `\
|
||||||
|
async ({ form, error }: IForm) => {
|
||||||
|
if (typeof error === "object" && Object.keys(error).length > 0)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
const data = { ...form };
|
||||||
|
delete data.${id};
|
||||||
|
|
||||||
|
if (form.${id}) {
|
||||||
|
await db.${table}.update({
|
||||||
|
where: {
|
||||||
|
${id}: form.${id},
|
||||||
|
},
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const res = await db.${table}.create({
|
||||||
|
data,
|
||||||
|
select: { ${id}: true },
|
||||||
|
});
|
||||||
|
if (res) form.${id} = res.${id};
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
type IForm = { form: any; error: Record<string, string> }`;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
export type GFCol = {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
is_pk: boolean;
|
||||||
|
optional: boolean;
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue