From d14e07a1fce85d4f50714dc02ae99b9ba7c9986a Mon Sep 17 00:00:00 2001 From: rizky Date: Tue, 13 Aug 2024 03:42:11 -0700 Subject: [PATCH] fix kv --- comps/form/Form.tsx | 3 +++ comps/form/field/Field.tsx | 30 ++++++++++++++++++++++++++ comps/form/field/type/KeyValue.tsx | 32 ++++++++++++++++++++++------ comps/form/field/type/TypeInput.tsx | 1 + comps/form/gen/gen-form/on-submit.ts | 2 ++ comps/form/typings.ts | 3 ++- comps/form/utils/init.tsx | 3 +++ 7 files changed, 67 insertions(+), 7 deletions(-) diff --git a/comps/form/Form.tsx b/comps/form/Form.tsx index 3b644db..f7ef193 100755 --- a/comps/form/Form.tsx +++ b/comps/form/Form.tsx @@ -24,6 +24,7 @@ export const Form: FC = (props) => { reload: async () => { formReload(fm); }, + save_status: "init", fields: {}, events: { on_change(name: string, new_value: any) {}, @@ -81,7 +82,9 @@ export const Form: FC = (props) => { fm.soft_delete.field = null; } } + }, []); + const ref = useRef({ el: null as null | HTMLFormElement, rob: new ResizeObserver(([e]) => { diff --git a/comps/form/field/Field.tsx b/comps/form/field/Field.tsx index 11adaac..ff3edfb 100755 --- a/comps/form/field/Field.tsx +++ b/comps/form/field/Field.tsx @@ -6,6 +6,7 @@ import { useField } from "../utils/use-field"; import { validate } from "../utils/validate"; import { FieldInput } from "./FieldInput"; import { Label } from "./Label"; +import { hashSum } from "lib/utils/hash-sum"; export const Field: FC = (arg) => { const showlabel = arg.show_label || "y"; @@ -19,7 +20,33 @@ export const Field: FC = (arg) => { const w = field.width; useEffect(() => { + if (fm.save_status === "init" || fm.status !== "ready") return; + if (local.prev_val === undefined) { + if (typeof fm.data[name] === "object") { + const sfied = hashSum(fm.data[name]); + if (sfied !== local.prev_val) { + local.prev_val = sfied; + } else { + return; + } + } else { + local.prev_val = fm.data[name]; + } + return; + } + if (local.prev_val !== fm.data[name]) { + if (typeof fm.data[name] === "object") { + const sfied = hashSum(fm.data[name]); + if (sfied !== local.prev_val) { + local.prev_val = sfied; + } else { + return; + } + } else { + local.prev_val = fm.data[name]; + } + if ( (!local.prev_val && fm.data[name]) || (local.prev_val && !fm.data[name]) @@ -30,6 +57,9 @@ export const Field: FC = (arg) => { if (arg.on_change) { arg.on_change({ value: fm.data[name], name, fm }); } + + fm.save_status = "unsaved"; + if (!fm.events) { fm.events = { on_change(name, new_value) {}, diff --git a/comps/form/field/type/KeyValue.tsx b/comps/form/field/type/KeyValue.tsx index 78e682c..09d35cb 100755 --- a/comps/form/field/type/KeyValue.tsx +++ b/comps/form/field/type/KeyValue.tsx @@ -5,19 +5,30 @@ import { useEffect, useRef } from "react"; export const KeyValue = ({ value, onChange, + index, }: { value: any; onChange: (val: any) => void; + index?: "preserve" | "auto-sort"; }) => { const local = useLocal({ - entries: Object.entries(value), + entries: [] as [string, string][], new: { idx: -1, key: "", value: "" }, }); const ref = useRef(null); useEffect(() => { + let entries: any[] = []; + if (index === "preserve") { + if (Array.isArray(value)) { + local.entries = value; + } else { + local.entries = Object.entries(value); + } + } + if (local.entries.length > 0) { - Object.entries(value).forEach(([k, v], idx) => { + entries.forEach(([k, v], idx) => { const found = local.entries.find((e) => { if (e[0] === k) return true; return false; @@ -30,8 +41,9 @@ export const KeyValue = ({ } }); } else { - local.entries = Object.entries(value); + local.entries = entries; } + local.render(); }, [value]); @@ -87,7 +99,11 @@ export const KeyValue = ({ local.render(); }} onBlur={() => { - onChange(reverseEntries(local.entries)); + if (index === "preserve") { + onChange([...local.entries]); + } else { + onChange(reverseEntries(local.entries)); + } }} /> ))} @@ -106,7 +122,11 @@ export const KeyValue = ({ local.new.key = ""; local.new.value = ""; local.render(); - onChange(reverseEntries(local.entries)); + if (index === "preserve") { + onChange([...local.entries]); + } else { + onChange(reverseEntries(local.entries)); + } setTimeout(() => { ( ref?.current?.querySelector( @@ -186,7 +206,7 @@ const KVRow = ({ onChange={(e) => { update(idx, k, e.currentTarget.value || ""); }} - onKeyDown={(e) => { + onKeyUp={(e) => { if (e.key === "Backspace" && !e.currentTarget.value) { keyref.current?.focus(); } diff --git a/comps/form/field/type/TypeInput.tsx b/comps/form/field/type/TypeInput.tsx index ca77a21..fb7274b 100755 --- a/comps/form/field/type/TypeInput.tsx +++ b/comps/form/field/type/TypeInput.tsx @@ -217,6 +217,7 @@ export const FieldTypeInput: FC<{ case "key-value": return ( void; }; + save_status: "init" | "unsaved" | "saved"; fields: Record; field_def: Record; error: { diff --git a/comps/form/utils/init.tsx b/comps/form/utils/init.tsx index 409305f..1ecf283 100755 --- a/comps/form/utils/init.tsx +++ b/comps/form/utils/init.tsx @@ -23,6 +23,8 @@ export const formInit = (fm: FMLocal, props: FMProps) => { const toastSuccess = (opt: { addNewText: string }) => { const md = fm.deps.md as MDLocal; + fm.save_status = "saved"; + if (md) { toast.success(
{ } fm.data = result; + fm.save_status = "saved"; if (result === undefined) fm.data = {};