This commit is contained in:
Rizky 2024-06-29 21:52:21 -07:00
parent 61173c119a
commit 02a0b485f9
9 changed files with 94 additions and 70 deletions

View File

@ -14,7 +14,7 @@ const editorFormWidth = {} as Record<string, { w: number; f: any }>;
export { FMLocal } from "./typings"; export { FMLocal } from "./typings";
export const Form: FC<FMProps> = (props) => { export const Form: FC<FMProps> = (props) => {
const { PassProp, body, feature, sfd_field, style } = props; const { PassProp, body, feature, sfd_field } = props;
const fm = useLocal<FMInternal>({ const fm = useLocal<FMInternal>({
data: editorFormData[props.item.id] data: editorFormData[props.item.id]
? editorFormData[props.item.id].data ? editorFormData[props.item.id].data
@ -168,7 +168,6 @@ export const Form: FC<FMProps> = (props) => {
<div <div
className={cx( className={cx(
"form-inner c-flex c-flex-1 c-flex-wrap c-items-start c-content-start", "form-inner c-flex c-flex-1 c-flex-wrap c-items-start c-content-start",
style === "flex" ? "" : "c-absolute c-inset-0",
css` css`
padding-right: 10px; padding-right: 10px;
` `

View File

@ -15,7 +15,6 @@ export const BaseField = (prop: {
}) => { }) => {
const { field, fm, arg } = prop; const { field, fm, arg } = prop;
const w = field.width; const w = field.width;
const mode = fm.props.label_mode;
const prefix = const prefix =
typeof field.prefix === "function" typeof field.prefix === "function"
? field.prefix() ? field.prefix()
@ -30,8 +29,8 @@ export const BaseField = (prop: {
: null; : null;
const name = field.name; const name = field.name;
const errors = fm.error.get(name); const errors = fm.error.get(name);
let type_field = typeof arg.type === "function" ? arg.type() : arg.type; // tipe field
const showlabel = arg.show_label || "y";
return ( return (
<label <label
className={cx( className={cx(
@ -48,8 +47,9 @@ export const BaseField = (prop: {
w === "½" && "c-w-1/2", w === "½" && "c-w-1/2",
w === "⅓" && "c-w-1/3", w === "⅓" && "c-w-1/3",
w === "¼" && "c-w-1/4", w === "¼" && "c-w-1/4",
mode === "horizontal" && "c-flex-row c-items-center", field.type === "link"
mode === "vertical" && "c-flex-col c-space-y-1", ? "c-flex-row c-items-stretch c-min-h-[78px]"
: "c-flex-col c-space-y-1",
field.focused && "focused", field.focused && "focused",
field.disabled && "disabled", field.disabled && "disabled",
typeof fm.data[name] !== "undefined" && typeof fm.data[name] !== "undefined" &&
@ -58,12 +58,17 @@ export const BaseField = (prop: {
"filled" "filled"
)} )}
> >
{mode !== "hidden" && <Label field={field} fm={fm} />} {arg.show_label !== "n" && <Label field={field} fm={fm} />}
<div className="field-input c-flex c-flex-1 c-flex-col"> <div className="field-input c-flex c-flex-1 c-flex-col">
<div <div
className={cx( className={cx(
!["toogle", "button", "radio", "checkbox"].includes(arg.sub_type) !["toogle", "button", "radio", "checkbox"].includes(arg.sub_type)
? "field-outer c-overflow-hidden c-flex c-flex-1 c-flex-row c-rounded c-border c-text-sm" ? cx(
"field-outer c-overflow-hidden c-flex-1 c-flex c-flex-row c-text-sm c-bg-white",
field.type === "link"
? " c-items-center"
: "c-border c-rounded "
)
: "", : "",
fm.status === "loading" fm.status === "loading"
? css` ? css`
@ -100,6 +105,8 @@ export const BaseField = (prop: {
<div <div
className={cx( className={cx(
"field-inner c-flex-1 c-flex c-items-center", "field-inner c-flex-1 c-flex c-items-center",
field.type === "link" && "c-justify-end",
field.focused && "focused",
field.disabled && "c-pointer-events-none" field.disabled && "c-pointer-events-none"
)} )}
> >

View File

@ -9,7 +9,6 @@ import { validate } from "../utils/validate";
export const Field: FC<FieldProp> = (arg) => { export const Field: FC<FieldProp> = (arg) => {
const showlabel = arg.show_label || "y"; const showlabel = arg.show_label || "y";
let type: any = typeof arg.type === "function" ? arg.type() : arg.type; // tipe field
let sub_type: any = arg.sub_type; // tipe field let sub_type: any = arg.sub_type; // tipe field
const { fm } = arg; const { fm } = arg;
@ -17,7 +16,6 @@ export const Field: FC<FieldProp> = (arg) => {
const name = field.name; const name = field.name;
const local = useLocal({ prev_val: fm.data[name] }); const local = useLocal({ prev_val: fm.data[name] });
const mode = fm.props.label_mode;
const w = field.width; const w = field.width;
useEffect(() => { useEffect(() => {
@ -42,7 +40,7 @@ export const Field: FC<FieldProp> = (arg) => {
className={cx( className={cx(
"field", "field",
"c-flex", "c-flex",
type === "single-option" && sub_type === "checkbox" field.type === "single-option" && sub_type === "checkbox"
? css` ? css`
padding: 5px 0px 0px 7.5px; padding: 5px 0px 0px 7.5px;
` `
@ -56,16 +54,15 @@ export const Field: FC<FieldProp> = (arg) => {
w === "½" && "c-w-1/2", w === "½" && "c-w-1/2",
w === "⅓" && "c-w-1/3", w === "⅓" && "c-w-1/3",
w === "¼" && "c-w-1/4", w === "¼" && "c-w-1/4",
mode === "horizontal" && "c-flex-row c-items-center", field.type === "link"
mode === "vertical" && "c-flex-col c-space-y-1" ? "c-flex-row c-items-stretch c-min-h-[78px]"
: "c-flex-col c-space-y-1"
)} )}
{...props} {...props}
ref={typeof arg.field_ref === "function" ? arg.field_ref : undefined} ref={typeof arg.field_ref === "function" ? arg.field_ref : undefined}
> >
{mode !== "hidden" && showlabel === "y" && ( {showlabel !== "n" && <Label field={field} fm={fm} />}
<Label field={field} fm={fm} /> <div className="field-input c-flex c-flex-1 c-flex-col">
)}
<div className="field-inner c-flex c-flex-1 c-flex-col">
<FieldInput <FieldInput
field={field} field={field}
fm={fm} fm={fm}

View File

@ -104,7 +104,10 @@ export const FieldInput: FC<{
<div <div
className={cx( className={cx(
!["toogle", "button", "radio", "checkbox"].includes(arg.sub_type) !["toogle", "button", "radio", "checkbox"].includes(arg.sub_type)
? "field-outer c-overflow-hidden c-flex c-flex-1 c-flex-row c-rounded c-border c-text-sm c-bg-white" ? cx(
"field-outer c-overflow-hidden c-flex-1 c-flex c-flex-row c-text-sm c-bg-white",
field.type === "link" ? " c-items-center" : "c-border c-rounded "
)
: "", : "",
fm.status === "loading" fm.status === "loading"
? css` ? css`
@ -140,6 +143,7 @@ export const FieldInput: FC<{
<div <div
className={cx( className={cx(
"field-inner c-flex-1 c-flex c-items-center", "field-inner c-flex-1 c-flex c-items-center",
field.type === "link" && "c-justify-end",
field.focused && "focused", field.focused && "focused",
field.disabled && "c-pointer-events-none" field.disabled && "c-pointer-events-none"
)} )}
@ -152,6 +156,7 @@ export const FieldInput: FC<{
<>{custom}</> <>{custom}</>
) : ( ) : (
<> <>
{type_field === "link" && <>ini link</>}
{["date", "input"].includes(type_field) ? ( {["date", "input"].includes(type_field) ? (
<FieldTypeInput <FieldTypeInput
field={field} field={field}
@ -161,7 +166,7 @@ export const FieldInput: FC<{
{ {
type: type_field as any, type: type_field as any,
sub_type: arg.sub_type, sub_type: arg.sub_type,
model_upload: arg.model_upload model_upload: arg.model_upload,
} as PropTypeInput } as PropTypeInput
} }
/> />

View File

@ -11,11 +11,7 @@ export const Label: FC<{ field: FieldLocal; fm: FMLocal }> = ({
<div <div
className={cx( className={cx(
"label c-text-sm c-flex c-items-center", "label c-text-sm c-flex c-items-center",
fm.props.label_mode === "horizontal" && field.type === "link" ? "" : "c-mt-3"
css`
width: ${fm.props.label_width}px;
`,
fm.props.label_mode === "vertical" && "c-mt-3"
)} )}
> >
<span className={cx(errors.length > 0 && `c-text-red-600`)}> <span className={cx(errors.length > 0 && `c-text-red-600`)}>

View File

@ -37,6 +37,9 @@ export const generateForm = async (
return; return;
} }
if (pk) { if (pk) {
const is_md =
item.edit?.parent?.item?.component?.id ===
"cb52075a-14ab-455a-9847-6f1d929a2a73";
if (data["on_load"]) { if (data["on_load"]) {
result.on_load = { result.on_load = {
mode: "raw", mode: "raw",
@ -45,14 +48,16 @@ export const generateForm = async (
table, table,
select, select,
pks, pks,
opt: { opt: is_md
after_load: ` ? {
if (typeof md === "object") { after_load: `
opt.fm.status = "ready"; if (typeof md === "object") {
md.render(); opt.fm.status = "ready";
} md.render();
}
`, `,
}, }
: {},
}), }),
}; };
} }
@ -63,10 +68,15 @@ if (typeof md === "object") {
async ({ form, error, fm }: IForm) => { async ({ form, error, fm }: IForm) => {
let result = false; let result = false;
try { try {
${
is_md &&
`\
if (typeof md !== "undefined") { if (typeof md !== "undefined") {
fm.status = "saving"; fm.status = "saving";
md.render(); md.render();
} }`
}
const data = { ...form }; const data = { ...form };
const record = {} as Record<string, any>; const record = {} as Record<string, any>;
@ -84,13 +94,17 @@ async ({ form, error, fm }: IForm) => {
for (const [k, field] of Object.entries(fm.fields)) { for (const [k, field] of Object.entries(fm.fields)) {
validateField(field, fm); validateField(field, fm);
} }
${
is_md &&
`\
if (fm.error.list.length > 0) { if (fm.error.list.length > 0) {
if (typeof md !== "undefined") { if (typeof md !== "undefined") {
fm.status = "ready"; fm.status = "ready";
md.render(); md.render();
} }
return false; return false;
} }`
}
// pisahkan antara has_many dengan field biasa // pisahkan antara has_many dengan field biasa
for (const [k, v] of Object.entries(data) as any) { for (const [k, v] of Object.entries(data) as any) {
@ -183,6 +197,9 @@ async ({ form, error, fm }: IForm) => {
result = false; result = false;
} }
${
is_md &&
`\
if (typeof md !== "undefined") { if (typeof md !== "undefined") {
fm.status = "ready"; fm.status = "ready";
// kembali ke tabel // kembali ke tabel
@ -193,7 +210,8 @@ async ({ form, error, fm }: IForm) => {
md.params.apply(); md.params.apply();
md.render(); md.render();
}, 500); }, 500);
} }`
}
return result; return result;
}; };

View File

@ -13,14 +13,12 @@ export type FMProps = {
layout: "auto" | "1-col" | "2-col"; layout: "auto" | "1-col" | "2-col";
meta: any; meta: any;
item: any; item: any;
label_mode: "vertical" | "horizontal" | "hidden";
label_width: number; label_width: number;
gen_fields: any; gen_fields: any;
gen_table: string; gen_table: string;
on_load_deps?: any[]; on_load_deps?: any[];
feature?: any[]; feature?: any[];
sfd_field?: any; sfd_field?: any;
style: "default" | "flex";
}; };
export type GenField = export type GenField =
@ -37,8 +35,8 @@ export type GenField =
type FieldType = type FieldType =
| "-" | "-"
| "relation" | "date"
| "switch" | "link"
| "input" | "input"
| "single-option" | "single-option"
| "multi-option"; | "multi-option";
@ -71,7 +69,7 @@ export type FieldProp = {
opt_get_label: ( opt_get_label: (
row: any, row: any,
mode: "list" | "label", mode: "list" | "label",
opt?: { next?: any; prev?: any, } opt?: { next?: any; prev?: any }
) => string; ) => string;
opt_get_value: (arg: { opt_get_value: (arg: {
options: { label: string; value: string; item?: string }[]; options: { label: string; value: string; item?: string }[];
@ -95,11 +93,11 @@ export type FieldProp = {
pk: string; pk: string;
sub_type: string; sub_type: string;
placeholder: string; placeholder: string;
show_label: boolean; show_label: boolean | "y" | "n";
msg_error: string; msg_error: string;
gen_table?: string; gen_table?: string;
gen_fields?: string; gen_fields?: string;
model_upload?: "upload" | "import" model_upload?: "upload" | "import";
}; };
export type FMInternal = { export type FMInternal = {

View File

@ -20,14 +20,14 @@ import DataGrid, {
SELECT_COLUMN_KEY, SELECT_COLUMN_KEY,
SortColumn, SortColumn,
} from "react-data-grid"; } from "react-data-grid";
import "react-data-grid/lib/styles.css";
import { createPortal } from "react-dom"; import { createPortal } from "react-dom";
import { Toaster, toast } from "sonner"; import { Toaster, toast } from "sonner";
import { call_prasi_events } from "../../..";
import { filterWhere } from "../filter/parser/filter-where"; import { filterWhere } from "../filter/parser/filter-where";
import { getFilter } from "../filter/utils/get-filter"; import { getFilter } from "../filter/utils/get-filter";
import { Skeleton } from "../ui/skeleton"; import { Skeleton } from "../ui/skeleton";
import "react-data-grid/lib/styles.css";
import { sortTree } from "./utils/sort-tree"; import { sortTree } from "./utils/sort-tree";
import { call_prasi_events } from "../../..";
type OnRowClick = (arg: { type OnRowClick = (arg: {
row: any; row: any;
@ -519,12 +519,12 @@ export const TableList: FC<TableListProp> = ({
if (id_parent) load_args.paging = {}; if (id_parent) load_args.paging = {};
if (typeof on_load === "function") { if (typeof on_load === "function") {
let res = on_load({ ...load_args, mode: "query" }) as any; let res = on_load({ ...load_args, mode: "query" }) as any;
if(typeof res === "object" && res instanceof Promise){ if (typeof res === "object" && res instanceof Promise) {
res.then((e) => { res.then((e) => {
local.data = e local.data = e;
}) });
}else{ } else {
local.data = e local.data = res;
} }
} }
} }
@ -715,27 +715,31 @@ export const TableList: FC<TableListProp> = ({
className="w-full h-full overflow-y-auto" className="w-full h-full overflow-y-auto"
onScroll={local.paging.scroll} onScroll={local.paging.scroll}
> >
{Array.isArray(data) ? data.map((e, idx) => { {Array.isArray(data) ? (
return ( data.map((e, idx) => {
<div return (
className="flex-grow" <div
onClick={(ev) => { className="flex-grow"
if (!isEditor && typeof row_click === "function") { onClick={(ev) => {
row_click({ if (!isEditor && typeof row_click === "function") {
event: ev, row_click({
idx: idx, event: ev,
row: e, idx: idx,
rows: local.data, row: e,
}); rows: local.data,
} });
}} }
> }}
<PassProp idx={idx} row={e} col={{}} rows={local.data}> >
{child} <PassProp idx={idx} row={e} col={{}} rows={local.data}>
</PassProp> {child}
</div> </PassProp>
); </div>
}) : <>No Data</>} );
})
) : (
<>No Data</>
)}
</div> </div>
</> </>
)} )}

View File

@ -49,7 +49,7 @@ export const MasterFilter = lazify(
export const FilterField = lazify( export const FilterField = lazify(
async () => (await import("@/comps/filter/FilterField")).FilterField async () => (await import("@/comps/filter/FilterField")).FilterField
); );
/** Generator */ /** Generator */
export { generateFilter as genereteFilter } from "@/comps/filter/gen/gen-filter"; export { generateFilter as genereteFilter } from "@/comps/filter/gen/gen-filter";
export { generateRelation } from "@/comps/form/gen/gen-rel"; export { generateRelation } from "@/comps/form/gen/gen-rel";