fix lib
This commit is contained in:
parent
eb4d36c730
commit
f83cad0fa2
|
|
@ -78,6 +78,20 @@ async ({ form, error, fm }: IForm) => {
|
||||||
fk: string;
|
fk: string;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
// validasi
|
||||||
|
fm.error.clear();
|
||||||
|
for (const [k, field] of Object.entries(fm.fields)) {
|
||||||
|
validateField(field, fm);
|
||||||
|
}
|
||||||
|
if (fm.error.list.length > 0) {
|
||||||
|
if (typeof md !== "undefined") {
|
||||||
|
fm.status = "ready";
|
||||||
|
md.render();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// pisahkan antara has_many dengan field biasa
|
// pisahkan antara has_many dengan field biasa
|
||||||
for (const [k, v] of Object.entries(data) as any) {
|
for (const [k, v] of Object.entries(data) as any) {
|
||||||
if (Array.isArray(v)) {
|
if (Array.isArray(v)) {
|
||||||
|
|
@ -100,6 +114,8 @@ async ({ form, error, fm }: IForm) => {
|
||||||
// prisma create / update ga boleh ada record.${pk}
|
// prisma create / update ga boleh ada record.${pk}
|
||||||
if (record) delete record.${pk};
|
if (record) delete record.${pk};
|
||||||
|
|
||||||
|
call_prasi_events("form", "before_save", [fm, record]);
|
||||||
|
|
||||||
if (form.${pk}) {
|
if (form.${pk}) {
|
||||||
await db.${table}.update({
|
await db.${table}.update({
|
||||||
where: {
|
where: {
|
||||||
|
|
@ -165,7 +181,14 @@ async ({ form, error, fm }: IForm) => {
|
||||||
|
|
||||||
if (typeof md !== "undefined") {
|
if (typeof md !== "undefined") {
|
||||||
fm.status = "ready";
|
fm.status = "ready";
|
||||||
|
// kembali ke tabel
|
||||||
|
setTimeout(() => {
|
||||||
|
md.selected = null;
|
||||||
|
md.tab.active = "master";
|
||||||
|
md.internal.action_should_refresh = true;
|
||||||
|
md.params.apply();
|
||||||
md.render();
|
md.render();
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,16 @@ async (opt) => {
|
||||||
${pk}: id,
|
${pk}: id,
|
||||||
};
|
};
|
||||||
if (id){
|
if (id){
|
||||||
|
//@ts-ignore
|
||||||
const table = db[gen__table] as any;
|
const table = db[gen__table] as any;
|
||||||
|
//@ts-ignore
|
||||||
const fields = parseGenField(gen__fields);
|
const fields = parseGenField(gen__fields);
|
||||||
|
|
||||||
|
if (Array.isArray(fields)) {
|
||||||
|
const pk = fields.find((e) => e.is_pk);
|
||||||
|
if (pk && pk.type === "int") id = parseInt(id);
|
||||||
|
}
|
||||||
|
|
||||||
const gen = generateSelect(fields);
|
const gen = generateSelect(fields);
|
||||||
item = await table?.findFirst({
|
item = await table?.findFirst({
|
||||||
where,
|
where,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { GFCol } from "@/gen/utils";
|
import { GFCol } from "@/gen/utils";
|
||||||
import { MutableRefObject, ReactNode } from "react";
|
import { MutableRefObject, ReactElement, ReactNode } from "react";
|
||||||
import { editorFormData } from "./utils/ed-data";
|
import { editorFormData } from "./utils/ed-data";
|
||||||
|
|
||||||
export type FMProps = {
|
export type FMProps = {
|
||||||
|
|
@ -20,7 +20,7 @@ export type FMProps = {
|
||||||
on_load_deps?: any[];
|
on_load_deps?: any[];
|
||||||
feature?: any[];
|
feature?: any[];
|
||||||
sfd_field?: any;
|
sfd_field?: any;
|
||||||
style: "default" | "flex"
|
style: "default" | "flex";
|
||||||
};
|
};
|
||||||
|
|
||||||
export type GenField =
|
export type GenField =
|
||||||
|
|
@ -51,7 +51,7 @@ export type FieldProp = {
|
||||||
type: FieldType | (() => FieldType);
|
type: FieldType | (() => FieldType);
|
||||||
required: ("y" | "n") | (() => "y" | "n");
|
required: ("y" | "n") | (() => "y" | "n");
|
||||||
field_ref?: (ref: any) => void;
|
field_ref?: (ref: any) => void;
|
||||||
required_msg: (name: string) => string;
|
required_msg: (name: string) => string | ReactElement;
|
||||||
on_change: (arg: { value: any }) => void | Promise<void>;
|
on_change: (arg: { value: any }) => void | Promise<void>;
|
||||||
PassProp: any;
|
PassProp: any;
|
||||||
disabled: "y" | "n";
|
disabled: "y" | "n";
|
||||||
|
|
@ -109,7 +109,7 @@ export type FMInternal = {
|
||||||
error: {
|
error: {
|
||||||
readonly object: Record<string, string>;
|
readonly object: Record<string, string>;
|
||||||
readonly list: { name: string; error: string[] }[];
|
readonly list: { name: string; error: string[] }[];
|
||||||
set: (name: string, error: string[]) => void;
|
set: (name: string, error: (string | ReactElement)[]) => void;
|
||||||
get: (name: string) => string[];
|
get: (name: string) => string[];
|
||||||
clear: (name?: string) => void;
|
clear: (name?: string) => void;
|
||||||
};
|
};
|
||||||
|
|
@ -256,4 +256,3 @@ export const FieldTypeCustom = `type CustomField =
|
||||||
{ field: "text", type: "text" | "password" | "number" | "date" | "datetime" }
|
{ field: "text", type: "text" | "password" | "number" | "date" | "datetime" }
|
||||||
| { field: "relation", type: "has-many" | "has-one" }
|
| { field: "relation", type: "has-many" | "has-one" }
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@ export const formError = (fm: FMLocal) => {
|
||||||
const error = {
|
const error = {
|
||||||
_internal: {},
|
_internal: {},
|
||||||
get list() {
|
get list() {
|
||||||
if (fm.status !== "ready") return [];
|
|
||||||
|
|
||||||
const res = Object.entries(this._internal).map(([name, error]) => {
|
const res = Object.entries(this._internal).map(([name, error]) => {
|
||||||
return { name, error };
|
return { name, error };
|
||||||
});
|
});
|
||||||
|
|
@ -28,7 +26,7 @@ export const formError = (fm: FMLocal) => {
|
||||||
return this._internal[name] || [];
|
return this._internal[name] || [];
|
||||||
},
|
},
|
||||||
set(name, error) {
|
set(name, error) {
|
||||||
this._internal[name] = error;
|
this._internal[name] = error as any;
|
||||||
},
|
},
|
||||||
} as FMLocal["error"] & {
|
} as FMLocal["error"] & {
|
||||||
_internal: Record<string, string[]>;
|
_internal: Record<string, string[]>;
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
import { FMLocal, FieldLocal } from "../typings";
|
|
||||||
|
|
||||||
export const validate = (field: FieldLocal, fm: FMLocal) => {
|
|
||||||
if (fm.status !== "ready") return;
|
|
||||||
|
|
||||||
let msg = (name: string) => {
|
|
||||||
return `${name} harus diisi`;
|
|
||||||
};
|
|
||||||
if (typeof field.required_msg === "function") {
|
|
||||||
msg = field.required_msg;
|
|
||||||
}
|
|
||||||
if (field.required) {
|
|
||||||
const error_msg = msg(field.name);
|
|
||||||
const error_list = fm.error.get(field.name).filter((e) => e !== error_msg);
|
|
||||||
if (!fm.data[field.name]) {
|
|
||||||
fm.error.set(field.name, [error_msg, ...error_list]);
|
|
||||||
} else {
|
|
||||||
fm.error.set(field.name, error_list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { FMLocal, FieldLocal } from "../typings";
|
||||||
|
|
||||||
|
export const validate = (field: FieldLocal, fm: FMLocal, record?: any) => {
|
||||||
|
const msg = (name: string) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<b
|
||||||
|
className={css`
|
||||||
|
font-weight: bold;
|
||||||
|
text-transform: capitalize;
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{name}
|
||||||
|
</b>{" "}
|
||||||
|
is required.
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
if (field.required) {
|
||||||
|
const data = record || fm.data;
|
||||||
|
const error_msg = msg(field.name);
|
||||||
|
if (!data[field.name]) {
|
||||||
|
fm.error.set(field.name, [error_msg]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -61,6 +61,8 @@ export { parseGenField } from "@/gen/utils";
|
||||||
export { filterModifier } from "@/comps/filter/utils/filter-modifier";
|
export { filterModifier } from "@/comps/filter/utils/filter-modifier";
|
||||||
export { generateField } from "@/comps/form/gen/gen-field";
|
export { generateField } from "@/comps/form/gen/gen-field";
|
||||||
export { generateForm } from "@/comps/form/gen/gen-form";
|
export { generateForm } from "@/comps/form/gen/gen-form";
|
||||||
|
export { validate as validateField } from "./comps/form/utils/validate";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
FMLocal,
|
FMLocal,
|
||||||
FieldTypeCustom,
|
FieldTypeCustom,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
import { on_load } from "lib/comps/form/gen/on_load";
|
||||||
import { codeBuild } from "../master_detail/utils";
|
import { codeBuild } from "../master_detail/utils";
|
||||||
import { GFCol, parseGenField } from "../utils";
|
import { GFCol, parseGenField } from "../utils";
|
||||||
import { newField } from "./new_field";
|
import { newField } from "./new_field";
|
||||||
import { on_load } from "./on_load";
|
|
||||||
import { on_submit } from "./on_submit";
|
import { on_submit } from "./on_submit";
|
||||||
|
|
||||||
export const gen_form = async (modify: (data: any) => void, data: any) => {
|
export const gen_form = async (modify: (data: any) => void, data: any) => {
|
||||||
|
|
@ -43,7 +43,7 @@ export const gen_form = async (modify: (data: any) => void, data: any) => {
|
||||||
const code = {} as any;
|
const code = {} as any;
|
||||||
if (data["on_load"]) {
|
if (data["on_load"]) {
|
||||||
result["on_load"] = data["on_load"];
|
result["on_load"] = data["on_load"];
|
||||||
result["on_load"].value = on_load({ pk, pks, select, table });
|
result["on_load"].value = on_load({ pk: pk.name, pks, select, table });
|
||||||
code.on_load = result["on_load"].value;
|
code.on_load = result["on_load"].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
import { GFCol } from "../utils";
|
|
||||||
|
|
||||||
export const on_load = ({
|
|
||||||
pk,
|
|
||||||
table,
|
|
||||||
select,
|
|
||||||
pks,
|
|
||||||
opt,
|
|
||||||
}: {
|
|
||||||
pk: GFCol;
|
|
||||||
table: string;
|
|
||||||
select: any;
|
|
||||||
pks: Record<string, string>;
|
|
||||||
opt?: {
|
|
||||||
before_load: string;
|
|
||||||
after_load: string;
|
|
||||||
};
|
|
||||||
}) => {
|
|
||||||
const sample: any = {};
|
|
||||||
for (const [k, v] of Object.entries(select) as any) {
|
|
||||||
if (typeof v === "object") {
|
|
||||||
sample[k] = {};
|
|
||||||
|
|
||||||
Object.keys(v.select).map((e) => {
|
|
||||||
sample[k][e] = "sample";
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
sample[k] = "sample";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return `\
|
|
||||||
async (opt) => {
|
|
||||||
if (isEditor) return ${JSON.stringify(sample)};
|
|
||||||
|
|
||||||
let raw_id = params.id;
|
|
||||||
if (typeof md === 'object' && md.selected && md.pk) {
|
|
||||||
const pk = md.pk?.name;
|
|
||||||
if (md.selected[pk]) {
|
|
||||||
raw_id = md.selected[pk];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parseInt(raw_id)) raw_id = parseInt(raw_id);
|
|
||||||
|
|
||||||
${
|
|
||||||
opt?.before_load
|
|
||||||
? opt.before_load
|
|
||||||
: `let id = ${pk.type === "int" ? "parseInt(raw_id)" : "raw_id"};`
|
|
||||||
}
|
|
||||||
|
|
||||||
let item = {};
|
|
||||||
if (id){
|
|
||||||
item = await db.${table}.findFirst({
|
|
||||||
where: {
|
|
||||||
${pk.name}: id,
|
|
||||||
},
|
|
||||||
select: ${JSON.stringify(select, null, 2).split("\n").join("\n ")},
|
|
||||||
});
|
|
||||||
|
|
||||||
${opt?.after_load ? opt?.after_load : ""}
|
|
||||||
|
|
||||||
return item;
|
|
||||||
} else {
|
|
||||||
${opt?.after_load ? opt?.after_load : ""}
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
};
|
|
||||||
|
|
@ -5,8 +5,8 @@ const w = window as any;
|
||||||
const parse = parser.exportAsFunctionAny("en-US");
|
const parse = parser.exportAsFunctionAny("en-US");
|
||||||
export const loadSession = (url_login?: string) => {
|
export const loadSession = (url_login?: string) => {
|
||||||
if (!isEditor) {
|
if (!isEditor) {
|
||||||
let id_site = ""
|
let id_site = "";
|
||||||
if (location.hostname === "prasi.avolut.com" ) {
|
if (location.hostname === "prasi.avolut.com") {
|
||||||
const parts = location.pathname.split("/");
|
const parts = location.pathname.split("/");
|
||||||
id_site = parts[2];
|
id_site = parts[2];
|
||||||
}
|
}
|
||||||
|
|
@ -25,6 +25,7 @@ export const loadSession = (url_login?: string) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return w.user;
|
||||||
} else {
|
} else {
|
||||||
if (url_login) logout(url_login);
|
if (url_login) logout(url_login);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
import { FMLocal } from "../..";
|
import { FMLocal } from "../..";
|
||||||
import { Prisma } from "../../typings/prisma";
|
import { Prisma } from "../../typings/prisma";
|
||||||
|
import { set } from "./set";
|
||||||
|
|
||||||
const events = {
|
const events = {
|
||||||
form: {
|
form: {
|
||||||
where: async (fm: FMLocal, where: any) => {},
|
where: async (fm: FMLocal, where: any) => {},
|
||||||
before_update: async (fm: FMLocal) => {},
|
before_save: async (fm: FMLocal, record: any) => {},
|
||||||
after_update: async (fm: FMLocal) => {},
|
|
||||||
before_insert: async (fm: FMLocal) => {},
|
|
||||||
after_insert: async (fm: FMLocal) => {},
|
|
||||||
before_load: async (fm: FMLocal) => {},
|
before_load: async (fm: FMLocal) => {},
|
||||||
after_load: async (fm: FMLocal) => {},
|
after_load: async (fm: FMLocal) => {},
|
||||||
},
|
},
|
||||||
|
|
@ -16,16 +14,24 @@ const events = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let w = null as any;
|
|
||||||
if (typeof window !== "undefined") {
|
|
||||||
w = window;
|
|
||||||
if (!w.prasi_events) {
|
|
||||||
w.prasi_events = events;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type PRASI_EVENT = typeof events;
|
type PRASI_EVENT = typeof events;
|
||||||
export const prasi_events: PRASI_EVENT = w.prasi_events;
|
export const prasi_events = <
|
||||||
|
K extends keyof PRASI_EVENT,
|
||||||
|
L extends keyof PRASI_EVENT[K]
|
||||||
|
>(
|
||||||
|
k: K,
|
||||||
|
l: L,
|
||||||
|
fn?: PRASI_EVENT[K][L]
|
||||||
|
) => {
|
||||||
|
const w = window as any;
|
||||||
|
if (!w.__prasi_custom_events) {
|
||||||
|
w.__prasi_custom_events = events;
|
||||||
|
}
|
||||||
|
if (fn) {
|
||||||
|
set(w.__prasi_custom_events, `${k}.${l as string}`, fn);
|
||||||
|
}
|
||||||
|
return w.__prasi_custom_events?.[k]?.[l];
|
||||||
|
};
|
||||||
export const call_prasi_events = async <
|
export const call_prasi_events = async <
|
||||||
K extends keyof PRASI_EVENT,
|
K extends keyof PRASI_EVENT,
|
||||||
L extends keyof PRASI_EVENT[K]
|
L extends keyof PRASI_EVENT[K]
|
||||||
|
|
@ -34,7 +40,7 @@ export const call_prasi_events = async <
|
||||||
l: L,
|
l: L,
|
||||||
args: any[]
|
args: any[]
|
||||||
) => {
|
) => {
|
||||||
const fn = prasi_events?.[k]?.[l] as any;
|
const fn = prasi_events(k, l);
|
||||||
|
|
||||||
if (fn) {
|
if (fn) {
|
||||||
await fn(...args);
|
await fn(...args);
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,16 @@
|
||||||
import { prasi_gen } from "lib/gen/prasi_gen";
|
import { prasi_gen } from "lib/gen/prasi_gen";
|
||||||
|
|
||||||
export const sofDeleteField = async (
|
export const sofDeleteField = async (table: string, field: string) => {
|
||||||
table: string,
|
|
||||||
field: string
|
|
||||||
) => {
|
|
||||||
const result = {} as any;
|
const result = {} as any;
|
||||||
const fields =await prasi_gen.prop.fields(table);
|
const fields = await prasi_gen.prop.fields(table);
|
||||||
const value = fields.find((e: any) => {
|
const value = fields.find((e: any) => {
|
||||||
const val = JSON.parse(e.value);
|
const val = JSON.parse(e.value);
|
||||||
if (val.type === "has-one" || val.type === "has-many" || val.is_pk) {
|
if (val.type === "has-one" || val.type === "has-many" || val.is_pk) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (e.label === field);
|
return e.label === field;
|
||||||
});
|
});
|
||||||
if(value) return JSON.parse(value.value)
|
if (typeof value === "object" && typeof value.value === "string")
|
||||||
|
return JSON.parse(value.value);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue