This commit is contained in:
Rizky 2024-06-24 03:46:05 -07:00
parent 1bdfab9c1b
commit 9df6372ea8
10 changed files with 241 additions and 50 deletions

View File

@ -7,7 +7,8 @@ export const ShowHidePanel: FC<{
body: ReactNode; body: ReactNode;
open: string; open: string;
PassProp: any; PassProp: any;
}> = ({ head, body, open, PassProp }) => { on_init: (e?: any) => void
}> = ({ head, body, open, PassProp, on_init}) => {
const local = useLocal( const local = useLocal(
{ {
open: true, open: true,
@ -22,6 +23,7 @@ export const ShowHidePanel: FC<{
useEffect(() => { useEffect(() => {
local.open = open === "true" ? true : false; local.open = open === "true" ? true : false;
local.render(); local.render();
// on_init(local);
}, [open]); }, [open]);
return ( return (

View File

@ -38,7 +38,7 @@ export const Field: FC<FieldProp> = (arg) => {
className={cx( className={cx(
"field", "field",
"c-flex", "c-flex",
css` type === "single-option" && sub_type === "checkbox" ? css`padding: 5px 0px 0px 7.5px;` : css`
padding: 5px 0px 0px 10px; padding: 5px 0px 0px 10px;
`, `,
w === "auto" && fm.size.field === "full" && "c-w-full", w === "auto" && fm.size.field === "full" && "c-w-full",

View File

@ -8,7 +8,6 @@ export const FieldCheckbox: FC<{
fm: FMLocal; fm: FMLocal;
arg: FieldProp; arg: FieldProp;
}> = ({ field, fm, arg }) => { }> = ({ field, fm, arg }) => {
// console.log({field, fm, arg})
const local = useLocal({ const local = useLocal({
list: [] as any[], list: [] as any[],
}); });

View File

@ -26,20 +26,22 @@ export const TypeDropdown: FC<{
useEffect(() => { useEffect(() => {
if (typeof arg.on_load === "function") { if (typeof arg.on_load === "function") {
const options = arg.on_load({}); const options = arg.on_load({});
// console.log(field.name, {options})
if (options instanceof Promise) { if (options instanceof Promise) {
options.then((res) => { options.then((res) => {
// console.log(field.name, {res})
if (Array.isArray(res)) { if (Array.isArray(res)) {
const list: any = res.map((e: any) => { const list: any = res.map((e: any) => {
return { return {
label: arg.opt_get_label(e), label: arg.opt_get_label(e),
value: e.value, value: e.value,
data: e.data
}; };
}); });
local.options = list; local.options = list;
} else { } else {
local.options = res; local.options = res;
} }
if ( if (
field.type === "single-option" && field.type === "single-option" &&
!value && !value &&
@ -53,6 +55,14 @@ export const TypeDropdown: FC<{
options: local.options, options: local.options,
selected: [local.options[0]?.value], selected: [local.options[0]?.value],
}); });
} else if (field.type === "single-option" && value) {
arg.opt_set_value({
fm,
name: field.name,
type: field.type,
options: local.options,
selected: [value],
});
} }
local.loaded = true; local.loaded = true;
@ -60,7 +70,7 @@ export const TypeDropdown: FC<{
}); });
} else { } else {
local.loaded = true; local.loaded = true;
local.options = []; local.options = Array.isArray(options) ? options : [] as any;
local.render(); local.render();
} }
} }

View File

@ -40,11 +40,11 @@ export const FieldMoney: FC<{
type={"number"} type={"number"}
onClick={() => {}} onClick={() => {}}
onChange={(ev) => { onChange={(ev) => {
fm.data[field.name] = ev.currentTarget.value; fm.data[field.name] = Number(ev.currentTarget.value);
fm.render(); fm.render();
if (field.on_change) { if (field.on_change) {
field.on_change({ field.on_change({
value: fm.data[field.name], value: Number(fm.data[field.name]),
name: field.name, name: field.name,
fm, fm,
}); });

View File

@ -0,0 +1,76 @@
import { useLocal } from "@/utils/use-local";
import get from "lodash.get";
import { FC, useEffect } from "react";
import { FMLocal, FieldLocal, FieldProp } from "../../typings";
export const FieldSingleCheckbox: FC<{
field: FieldLocal;
fm: FMLocal;
arg: FieldProp;
}> = ({ field, fm, arg }) => {
const local = useLocal({
list: [] as any[],
});
useEffect(() => {
const callback = (res: any[]) => {
if (Array.isArray(res)) {
const list: any = res.map((e: any) => {
return {
label: arg.opt_get_label(e),
value: e.value,
};
});
local.list = list;
} else {
local.list = [];
}
local.render();
};
const res = arg.on_load({});
if (res instanceof Promise) res.then(callback);
else callback(res);
}, []);
let value: boolean =fm.data[field.name];
return (
<>
<div className={cx("c-flex c-items-center c-w-full c-flex-row")}>
<div className={cx(`c-flex c-flex-col c-space-y-1 c-p-0.5`)}>
<div
onClick={() => {
fm.data[field.name] = !value;
fm.render();
}}
className="c-flex c-flex-row c-space-x-1 cursor-pointer c-items-center rounded-full p-0.5"
>
{value ? (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
className="c-fill-sky-500"
>
<path
fill="currentColor"
d="m10.6 14.092l-2.496-2.496q-.14-.14-.344-.15q-.204-.01-.364.15t-.16.354q0 .194.16.354l2.639 2.638q.242.243.565.243q.323 0 .565-.243l5.477-5.477q.14-.14.15-.344q.01-.204-.15-.363q-.16-.16-.354-.16q-.194 0-.353.16L10.6 14.092ZM5.615 20q-.69 0-1.152-.462Q4 19.075 4 18.385V5.615q0-.69.463-1.152Q4.925 4 5.615 4h12.77q.69 0 1.152.463q.463.462.463 1.152v12.77q0 .69-.462 1.152q-.463.463-1.153.463H5.615Z"
/>
</svg>
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M5.615 20q-.69 0-1.152-.462Q4 19.075 4 18.385V5.615q0-.69.463-1.152Q4.925 4 5.615 4h12.77q.69 0 1.152.463q.463.462.463 1.152v12.77q0 .69-.462 1.152q-.463.463-1.153.463H5.615Zm0-1h12.77q.23 0 .423-.192q.192-.193.192-.423V5.615q0-.23-.192-.423Q18.615 5 18.385 5H5.615q-.23 0-.423.192Q5 5.385 5 5.615v12.77q0 .23.192.423q.193.192.423.192Z"
/>
</svg>
)}
</div>
</div>
</div>
</>
);
};

View File

@ -4,6 +4,7 @@ import { FieldButton } from "./TypeButton";
import { TypeDropdown } from "./TypeDropdown"; import { TypeDropdown } from "./TypeDropdown";
import { FieldRadio } from "./TypeRadio"; import { FieldRadio } from "./TypeRadio";
import { FieldToggle } from "./TypeToggle"; import { FieldToggle } from "./TypeToggle";
import { FieldSingleCheckbox } from "./TypeSingleCheckbox";
export const SingleOption: FC<{ export const SingleOption: FC<{
field: FieldLocal; field: FieldLocal;
@ -20,7 +21,9 @@ export const SingleOption: FC<{
<FieldButton arg={arg} field={field} fm={fm} /> <FieldButton arg={arg} field={field} fm={fm} />
) : arg.sub_type === "radio" ? ( ) : arg.sub_type === "radio" ? (
<FieldRadio arg={arg} field={field} fm={fm} /> <FieldRadio arg={arg} field={field} fm={fm} />
) : ( ) : arg.sub_type === "checkbox" ? (
<FieldSingleCheckbox arg={arg} field={field} fm={fm} />
) :(
<></> <></>
)} )}
</> </>

View File

@ -11,7 +11,9 @@ export const FieldToggle: FC<{
const local = useLocal({ const local = useLocal({
list: [] as any[], list: [] as any[],
value: [] as any[], value: [] as any[],
ref: null as any,
}); });
useEffect(() => { useEffect(() => {
const callback = (res: any[]) => { const callback = (res: any[]) => {
local.list = res; local.list = res;
@ -30,12 +32,21 @@ export const FieldToggle: FC<{
options: local.list, options: local.list,
type: field.type, type: field.type,
}); });
let checked = local.value.indexOf(value) > 0 ? true : false; let checked =
typeof value === "boolean"
? value
: local.value.indexOf(value) > 0
? true
: false;
return ( return (
<> <>
<div className={cx("c-flex c-items-center c-justify-start c-w-full")}> <div className={cx("c-flex c-items-center c-justify-start c-w-full")}>
<label className="c-flex c-items-center c-cursor-pointer"> <label className="c-flex c-items-center c-cursor-pointer" onClick={(e) => {
if(local.ref){
local.ref.click();
}
}}>
<div className="c-mr-3 c-text-gray-700 c-font-medium"> <div className="c-mr-3 c-text-gray-700 c-font-medium">
{get(local, "list[0].label")} {get(local, "list[0].label")}
</div> </div>
@ -53,18 +64,18 @@ export const FieldToggle: FC<{
)} )}
> >
<input <input
ref={(ref) => (local.ref = ref)}
type="checkbox" type="checkbox"
id="toggleB" id="toggleB"
checked={checked} checked={checked}
className="c-sr-only" className="c-sr-only"
onChange={(e) => { onChange={(e) => {
const check = e.target.checked; const check = e.target.checked;
if (check) { if (check) {
arg.opt_set_value({ arg.opt_set_value({
fm, fm,
name: field.name, name: field.name,
selected: [local.list[1]?.value], selected: [local.list[0]?.value],
options: local.list, options: local.list,
type: field.type, type: field.type,
}); });
@ -72,7 +83,7 @@ export const FieldToggle: FC<{
arg.opt_set_value({ arg.opt_set_value({
fm, fm,
name: field.name, name: field.name,
selected: [local.list[0]?.value], selected: [local.list[1]?.value],
options: local.list, options: local.list,
type: field.type, type: field.type,
}); });

View File

@ -380,38 +380,82 @@ export const TableList: FC<TableListProp> = ({
for (const child of childs) { for (const child of childs) {
let key = getProp(child, "name", {}); let key = getProp(child, "name", {});
const name = getProp(child, "title", ""); const name = getProp(child, "title", "");
const type = getProp(child, "type", "");
const width = parseInt(getProp(child, "width", {})); const width = parseInt(getProp(child, "width", {}));
if (type === "checkbox") {
const on_click = getProp(child, "opt__on_click", "");
console.log({ on_click });
columns.push({
key,
name,
width: 35,
minWidth: 45,
resizable: true,
sortable: true,
frozen: true,
renderHeaderCell(props) {
return (
<div>
<CheckboxList value={false} on_click={on_click} />
</div>
);
},
renderCell(props) {
if (typeof render_col === "function")
return render_col({
props,
tbl: local,
child,
});
columns.push({ return (
key, <PassProp
name, idx={props.rowIdx}
width: width > 0 ? width : undefined, row={props.row}
resizable: true, col={{
sortable: true, name: props.column.key,
renderCell(props) { value: props.row[props.column.key],
if (typeof render_col === "function") depth: props.row.__depth || 0,
return render_col({ }}
props, rows={local.data}
tbl: local, >
child, {child}
}); </PassProp>
);
},
});
} else {
columns.push({
key,
name,
width: width > 0 ? width : undefined,
resizable: true,
sortable: true,
renderCell(props) {
if (typeof render_col === "function")
return render_col({
props,
tbl: local,
child,
});
return ( return (
<PassProp <PassProp
idx={props.rowIdx} idx={props.rowIdx}
row={props.row} row={props.row}
col={{ col={{
name: props.column.key, name: props.column.key,
value: props.row[props.column.key], value: props.row[props.column.key],
depth: props.row.__depth || 0, depth: props.row.__depth || 0,
}} }}
rows={local.data} rows={local.data}
> >
{child} {child}
</PassProp> </PassProp>
); );
}, },
}); });
}
} }
if (mode === "list") { if (mode === "list") {
@ -690,7 +734,55 @@ export const TableList: FC<TableListProp> = ({
} else { } else {
} }
}; };
const CheckboxList: FC<{
on_click: (e: any) => void;
value?: boolean;
}> = ({ value, on_click }) => {
const local = useLocal({
value: false as boolean,
});
return (
<div className={cx("c-flex c-items-center c-w-full c-flex-row")}>
<div className={cx(`c-flex c-flex-col c-space-y-1 c-p-0.5`)}>
<div
onClick={() => {
local.value = !local.value;
on_click(local.value);
local.render();
}}
className="c-flex c-flex-row c-space-x-1 cursor-pointer c-items-center rounded-full p-0.5"
>
{local.value ? (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
className="c-fill-sky-500"
>
<path
fill="currentColor"
d="m10.6 14.092l-2.496-2.496q-.14-.14-.344-.15q-.204-.01-.364.15t-.16.354q0 .194.16.354l2.639 2.638q.242.243.565.243q.323 0 .565-.243l5.477-5.477q.14-.14.15-.344q.01-.204-.15-.363q-.16-.16-.354-.16q-.194 0-.353.16L10.6 14.092ZM5.615 20q-.69 0-1.152-.462Q4 19.075 4 18.385V5.615q0-.69.463-1.152Q4.925 4 5.615 4h12.77q.69 0 1.152.463q.463.462.463 1.152v12.77q0 .69-.462 1.152q-.463.463-1.153.463H5.615Z"
/>
</svg>
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M5.615 20q-.69 0-1.152-.462Q4 19.075 4 18.385V5.615q0-.69.463-1.152Q4.925 4 5.615 4h12.77q.69 0 1.152.463q.463.462.463 1.152v12.77q0 .69-.462 1.152q-.463.463-1.153.463H5.615Zm0-1h12.77q.23 0 .423-.192q.192-.193.192-.423V5.615q0-.23-.192-.423Q18.615 5 18.385 5H5.615q-.23 0-.423.192Q5 5.385 5 5.615v12.77q0 .23.192.423q.193.192.423.192Z"
/>
</svg>
)}
</div>
</div>
</div>
);
};
const genRows = (total: number) => { const genRows = (total: number) => {
const result = [] as any[]; const result = [] as any[];
for (let i = 0; i < total; i++) { for (let i = 0; i < total; i++) {

View File

@ -50,13 +50,8 @@ export const gen_prop_fields = async (gen_table: string, depth?: number) => {
id_site = window.location.hostname; id_site = window.location.hostname;
} }
const schema = getSchemaOnStorage(id_site, gen_table); const schema = getSchemaOnStorage(id_site, gen_table);
if (!schema) { if (!schema) {
// const result: { console.log({depth})
// label: string;
// value: string;
// options?: any[];
// checked?: boolean;
// }[] = [];
const result = await load_layer_schema( const result = await load_layer_schema(
typeof depth === "undefined" ? 3 : depth, typeof depth === "undefined" ? 3 : depth,
{}, {},
@ -153,8 +148,10 @@ export const gen_prop_fields = async (gen_table: string, depth?: number) => {
} catch (e: any) { } catch (e: any) {
console.error(e.message); console.error(e.message);
} }
console.log({result})
return result; return result;
} else { } else {
console.log({schema})
return schema; return schema;
} }
}; };
@ -172,6 +169,7 @@ const get_layer = async (
table: string table: string
) => { ) => {
const { cols, rels } = await load_single(table); const { cols, rels } = await load_single(table);
console.log({cols, rels , table})
const options = []; const options = [];
if (cols) { if (cols) {
for (const [k, v] of Object.entries(cols)) { for (const [k, v] of Object.entries(cols)) {