This commit is contained in:
rizky 2024-08-09 02:49:10 -07:00
parent 358b0bbb57
commit b1e40bf2ed
6 changed files with 127 additions and 39 deletions

View File

@ -119,7 +119,7 @@ export const Form: FC<FMProps> = (props) => {
fm.status = "init"; fm.status = "init";
fm.render(); fm.render();
} }
}, [getPathname()]); }, [getPathname({ hash: true })]);
useEffect(() => { useEffect(() => {
if (fm.status === "ready") { if (fm.status === "ready") {

View File

@ -124,7 +124,11 @@ export const BaseField = (prop: {
<div <div
className={cx( className={cx(
"field-error c-p-2 c-text-xs c-text-red-600", "field-error c-p-2 c-text-xs c-text-red-600",
field.desc && "c-pt-0" field.desc && "c-pt-0",
css`
padding-left: 0px !important;
`
)} )}
> >
{errors.map((err) => { {errors.map((err) => {

View File

@ -30,12 +30,10 @@ export const Field: FC<FieldProp> = (arg) => {
if (arg.on_change) { if (arg.on_change) {
arg.on_change({ value: fm.data[name], name, fm }); arg.on_change({ value: fm.data[name], name, fm });
} }
if(!fm.events){ if (!fm.events) {
fm.events = { fm.events = {
on_change(name, new_value) { on_change(name, new_value) {},
};
},
}
} }
fm.events.on_change(name, fm.data[name]); fm.events.on_change(name, fm.data[name]);
@ -52,8 +50,8 @@ export const Field: FC<FieldProp> = (arg) => {
}, [field]); }, [field]);
if (field.status === "init" && !isEditor) return null; if (field.status === "init" && !isEditor) return null;
let errors = fm.error.get(name); let errors = fm.error.get(name);
if(field.error){ if (field.error) {
errors = [field.error] errors = [field.error];
} }
const props = { ...arg.props }; const props = { ...arg.props };
@ -122,14 +120,19 @@ export const Field: FC<FieldProp> = (arg) => {
<div <div
className={cx( className={cx(
"field-error c-p-2 c-text-xs c-text-red-600", "field-error c-p-2 c-text-xs c-text-red-600",
field.desc && "c-pt-0" field.desc && "c-pt-0",
css`
padding-left: 0px !important;
`
)} )}
> >
{errors.map((err) => { {errors.map((err) => {
return <div>{err}</div>; return <div>{err}</div>;
})} })}
</div> </div>
) : <></>} ) : (
<></>
)}
</div> </div>
</LabelDiv> </LabelDiv>
); );

View File

@ -1,10 +1,12 @@
import { parseGenField } from "@/gen/utils"; import { parseGenField } from "@/gen/utils";
import get from "lodash.get"; import get from "lodash.get";
import { AlertTriangle, Check, Loader2 } from "lucide-react"; import { AlertTriangle, Check, ChevronLeft, Loader2, Plus } from "lucide-react";
import { FMLocal, FMProps } from "../typings"; import { FMLocal, FMProps } from "../typings";
import { editorFormData } from "./ed-data"; import { editorFormData } from "./ed-data";
import { formError } from "./error"; import { formError } from "./error";
import { toast } from "lib/comps/ui/toast"; import { toast } from "lib/comps/ui/toast";
import { Button } from "lib/comps/ui/button";
import { MDLocal } from "lib/comps/md/utils/typings";
export const formInit = (fm: FMLocal, props: FMProps) => { export const formInit = (fm: FMLocal, props: FMProps) => {
for (const [k, v] of Object.entries(props)) { for (const [k, v] of Object.entries(props)) {
@ -19,6 +21,107 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
fm.field_def[d.name] = d; fm.field_def[d.name] = d;
} }
const toastSuccess = (opt: { addNewText: string }) => {
const md = fm.deps.md as MDLocal;
if (md) {
toast.success(
<div
className={cx(
"c-flex c-flex-col c-select-none c-items-stretch c-flex-1 c-w-full"
)}
onClick={() => {
toast.dismiss();
}}
>
<div className="c-flex c-text-green-700 c-items-center success-title c-font-semibold">
<Check className="c-h-6 c-w-6 c-mr-1 " />
Record Saved
</div>
<div
className={cx(
"c-flex c-items-center c-justify-between c-space-x-2 c-p-3",
css`
border-radius: 10px;
margin: 0px -10px -10px -10px;
background: white;
border: 1px solid rgb(164, 208, 180);
padding-left: 5px !important;
.button {
font-size: 13px;
}
`
)}
>
<Button
variant={"link"}
size={"xs"}
className="c-cursor-pointer"
onClick={() => {
toast.dismiss();
md.selected = null;
md.tab.active = "master";
md.params.apply();
md.render();
md.master.reload();
}}
>
<ChevronLeft size={18} />{" "}
<div className="c-px-1">Back To List</div>
</Button>
<Button
variant={"default"}
size={"xs"}
className="c-cursor-pointer"
onClick={() => {
toast.dismiss();
for (const k of Object.keys(md.selected)) {
delete md.selected[k];
}
md.tab.active = "detail";
md.params.hash[md.name] = "+";
md.params.apply();
md.render();
}}
>
<div className="c-px-1">{opt.addNewText}</div> <Plus size={18} />
</Button>
</div>
</div>,
{
duration: 60 * 1000,
className: css`
background: #e4ffed;
border: 2px solid green;
.success-title {
margin-bottom: 20px;
}
`,
}
);
} else {
toast.success(
<div
className={cx("c-flex c-flex-col c-select-none")}
onClick={() => {}}
>
<div className="c-flex c-text-green-700 c-items-center">
<Check className="c-h-4 c-w-4 c-mr-1 " />
Saved
</div>
</div>,
{
duration: 60 * 1000,
className: css`
background: #e4ffed;
border: 2px solid green;
`,
}
);
}
};
fm.reload = async () => { fm.reload = async () => {
fm.status = isEditor ? "ready" : "loading"; fm.status = isEditor ? "ready" : "loading";
fm.render(); fm.render();
@ -82,18 +185,7 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
if (fm.is_newly_created) { if (fm.is_newly_created) {
fm.is_newly_created = false; fm.is_newly_created = false;
toast.success( toastSuccess({ addNewText: "Add Another" });
<div className="c-flex c-text-green-700 c-items-center">
<Check className="c-h-4 c-w-4 c-mr-1 " />
Saved
</div>,
{
className: css`
background: #e4ffed;
border: 2px solid green;
`,
}
);
} }
fm.status = "ready"; fm.status = "ready";
@ -176,18 +268,7 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
} }
); );
} else { } else {
toast.success( toastSuccess({ addNewText: "Add New" });
<div className="c-flex c-text-green-700 c-items-center">
<Check className="c-h-4 c-w-4 c-mr-1 " />
Saved
</div>,
{
className: css`
background: #e4ffed;
border: 2px solid green;
`,
}
);
} }
} }
return success; return success;

View File

@ -26,7 +26,7 @@ export const toast = {
}, },
success: ( success: (
el: ReactElement, el: ReactElement,
props?: { dismissible?: boolean; className?: string } props?: { dismissible?: boolean; className?: string; duration?: number }
) => { ) => {
clearTimeout(timer.timeout); clearTimeout(timer.timeout);
timer.timeout = setTimeout(() => { timer.timeout = setTimeout(() => {

View File

@ -10,7 +10,7 @@ export const getPathname = (opt?: { hash?: boolean }) => {
) { ) {
const hash = location.hash; const hash = location.hash;
if (hash !== "" && opt?.hash !== false) { if (hash !== "" && opt?.hash === true) {
return "/" + location.pathname.split("/").slice(3).join("/") + hash; return "/" + location.pathname.split("/").slice(3).join("/") + hash;
} else { } else {
return "/" + location.pathname.split("/").slice(3).join("/"); return "/" + location.pathname.split("/").slice(3).join("/");