From 0a02fc3c0eadf929a23784ae9b824037b998da5e Mon Sep 17 00:00:00 2001 From: rizky Date: Mon, 25 Mar 2024 19:49:50 -0700 Subject: [PATCH] wip fix --- comps/form/Dropdown/relation.tsx | 78 +- comps/form/Form.tsx | 101 +- comps/form/utils/utils.ts | 1 + comps/list/Table.tsx | 38 +- comps/mst/MDAction.tsx | 51 + comps/mst/MDTitle.tsx | 44 + comps/mst/MasterDetail.tsx | 163 ++ comps/mst/type.ts | 59 + comps/ui/sonner.tsx | 29 + comps/ui/tabs.tsx | 38 +- gen/{ => gen_form}/gen_form.ts | 19 +- gen/gen_form/new_field.ts | 6 +- gen/gen_form/on_load.ts | 12 +- gen/gen_form/on_submit.ts | 2 +- gen/gen_form/type.ts | 6 - gen/gen_md/form_before_load.ts | 46 + gen/gen_md/gen_detail.ts | 2887 ++++++++++++++++++++++++++++++ gen/gen_md/gen_header.ts | 223 +++ gen/gen_md/gen_master.ts | 302 ++++ gen/gen_md/gen_md.ts | 97 + gen/gen_table/columns.ts | 26 + gen/gen_table/gen_table.ts | 64 + gen/gen_table/new_field.ts | 89 + gen/gen_table/on_load.ts | 43 + gen/utils.ts | 20 + 25 files changed, 4361 insertions(+), 83 deletions(-) create mode 100755 comps/mst/MDAction.tsx create mode 100755 comps/mst/MDTitle.tsx create mode 100755 comps/mst/MasterDetail.tsx create mode 100755 comps/mst/type.ts create mode 100755 comps/ui/sonner.tsx rename gen/{ => gen_form}/gen_form.ts (82%) delete mode 100755 gen/gen_form/type.ts create mode 100755 gen/gen_md/form_before_load.ts create mode 100755 gen/gen_md/gen_detail.ts create mode 100755 gen/gen_md/gen_header.ts create mode 100755 gen/gen_md/gen_master.ts create mode 100755 gen/gen_md/gen_md.ts create mode 100755 gen/gen_table/columns.ts create mode 100755 gen/gen_table/gen_table.ts create mode 100755 gen/gen_table/new_field.ts create mode 100755 gen/gen_table/on_load.ts create mode 100755 gen/utils.ts diff --git a/comps/form/Dropdown/relation.tsx b/comps/form/Dropdown/relation.tsx index eff986c..7e4aef8 100755 --- a/comps/form/Dropdown/relation.tsx +++ b/comps/form/Dropdown/relation.tsx @@ -40,32 +40,39 @@ export const Relation: FC = ({ if (form) { local.status = "loading"; local.render(); - const table_fn = (db as any)[relation.table]; - const select = {} as any; - local.pk_field = ""; - for (const f of relation.fields) { - if (f.startsWith("::")) { - select[f.substring(2)] = true; - local.pk_field = f.substring(2); - } else { - select[f] = true; - } - } - let q = {}; - if (typeof relation.query === "function") { - q = await relation.query(); - } - - const list = await table_fn.findMany({ select, ...q }); - if (Array.isArray(list)) { - local.list = list.map((item: any) => { - let label = []; - for (const [k, v] of Object.entries(item)) { - if (k !== local.pk_field) label.push(v); + if (form.cache[name]) { + local.pk_field = form.cache[name].pk_field; + local.list = form.cache[name].list; + } else { + const table_fn = (db as any)[relation.table]; + const select = {} as any; + local.pk_field = ""; + for (const f of relation.fields) { + if (f.startsWith("::")) { + select[f.substring(2)] = true; + local.pk_field = f.substring(2); + } else { + select[f] = true; } - return { value: item[local.pk_field], label: label.join(" - ") }; - }); + } + let q = {}; + + if (typeof relation.query === "function") { + q = await relation.query(); + } + + const list = await table_fn.findMany({ select, ...q }); + if (Array.isArray(list)) { + local.list = list.map((item: any) => { + let label = []; + for (const [k, v] of Object.entries(item)) { + if (k !== local.pk_field) label.push(v); + } + return { value: item[local.pk_field], label: label.join(" - ") }; + }); + } + form.cache[name] = { list: local.list, pk_field: local.pk_field }; } const found = local.list.find((e) => { @@ -109,9 +116,10 @@ export const Relation: FC = ({ content={
@@ -124,15 +132,25 @@ export const Relation: FC = ({ )} {local.status === "ready" && ( - <> +
{filtered.map((item, idx) => { + let is_active = false; + if (typeof value === "object") { + const c = (value as any).connect; + if (c) { + is_active = item.value === c[local.pk_field]; + } + } else { + is_active = item.value === value; + } + return (
0 && "c-border-t", @@ -149,11 +167,11 @@ export const Relation: FC = ({ } }} > - {item.label} + {item.label || "-"}
); })} - +
)}
} @@ -197,7 +215,7 @@ export const Relation: FC = ({ /> {!local.open && (
- {local.label} + {local.label || "-"}
)} diff --git a/comps/form/Form.tsx b/comps/form/Form.tsx index f106733..49f7fcd 100755 --- a/comps/form/Form.tsx +++ b/comps/form/Form.tsx @@ -1,16 +1,22 @@ import { Form as FForm } from "@/comps/ui/form"; +import { Toaster } from "@/comps/ui/sonner"; import { useLocal } from "@/utils/use-local"; import { FC } from "react"; +import { createPortal } from "react-dom"; import { useForm } from "react-hook-form"; +import { toast } from "sonner"; import { FormHook } from "./utils/utils"; +import { AlertTriangle, Check, Loader2 } from "lucide-react"; +import { cn } from "@/utils"; export const Form: FC<{ on_init: (arg: { submit: any }) => any; on_load: () => any; - on_submit: (arg: { form: any; error: any }) => any; + on_submit: (arg: { form: any; error: any }) => Promise; body: any; form: FormHook; PassProp: any; + cache: () => any; layout: "auto" | "1-col" | "2-col"; }> = ({ on_init, @@ -19,10 +25,11 @@ export const Form: FC<{ form, PassProp, on_submit, + cache, layout: _layout, }) => { const form_hook = useForm({ - defaultValues: on_load, + defaultValues: {}, }); const local = useLocal({ @@ -33,6 +40,13 @@ export const Form: FC<{ }); form.hook = form_hook; + if (!form.cache && typeof cache === "function") { + try { + form.cache = cache() || {}; + } catch (e) {} + } + if (!form.cache) form.cache = {}; + if (!form.validation) { form.validation = {}; } @@ -45,7 +59,19 @@ export const Form: FC<{ const submit = () => { clearTimeout(local.submit_timeout); - local.submit_timeout = setTimeout(() => { + local.submit_timeout = setTimeout(async () => { + toast.loading( + <> + + Saving ... + , + { + dismissible: true, + className: css` + background: #e4f7ff; + `, + } + ); const data = form.hook.getValues(); form.hook.clearErrors(); for (const [k, v] of Object.entries(form.validation)) { @@ -61,22 +87,88 @@ export const Form: FC<{ } } - on_submit({ + await on_submit({ form: data, error: form.hook.formState.errors, }); + toast.dismiss(); + + if (Object.keys(form.hook.formState.errors).length > 0) { + toast.error( +
+ + Save Failed, please correct{" "} + {Object.keys(form.hook.formState.errors).length} errors. +
, + { + dismissible: true, + className: css` + background: #ffecec; + border: 2px solid red; + `, + } + ); + } else { + toast.success( +
+ + Data saved +
, + { + className: css` + background: #e4f5ff; + border: 2px solid blue; + `, + } + ); + } }, 300); }; if (!local.init) { local.init = true; on_init({ submit }); + const res = on_load(); + const loaded = (values: any) => { + setTimeout(() => { + toast.dismiss(); + }); + if (!!values) { + for (const [k, v] of Object.entries(values)) { + form.hook.setValue(k, v); + } + } + local.render(); + }; + if (res instanceof Promise) { + setTimeout(() => { + if (!isEditor) { + toast.loading( + <> + + Loading data... + + ); + } + res.then(loaded); + }); + } else { + loaded(res); + } } form.submit = submit; + if (document.getElementsByClassName("prasi-toaster").length === 0) { + const elemDiv = document.createElement("div"); + elemDiv.className = "prasi-toaster"; + document.body.appendChild(elemDiv); + } + const toaster_el = document.getElementsByClassName("prasi-toaster")[0]; + return ( + {toaster_el && createPortal(, toaster_el)}
{ - console.log("on submit"); e.preventDefault(); e.stopPropagation(); submit(); diff --git a/comps/form/utils/utils.ts b/comps/form/utils/utils.ts index 05593a8..8c49a6b 100755 --- a/comps/form/utils/utils.ts +++ b/comps/form/utils/utils.ts @@ -24,6 +24,7 @@ export type FormHook = { ref: HTMLFormElement; submit: any; label: Record; + cache: any; validation: Record; render: () => void; }; diff --git a/comps/list/Table.tsx b/comps/list/Table.tsx index 46c6fac..1800ee5 100755 --- a/comps/list/Table.tsx +++ b/comps/list/Table.tsx @@ -1,15 +1,26 @@ import { useLocal } from "@/utils/use-local"; import { FC, useEffect } from "react"; -import DataGrid, { ColumnOrColumnGroup, SortColumn } from "react-data-grid"; +import DataGrid, { + ColumnOrColumnGroup, + Row, + SortColumn, +} from "react-data-grid"; import "react-data-grid/lib/styles.css"; import { Skeleton } from "../ui/skeleton"; +type OnRowClick = { + row: any; + rows: any[]; + idx: any; + event: React.MouseEvent; +}; export const Table: FC<{ columns: () => Promise[]>; on_load: () => Promise; child: any; PassProp: any; -}> = ({ columns, on_load, child, PassProp }) => { + row_click: (arg: OnRowClick) => void; +}> = ({ columns, on_load, child, PassProp, row_click }) => { const local = useLocal({ loading: false, data: undefined as unknown as any[], @@ -56,6 +67,7 @@ export const Table: FC<{ return ( []; data?: any[]; render: () => void; -}> = ({ columns, data, render }) => { + row_click: (arg: OnRowClick) => void; +}> = ({ columns, data, render, row_click }) => { const local = useLocal({ width: 0, height: 0, @@ -134,7 +147,6 @@ const TableInternal: FC<{ > { local.sort = []; @@ -160,6 +172,24 @@ const TableInternal: FC<{ typeof data === "undefined" ? undefined : { + renderRow(key, props) { + return ( + { + if (typeof row_click === "function") { + row_click({ + event: ev, + idx: props.rowIdx, + row: props.row, + rows: data, + }); + } + }} + /> + ); + }, noRowsFallback: (
diff --git a/comps/mst/MDAction.tsx b/comps/mst/MDAction.tsx new file mode 100755 index 0000000..6efb8f9 --- /dev/null +++ b/comps/mst/MDAction.tsx @@ -0,0 +1,51 @@ +import { FC } from "react"; +import { MasterDetailConfig } from "./type"; +import { Button } from "../ui/button"; + +export const MDAction: FC<{ md: MasterDetailConfig }> = ({ md }) => { + return ( +
+ {md.ui.actions.length > 0 && + md.ui.actions.map((e, idx) => { + return ( + + ); + })} +
+ ); +}; diff --git a/comps/mst/MDTitle.tsx b/comps/mst/MDTitle.tsx new file mode 100755 index 0000000..ae797f7 --- /dev/null +++ b/comps/mst/MDTitle.tsx @@ -0,0 +1,44 @@ +import { FC } from "react"; +import { MasterDetailConfig } from "./type"; + +export const MDTitle: FC<{ md: MasterDetailConfig }> = ({ md }) => { + return ( +
+ {md.ui.breadcrumb.length > 0 + ? md.ui.breadcrumb.map((e, idx) => { + let label = (typeof e === "object" ? e?.[0] : e) || "-"; + let url = typeof e === "object" ? e?.[1] : null; + + return ( + <> + {idx > 0 && ( + + / + + )} + + { + if (url === "") { + md.ui.actions = [...md.ui.default_actions]; + md.ui.breadcrumb = []; + md.ui.back = false; + md.selected = null; + md.render(); + } + }} + className={cx( + typeof url === "string" + ? "c-cursor-pointer hover:c-underline" + : "c-text-gray-500" + )} + > + {label} + + + ); + }) + : md.ui.title} +
+ ); +}; diff --git a/comps/mst/MasterDetail.tsx b/comps/mst/MasterDetail.tsx new file mode 100755 index 0000000..2449af5 --- /dev/null +++ b/comps/mst/MasterDetail.tsx @@ -0,0 +1,163 @@ +import { useLocal } from "@/utils/use-local"; +import get from "lodash.get"; +import { FC, useEffect } from "react"; +import { + MasterDetailConfig, + MasterDetailLocal, + MasterDetailProp, +} from "./type"; +import { Tab } from "../custom/Tab"; +import { Tabs, TabsList, TabsTrigger } from "../ui/tabs"; + +export const MasterDetail: FC = (props) => { + const { header, PassProp, master, detail, mode, title, actions } = props; + const md = useLocal({ + mode, + selected: null, + active_tab: "", + ui: { + back: false, + title: title, + breadcrumb: [], + default_actions: null as any, + actions: null as any, + }, + cache_internal: {}, + cache: null as any, + }); + + if (!md.ui.actions) { + md.ui.actions = actions(md); + md.ui.default_actions = actions(md); + } + + if (!md.cache) { + md.cache = (name: string, opt?: { reset: boolean }) => { + if (!md.cache_internal[name] || opt?.reset) md.cache_internal[name] = {}; + return md.cache_internal[name]; + }; + } + + if (isEditor) { + useEffect(() => { + md.ui.title = title; + md.render(); + }, [title]); + } + + useEffect(() => { + let back = false; + if (md.selected && md.mode === "breadcrumb") { + back = true; + } + if (back !== md.ui.back) { + md.ui.back = back; + md.render(); + } + }, [md.selected]); + + return ( +
+ {header} + +
+ ); +}; + +const BreadcrumbMode: FC<{ + props: MasterDetailProp; + md: MasterDetailConfig; +}> = ({ props, md }) => { + return ( +
+
+ {props.master} +
+ {md.selected && } +
+ ); +}; + +const Detail: FC<{ + props: MasterDetailProp; + md: MasterDetailConfig; +}> = ({ props, md }) => { + const childs = get( + props.detail, + "props.meta.item.component.props.detail.content.childs" + ); + + let idx = childs.findIndex( + (e: any) => e.name.toLowerCase() === md.active_tab.toLowerCase() + ); + if (idx < 0) { + idx = 0; + md.active_tab = childs[idx].name; + setTimeout(md.render); + } + const content = childs[idx]; + + return ( + <> + {childs.length > 1 && ( + + + {childs.map((e: { name: string }) => { + return ( + { + md.active_tab = e.name; + md.render(); + }} + overrideClassName + > +
+
+ {e.name} +
+
+
+ ); + })} +
+
+ )} + {content} + + ); +}; diff --git a/comps/mst/type.ts b/comps/mst/type.ts new file mode 100755 index 0000000..f981f45 --- /dev/null +++ b/comps/mst/type.ts @@ -0,0 +1,59 @@ +import { ReactElement, ReactNode } from "react"; + +export type MasterDetailProp = { + header: any; + PassProp: any; + master: any; + detail: any; + mode: "breadcrumb" | "vertical" | "horizontal"; + title: string; + actions: (md: any) => MasterDetailAction[]; +}; + +type MasterDetailAction = { + label: string; + onClick?: () => Promise; + type?: "default" | "ghost" | "secondary" | "destructive"; + icon?: string; +}; + +export type MasterDetailLocal = { + mode: MasterDetailProp["mode"]; + selected: null | Record; + active_tab: string; + ui: { + back: boolean; + title: string; + breadcrumb: ([string, string] | string)[]; + default_actions: MasterDetailAction[]; + actions: MasterDetailAction[]; + }; + cache: (name: string, opt?: { reset: boolean }) => any; +}; + +export type MasterDetailConfig = MasterDetailLocal & { render: () => void }; + +const action_type = `{ + label: string; + onClick?: () => Promise; + type?: "default" | "ghost" | "secondary" | "destructive"; + icon?: string; +}`; + +export const master_detail_typings = { + md: `{ + mode: "breadcrumb" | "vertical" | "horizontal"; + selected: null | Record; + active_tab: string; + render: () => void; + ui: { + back: boolean; + title: string; + breadcrumb: ([string, string] | string)[]; + default_actions: ${action_type}[]; + actions: ${action_type}[]; + }; + cache: (name: string, opt?: { reset: boolean }) => any; + }`, + action_type, +}; diff --git a/comps/ui/sonner.tsx b/comps/ui/sonner.tsx new file mode 100755 index 0000000..1a922be --- /dev/null +++ b/comps/ui/sonner.tsx @@ -0,0 +1,29 @@ +import { useTheme } from "next-themes" +import { Toaster as Sonner } from "sonner" + +type ToasterProps = React.ComponentProps + +const Toaster = ({ ...props }: ToasterProps) => { + const { theme = "system" } = useTheme() + + return ( + + ) +} + +export { Toaster } diff --git a/comps/ui/tabs.tsx b/comps/ui/tabs.tsx index 2db4fce..67063d9 100755 --- a/comps/ui/tabs.tsx +++ b/comps/ui/tabs.tsx @@ -1,39 +1,47 @@ -import * as React from "react" -import * as TabsPrimitive from "@radix-ui/react-tabs" +import * as React from "react"; +import * as TabsPrimitive from "@radix-ui/react-tabs"; -import { cn } from "@/utils" +import { cn } from "@/utils"; -const Tabs = TabsPrimitive.Root +const Tabs = TabsPrimitive.Root; const TabsList = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef + React.ComponentPropsWithoutRef & { + overrideClassName?: boolean; + } >(({ className, ...props }, ref) => ( -)) -TabsList.displayName = TabsPrimitive.List.displayName +)); +TabsList.displayName = TabsPrimitive.List.displayName; const TabsTrigger = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef + React.ComponentPropsWithoutRef & { + overrideClassName?: boolean; + } >(({ className, ...props }, ref) => ( -)) -TabsTrigger.displayName = TabsPrimitive.Trigger.displayName +)); +TabsTrigger.displayName = TabsPrimitive.Trigger.displayName; const TabsContent = React.forwardRef< React.ElementRef, @@ -47,7 +55,7 @@ const TabsContent = React.forwardRef< )} {...props} /> -)) -TabsContent.displayName = TabsPrimitive.Content.displayName +)); +TabsContent.displayName = TabsPrimitive.Content.displayName; -export { Tabs, TabsList, TabsTrigger, TabsContent } +export { Tabs, TabsList, TabsTrigger, TabsContent }; diff --git a/gen/gen_form.ts b/gen/gen_form/gen_form.ts similarity index 82% rename from gen/gen_form.ts rename to gen/gen_form/gen_form.ts index 686374e..97355ef 100755 --- a/gen/gen_form.ts +++ b/gen/gen_form/gen_form.ts @@ -1,9 +1,8 @@ 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"; +import { GFCol as Col, formatName } from "../utils"; +import { NewFieldArg, newField } from "./new_field"; +import { on_load } from "./on_load"; +import { on_submit } from "./on_submit"; export const gen_form = (modify: (data: any) => void, data: any) => { const mode = JSON.parse(data.gen_mode.value) as ( @@ -59,7 +58,6 @@ export const gen_form = (modify: (data: any) => void, data: any) => { select[col.name] = true; } } - console.log(new_fields); const result: any = {}; if (pk) { @@ -76,7 +74,6 @@ export const gen_form = (modify: (data: any) => void, data: any) => { result["body"] = data["body"]; const childs = get(result, "body.content.childs"); if (Array.isArray(childs)) { - result.body.content.childs = new_fields.map(newField); } } @@ -84,11 +81,3 @@ export const gen_form = (modify: (data: any) => void, data: any) => { alert("Prop Generated!"); }; - -const formatName = (name: string) => { - return name - .split("_") - .filter((e) => e.length > 1) - .map((e) => capitalize(e)) - .join(" "); -}; diff --git a/gen/gen_form/new_field.ts b/gen/gen_form/new_field.ts index ca3d623..c742096 100755 --- a/gen/gen_form/new_field.ts +++ b/gen/gen_form/new_field.ts @@ -265,10 +265,8 @@ export const newField = (arg: NewFieldArg) => { 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', + value: "async () => {\n return {\n };\n}", + valueBuilt: " async () => {\n return {\n };\n};\n", meta: { type: "text", }, diff --git a/gen/gen_form/on_load.ts b/gen/gen_form/on_load.ts index 88f3c70..133c473 100755 --- a/gen/gen_form/on_load.ts +++ b/gen/gen_form/on_load.ts @@ -1,22 +1,27 @@ -import { GFCol } from "./type"; +import { GFCol } from "../utils"; export const on_load = ({ pk, table, select, pks, + opt, }: { pk: GFCol; table: string; select: any; pks: Record; + opt?: { + before_load: string; + }; }) => { return `\ async (opt) => { if (isEditor) return {}; let id = ${pk.type === "int" ? "parseInt(params.id)" : "params.id"}; - + ${opt?.before_load} + if (id){ const item = await db.${table}.findFirst({ where: { @@ -30,7 +35,8 @@ async (opt) => { .map(([k, v]) => { return `\ if (k === "${k}") { - item[k] = { connect: { ${v}: v["${v}"] } } as any; + if (v?.["${v}"]) item[k] = { connect: { ${v}: v?.["${v}"] } } as any; + else delete item[k]; }`; }) .join("\n")} diff --git a/gen/gen_form/on_submit.ts b/gen/gen_form/on_submit.ts index d6df955..f087bba 100755 --- a/gen/gen_form/on_submit.ts +++ b/gen/gen_form/on_submit.ts @@ -1,4 +1,4 @@ -import { GFCol } from "./type"; +import { GFCol } from "../utils"; export const on_submit = ({ pk, diff --git a/gen/gen_form/type.ts b/gen/gen_form/type.ts deleted file mode 100755 index 6c1a45b..0000000 --- a/gen/gen_form/type.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type GFCol = { - name: string; - type: string; - is_pk: boolean; - optional: boolean; -}; diff --git a/gen/gen_md/form_before_load.ts b/gen/gen_md/form_before_load.ts new file mode 100755 index 0000000..5ffa00b --- /dev/null +++ b/gen/gen_md/form_before_load.ts @@ -0,0 +1,46 @@ +export const form_before_load = (pk: string, title: string, name: string) => { + return ` + const after_load = (item: any) => { + const set_actions = () => + (md.ui.actions = [ + { + label: "Delete", + type: "destructive", + onClick: async () => { + if (confirm("Are you sure ?")) { + md.ui.actions = [{ label: "Deleting...", type: "ghost" }]; + md.render(); + + await db.m_aset.delete({ where: { ${pk}: item.${pk} } }); + + setTimeout(() => { + md.ui.actions = [...md.ui.default_actions]; + md.ui.breadcrumb = []; + md.ui.back = false; + md.selected = null; + md.render(); + }); + } + }, + icon: \`\`, + }, + { + label: "Save", + onClick: async () => { + md.ui.actions = [{ label: "Saving...", type: "ghost" }]; + md.render(); + await md.cache("form")._submit(); + setTimeout(() => { + set_actions(); + md.render(); + }, 500); + }, + icon: \`\`, + }, + ]); + set_actions(); + md.ui.breadcrumb = [[${title}, ""], item?.nama_aset_komersial]; + md.render(); + }; +`; +}; diff --git a/gen/gen_md/gen_detail.ts b/gen/gen_md/gen_detail.ts new file mode 100755 index 0000000..828debd --- /dev/null +++ b/gen/gen_md/gen_detail.ts @@ -0,0 +1,2887 @@ +import { createId } from "@paralleldrive/cuid2"; + +export const gen_detail = () => { + const res = { + id: createId(), + name: "prop_3", + type: "item", + dim: { + w: "full", + h: "full", + }, + childs: [ + { + id: createId(), + name: "detail", + type: "item", + dim: { + w: "full", + h: "full", + }, + childs: [ + { + id: createId(), + adv: { + js: '
\n \n {children}\n \n
', + css: "", + jsBuilt: + 'render(/* @__PURE__ */ React.createElement("div", { ...props }, /* @__PURE__ */ React.createElement(\n Local,\n {\n name: "form",\n value: {\n hook: null\n }\n },\n children\n)));\n', + }, + dim: { + h: "full", + w: "full", + }, + name: "form", + type: "item", + childs: [ + { + id: createId(), + adv: { + css: "", + }, + dim: { + h: "full", + w: "full", + }, + name: "jsx: body", + type: "item", + childs: [ + { + id: createId(), + adv: { + css: "", + }, + dim: { + h: "full", + w: "full", + }, + name: "field", + type: "item", + childs: [], + script: { + props: { + name: { + value: '"hello"', + }, + type: { + value: ' "text";\n', + }, + label: { + value: '"hello"', + }, + }, + }, + component: { + id: "32550d01-42a3-4b15-a04a-2c2d5c3c8e67", + props: { + fill: { + idx: 11, + meta: { + type: "text", + }, + name: "prop_11", + type: "string", + value: "`Haha`", + valueBuilt: "`Haha`", + }, + name: { + idx: 1, + meta: { + type: "text", + }, + name: "prop_1", + type: "string", + value: "`field_name`", + valueBuilt: "`field_name`", + }, + type: { + idx: 3, + meta: { + type: "option", + options: + '[\n "text", "buttons", "date", "datetime"\n]', + optionsBuilt: + ' [\n "text",\n "buttons",\n "date",\n "datetime"\n];\n', + }, + name: "prop_3", + type: "string", + value: '"text"', + valueBuilt: '"text"', + }, + label: { + idx: 1, + meta: { + type: "text", + }, + name: "prop_1", + type: "string", + value: "`Name`", + valueBuilt: "`Name`", + }, + title: { + idx: 7, + meta: { + type: "text", + }, + name: "prop_7", + type: "string", + value: '"hello"', + valueBuilt: ' "hello";\n', + }, + custom: { + idx: 5, + 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: '"y"', + valueBuilt: '"y"', + }, + options: { + idx: 5, + 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}', + valueBuilt: + ' async () => {\n return [\n {\n value: "sample1",\n label: "sample1"\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: '"n"', + valueBuilt: ' "n";\n', + }, + label_alt: { + idx: 2, + meta: { + type: "text", + }, + name: "prop_10", + type: "string", + value: '""', + valueBuilt: ' "";\n', + }, + on_change: { + idx: 11, + meta: { + type: "text", + }, + name: "prop_11", + type: "string", + value: "({ value }) => {}", + valueBuilt: " ({ value }) => {\n};\n", + }, + placeholder: { + idx: 3, + meta: { + type: "text", + }, + name: "prop_11", + type: "string", + value: '""', + visible: + '["text", "number", "password"].includes(type)', + valueBuilt: ' "";\n', + }, + slider_options: { + 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}', + 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', + }, + rel_fields: { + idx: 11, + name: "prop_11", + type: "string", + value: "[]", + valueBuilt: " [];\n", + meta: { + type: "option", + option_mode: "checkbox", + options: + "async () => {\n const result: { label: string; value: string; options?: any[] }[] = [];\n const fields = await db._schema.columns(rel_table);\n for (const [k, v] of Object.entries(fields)) {\n result.push({ value: k, label: k });\n }\n\n const rels = await db._schema.rels(rel_table);\n for (const [k, v] of Object.entries(rels)) {\n let options = [];\n const fields = await db._schema.columns(v.to.table);\n for (const [k, v] of Object.entries(fields)) {\n options.push({ value: k, label: k });\n }\n\n result.push({ value: k, label: k, options });\n }\n\n return result;\n}", + optionsBuilt: + " async () => {\n const result = [];\n const fields = await db._schema.columns(rel_table);\n for (const [k, v] of Object.entries(fields)) {\n result.push({ value: k, label: k });\n }\n const rels = await db._schema.rels(rel_table);\n for (const [k, v] of Object.entries(rels)) {\n let options = [];\n const fields2 = await db._schema.columns(v.to.table);\n for (const [k2, v2] of Object.entries(fields2)) {\n options.push({ value: k2, label: k2 });\n }\n result.push({ value: k, label: k, options });\n }\n return result;\n};\n", + }, + label: "fields", + }, + rel_query: { + idx: 11, + name: "prop_11", + type: "string", + value: "async () => {\n return {};\n}", + valueBuilt: " async () => {\n return {};\n};\n", + meta: { + type: "text", + }, + label: "query", + }, + }, + ref_ids: {}, + instances: { + npj543t5rpwx932a153hsfyl: { + zmit41kbgkbqcsmm8aspp8zy: "mo4m0rnyey4y6v7tlajod95l", + }, + }, + }, + originalid: createId(), + }, + ], + }, + { + id: createId(), + adv: { + js: "", + css: "", + jsBuilt: + "render(/* @__PURE__ */ React.createElement(\n Form,\n {\n on_init,\n on_load,\n form,\n PassProp,\n body,\n props,\n layout,\n on_submit\n }\n));\n", + }, + dim: { + h: "full", + w: "full", + }, + name: "el", + type: "item", + childs: [], + mobile: { + dim: { + h: "fit", + w: "full", + }, + }, + script: {}, + }, + ], + script: { + local: { + end: 85, + name: "form", + start: 53, + value: "{hook: null as any}", + }, + }, + component: { + id: "c4e65c26-4f36-48aa-a5b3-0771feac082e", + props: { + generate: { + idx: 5, + name: "prop_6", + type: "string", + value: '"n"', + valueBuilt: '"n"', + meta: { + 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', + type: "option", + }, + }, + gen_table: { + visible: "generate === 'y'", + idx: 6, + name: "prop_8", + type: "string", + value: '"m_aset"', + valueBuilt: '"m_aset"', + meta: { + options: + 'async () => {\n return (await db._schema.tables()).map((e) => ({\n value: e,\n label: e,\n reload: ["gen_fields"],\n }));\n}', + optionsBuilt: + ' async () => {\n return (await db._schema.tables()).map((e) => ({\n value: e,\n label: e,\n reload: ["gen_fields"]\n }));\n};\n', + type: "option", + option_mode: "dropdown", + }, + label: "table", + }, + gen_fields: { + idx: 7, + name: "prop_10", + type: "string", + value: + '["{\\"name\\":\\"id\\",\\"is_pk\\":true,\\"type\\":\\"int\\",\\"optional\\":false}","{\\"name\\":\\"nama_aset\\",\\"is_pk\\":false,\\"type\\":\\"varchar\\",\\"optional\\":true}","{\\"name\\":\\"nama_aset_keuangan\\",\\"is_pk\\":false,\\"type\\":\\"varchar\\",\\"optional\\":true}","{\\"name\\":\\"nama_aset_komersial\\",\\"is_pk\\":false,\\"type\\":\\"varchar\\",\\"optional\\":true}","{\\"name\\":\\"asset_number\\",\\"is_pk\\":false,\\"type\\":\\"varchar\\",\\"optional\\":true}","{\\"name\\":\\"luas_setifikat\\",\\"is_pk\\":false,\\"type\\":\\"decimal\\",\\"optional\\":true}","{\\"name\\":\\"tanggal_sertifikat\\",\\"is_pk\\":false,\\"type\\":\\"varchar\\",\\"optional\\":true}",{"value":"{\\"name\\":\\"m_cabang\\",\\"is_pk\\":false,\\"type\\":\\"has-one\\",\\"optional\\":true}","checked":["{\\"name\\":\\"id\\",\\"is_pk\\":true,\\"type\\":\\"int\\",\\"optional\\":false}","{\\"name\\":\\"nama_cabang\\",\\"is_pk\\":false,\\"type\\":\\"string\\",\\"optional\\":true}"]},{"value":"{\\"name\\":\\"m_regional\\",\\"is_pk\\":false,\\"type\\":\\"has-one\\",\\"optional\\":true}","checked":["{\\"name\\":\\"id\\",\\"is_pk\\":true,\\"type\\":\\"int\\",\\"optional\\":false}","{\\"name\\":\\"regional\\",\\"is_pk\\":false,\\"type\\":\\"varchar\\",\\"optional\\":false}"]}]', + valueBuilt: + '["{\\"name\\":\\"id\\",\\"is_pk\\":true,\\"type\\":\\"int\\",\\"optional\\":false}","{\\"name\\":\\"nama_aset\\",\\"is_pk\\":false,\\"type\\":\\"varchar\\",\\"optional\\":true}","{\\"name\\":\\"nama_aset_keuangan\\",\\"is_pk\\":false,\\"type\\":\\"varchar\\",\\"optional\\":true}","{\\"name\\":\\"nama_aset_komersial\\",\\"is_pk\\":false,\\"type\\":\\"varchar\\",\\"optional\\":true}","{\\"name\\":\\"asset_number\\",\\"is_pk\\":false,\\"type\\":\\"varchar\\",\\"optional\\":true}","{\\"name\\":\\"luas_setifikat\\",\\"is_pk\\":false,\\"type\\":\\"decimal\\",\\"optional\\":true}","{\\"name\\":\\"tanggal_sertifikat\\",\\"is_pk\\":false,\\"type\\":\\"varchar\\",\\"optional\\":true}",{"value":"{\\"name\\":\\"m_cabang\\",\\"is_pk\\":false,\\"type\\":\\"has-one\\",\\"optional\\":true}","checked":["{\\"name\\":\\"id\\",\\"is_pk\\":true,\\"type\\":\\"int\\",\\"optional\\":false}","{\\"name\\":\\"nama_cabang\\",\\"is_pk\\":false,\\"type\\":\\"string\\",\\"optional\\":true}"]},{"value":"{\\"name\\":\\"m_regional\\",\\"is_pk\\":false,\\"type\\":\\"has-one\\",\\"optional\\":true}","checked":["{\\"name\\":\\"id\\",\\"is_pk\\":true,\\"type\\":\\"int\\",\\"optional\\":false}","{\\"name\\":\\"regional\\",\\"is_pk\\":false,\\"type\\":\\"varchar\\",\\"optional\\":false}"]}]', + meta: { + options: + "async () => {\n const result: { label: string; value: string; options?: any[] }[] = [];\n const fields = await db._schema.columns(gen_table);\n for (const [k, v] of Object.entries(fields)) {\n result.push({\n value: JSON.stringify({\n name: k,\n is_pk: v.is_pk,\n type: v.db_type || v.type,\n optional: v.optional,\n }),\n label: k,\n });\n }\n const rels = await db._schema.rels(gen_table);\n for (const [k, v] of Object.entries(rels)) {\n let options = [];\n const fields = await db._schema.columns(v.to.table);\n for (const [k, v] of Object.entries(fields)) {\n options.push({\n value: JSON.stringify({\n name: k,\n is_pk: v.is_pk,\n type: v.db_type || v.type,\n optional: v.optional,\n }),\n label: k,\n });\n }\n result.push({\n value: JSON.stringify({\n name: k,\n is_pk: false,\n type: v.type,\n optional: true,\n }),\n label: k,\n options,\n });\n }\n\n return result;\n}", + optionsBuilt: + " async () => {\n const result = [];\n const fields = await db._schema.columns(gen_table);\n for (const [k, v] of Object.entries(fields)) {\n result.push({\n value: JSON.stringify({\n name: k,\n is_pk: v.is_pk,\n type: v.db_type || v.type,\n optional: v.optional\n }),\n label: k\n });\n }\n const rels = await db._schema.rels(gen_table);\n for (const [k, v] of Object.entries(rels)) {\n let options = [];\n const fields2 = await db._schema.columns(v.to.table);\n for (const [k2, v2] of Object.entries(fields2)) {\n options.push({\n value: JSON.stringify({\n name: k2,\n is_pk: v2.is_pk,\n type: v2.db_type || v2.type,\n optional: v2.optional\n }),\n label: k2\n });\n }\n result.push({\n value: JSON.stringify({\n name: k,\n is_pk: false,\n type: v.type,\n optional: true\n }),\n label: k,\n options\n });\n }\n return result;\n};\n", + type: "option", + option_mode: "checkbox", + }, + label: "fields", + visible: "generate === 'y'", + }, + gen_btn: { + idx: 9, + name: "prop_10", + type: "string", + value: + '[\n {\n label: "Generate",\n onClick: gen_form,\n },\n]', + valueBuilt: + ' [\n {\n label: "Generate",\n onClick: gen_form\n }\n];\n', + meta: { + type: "button", + }, + label: "_", + visible: "generate === 'y'", + }, + body: { + idx: 4, + meta: { + type: "content-element", + }, + name: "prop_3", + type: "string", + value: '"hello"', + content: { + id: createId(), + adv: { + css: "", + }, + dim: { + h: "full", + w: "full", + }, + name: "body", + type: "item", + childs: [ + { + id: createId(), + adv: { + js: '\n \n
', + 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: "`nama_aset`", + is_name: true, + valueBuilt: "`nama_aset`", + }, + 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: '"text"', + content: { + id: createId(), + adv: { + css: "", + }, + dim: { + h: "full", + w: "full", + }, + name: "type", + type: "item", + childs: [], + }, + is_name: false, + valueBuilt: '"text"', + }, + child: { + idx: 11, + meta: { + type: "content-element", + }, + name: "prop_11", + type: "string", + value: '"hello"', + content: { + id: createId(), + 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: "`Nama Aset`", + is_name: false, + valueBuilt: "`Nama Aset`", + }, + 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: "`n`", + is_name: false, + valueBuilt: "`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", + }, + }, + rel_table: { + idx: 11, + name: "prop_11", + type: "string", + value: '""', + valueBuilt: '""', + meta: { + type: "text", + }, + content: { + id: createId(), + name: "rel_table", + type: "item", + dim: { + w: "full", + h: "full", + }, + childs: [], + adv: { + css: "", + }, + }, + }, + rel_fields: { + idx: 11, + name: "prop_11", + type: "string", + value: "[]", + valueBuilt: "[]", + meta: { + type: "option", + }, + }, + default_value: { + idx: 11, + name: "prop_11", + type: "string", + value: '"hello"', + valueBuilt: '"hello"', + meta: { + type: "text", + }, + }, + }, + ref_ids: {}, + instances: {}, + }, + }, + { + id: createId(), + adv: { + js: '\n \n
', + 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: "`nama_aset_keuangan`", + is_name: true, + valueBuilt: "`nama_aset_keuangan`", + }, + 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: '"text"', + content: { + id: createId(), + adv: { + css: "", + }, + dim: { + h: "full", + w: "full", + }, + name: "type", + type: "item", + childs: [], + }, + is_name: false, + valueBuilt: '"text"', + }, + child: { + idx: 11, + meta: { + type: "content-element", + }, + name: "prop_11", + type: "string", + value: '"hello"', + content: { + id: createId(), + 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: "`Nama Aset Keuangan`", + is_name: false, + valueBuilt: "`Nama Aset Keuangan`", + }, + 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: "`n`", + is_name: false, + valueBuilt: "`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", + }, + }, + + rel_table: { + idx: 11, + name: "prop_11", + type: "string", + value: '""', + valueBuilt: '""', + meta: { + type: "text", + }, + content: { + id: createId(), + name: "rel_table", + type: "item", + dim: { + w: "full", + h: "full", + }, + childs: [], + adv: { + css: "", + }, + }, + }, + rel_fields: { + idx: 11, + name: "prop_11", + type: "string", + value: "[]", + valueBuilt: "[]", + meta: { + type: "option", + }, + }, + default_value: { + idx: 11, + name: "prop_11", + type: "string", + value: '"hello"', + valueBuilt: '"hello"', + meta: { + type: "text", + }, + }, + }, + ref_ids: {}, + instances: {}, + }, + }, + { + id: createId(), + adv: { + js: '\n \n', + 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: "`nama_aset_komersial`", + is_name: true, + valueBuilt: "`nama_aset_komersial`", + }, + 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: '"text"', + content: { + id: createId(), + adv: { + css: "", + }, + dim: { + h: "full", + w: "full", + }, + name: "type", + type: "item", + childs: [], + }, + is_name: false, + valueBuilt: '"text"', + }, + child: { + idx: 11, + meta: { + type: "content-element", + }, + name: "prop_11", + type: "string", + value: '"hello"', + content: { + id: createId(), + 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: "`Nama Aset Komersial`", + is_name: false, + valueBuilt: "`Nama Aset Komersial`", + }, + 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: "`n`", + is_name: false, + valueBuilt: "`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", + }, + }, + + rel_table: { + idx: 11, + name: "prop_11", + type: "string", + value: '""', + valueBuilt: '""', + meta: { + type: "text", + }, + content: { + id: createId(), + name: "rel_table", + type: "item", + dim: { + w: "full", + h: "full", + }, + childs: [], + adv: { + css: "", + }, + }, + }, + rel_fields: { + idx: 11, + name: "prop_11", + type: "string", + value: "[]", + valueBuilt: "[]", + meta: { + type: "option", + }, + }, + default_value: { + idx: 11, + name: "prop_11", + type: "string", + value: '"hello"', + valueBuilt: '"hello"', + meta: { + type: "text", + }, + }, + }, + ref_ids: {}, + instances: {}, + }, + }, + { + id: createId(), + adv: { + js: '\n \n', + 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: "`asset_number`", + is_name: true, + valueBuilt: "`asset_number`", + }, + 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: '"text"', + content: { + id: createId(), + adv: { + css: "", + }, + dim: { + h: "full", + w: "full", + }, + name: "type", + type: "item", + childs: [], + }, + is_name: false, + valueBuilt: '"text"', + }, + child: { + idx: 11, + meta: { + type: "content-element", + }, + name: "prop_11", + type: "string", + value: '"hello"', + content: { + id: createId(), + 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: "`Asset Number`", + is_name: false, + valueBuilt: "`Asset Number`", + }, + 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: "`n`", + is_name: false, + valueBuilt: "`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", + }, + }, + + rel_table: { + idx: 11, + name: "prop_11", + type: "string", + value: '""', + valueBuilt: '""', + meta: { + type: "text", + }, + content: { + id: createId(), + name: "rel_table", + type: "item", + dim: { + w: "full", + h: "full", + }, + childs: [], + adv: { + css: "", + }, + }, + }, + rel_fields: { + idx: 11, + name: "prop_11", + type: "string", + value: "[]", + valueBuilt: "[]", + meta: { + type: "option", + }, + }, + default_value: { + idx: 11, + name: "prop_11", + type: "string", + value: '"hello"', + valueBuilt: '"hello"', + meta: { + type: "text", + }, + }, + }, + ref_ids: {}, + instances: {}, + }, + }, + { + id: createId(), + adv: { + js: '\n \n', + 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: "`luas_setifikat`", + is_name: true, + valueBuilt: "`luas_setifikat`", + }, + 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: '"text"', + content: { + id: createId(), + adv: { + css: "", + }, + dim: { + h: "full", + w: "full", + }, + name: "type", + type: "item", + childs: [], + }, + is_name: false, + valueBuilt: '"text"', + }, + child: { + idx: 11, + meta: { + type: "content-element", + }, + name: "prop_11", + type: "string", + value: '"hello"', + content: { + id: createId(), + 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: "`Luas Setifikat`", + is_name: false, + valueBuilt: "`Luas Setifikat`", + }, + 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: "`n`", + is_name: false, + valueBuilt: "`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", + }, + }, + + rel_table: { + idx: 11, + name: "prop_11", + type: "string", + value: '""', + valueBuilt: '""', + meta: { + type: "text", + }, + content: { + id: createId(), + name: "rel_table", + type: "item", + dim: { + w: "full", + h: "full", + }, + childs: [], + adv: { + css: "", + }, + }, + }, + rel_fields: { + idx: 11, + name: "prop_11", + type: "string", + value: "[]", + valueBuilt: "[]", + meta: { + type: "option", + }, + }, + default_value: { + idx: 11, + name: "prop_11", + type: "string", + value: '"hello"', + valueBuilt: '"hello"', + meta: { + type: "text", + }, + }, + }, + ref_ids: {}, + instances: {}, + }, + }, + { + id: createId(), + adv: { + js: '\n \n', + 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: "`tanggal_sertifikat`", + is_name: true, + valueBuilt: "`tanggal_sertifikat`", + }, + 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: '"text"', + content: { + id: createId(), + adv: { + css: "", + }, + dim: { + h: "full", + w: "full", + }, + name: "type", + type: "item", + childs: [], + }, + is_name: false, + valueBuilt: '"text"', + }, + child: { + idx: 11, + meta: { + type: "content-element", + }, + name: "prop_11", + type: "string", + value: '"hello"', + content: { + id: createId(), + 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: "`Tanggal Sertifikat`", + is_name: false, + valueBuilt: "`Tanggal Sertifikat`", + }, + 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: "`n`", + is_name: false, + valueBuilt: "`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", + }, + }, + + rel_table: { + idx: 11, + name: "prop_11", + type: "string", + value: '""', + valueBuilt: '""', + meta: { + type: "text", + }, + content: { + id: createId(), + name: "rel_table", + type: "item", + dim: { + w: "full", + h: "full", + }, + childs: [], + adv: { + css: "", + }, + }, + }, + rel_fields: { + idx: 11, + name: "prop_11", + type: "string", + value: "[]", + valueBuilt: "[]", + meta: { + type: "option", + }, + }, + default_value: { + idx: 11, + name: "prop_11", + type: "string", + value: '"hello"', + valueBuilt: '"hello"', + meta: { + type: "text", + }, + }, + }, + ref_ids: {}, + instances: {}, + }, + }, + { + id: createId(), + adv: { + js: '\n \n', + 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: "`m_cabang`", + is_name: true, + valueBuilt: "`m_cabang`", + }, + 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: '"relation"', + content: { + id: createId(), + adv: { + css: "", + }, + dim: { + h: "full", + w: "full", + }, + name: "type", + type: "item", + childs: [], + }, + is_name: false, + valueBuilt: '"relation"', + }, + child: { + idx: 11, + meta: { + type: "content-element", + }, + name: "prop_11", + type: "string", + value: '"hello"', + content: { + id: createId(), + 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: "`Cabang`", + is_name: false, + valueBuilt: "`Cabang`", + }, + 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: "`n`", + is_name: false, + valueBuilt: "`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 // name: 'asc'\n // }\n };\n}", + valueBuilt: + " async () => {\n return {\n // orderBy: {\n // name: 'asc'\n // }\n };\n};\n", + meta: { + type: "text", + }, + }, + + rel_table: { + idx: 11, + name: "prop_11", + type: "string", + value: '"m_cabang"', + valueBuilt: '"m_cabang"', + meta: { + type: "text", + }, + content: { + id: createId(), + name: "rel_table", + type: "item", + dim: { + w: "full", + h: "full", + }, + childs: [], + adv: { + css: "", + }, + }, + }, + rel_fields: { + idx: 11, + name: "prop_11", + type: "string", + value: '["::id","nama_cabang"]', + valueBuilt: '["::id","nama_cabang"]', + meta: { + type: "option", + }, + }, + default_value: { + idx: 11, + name: "prop_11", + type: "string", + value: '"hello"', + valueBuilt: '"hello"', + meta: { + type: "text", + }, + }, + }, + ref_ids: {}, + instances: {}, + }, + }, + { + id: createId(), + adv: { + js: '\n \n', + 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: "`m_regional`", + is_name: true, + valueBuilt: "`m_regional`", + }, + 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: '"relation"', + content: { + id: createId(), + adv: { + css: "", + }, + dim: { + h: "full", + w: "full", + }, + name: "type", + type: "item", + childs: [], + }, + is_name: false, + valueBuilt: '"relation"', + }, + child: { + idx: 11, + meta: { + type: "content-element", + }, + name: "prop_11", + type: "string", + value: '"hello"', + content: { + id: createId(), + 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: "`Regional`", + is_name: false, + valueBuilt: "`Regional`", + }, + 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: "`n`", + is_name: false, + valueBuilt: "`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", + }, + }, + + rel_table: { + idx: 11, + name: "prop_11", + type: "string", + value: '"m_regional"', + valueBuilt: '"m_regional"', + meta: { + type: "text", + }, + content: { + id: createId(), + name: "rel_table", + type: "item", + dim: { + w: "full", + h: "full", + }, + childs: [], + adv: { + css: "", + }, + }, + }, + rel_fields: { + idx: 11, + name: "prop_11", + type: "string", + value: '["::id","regional"]', + valueBuilt: '["::id","regional"]', + meta: { + type: "option", + }, + }, + default_value: { + idx: 11, + name: "prop_11", + type: "string", + value: '"hello"', + valueBuilt: '"hello"', + meta: { + type: "text", + }, + }, + }, + ref_ids: {}, + instances: {}, + }, + }, + ], + padding: { + l: 10, + b: 10, + t: 10, + r: 10, + }, + }, + typings: 'const typings = {\n data: "any",\n}', + valueBuilt: ' "hello";\n', + jsxCalledBy: [ + "bca0tc62ycv8tarukqpo1vf8", + "deqnuhatpkpyf5uqjsxcdpe0", + ], + }, + layout: { + idx: 3, + meta: { + type: "option", + options: '["auto", "1-col", "2-col"]', + optionsBuilt: ' ["auto", "1-col", "2-col"];\n', + }, + name: "prop_5", + type: "string", + value: '"auto"', + valueBuilt: ' "auto";\n', + }, + on_init: { + idx: 0, + meta: { + type: "text", + }, + name: "prop_5", + type: "string", + value: + '({ submit }: Init) => {\n // on init\n md.cache("form")._submit = submit;\n};\n\ntype Init = { submit: () => void }', + valueBuilt: + ' ({ submit }) => {\n md.cache("form")._submit = submit;\n};\n', + }, + on_load: { + idx: 1, + meta: { + type: "text", + }, + name: "prop_1", + type: "string", + value: + 'async (opt) => {\n if (isEditor) return {};\n\n let id = parseInt(md.selected.id);\n\n const after_load = (item: any) => {\n const set_actions = () =>\n (md.ui.actions = [\n {\n label: "Delete",\n type: "destructive",\n onClick: async () => {\n if (confirm("Are you sure ?")) {\n md.ui.actions = [{ label: "Deleting...", type: "ghost" }];\n md.render();\n\n await db.m_aset.delete({ where: { id: item.id } });\n\n setTimeout(() => {\n md.ui.actions = [...md.ui.default_actions];\n md.ui.breadcrumb = [];\n md.ui.back = false;\n md.selected = null;\n md.render();\n });\n }\n },\n icon: ``,\n },\n {\n label: "Save",\n onClick: async () => {\n md.ui.actions = [{ label: "Saving...", type: "ghost" }];\n md.render();\n await md.cache("form")._submit();\n setTimeout(() => {\n set_actions();\n md.render();\n }, 500);\n },\n icon: ``,\n },\n ]);\n set_actions();\n md.ui.breadcrumb = [["Master Aset", ""], item?.nama_aset_komersial];\n md.render();\n };\n\n if (id) {\n md.ui.breadcrumb = [["Master Aset", ""], "..."];\n md.render();\n\n const item = await db.m_aset.findFirst({\n where: {\n id: id,\n },\n select: {\n id: true,\n nama_aset: true,\n nama_aset_keuangan: true,\n nama_aset_komersial: true,\n asset_number: true,\n luas_setifikat: true,\n tanggal_sertifikat: true,\n m_cabang: {\n select: {\n id: true,\n },\n },\n m_regional: {\n select: {\n id: true,\n },\n },\n },\n });\n\n for (const [k, v] of Object.entries(item)) {\n if (k === "m_cabang") {\n if (v?.["id"]) item[k] = { connect: { id: v?.["id"] } } as any;\n else delete item[k];\n }\n if (k === "m_regional") {\n if (v?.["id"]) item[k] = { connect: { id: v?.["id"] } } as any;\n else delete item[k];\n }\n }\n\n after_load(item);\n\n return item;\n } else {\n after_load({});\n }\n}', + valueBuilt: + ' async (opt) => {\n if (isEditor)\n return {};\n let id = parseInt(md.selected.id);\n const after_load = (item) => {\n const set_actions = () => md.ui.actions = [\n {\n label: "Delete",\n type: "destructive",\n onClick: async () => {\n if (confirm("Are you sure ?")) {\n md.ui.actions = [{ label: "Deleting...", type: "ghost" }];\n md.render();\n await db.m_aset.delete({ where: { id: item.id } });\n setTimeout(() => {\n md.ui.actions = [...md.ui.default_actions];\n md.ui.breadcrumb = [];\n md.ui.back = false;\n md.selected = null;\n md.render();\n });\n }\n },\n icon: ``\n },\n {\n label: "Save",\n onClick: async () => {\n md.ui.actions = [{ label: "Saving...", type: "ghost" }];\n md.render();\n await md.cache("form")._submit();\n setTimeout(() => {\n set_actions();\n md.render();\n }, 500);\n },\n icon: ``\n }\n ];\n set_actions();\n md.ui.breadcrumb = [["Master Aset", ""], item?.nama_aset_komersial];\n md.render();\n };\n if (id) {\n md.ui.breadcrumb = [["Master Aset", ""], "..."];\n md.render();\n const item = await db.m_aset.findFirst({\n where: {\n id\n },\n select: {\n id: true,\n nama_aset: true,\n nama_aset_keuangan: true,\n nama_aset_komersial: true,\n asset_number: true,\n luas_setifikat: true,\n tanggal_sertifikat: true,\n m_cabang: {\n select: {\n id: true\n }\n },\n m_regional: {\n select: {\n id: true\n }\n }\n }\n });\n for (const [k, v] of Object.entries(item)) {\n if (k === "m_cabang") {\n if (v?.["id"])\n item[k] = { connect: { id: v?.["id"] } };\n else\n delete item[k];\n }\n if (k === "m_regional") {\n if (v?.["id"])\n item[k] = { connect: { id: v?.["id"] } };\n else\n delete item[k];\n }\n }\n after_load(item);\n return item;\n } else {\n after_load({});\n }\n};\n', + }, + on_submit: { + idx: 2, + meta: { + type: "text", + }, + name: "prop_1", + type: "string", + value: + 'async ({ form, error }: IForm) => {\n if (typeof error === "object" && Object.keys(error).length > 0) return {};\n\n const data = { ...form };\n delete data.id;\n\n if (form.id) {\n await db.m_aset.update({\n where: {\n id: form.id,\n },\n data,\n });\n } else {\n const res = await db.m_aset.create({\n data,\n select: { id: true },\n });\n if (res) form.id = res.id;\n }\n\n return true;\n};\n\ntype IForm = { form: any; error: Record }', + valueBuilt: + ' async ({ form, error }) => {\n if (typeof error === "object" && Object.keys(error).length > 0)\n return {};\n const data = { ...form };\n delete data.id;\n if (form.id) {\n await db.m_aset.update({\n where: {\n id: form.id\n },\n data\n });\n } else {\n const res = await db.m_aset.create({\n data,\n select: { id: true }\n });\n if (res)\n form.id = res.id;\n }\n return true;\n};\n', + }, + gen_mode: { + idx: 8, + name: "prop_10", + type: "string", + value: + '["on_init",{"value":"fields","checked":["clear","add","update"]},"on_submit","on_load"]', + valueBuilt: + '["on_init",{"value":"fields","checked":["clear","add","update"]},"on_submit","on_load"]', + meta: { + options: + '[\n {\n label: "on_init",\n value: "on_init",\n },\n {\n label: "on_load",\n value: "on_load",\n },\n {\n label: "on_submit",\n value: "on_submit",\n },\n\n {\n label: "fields",\n value: "fields",\n options: [\n {\n label: "clear",\n value: "clear",\n },\n {\n label: "add",\n value: "add",\n },\n {\n label: "update",\n value: "update",\n },\n ],\n },\n]', + optionsBuilt: + ' [\n {\n label: "on_init",\n value: "on_init"\n },\n {\n label: "on_load",\n value: "on_load"\n },\n {\n label: "on_submit",\n value: "on_submit"\n },\n {\n label: "fields",\n value: "fields",\n options: [\n {\n label: "clear",\n value: "clear"\n },\n {\n label: "add",\n value: "add"\n },\n {\n label: "update",\n value: "update"\n }\n ]\n }\n];\n', + type: "option", + option_mode: "checkbox", + }, + label: "mode", + visible: "generate === 'y'", + }, + prop_11: { + idx: 11, + name: "prop_11", + type: "string", + value: '"hello"', + valueBuilt: '"hello"', + meta: { + type: "text", + }, + }, + cache: { + idx: 11, + name: "prop_11", + type: "string", + value: '() => {\n return md.cache("form");\n}', + valueBuilt: ' () => {\n return md.cache("form");\n};\n', + meta: { + type: "text", + }, + }, + }, + ref_ids: {}, + useStyle: false, + instances: {}, + }, + originalid: createId(), + }, + ], + adv: { + css: "", + js: "", + jsBuilt: "render();\n", + }, + }, + ], + adv: { + css: "", + js: "", + jsBuilt: "render();\n", + }, + }; + + return { content: res, props: res.childs[0].childs[0].component.props }; +}; diff --git a/gen/gen_md/gen_header.ts b/gen/gen_md/gen_header.ts new file mode 100755 index 0000000..5a7f493 --- /dev/null +++ b/gen/gen_md/gen_header.ts @@ -0,0 +1,223 @@ +import { createId } from "@paralleldrive/cuid2"; + +export const gen_header = () => { + return { + id: createId(), + name: "prop_1", + type: "item", + dim: { + w: "full", + h: 40, + hUnit: "px", + }, + childs: [ + { + id: createId(), + name: "breadcrumb", + type: "item", + dim: { + w: "full", + h: 40, + hUnit: "px", + }, + childs: [ + { + id: createId(), + name: "back", + type: "item", + dim: { + w: "fit", + h: "full", + }, + childs: [ + { + id: createId(), + name: "icon", + type: "item", + dim: { + w: "full", + h: "full", + }, + childs: [], + adv: { + html: '\n \n', + css: "", + }, + layout: { + dir: "col", + align: "center", + gap: 0, + wrap: "flex-nowrap", + }, + }, + { + id: createId(), + name: "back_text", + type: "text", + dim: { + w: "fit", + h: "full", + }, + layout: { + align: "center", + dir: "col", + gap: 0, + }, + text: "", + html: "
Back
", + adv: { + css: "", + }, + }, + ], + adv: { + js: '<>\n {md.ui.back && (\n {\n md.ui.actions = [...md.ui.default_actions];\n md.ui.breadcrumb = [];\n md.ui.back = false;\n md.selected = null;\n md.render();\n }}\n >\n {children}\n \n )}\n', + jsBuilt: + 'render(/* @__PURE__ */ React.createElement(React.Fragment, null, md.ui.back && /* @__PURE__ */ React.createElement(\n "div",\n {\n ...props,\n className: cx(props.className, ""),\n onClick: () => {\n md.ui.actions = [...md.ui.default_actions];\n md.ui.breadcrumb = [];\n md.ui.back = false;\n md.selected = null;\n md.render();\n }\n },\n children\n)));\n', + css: "& {\n display: flex;\n cursor: pointer;\n\n // &.mobile {}\n // &.desktop {}\n &:hover {\n background: rgb(237, 246, 255);\n }\n}", + }, + script: {}, + layout: { + dir: "row", + align: "top-left", + gap: 0, + wrap: "flex-nowrap", + }, + border: { + style: "solid", + stroke: { + r: 1, + }, + color: "#ececeb", + }, + padding: { + l: 10, + b: 0, + t: 0, + r: 10, + }, + }, + { + id: createId(), + name: "title", + type: "item", + childs: [], + adv: { + js: '
\n \n
', + jsBuilt: + 'render(/* @__PURE__ */ React.createElement("div", { ...props, className: cx(props.className, "") }, /* @__PURE__ */ React.createElement(MDTitle, { md })));\n', + }, + script: {}, + padding: { + l: 10, + b: 0, + t: 0, + r: 10, + }, + dim: { + w: "full", + h: "full", + wUnit: "px", + hUnit: "px", + }, + layout: { + dir: "col", + align: "left", + gap: 0, + wrap: "flex-nowrap", + }, + }, + { + id: createId(), + name: "right", + type: "item", + childs: [ + { + id: createId(), + name: "mode", + type: "item", + dim: { + w: "fit", + h: "full", + }, + childs: [], + adv: { + js: '<>\n {!md.ui.back && (\n
\n {children}\n
\n )}\n', + jsBuilt: + 'render(/* @__PURE__ */ React.createElement(React.Fragment, null, !md.ui.back && /* @__PURE__ */ React.createElement("div", { ...props, className: cx(props.className, "") }, children)));\n', + css: "", + }, + script: {}, + padding: { + l: 0, + b: 0, + t: 0, + r: 10, + }, + }, + { + id: createId(), + name: "actions", + type: "item", + dim: { + w: "fit", + h: "full", + }, + childs: [], + adv: { + js: '
\n \n
', + jsBuilt: + 'render(/* @__PURE__ */ React.createElement("div", { ...props, className: cx(props.className, "") }, /* @__PURE__ */ React.createElement(MDAction, { md })));\n', + css: "", + }, + script: {}, + padding: { + l: 0, + b: 0, + t: 0, + r: 10, + }, + }, + ], + layout: { + dir: "row", + align: "top-left", + gap: 0, + wrap: "flex-nowrap", + }, + }, + ], + adv: { + js: '<>\n {md.mode === "breadcrumb" && (\n
\n {children}\n
\n )}\n', + jsBuilt: + 'render(/* @__PURE__ */ React.createElement(React.Fragment, null, md.mode === "breadcrumb" && /* @__PURE__ */ React.createElement("div", { ...props, className: cx(props.className, "") }, children)));\n', + css: "", + }, + script: {}, + padding: { + l: 0, + b: 0, + t: 0, + r: 0, + }, + layout: { + dir: "row", + align: "left", + gap: 0, + wrap: "flex-nowrap", + }, + border: { + style: "solid", + stroke: { + b: 1, + }, + color: "#ccc", + }, + }, + ], + adv: { + css: "", + }, + hidden: false, + }; +}; diff --git a/gen/gen_md/gen_master.ts b/gen/gen_md/gen_master.ts new file mode 100755 index 0000000..c760467 --- /dev/null +++ b/gen/gen_md/gen_master.ts @@ -0,0 +1,302 @@ +import { createId } from "@paralleldrive/cuid2"; + +export const gen_master = () => { + const res = { + id: createId(), + name: "prop_1", + type: "item", + dim: { + w: "full", + h: "full", + }, + childs: [ + { + id: createId(), + adv: { + js: "", + css: "", + jsBuilt: + "render(/* @__PURE__ */ React.createElement(Table, { on_load, columns, child, PassProp }));\n", + }, + dim: { + h: "full", + w: "full", + }, + name: "table", + type: "item", + childs: [ + { + id: createId(), + adv: { + css: "", + }, + dim: { + h: "full", + w: "full", + }, + name: "jsx: child", + type: "item", + childs: [ + { + id: createId(), + adv: { + js: '<>{cell.key !== "action" && cell.value}', + css: "", + jsBuilt: + 'render(/* @__PURE__ */ React.createElement(React.Fragment, null, cell.key !== "action" && cell.value));\n', + }, + dim: { + h: "full", + w: "full", + }, + name: "text", + type: "item", + childs: [], + script: {}, + }, + { + id: createId(), + adv: { + js: '<>\n {cell.key === "action" && (\n
\n \n {cell.value}\n
\n \n )}\n', + css: "", + jsBuilt: + 'render(/* @__PURE__ */ React.createElement(React.Fragment, null, cell.key === "action" && /* @__PURE__ */ React.createElement("div", { className: "flex items-center h-full" }, /* @__PURE__ */ React.createElement(\n "div",\n {\n className: cx(\n "bg-white border flex items-center px-3 cursor-pointer capitalize",\n css`\n height:25px; \n &:hover {\n background:blue;\n color:white;\n }\n `\n )\n },\n cell.value\n))));\n', + }, + dim: { + h: "full", + w: "full", + }, + name: "action", + type: "item", + childs: [], + script: {}, + }, + ], + }, + ], + script: {}, + component: { + id: "df4e3552-3221-496c-b07b-0c1295f811be", + props: { + child: { + idx: 3, + meta: { + type: "content-element", + }, + name: "prop_3", + type: "string", + value: '"hello"', + content: { + id: createId(), + adv: { + css: "", + js: "<>{children}", + jsBuilt: + "render(/* @__PURE__ */ React.createElement(React.Fragment, null, children));\n", + }, + dim: { + h: "full", + w: "full", + }, + name: "prop_3", + type: "item", + childs: [ + { + id: createId(), + adv: { + js: '<>\n {cell.key === "id" && (\n
\n {cell.value}\n
\n )}\n', + css: "", + jsBuilt: + 'render(\n React.createElement(\n React.Fragment,\n null,\n cell.key === "id" &&\n React.createElement(\n "div",\n Object.assign({}, props, { className: cx(props.className, "") }),\n cell.value\n )\n )\n)', + }, + dim: { + h: "full", + w: "full", + }, + name: "id", + type: "item", + childs: [], + script: {}, + }, + { + id: createId(), + adv: { + js: '<>\n {cell.key === "nama_aset_komersial" && (\n
\n {cell.value}\n
\n )}\n', + css: "", + jsBuilt: + 'render(\n React.createElement(\n React.Fragment,\n null,\n cell.key === "nama_aset_komersial" &&\n React.createElement(\n "div",\n Object.assign({}, props, { className: cx(props.className, "") }),\n cell.value\n )\n )\n)', + }, + dim: { + h: "full", + w: "full", + }, + name: "nama_aset_komersial", + type: "item", + childs: [], + script: {}, + }, + { + id: createId(), + adv: { + js: '<>\n {cell.key === "m_cabang" && (\n
\n {cell.value?.["nama_cabang"]}\n
\n )}\n', + css: "", + jsBuilt: + 'render(\n React.createElement(\n React.Fragment,\n null,\n cell.key === "m_cabang" &&\n React.createElement(\n "div",\n Object.assign({}, props, { className: cx(props.className, "") }),\n cell.value?.["nama_cabang"]\n )\n )\n)', + }, + dim: { + h: "full", + w: "full", + }, + name: "m_cabang", + type: "item", + childs: [], + script: {}, + }, + { + id: createId(), + adv: { + js: '<>\n {cell.key === "m_regional" && (\n
\n {cell.value?.["regional"]}\n
\n )}\n', + css: "", + jsBuilt: + 'render(\n React.createElement(\n React.Fragment,\n null,\n cell.key === "m_regional" &&\n React.createElement(\n "div",\n Object.assign({}, props, { className: cx(props.className, "") }),\n cell.value?.["regional"]\n )\n )\n)', + }, + dim: { + h: "full", + w: "full", + }, + name: "m_regional", + type: "item", + childs: [], + script: {}, + }, + { + id: createId(), + adv: { + js: '<>\n {cell.key === "luas_setifikat" && (\n
\n {cell.value}\n
\n )}\n', + css: "", + jsBuilt: + 'render(\n React.createElement(\n React.Fragment,\n null,\n cell.key === "luas_setifikat" &&\n React.createElement(\n "div",\n Object.assign({}, props, { className: cx(props.className, "") }),\n cell.value\n )\n )\n)', + }, + dim: { + h: "full", + w: "full", + }, + name: "luas_setifikat", + type: "item", + childs: [], + script: {}, + }, + { + id: createId(), + adv: { + js: '<>\n {cell.key === "tanggal_sertifikat" && (\n
\n {cell.value}\n
\n )}\n', + css: "", + jsBuilt: + 'render(\n React.createElement(\n React.Fragment,\n null,\n cell.key === "tanggal_sertifikat" &&\n React.createElement(\n "div",\n Object.assign({}, props, { className: cx(props.className, "") }),\n cell.value\n )\n )\n)', + }, + dim: { + h: "full", + w: "full", + }, + name: "tanggal_sertifikat", + type: "item", + childs: [], + script: {}, + }, + ], + hidden: false, + }, + typings: + "const typings = {\n cell: `{ key: string, value: any }`,\n row: `any`,\n idx: `number`,\n rows: `any[]`,\n}", + valueBuilt: ' "hello";\n', + }, + columns: { + idx: 0, + meta: { + type: "text", + }, + name: "prop_1", + type: "string", + value: + 'async (): Promise<\n { key: string; name: string; width?: number; frozen?: boolean }[]\n > => {\n return [\n { key: "id", name: "#", width: 60, frozen: true },\n {"key":"nama_aset_komersial","name":"Nama Aset Komersial"},\n {"key":"m_cabang","name":"Cabang"},\n {"key":"m_regional","name":"Regional"},\n {"key":"luas_setifikat","name":"Luas Setifikat"},\n {"key":"tanggal_sertifikat","name":"Tanggal Sertifikat"}\n ];\n }', + valueBuilt: + ' async () => {\n return [\n { key: "id", name: "#", width: 60, frozen: true },\n { "key": "nama_aset_komersial", "name": "Nama Aset Komersial" },\n { "key": "m_cabang", "name": "Cabang" },\n { "key": "m_regional", "name": "Regional" },\n { "key": "luas_setifikat", "name": "Luas Setifikat" },\n { "key": "tanggal_sertifikat", "name": "Tanggal Sertifikat" }\n ];\n};\n', + }, + on_load: { + idx: 1, + meta: { + type: "text", + }, + name: "prop_1", + type: "string", + value: + "async () => {\n if (isEditor)\n return [\n {\n id: createId(),\n },\n });\n\n return items;\n}", + valueBuilt: + ' async () => {\n if (isEditor)\n return [\n {\n id: createId(),\n tanggal_sertifikat: "sample"\n }\n ];\n const items = await db.m_aset.findMany({\n select: {\n id: true,\n nama_aset_komersial: true,\n m_cabang: {\n select: {\n id: true,\n nama_cabang: true\n }\n },\n m_regional: {\n select: {\n regional: true,\n id: true\n }\n },\n luas_setifikat: true,\n tanggal_sertifikat: true\n },\n orderBy: {\n id: "desc"\n }\n });\n return items;\n};\n', + }, + generate: { + idx: 5, + name: "prop_5", + type: "string", + value: '"n"', + valueBuilt: '"n"', + meta: { + type: "option", + }, + }, + gen_table: { + idx: 7, + name: "prop_7", + type: "string", + value: '""', + valueBuilt: '""', + meta: { + type: "option", + }, + }, + gen_fields: { + idx: 9, + name: "prop_9", + type: "string", + value: "[]", + valueBuilt: "[]", + meta: { + type: "option", + }, + }, + row_click: { + idx: 11, + name: "prop_11", + type: "string", + value: + "({ row, rows, idx, event }: OnRowClick) => {\n md.selected = row;\n md.render();\n};\n\ntype OnRowClick = {\n row: any;\n rows: any[];\n idx: any;\n event: React.MouseEvent;\n}", + valueBuilt: + " ({ row, rows, idx, event }) => {\n md.selected = row;\n md.render();\n};\n", + meta: { + type: "text", + }, + }, + gen_button: { + idx: 11, + name: "prop_11", + type: "string", + value: '"hello"', + valueBuilt: '"hello"', + meta: { + type: "button", + }, + }, + }, + ref_ids: {}, + instances: {}, + }, + originalId: "gxwni8zmj8zhiogfa52eoq6a", + }, + ], + adv: { + css: "& {\n display: flex;\n\n .rdg-row {\n cursor: pointer;\n }\n\n // &.mobile {}\n // &.desktop {}\n // &:hover {}\n}", + }, + }; + + return { content: res, props: res.childs[0].component.props }; +}; diff --git a/gen/gen_md/gen_md.ts b/gen/gen_md/gen_md.ts new file mode 100755 index 0000000..8f94f03 --- /dev/null +++ b/gen/gen_md/gen_md.ts @@ -0,0 +1,97 @@ +import get from "lodash.get"; +import { GFCol as Col, GFCol, formatName } from "../utils"; +import { NewFieldArg } from "../gen_form/new_field"; +import { gen_header } from "./gen_header"; +import { gen_master } from "./gen_master"; +import { on_load as table_on_load } from "../gen_table/on_load"; +import { on_load as form_on_load } from "../gen_form/on_load"; +import { on_submit as form_on_submit } from "../gen_form/on_submit"; +import { gen_columns } from "../gen_table/columns"; +import { newField as table_new_field } from "../gen_table/new_field"; +import { gen_detail } from "./gen_detail"; +import { form_before_load } from "./form_before_load"; + +export const gen_md = (modify: (data: any) => void, data: any) => { + const table = JSON.parse(data.gen_table.value); + const fields = JSON.parse(data.gen_fields.value); + const select = {} as any; + const columns = [] as GFCol[]; + const new_fields: NewFieldArg[] = []; + + let pk: Col | null = null; + let pks: Record = {}; + + 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 } }; + col.relation = { table: col.name, pk: sel.name }; + } else { + fields.push(c.name); + } + } + columns.push(col); + 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; + columns.push(col); + } + } + + const result: any = {}; + if (pk) { + result["header"] = data["header"]; + result["header"].content = gen_header(); + + result["master"] = data["master"]; + const { content, props } = gen_master(); + props["columns"].value = gen_columns(columns); + props["on_load"].value = table_on_load({ pk: pk.name, table, select, pks }); + props["child"].content.childs = table_new_field(select, pks); + result["master"].content = content; + + result["detail"] = data["detail"]; + const detail = gen_detail(); + const title = JSON.parse(get(data, "title.value")); + const before_load = form_before_load(pk.name, title, ""); + + detail.props["on_load"].value = form_on_load({ pk, pks, select, table }); + detail.props["on_submit"].value = form_on_submit({ + pk, + table, + select, + pks, + }); + result["detail"].content = detail.content; + } + // modify(result); + + alert("Prop Generated!"); +}; diff --git a/gen/gen_table/columns.ts b/gen/gen_table/columns.ts new file mode 100755 index 0000000..6fcaf70 --- /dev/null +++ b/gen/gen_table/columns.ts @@ -0,0 +1,26 @@ +import { GFCol, formatName } from "../utils"; + +export const gen_columns = (cols: GFCol[]) => { + return `async (): Promise< + { key: string; name: string; width?: number; frozen?: boolean }[] + > => { + return [ + { key: "id", name: "#", width: 60, frozen: true }, +${cols + .filter((e) => { + if (e.is_pk) return false; + return true; + }) + .map((e) => { + return ( + " " + + JSON.stringify({ + key: e.name, + name: formatName(e.name), + }) + ); + }) + .join(",\n")} + ]; + }`; +}; diff --git a/gen/gen_table/gen_table.ts b/gen/gen_table/gen_table.ts new file mode 100755 index 0000000..8c4cf49 --- /dev/null +++ b/gen/gen_table/gen_table.ts @@ -0,0 +1,64 @@ +import capitalize from "lodash.capitalize"; +import { GFCol } from "../utils"; +import { gen_columns } from "./columns"; +import { newField } from "./new_field"; +import { on_load } from "./on_load"; + +export const gen_table = (modify: (data: any) => void, data: any) => { + const table = JSON.parse(data.gen_table.value) as string; + const fields = JSON.parse(data.gen_fields.value) as ( + | string + | { value: string; checked: string[] } + )[]; + const select = {} as any; + const columns = [] as GFCol[]; + let pk = ""; + let pks: Record = {}; + + for (const f of fields) { + if (typeof f === "string") { + const col = JSON.parse(f) as GFCol; + columns.push(col); + select[col.name] = true; + if (col.is_pk) pk = col.name; + } else { + const col = JSON.parse(f.value) as GFCol; + const subsel: any = {}; + for (const s of f.checked) { + const sel = JSON.parse(s) as GFCol; + if (sel.is_pk) { + pks[col.name] = sel.name; + col.relation = { table: col.name, pk: sel.name }; + } + subsel[sel.name] = true; + } + select[col.name] = { select: subsel }; + columns.push(col); + } + } + + const result = {} as any; + if (data["columns"]) { + result["columns"] = data["columns"]; + result["columns"].value = gen_columns(columns); + } + if (data["on_load"]) { + result["on_load"] = data["on_load"]; + result["on_load"].value = on_load({ pk, table, select, pks }); + } + if (data["child"]) { + result["child"] = data["child"]; + result["child"].content.childs = newField(select, pks); + } + modify(result); + + alert("Prop Generated!"); +}; + +const formatName = (name: string) => { + return name + .split("_") + .filter((e) => e.length > 1) + .map((e) => capitalize(e)) + .join(" "); +}; diff --git a/gen/gen_table/new_field.ts b/gen/gen_table/new_field.ts new file mode 100755 index 0000000..500cdfa --- /dev/null +++ b/gen/gen_table/new_field.ts @@ -0,0 +1,89 @@ +import { createId } from "@paralleldrive/cuid2"; +import { GFCol } from "../utils"; + +export const newField = (select: any, pks: Record) => { + const result = []; + + for (const [k, v] of Object.entries(select) as any) { + if (typeof v === "object") { + const res = Object.keys(v.select) + .filter((e) => e !== pks[k]) + .map((e) => `cell.value?.["${e}"]`) + .join('+ " " +'); + + result.push({ + id: createId(), + adv: { + js: `\ +<> + {cell.key === "${k}" && ( +
+ {${res}} +
+ )} +`, + css: "", + jsBuilt: `\ +render( + React.createElement( + React.Fragment, + null, + cell.key === "${k}" && + React.createElement( + "div", + Object.assign({}, props, { className: cx(props.className, "") }), + ${res} + ) + ) +)`, + }, + dim: { + h: "full", + w: "full", + }, + name: k, + type: "item", + childs: [], + script: {}, + }); + } else { + result.push({ + id: createId(), + adv: { + js: `\ +<> + {cell.key === "${k}" && ( +
+ {cell.value} +
+ )} +`, + css: "", + jsBuilt: `\ +render( + React.createElement( + React.Fragment, + null, + cell.key === "${k}" && + React.createElement( + "div", + Object.assign({}, props, { className: cx(props.className, "") }), + cell.value + ) + ) +)`, + }, + dim: { + h: "full", + w: "full", + }, + name: k, + type: "item", + childs: [], + script: {}, + }); + } + } + + return result; +}; diff --git a/gen/gen_table/on_load.ts b/gen/gen_table/on_load.ts new file mode 100755 index 0000000..bf63fe5 --- /dev/null +++ b/gen/gen_table/on_load.ts @@ -0,0 +1,43 @@ +import { GFCol } from "../utils"; + +export const on_load = ({ + pk, + table, + select, + pks, +}: { + pk: string; + table: string; + select: any; + pks: Record; +}) => { + const sample = {} as any; + + for (const [k, v] of Object.entries(select) as any) { + if (typeof v === "object") { + sample[k] = {}; + + Object.keys(v.select) + .filter((e) => e !== pks[k]) + .map((e) => { + sample[k][e] = "sample"; + }); + } else { + sample[k] = "sample"; + } + } + + return `\ +async () => { + if (isEditor) return [${JSON.stringify(sample)}]; + + const items = await db.${table}.findMany({ + select: ${JSON.stringify(select, null, 2).split("\n").join("\n ")}, + orderBy: { + ${pk}: "desc" + } + }); + + return items; +}`; +}; diff --git a/gen/utils.ts b/gen/utils.ts new file mode 100755 index 0000000..c9ea64b --- /dev/null +++ b/gen/utils.ts @@ -0,0 +1,20 @@ +import capitalize from "lodash.capitalize"; + +export type GFCol = { + name: string; + type: string; + is_pk: boolean; + optional: boolean; + relation?: { + table: string; + pk: string; + }; +}; + +export const formatName = (name: string) => { + return (name || "") + .split("_") + .filter((e) => e.length > 1) + .map((e) => capitalize(e)) + .join(" "); +};