This commit is contained in:
rizky 2024-04-09 19:40:08 -07:00
parent 29cb938e60
commit 70a4422600
10 changed files with 146 additions and 27 deletions

View File

@ -14,6 +14,7 @@ export const Form: FC<FMProps> = (props) => {
reload: async () => {
formReload(fm);
},
fields: {},
submit: null as any,
error: {} as any,
internal: {

23
comps/form/field/Field.tsx Executable file
View File

@ -0,0 +1,23 @@
import { FC } from "react";
import { FieldProp } from "../typings";
import { createField } from "../utils/create-field";
import { Label } from "./Label";
export const Field: FC<FieldProp> = (arg) => {
const field = createField(arg);
if (field.status === "init") return null;
const mode = field.label_mode;
return (
<div
className={cx(
"field",
mode === "horizontal" && "",
mode === "vertical" && ""
)}
>
{mode !== "hidden" && <Label field={field} />}
</div>
);
};

8
comps/form/field/Input.tsx Executable file
View File

@ -0,0 +1,8 @@
import { FMLocal, FieldLocal } from "../typings";
export const FieldInput: FC<{ field: FieldLocal; fm: FMLocal }> = ({
field,
fm,
}) => {
return <></>;
};

6
comps/form/field/Label.tsx Executable file
View File

@ -0,0 +1,6 @@
import { FC } from "react";
import { FieldLocal } from "../typings";
export const Label: FC<{ field: FieldLocal }> = ({ field }) => {
return <div className={cx("label")}>{field.label}</div>;
};

View File

@ -1,6 +0,0 @@
import { FC } from "react";
import { FieldProp } from "../typings";
export const Field: FC<FieldProp> = ({ fm }) => {
return <></>;
};

View File

@ -1,6 +1,8 @@
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";
export type FMProps = {
on_init: (arg: { fm: FMLocal; submit: any; reload: any }) => any;
@ -12,12 +14,15 @@ export type FMProps = {
props: any;
sonar: "on" | "off";
layout: "auto" | "1-col" | "2-col";
meta: any;
item: any;
};
export type FieldProp = {
name: string;
label: string;
desc?: string;
label_mode: "vertical" | "horizontal" | "hidden";
fm: FMLocal;
type:
| "text"
@ -40,6 +45,7 @@ export type FieldProp = {
custom: "y" | "n";
child: any;
selection: "single" | "multi";
prefix: any;
suffix: any;
placeholder?: any;
rel_table: string;
@ -52,6 +58,7 @@ export type FMInternal = {
data: any;
reload: () => Promise<void>;
submit: () => Promise<void>;
fields: Record<string, FieldLocal>;
error: {
list: { name: string; error: string }[];
set: (name: string, error: string) => void;
@ -69,11 +76,40 @@ export type FMInternal = {
};
export type FMLocal = FMInternal & { render: () => void };
export const formType = (active: { item_id: string }) => {
console.log("auoaou", typeof active);
return `{
export type FieldInternal = {
status: "init" | "loading" | "ready";
name: FieldProp["name"];
type: FieldProp["type"];
label: FieldProp["label"];
desc: FieldProp["desc"];
prefix: FieldProp["prefix"];
suffix: FieldProp["suffix"];
label_mode: FieldProp["label_mode"];
Child: () => ReactNode;
};
export type FieldLocal = FieldInternal & { render: () => void };
export const formType = (active: { item_id: string }, meta: any) => {
let data = "null as any";
const cache = editorFormData[active.item_id];
if (cache && cache.data) {
data = JSON.stringify(cache.data);
} else {
const m = meta[active.item_id];
if (m && m.parent && m.parent.id) {
const cache = editorFormData[m.parent.id];
if (cache && cache.data) {
data = JSON.stringify(cache.data);
}
}
}
return `
const ___data = ${data};
const fm = null as unknown as {
status: "init" | "loading" | "saving" | "ready";
data: any;
data: typeof ___data;
reload: () => Promise<void>;
submit: () => Promise<void>;
error: {

View File

@ -0,0 +1,31 @@
import { useLocal } from "@/utils/use-local";
import { FMLocal, FieldInternal, FieldProp } from "../typings";
import { useEffect } from "react";
export const createField = (arg: FieldProp) => {
const field = useLocal<FieldInternal>({
status: "init",
name: arg.name,
label: arg.label,
type: arg.type,
desc: arg.desc,
prefix: arg.prefix,
suffix: arg.suffix,
label_mode: arg.label_mode,
Child: () => {
return <arg.PassProp>{arg.child}</arg.PassProp>;
},
});
const fm = arg.fm;
useEffect(() => {
if (field.status === "init") {
field.status = "ready";
fm.fields[arg.name] = field;
field.render();
}
}, []);
return field;
};

View File

@ -1 +1,4 @@
export const editorFormData = {} as Record<string, any>;
export const editorFormData = {} as Record<
string,
{ on_load: string; data: any }
>;

View File

@ -3,10 +3,11 @@ import { toast } from "sonner";
import { FMLocal, FMProps } from "../typings";
import { formError } from "./error";
import { editorFormData } from "./ed-data";
import get from "lodash.get";
export const formInit = (fm: FMLocal, props: FMProps) => {
for (const [k, v] of Object.entries(props)) {
if (["PassProp", "body"].includes(k)) continue;
if (["PassProp", "body", "meta", "item"].includes(k)) continue;
(fm.props as any)[k] = v;
}
const { on_load, sonar } = fm.props;
@ -31,6 +32,21 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
});
}
let should_load = true;
if (isEditor) {
const item_id = props.item.id;
if (item_id) {
const cache = editorFormData[item_id];
if (
cache &&
cache.on_load === get(props.item, "component.props.on_load.value")
) {
fm.data = cache.data;
should_load = false;
}
}
}
if (should_load) {
const res = on_load({ fm });
if (typeof res === "object" && res instanceof Promise) {
@ -39,15 +55,16 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
fm.data = res;
}
// if (isEditor) {
// const item_id = (props?.props?.className || "")
// .split(" ")
// .find((e: string) => e.startsWith("s-"));
// if (item_id) {
// console.log(item_id);
// }
// }
if (isEditor) {
const item_id = props.item.id;
if (item_id) {
editorFormData[item_id] = {
data: fm.data,
on_load: get(props.item, "component.props.on_load.value"),
};
}
}
}
fm.internal.reload.done.map((e) => e());
}, 50);

View File

@ -1,5 +1,5 @@
export { Form } from "@/comps/form/Form";
export { Field } from "@/comps/form/fields/Field";
export { Field } from "@/comps/form/field/Field";
export { formType } from "@/comps/form/typings";
export { TableList } from "@/comps/list/TableList";
export { TableListType } from "@/comps/list/typings";