This commit is contained in:
rizky 2024-08-16 21:12:06 -07:00
parent 53c2009509
commit e49b299249
4 changed files with 100 additions and 68 deletions

View File

@ -1,7 +1,8 @@
import { ReactNode, useCallback, useEffect, useState } from "react";
import { BaseFormLocal, default_base_form_local } from "./types";
import { useLocal } from "lib/utils/use-local";
import { FieldLocal, FieldProp, fieldType } from "../typings";
import { FieldLocal, FieldProp, fieldType, FMLocal } from "../typings";
import { FieldLoading } from "lib/exports";
export type BaseFormProps<T> = {
data: T;
@ -9,13 +10,16 @@ export type BaseFormProps<T> = {
on_submit?: (form: BaseFormLocal<T>) => Promise<any> | any;
children: ReactNode | ((form: BaseFormLocal<T>) => ReactNode);
render?: () => void;
on_change?: (fm: FMLocal, name: string, new_value: any) => any;
is_form?: boolean;
};
export const BaseForm = <T extends Record<string, any>>(
props: BaseFormProps<T>
) => {
const { data, children, className, on_submit, render } = props;
const form = useLocal({ ...default_base_form_local }) as BaseFormLocal<T>;
const { data, children, className, on_submit, render, on_change } = props;
const form = useLocal({
...default_base_form_local,
}) as BaseFormLocal<T>;
if (render) {
form.render = render;
@ -73,12 +77,21 @@ export const BaseForm = <T extends Record<string, any>>(
}
form.fm = {
data: data,
status: "ready",
deps: {},
props: { label_mode: "vertical" },
error: {
get: () => {
return [];
},
},
events: {
on_change: (n: any, v: any) => {
if (on_change && form.fm) {
on_change(form.fm, n, v);
}
},
},
submit: () => on_submit?.(form),
size: { field: size },
render: form.render,
@ -109,27 +122,14 @@ export const BaseForm = <T extends Record<string, any>>(
form.status = "ready";
}
if (!form.fm) {
form.fm = form.createFm();
}
if (typeof props.is_form === "boolean") {
if (!props.is_form) {
return (
<div
className={cx(
"form c-flex-1 c-flex-col c-w-full c-h-full c-relative c-overflow-auto c-contents",
className
)}
>
<div
className={cx(
"form-inner c-flex-1 c-flex-wrap c-items-start c-content-start c-absolute c-inset-0 c-contents",
css`
padding-right: 10px;
`
)}
>
{typeof children === "function" ? children(form) : children}
</div>
</div>
);
if (!form.fm.data) return <FieldLoading />;
return <>{typeof children === "function" ? children(form) : children}</>;
}
}
@ -142,9 +142,6 @@ export const BaseForm = <T extends Record<string, any>>(
form.render();
}, 50);
}
if (!form.fm) {
form.fm = form.createFm();
}
return (
<form
onSubmit={(e) => {

View File

@ -54,6 +54,14 @@ export const Field: FC<FieldProp> = (arg) => {
} else {
local.prev_val = fm.data[name];
}
if (!fm.events) {
fm.events = {
on_change(name, new_value) {},
};
}
fm.events.on_change(name, fm.data[name]);
return;
}
@ -169,7 +177,12 @@ export const Field: FC<FieldProp> = (arg) => {
arg={arg}
/>
{field.desc && (
<div className={cx("c-p-2 c-pl-0 c-text-xs", errors.length > 0 && "c-pb-1")}>
<div
className={cx(
"c-p-2 c-pl-0 c-text-xs",
errors.length > 0 && "c-pb-1"
)}
>
{field.desc}
</div>
)}

View File

@ -3,6 +3,7 @@ import { useLocal } from "lib/utils/use-local";
import { FC, useEffect, useRef } from "react";
import { FMLocal } from "../../typings";
import get from "lodash.get";
import { BaseForm } from "../../base/BaseForm";
export const TableEdit: FC<{
on_init: () => FMLocal;
@ -43,7 +44,17 @@ export const TableEdit: FC<{
"props.meta.item.component.props.child.content.childs"
);
let columns: any[] = [];
let columns: {
key: string;
name?: string;
label?: string;
width?: number;
minWidth?: number;
resizable?: boolean;
sortable?: boolean;
frozen?: boolean;
renderCell: (arg: any) => any;
}[] = [];
let childs: any[] = [];
const mode_child = raw_childs.find((e: any) =>
["tbl-col", "table: columns"].includes(e.name)
@ -73,7 +84,6 @@ export const TableEdit: FC<{
renderCell(arg: any) {
// return <></>;
const { props, tbl } = arg;
const fm_row = { ...fm, render: local.render };
return (
<PassProp
idx={props.rowIdx}
@ -84,7 +94,7 @@ export const TableEdit: FC<{
value: get(props.row, props.column.key),
depth: 0,
}}
fm={fm_row}
fm={arg.fm}
ext_fm={{
idx: props.rowIdx,
change: () => {},
@ -114,8 +124,6 @@ export const TableEdit: FC<{
sortable: true,
renderCell(arg: any) {
const { props, tbl } = arg;
const fm_row = { ...fm, render: local.render };
fm_row.data = props.row;
local.tbl = tbl;
const key = props.column.key;
return (
@ -128,7 +136,7 @@ export const TableEdit: FC<{
depth: props.row.__depth || 0,
}}
rows={tbl.data}
fm={fm_row}
fm={props.fm}
fm_parent={parent}
ext_fm={{
idx: props.rowIdx,
@ -205,7 +213,7 @@ export const TableEdit: FC<{
css`
background-color: #f9f9f9;
`,
header.width > 0
header.width || 0 > 0
? css`
width: ${header.width}px;
`
@ -216,7 +224,7 @@ export const TableEdit: FC<{
className={cx(
"rdg-cell c-py-2 c-px-4 c-flex c-flex-row c-items-center c-h-full",
header.width > 0
header.width || 0 > 0
? css`
width: ${header.width}px;
`
@ -244,15 +252,25 @@ export const TableEdit: FC<{
{Array.isArray(value) && value.length ? (
<>
{value.map((row: any, idx: number) => {
return (
<BaseForm
is_form={false}
data={row}
on_change={(_fm) => {
fm.data[name][idx] = _fm.data;
fm.render();
}}
>
{(form) => {
return (
<tr>
{columns.map((header) => {
return (
<td
className={cx(
header.width > 0
header.width || 0 > 0
? css`
width: ${header.width}px;
width: ${header.width || 0}px;
`
: ""
)}
@ -268,6 +286,7 @@ export const TableEdit: FC<{
row: row,
rowIdx: idx,
column: header,
fm: form.fm,
},
tbl: {
data: value,
@ -279,6 +298,9 @@ export const TableEdit: FC<{
})}
</tr>
);
}}
</BaseForm>
);
})}
</>
) : (