diff --git a/comps/filter/Filter.tsx b/comps/filter/Filter.tsx old mode 100644 new mode 100755 diff --git a/comps/form-old/Date/index.tsx b/comps/form-old/Date/index.tsx deleted file mode 100755 index 687457c..0000000 --- a/comps/form-old/Date/index.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { FC } from "react"; - -export const Date: FC<{ - on_select: (val: any) => void; -}> = ({ on_select }) => { - return ( - { - on_select(event.target.value); - }} - > - ); -}; diff --git a/comps/form-old/Datetime/index.tsx b/comps/form-old/Datetime/index.tsx deleted file mode 100755 index 95596e4..0000000 --- a/comps/form-old/Datetime/index.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { FC } from "react"; - -export const Datetime: FC<{ - on_select: (val: any) => void; -}> = ({ on_select }) => { - return ( - { - on_select(event.target.value); - }} - /> - ); -}; diff --git a/comps/form-old/Dropdown/index.tsx b/comps/form-old/Dropdown/index.tsx deleted file mode 100755 index 98d00f2..0000000 --- a/comps/form-old/Dropdown/index.tsx +++ /dev/null @@ -1,174 +0,0 @@ -import { Popover } from "@/comps/custom/Popover"; -import { Input } from "@/comps/ui/input"; -import { Skeleton } from "@/comps/ui/skeleton"; -import { useLocal } from "@/utils/use-local"; -import { ChevronDown } from "lucide-react"; -import { FC, useEffect } from "react"; -import { FieldListItem, FieldOptions } from "../type"; -import { FormHook } from "../utils/utils"; - -type DropdownProps = { - value: string; - options: FieldOptions; - form?: FormHook; - name: string; -}; - -export const Dropdown: FC = ({ value, options, form, name }) => { - const local = useLocal({ - status: "loading" as "loading" | "ready", - open: false, - ref: { input: null as null | HTMLInputElement }, - list: [] as FieldListItem[], - input: "", - label: "", - filter: "", - }); - - useEffect(() => { - if (form) { - local.status = "loading"; - local.render(); - const callback = (result: any[]) => { - local.list = result.map((e) => { - if (typeof e === "string") { - return { - value: e, - label: e, - }; - } - return e; - }); - - const found = local.list.find((e) => e.value === value); - if (found) { - local.label = found.label; - } - - local.status = "ready"; - local.render(); - }; - - const res = options({ data: form.hook.getValues(), current_name: name }); - if (res instanceof Promise) { - res.then(callback); - } else { - callback(res); - } - } - }, [options]); - - let filtered = local.list; - - if (local.filter) { - filtered = local.list.filter((e) => { - if (e.label.toLowerCase().includes(local.filter)) return true; - return false; - }); - } - - return ( - { - local.open = false; - local.render(); - }} - arrow={false} - className={cx("c-rounded-sm c-bg-white")} - content={ -
- {local.status === "loading" && ( - <> -
- - -
- - )} - {local.status === "ready" && ( - <> - {filtered.map((item, idx) => { - return ( -
0 && "c-border-t", - idx === 0 && "c-rounded-t-sm", - idx === local.list.length - 1 && "c-rounded-b-sm" - )} - onClick={() => { - if (form) { - local.open = false; - form.hook.setValue(name, item.value); - form.render(); - } - }} - > - {item.label} -
- ); - })} - - )} -
- } - > -
{ - local.open = true; - local.input = local.label; - local.filter = ""; - local.render(); - setTimeout(() => { - local.ref.input?.focus(); - }); - }} - > -
- -
- { - local.input = e.currentTarget.value; - local.filter = local.input.toLowerCase(); - local.render(); - }} - ref={(el) => { - local.ref.input = el; - }} - type="text" - /> - {!local.open && ( -
- {local.label} -
- )} -
-
- ); -}; diff --git a/comps/form-old/Dropdown/relation.tsx b/comps/form-old/Dropdown/relation.tsx deleted file mode 100755 index 873f622..0000000 --- a/comps/form-old/Dropdown/relation.tsx +++ /dev/null @@ -1,232 +0,0 @@ -import { Popover } from "@/comps/custom/Popover"; -import { Input } from "@/comps/ui/input"; -import { Skeleton } from "@/comps/ui/skeleton"; -import { useLocal } from "@/utils/use-local"; -import { ChevronDown, Loader2 } from "lucide-react"; -import { FC, useEffect } from "react"; -import { FieldListItem, FieldOptions } from "../type"; -import { FormHook } from "../utils/utils"; - -type RelationProps = { - value: string; - relation: { - table: string; - fields: string[]; - query: () => Promise; - }; - form?: FormHook; - name: string; -}; - -export const Relation: FC = ({ - relation, - value, - form, - name, -}) => { - const local = useLocal({ - status: "init" as "init" | "loading" | "ready", - open: false, - ref: { input: null as null | HTMLInputElement }, - list: [] as FieldListItem[], - input: "", - label: "", - filter: "", - pk_field: "", - timeout: null as any, - }); - - useEffect(() => { - clearTimeout(local.timeout); - local.timeout = setTimeout(async () => { - if (form) { - local.status = "loading"; - local.render(); - - 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 (typeof f === "string") { - 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); - } - 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) => { - if (typeof value === "object") { - if (value["connect"]) { - return e.value === value["connect"][local.pk_field]; - } - return e.value === value[local.pk_field]; - } else { - return e.value === value; - } - }); - if (found) { - local.label = found.label; - } - - local.status = "ready"; - local.render(); - } - }, 100); - }, [relation, location.hash, location.pathname, value]); - - let filtered = local.list; - - if (local.filter) { - filtered = local.list.filter((e) => { - if (e.label.toLowerCase().includes(local.filter)) return true; - return false; - }); - } - - return ( - { - local.open = false; - local.render(); - }} - arrow={false} - className={cx("c-rounded-sm c-bg-white")} - content={ -
- {local.status === "loading" && ( - <> -
- - -
- - )} - {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", - idx === 0 && "c-rounded-t-sm", - idx === local.list.length - 1 && "c-rounded-b-sm" - )} - onClick={() => { - if (form) { - local.open = false; - form.hook.setValue(name, { - connect: { [local.pk_field]: item.value }, - }); - form.render(); - } - }} - > - {item.label || "-"} -
- ); - })} -
- )} -
- } - > -
{ - local.open = true; - local.input = local.label; - local.filter = ""; - local.render(); - setTimeout(() => { - local.ref.input?.focus(); - }); - }} - > -
- -
- { - local.input = e.currentTarget.value; - local.filter = local.input.toLowerCase(); - local.render(); - }} - ref={(el) => { - local.ref.input = el; - }} - type="text" - /> - {!local.open && ( -
- {local.status !== "ready" ? ( - - ) : ( - <> {local.label || "-"} - )} -
- )} -
-
- ); -}; diff --git a/comps/form-old/Field.tsx b/comps/form-old/Field.tsx deleted file mode 100755 index 6a3e73e..0000000 --- a/comps/form-old/Field.tsx +++ /dev/null @@ -1,357 +0,0 @@ -import { - FormControl, - FormDescription, - FormField, - FormItem, - FormLabel, - FormMessage, -} from "@/comps/ui/form"; -import { useLocal } from "@/utils/use-local"; -import autosize from "autosize"; -import { FC, ReactNode, useEffect, useRef } from "react"; -import { Input } from "../ui/input"; -import { Textarea } from "../ui/textarea"; -import { Date } from "./Date"; -import { Datetime } from "./Datetime"; -import { Dropdown } from "./Dropdown"; -import { Relation } from "./Dropdown/relation"; -import { InputMoney } from "./InputMoney"; -import { Radio } from "./Radio"; -import { SliderOptions } from "./Slider/types"; -import { FieldOptions } from "./type"; -import { FormHook, modify } from "./utils/utils"; - -export const Field: FC<{ - name: string; - label: string; - desc?: string; - form?: FormHook; - type: - | "text" - | "number" - | "textarea" - | "dropdown" - | "relation" - | "password" - | "radio" - | "date" - | "datetime" - | "money" - | "slider" - | "master-link" - | "custom"; - required: "y" | "n"; - options: FieldOptions; - slider: () => Promise; - on_change: (arg: { value: any }) => void | Promise; - PassProp: any; - custom: "y" | "n"; - child: any; - selection: "single" | "multi"; - suffix: any; - placeholder?: any; - label_alt: - | ReactNode - | FC<{ modify: typeof modify; data: any; current_name: string }>; - rel_table: string; - rel_fields: string[]; - rel_query: () => any; -}> = ({ - name, - form, - desc, - label, - type, - required, - options, - slider, - on_change, - PassProp, - custom, - selection, - suffix, - child, - placeholder, - label_alt, - rel_fields, - rel_table, - rel_query, -}) => { - const values = form?.hook.getValues(); - const value = values[name]; - const local = useLocal({ - date: { - // label: "", - popup: false, - }, - slider: { - value: 0, - opt: { - step: 1, - min: { value: 0, label: "Start" }, - max: { value: 100, label: "End" }, - } as SliderOptions, - status: "init" as "init" | "loading" | "ready", - }, - modify: null as any, - }); - const textAreaRef = useRef(); - useEffect(() => { - autosize(textAreaRef.current); - return () => { - autosize.destroy(textAreaRef.current); - }; - }, []); - - useEffect(() => { - if (type === "slider") { - local.slider.value = parseSliderValue(value, local.slider.opt); - if (typeof slider === "function") { - if (local.slider.status === "init") { - local.slider.status = "ready"; - local.render(); - (async () => { - const res = await slider(); - - local.slider.opt = res; - local.render(); - })(); - } - } else { - local.slider.status = "ready"; - local.render(); - } - } - }, [value]); - - const inputKeyDown = (e: any) => { - if (e.key === "Enter" && form?.ref) { - form.submit(); - } - }; - - const onChange = (e: any) => { - form?.hook.setValue(name, e.currentTarget.value); - form?.render(); - }; - - if (form) { - form.label[name] = label; - if (required === "y") { - form.validation[name] = "required"; - - if (value) { - delete form.hook.formState.errors[name]; - } - } else { - delete form.validation[name]; - } - } - - return ( - <> - ( - - -
- {label} - {required === "y" && ( -

*

- )} -
-
- {typeof label_alt === "function" && - form && - label_alt({ - modify: local.modify - ? local.modify - : modify.bind({ - form, - }), - current_name: name, - data: form.hook.getValues(), - })} - {typeof label_alt !== "function" && label_alt} -
-
- - <> - {type === "custom" && ( -
- {custom} -
- )} - {type === "slider" && ( -
-
-
{local.slider.opt.min.value}
-
{local.slider.opt.min.label}
-
-
- { - const value = e.currentTarget.value; - - local.slider.value = parseSliderValue( - value, - local.slider.opt - ); - form?.hook.setValue(name, value); - local.render(); - }} - value={local.slider.value} - min={local.slider.opt.min.value} - max={local.slider.opt.max.value} - /> -
- {local.slider.value} -
-
- -
-
{local.slider.opt.max.value}
-
{local.slider.opt.max.label}
-
-
- )} - - {["text", "number", "password"].includes(type) && - (suffix !== "" ? ( -
- - - {suffix || "-"} - -
- ) : ( - - ))} - - {type === "textarea" && ( -