This commit is contained in:
Rizky 2024-07-01 21:19:47 -07:00
parent 82f625bf38
commit edb153e260
18 changed files with 215 additions and 53 deletions

View File

@ -187,6 +187,8 @@ export function Popover({
content?: React.ReactNode; content?: React.ReactNode;
arrow?: boolean; arrow?: boolean;
} & PopoverOptions) { } & PopoverOptions) {
if (isEditor) return children;
const popover = usePopover({ modal, ...restOptions }); const popover = usePopover({ modal, ...restOptions });
let _content = content; let _content = content;

View File

@ -36,6 +36,7 @@ export const FieldInput: FC<{
const errors = fm.error.get(name); const errors = fm.error.get(name);
let type_field: any = typeof arg.type === "function" ? arg.type() : arg.type; // tipe field let type_field: any = typeof arg.type === "function" ? arg.type() : arg.type; // tipe field
const disabled = typeof field.disabled === "function" ? field.disabled() : field.disabled;
let custom = <></>; let custom = <></>;
if (field.type === "custom") { if (field.type === "custom") {
let res = arg.custom?.() || <></>; let res = arg.custom?.() || <></>;
@ -113,7 +114,7 @@ export const FieldInput: FC<{
? css` ? css`
border-color: transparent; border-color: transparent;
` `
: field.disabled : disabled
? "c-border-gray-100" ? "c-border-gray-100"
: errors.length > 0 : errors.length > 0
? field.focused ? field.focused
@ -145,7 +146,7 @@ export const FieldInput: FC<{
"field-inner c-flex-1 c-flex c-items-center", "field-inner c-flex-1 c-flex c-items-center",
field.type === "link" && "c-justify-end", field.type === "link" && "c-justify-end",
field.focused && "focused", field.focused && "focused",
field.disabled && "c-pointer-events-none" disabled && "c-pointer-events-none"
)} )}
> >
{not_ready ? ( {not_ready ? (

View File

@ -46,7 +46,6 @@ export const TypeDropdown: FC<{
} }
if ( if (
field.type === "single-option" && field.type === "single-option" &&
!value &&
field.required && field.required &&
local.options.length > 0 local.options.length > 0
) { ) {
@ -104,6 +103,7 @@ export const TypeDropdown: FC<{
); );
} }
} }
const disabled = typeof field.disabled === "function" ? field.disabled() : field.disabled;
if (!local.loaded) return <FieldLoading />; if (!local.loaded) return <FieldLoading />;
if (field.type === "single-option") { if (field.type === "single-option") {
@ -129,7 +129,7 @@ export const TypeDropdown: FC<{
return item?.value || search; return item?.value || search;
}} }}
disabled={field.disabled} disabled={disabled}
allowNew={false} allowNew={false}
autoPopupWidth={true} autoPopupWidth={true}
focusOpen={true} focusOpen={true}
@ -165,7 +165,7 @@ export const TypeDropdown: FC<{
autoPopupWidth={true} autoPopupWidth={true}
focusOpen={true} focusOpen={true}
mode={"multi"} mode={"multi"}
disabled={field.disabled} disabled={disabled}
placeholder={arg.placeholder} placeholder={arg.placeholder}
options={() => { options={() => {
return local.options; return local.options;

View File

@ -96,6 +96,7 @@ export const FieldTypeInput: FC<{
input.change_timeout = setTimeout(fm.render, 300); input.change_timeout = setTimeout(fm.render, 300);
}; };
const disabled = typeof field.disabled === "function" ? field.disabled() : field.disabled;
switch (type_field) { switch (type_field) {
case "toggle": case "toggle":
return ( return (
@ -144,7 +145,7 @@ export const FieldTypeInput: FC<{
renderOnChange(); renderOnChange();
}} }}
value={value || ""} value={value || ""}
disabled={field.disabled} disabled={disabled}
className="c-flex-1 c-bg-transparent c-outline-none c-p-2 c-text-sm c-w-full" className="c-flex-1 c-bg-transparent c-outline-none c-p-2 c-text-sm c-w-full"
spellCheck={false} spellCheck={false}
onFocus={() => { onFocus={() => {
@ -175,7 +176,7 @@ export const FieldTypeInput: FC<{
return ( return (
<Datepicker <Datepicker
value={{ startDate: value, endDate: value }} value={{ startDate: value, endDate: value }}
disabled={field.disabled} disabled={disabled}
displayFormat="DD MMM YYYY" displayFormat="DD MMM YYYY"
asSingle={true} asSingle={true}
useRange={false} useRange={false}
@ -215,7 +216,7 @@ export const FieldTypeInput: FC<{
}} }}
placeholder={prop.placeholder || arg.placeholder || ""} placeholder={prop.placeholder || arg.placeholder || ""}
value={value} value={value}
disabled={field.disabled} disabled={disabled}
className="c-flex-1 c-transition-all c-bg-transparent c-outline-none c-px-2 c-text-sm c-w-full" className="c-flex-1 c-transition-all c-bg-transparent c-outline-none c-px-2 c-text-sm c-w-full"
spellCheck={false} spellCheck={false}
onFocus={(e) => { onFocus={(e) => {

View File

@ -1,5 +1,5 @@
import { useLocal } from "@/utils/use-local"; import { useLocal } from "@/utils/use-local";
import { FC } from "react"; import { FC, useEffect } from "react";
import { FMLocal, FieldLocal, FieldProp } from "../../typings"; import { FMLocal, FieldLocal, FieldProp } from "../../typings";
import { PropTypeInput } from "./TypeInput"; import { PropTypeInput } from "./TypeInput";
import { isEmptyString } from "lib/utils/is-empty-string"; import { isEmptyString } from "lib/utils/is-empty-string";
@ -16,11 +16,17 @@ export const FieldMoney: FC<{
display: false as any, display: false as any,
ref: null as any, ref: null as any,
}); });
useEffect(() => {
input.value = value;
input.render();
}, [fm.data[field.name]]);
let display: any = null; let display: any = null;
const disabled =
typeof field.disabled === "function" ? field.disabled() : field.disabled;
const money = formatMoney(Number(value) || 0); const money = formatMoney(Number(value) || 0);
return ( return (
<div className="c-flex-grow c-flex-row c-flex c-w-full c-h-full"> <div className="c-flex-grow c-flex-row c-flex c-w-full c-h-full">
<div {/* <div
className={cx( className={cx(
input.display ? "c-hidden" : "", input.display ? "c-hidden" : "",
"c-flex-grow c-px-2 c-flex c-flex-row c-items-center", "c-flex-grow c-px-2 c-flex c-flex-row c-items-center",
@ -35,26 +41,47 @@ export const FieldMoney: FC<{
}} }}
> >
{isEmptyString(value) ? arg.placeholder : money} {isEmptyString(value) ? arg.placeholder : money}
</div> </div> */}
<input <input
ref={(el) => (input.ref = el)} ref={(el) => (input.ref = el)}
type={"number"} type={"text"}
onClick={() => {}} onClick={() => {}}
onChange={(ev) => { onChange={(ev) => {
fm.data[field.name] = Number(ev.currentTarget.value); const rawValue = ev.currentTarget.value
.replace(/[^0-9,-]/g, "")
.toString();
const now = Number(value) || 0;
if (
!rawValue.endsWith(",") &&
!rawValue.endsWith("-") &&
convertionCurrencyNumber(rawValue) !==
convertionCurrencyNumber(input.value)
) {
fm.data[field.name] = convertionCurrencyNumber(
formatCurrency(rawValue)
);
fm.render(); fm.render();
if (field.on_change) { if (field.on_change) {
field.on_change({ field.on_change({
value: Number(fm.data[field.name]), value: convertionCurrencyNumber(
formatCurrency(fm.data[field.name])
),
name: field.name, name: field.name,
fm, fm,
}); });
} }
input.value = formatCurrency(fm.data[field.name]);
input.render();
} else {
input.value = rawValue;
input.render();
}
}} }}
value={value} value={formatCurrency(input.value)}
disabled={field.disabled} disabled={disabled}
className={cx( className={cx(
!input.display ? "c-hidden" : "", // !input.display ? "c-hidden" : "",
"c-flex-1 c-bg-transparent c-outline-none c-px-2 c-text-sm c-w-full" "c-flex-1 c-bg-transparent c-outline-none c-px-2 c-text-sm c-w-full"
)} )}
spellCheck={false} spellCheck={false}
@ -62,8 +89,8 @@ export const FieldMoney: FC<{
field.focused = true; field.focused = true;
field.render(); field.render();
}} }}
placeholder={arg.placeholder || ""}
onBlur={() => { onBlur={() => {
console.log("blur");
field.focused = false; field.focused = false;
input.display = !input.display; input.display = !input.display;
input.render(); input.render();
@ -73,9 +100,91 @@ export const FieldMoney: FC<{
</div> </div>
); );
}; };
const convertionCurrencyNumber = (value: string) => {
if (!value) return null;
let numberString = value.toString().replace(/[^0-9,-]/g, "");
if (numberString.endsWith(",")) {
return Number(numberString.replace(",", "")) || 0;
}
if (numberString.endsWith("-")) {
return Number(numberString.replace("-", "")) || 0;
}
const rawValue = numberString.replace(/[^0-9,-]/g, "").replace(",", ".");
return parseFloat(rawValue) || 0;
return Number(numberString) || 0;
};
const formatCurrency = (value: any) => {
// Menghapus semua karakter kecuali angka, koma, dan tanda minusif (value === null || value === undefined) return '';
if (!value) return "";
let numberString = "";
if (typeof value === "number") {
numberString = formatMoney(value);
} else {
numberString = value.toString().replace(/[^0-9,-]/g, "");
}
if (numberString.endsWith("-") && numberString.startsWith("-")) {
return "-";
} else if (numberString.endsWith(",")) {
const isNegative = numberString.startsWith("-");
numberString = numberString.replace("-", "");
const split = numberString.split(",");
if (isNumberOrCurrency(split[0]) === "Number") {
split[0] = formatMoney(Number(split[0]));
}
let rupiah = split[0];
rupiah = split[1] !== undefined ? rupiah + "," + split[1] : rupiah;
return (isNegative ? "-" : "") + rupiah;
} else {
const isNegative = numberString.startsWith("-");
numberString = numberString.replace("-", "");
const split = numberString.split(",");
if (isNumberOrCurrency(split[0]) === "Number") {
split[0] = formatMoney(Number(split[0]));
}
let rupiah = split[0];
rupiah = split[1] !== undefined ? rupiah + "," + split[1] : rupiah;
return (isNegative ? "-" : "") + rupiah;
}
};
export const formatMoney = (res: number) => { export const formatMoney = (res: number) => {
const formattedAmount = new Intl.NumberFormat("id-ID", { const formattedAmount = new Intl.NumberFormat("id-ID", {
minimumFractionDigits: 0, minimumFractionDigits: 0,
}).format(res); }).format(res);
return formattedAmount; return formattedAmount;
}; };
const isNumberOrCurrency = (input: any) => {
// Pengecekan apakah input adalah angka biasa
if (typeof input === "string") {
let rs = input;
if (input.startsWith("-")) {
rs = rs.replace("-", "");
}
const dots = rs.match(/\./g);
if (dots && dots.length > 1) {
return "Currency";
} else if (dots && dots.length === 1) {
if (!hasNonZeroDigitAfterDecimal(rs)) {
return "Currency";
} else {
return "Number";
}
}
}
if (!isNaN(input)) {
return "Number";
}
// Pengecekan apakah input adalah format mata uang dengan pemisah ribuan
const currencyRegex = /^-?Rp?\s?\d{1,3}(\.\d{3})*$/;
if (currencyRegex.test(input)) {
return "Currency";
}
// Jika tidak terdeteksi sebagai angka atau format mata uang, kembalikan null atau sesuai kebutuhan
return null;
};
const hasNonZeroDigitAfterDecimal = (input: string) => {
// Ekspresi reguler untuk mencocokkan angka 1-9 setelah koma atau titik
const regex = /[.,]\d*[1-9]\d*/;
return regex.test(input);
};

View File

@ -21,6 +21,7 @@ export const FieldUpload: FC<{
drop: false as boolean, drop: false as boolean,
}); });
let display: any = null; let display: any = null;
const disabled = typeof field.disabled === "function" ? field.disabled() : field.disabled;
return ( return (
<div className="c-flex-grow c-flex-row c-flex c-w-full c-h-full"> <div className="c-flex-grow c-flex-row c-flex c-w-full c-h-full">
<div <div
@ -152,7 +153,7 @@ export const FieldUpload: FC<{
fm.render(); fm.render();
}} }}
value={value} value={value}
disabled={field.disabled} disabled={disabled}
className={cx( className={cx(
!input.display ? "c-hidden" : "", !input.display ? "c-hidden" : "",
"c-flex-1 c-bg-transparent c-outline-none c-px-2 c-text-sm c-w-full" "c-flex-1 c-bg-transparent c-outline-none c-px-2 c-text-sm c-w-full"

View File

@ -105,6 +105,37 @@ export const newField = async (
} else if (["has-many", "has-one"].includes(arg.type) && arg.relation) { } else if (["has-many", "has-one"].includes(arg.type) && arg.relation) {
const fields = parseGenField(opt.value); const fields = parseGenField(opt.value);
const res = generateSelect(fields); const res = generateSelect(fields);
if (res && res.select && Object.keys(res.select).length === 1) {
return createItem({
component: {
id: "32550d01-42a3-4b15-a04a-2c2d5c3c8e67",
props: {
name: arg.name,
label: formatName(arg.name),
type: "link",
link_opt: [
`({
url: () => {
return "";
},
where: () => {
return {} as ${
opt.parent_table
? `Prisma.${opt.parent_table}WhereInput`
: `Record<string, any>`
};
},
breadcrumbs: (existing: any[]) => {
return [...existing];
},
})`,
],
},
},
});
}
const load = on_load_rel({ const load = on_load_rel({
pk: res.pk, pk: res.pk,
table: arg.relation.to.table, table: arg.relation.to.table,

View File

@ -37,9 +37,11 @@ export const generateForm = async (
return; return;
} }
if (pk) { if (pk) {
const is_md = let is_md: boolean | string =
item.edit?.parent?.item?.component?.id === item.edit?.parent?.item?.component?.id ===
"cb52075a-14ab-455a-9847-6f1d929a2a73"; "cb52075a-14ab-455a-9847-6f1d929a2a73";
if (!is_md) is_md = "";
if (data["on_load"]) { if (data["on_load"]) {
result.on_load = { result.on_load = {
mode: "raw", mode: "raw",
@ -56,8 +58,9 @@ export const generateForm = async (
md.render(); md.render();
} }
`, `,
is_md: true,
} }
: {}, : { is_md },
}), }),
}; };
} }
@ -67,9 +70,7 @@ export const generateForm = async (
value: `\ value: `\
async ({ form, error, fm }: IForm) => { async ({ form, error, fm }: IForm) => {
let result = false; let result = false;
try { try {${
${
is_md && is_md &&
`\ `\
if (typeof md !== "undefined") { if (typeof md !== "undefined") {
@ -77,7 +78,6 @@ ${
md.render(); md.render();
}` }`
} }
const data = { ...form }; const data = { ...form };
const record = {} as Record<string, any>; const record = {} as Record<string, any>;

View File

@ -14,6 +14,7 @@ export const on_load = ({
opt?: { opt?: {
before_load?: string; before_load?: string;
after_load?: string; after_load?: string;
is_md?: boolean | string;
}; };
}) => { }) => {
const sample: any = {}; const sample: any = {};
@ -29,18 +30,26 @@ export const on_load = ({
} }
} }
let is_md: string | boolean =
typeof opt?.is_md === "undefined" ? true : !!opt?.is_md;
if (!is_md) is_md = "";
return `\ return `\
async (opt) => { async (opt) => {
if (isEditor) return ${JSON.stringify(sample)}; if (isEditor) return ${JSON.stringify(sample, null, 2)};
let raw_id = params.id; let raw_id = params.id;
${
is_md &&
`\
if (typeof md === 'object' && md.selected && md.pk) { if (typeof md === 'object' && md.selected && md.pk) {
const pk = md.pk?.name; const pk = md.pk?.name;
if (md.selected[pk]) { if (md.selected[pk]) {
raw_id = md.selected[pk]; raw_id = md.selected[pk];
} }
} }
`
}
${opt?.before_load ? opt.before_load : `let id = raw_id`} ${opt?.before_load ? opt.before_load : `let id = raw_id`}
let item = {}; let item = {};
if (id){ if (id){
@ -63,9 +72,7 @@ async (opt) => {
where, where,
select: gen.select, select: gen.select,
}); });
${opt?.after_load ? opt?.after_load : ""} ${opt?.after_load ? opt?.after_load : ""}
return item; return item;
} else { } else {
${opt?.after_load ? opt?.after_load : ""} ${opt?.after_load ? opt?.after_load : ""}

View File

@ -29,7 +29,6 @@ export const on_load_rel = ({
!isEmptyString(type) && !isEmptyString(type) &&
["checkbox", "typeahead", "button"].includes(type as any); ["checkbox", "typeahead", "button"].includes(type as any);
console.log(skip_select, type);
return `\ return `\
async (arg: { async (arg: {
reload: () => Promise<void>; reload: () => Promise<void>;

View File

@ -52,7 +52,7 @@ export type FieldProp = {
required_msg: (name: string) => string | ReactElement; 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") | (() => true | false);
child: any; child: any;
selection: "single" | "multi"; selection: "single" | "multi";
prefix: any; prefix: any;
@ -152,7 +152,7 @@ export type FieldInternal<T extends FieldProp["type"]> = {
width: FieldProp["width"]; width: FieldProp["width"];
required: boolean; required: boolean;
focused: boolean; focused: boolean;
disabled: boolean; disabled: boolean | (() => boolean);
required_msg: FieldProp["required_msg"]; required_msg: FieldProp["required_msg"];
col?: GFCol; col?: GFCol;
ref?: any; ref?: any;

View File

@ -23,7 +23,6 @@ export const useField = (
const label = typeof arg.label === "string" ? arg.label : arg.label(); const label = typeof arg.label === "string" ? arg.label : arg.label();
const required = const required =
typeof arg.required === "string" ? arg.required : arg.required(); typeof arg.required === "string" ? arg.required : arg.required();
const update_field = { const update_field = {
name: name.replace(/\s*/gi, ""), name: name.replace(/\s*/gi, ""),
label: label, label: label,
@ -35,7 +34,7 @@ export const useField = (
custom: arg.custom, custom: arg.custom,
required: required === "y", required: required === "y",
required_msg: arg.required_msg, required_msg: arg.required_msg,
disabled: arg.disabled === "y", disabled: typeof arg.disabled === "function" ? arg.disabled : arg.disabled === "y",
on_change: arg.on_change, on_change: arg.on_change,
}; };

View File

@ -399,7 +399,7 @@ export const TableList: FC<TableListProp> = ({
renderHeaderCell(props) { renderHeaderCell(props) {
return ( return (
<div> <div>
<CheckboxList value={false} on_click={on_click} /> {/* <CheckboxList value={false} on_click={on_click} /> */}
</div> </div>
); );
}, },

View File

@ -1,14 +1,13 @@
import { getPathname } from "lib/utils/pathname"; import { getPathname } from "lib/utils/pathname";
import { useLocal } from "lib/utils/use-local"; import { useLocal } from "lib/utils/use-local";
import get from "lodash.get"; import get from "lodash.get";
import { FC } from "react"; import { FC, useRef } from "react";
import { IMenu, MenuProp } from "../../preset/menu/utils/type-menu"; import { IMenu, MenuProp } from "../../preset/menu/utils/type-menu";
export const Menu: FC<MenuProp> = (props) => { export const Menu: FC<MenuProp> = (props) => {
const imenu = props.menu[0]; const imenu = props.menu[0];
let role = props.role; let role = props.role;
role = props.on_init() as string; role = props.on_init() as string;
const PassProp = props.PassProp; const PassProp = props.PassProp;
let menu = imenu[role] || []; let menu = imenu[role] || [];
const pathname = getPathname(); const pathname = getPathname();
@ -26,8 +25,10 @@ export const Menu: FC<MenuProp> = (props) => {
local.render(); local.render();
} }
} }
const ref = useRef<HTMLDivElement>(null);
return ( return (
<div <div
ref={ref}
className={cx( className={cx(
props.mode === "mini" ? "c-max-w-[35px]" : "", props.mode === "mini" ? "c-max-w-[35px]" : "",
"c-h-full c-w-full c-flex c-flex-row c-flex-grow c-px-3 c-py-4 c-overflow-y-auto c-rounded " "c-h-full c-w-full c-flex c-flex-row c-flex-grow c-px-3 c-py-4 c-overflow-y-auto c-rounded "

View File

@ -35,7 +35,7 @@ export const Popup: FC<PopupProp> = ({ on_close, open, child }) => {
createPortal( createPortal(
<div <div
ref={(e) => (local.ref = e)} ref={(e) => (local.ref = e)}
className="c-w-screen c-h-screen c-bg-transparent c-flex c-flex-row c-items-center c-justify-center" className="c-w-screen c-h-screen relative c-bg-transparent c-flex c-flex-row c-items-center c-justify-center"
onClick={(e) => { onClick={(e) => {
if (local.ref) { if (local.ref) {
if (e.target === local.ref) { if (e.target === local.ref) {

View File

@ -1,5 +1,6 @@
export { FieldLoading } from "@/comps/ui/field-loading"; export { FieldLoading } from "@/comps/ui/field-loading";
import { lazify, lazifyMany } from "@/utils/lazify"; import { lazify, lazifyMany } from "@/utils/lazify";
export { Popover } from "./comps/custom/Popover";
/** Master - Detail - List - Form */ /** Master - Detail - List - Form */
export const MasterDetail = lazify( export const MasterDetail = lazify(
@ -80,7 +81,7 @@ export { FormatValue } from "@/utils/format-value";
export { GetValue } from "@/utils/get-value"; export { GetValue } from "@/utils/get-value";
export { password } from "@/utils/password"; export { password } from "@/utils/password";
export { prasi_events, call_prasi_events } from "lib/utils/prasi-events"; export { prasi_events, call_prasi_events } from "lib/utils/prasi-events";
export { getFilter } from "@/comps/filter/utils/get-filter";
/** Session */ /** Session */
export { Login } from "@/preset/login/Login"; export { Login } from "@/preset/login/Login";
export { generateLogin } from "@/preset/login/utils/generate"; export { generateLogin } from "@/preset/login/utils/generate";

View File

@ -1,7 +1,7 @@
import { getPathname } from "lib/utils/pathname"; import { getPathname } from "lib/utils/pathname";
import { useLocal } from "lib/utils/use-local"; import { useLocal } from "lib/utils/use-local";
import get from "lodash.get"; import get from "lodash.get";
import { FC, useEffect } from "react"; import { FC, useEffect, useRef } from "react";
import { IMenu, MenuProp } from "./utils/type-menu"; import { IMenu, MenuProp } from "./utils/type-menu";
// import { icon } from "../../.."; // import { icon } from "../../..";
@ -22,7 +22,7 @@ export const Menu: FC<MenuProp> = (props) => {
let role = props.role; let role = props.role;
role = props.on_init(); role = props.on_init();
let menu = get(imenu, role) || []; let menu = get(imenu, role) || [];
const ref = useRef<HTMLDivElement>(null);
const local = useLocal({ ...local_default }); const local = useLocal({ ...local_default });
if (local.pathname !== getPathname()) { if (local.pathname !== getPathname()) {
@ -39,7 +39,10 @@ export const Menu: FC<MenuProp> = (props) => {
}, [props.mode]); }, [props.mode]);
return ( return (
<div className={cx("c-overflow-y-auto c-relative c-h-full c-w-full ")}> <div
className={cx("c-overflow-y-auto c-relative c-h-full c-w-full ")}
ref={ref}
>
<div className="sidebar-menu c-absolute c-inset-0 c-flex c-flex-col c-flex-grow c-px-3 c-py-4 "> <div className="sidebar-menu c-absolute c-inset-0 c-flex c-flex-col c-flex-grow c-px-3 c-py-4 ">
<SideBar <SideBar
data={menu} data={menu}

View File

@ -12,7 +12,7 @@ export const FormatValue: FC<{
name: string; name: string;
gen_fields: string[]; gen_fields: string[];
tree_depth?: number; tree_depth?: number;
mode?: "money" | "datetime" | "timeago"; mode?: "money" | "datetime" | "timeago" | "date";
}> = (prop) => { }> = (prop) => {
const { value, gen_fields, name, tree_depth, mode } = prop; const { value, gen_fields, name, tree_depth, mode } = prop;
if (gen_fields) { if (gen_fields) {
@ -54,6 +54,13 @@ export const FormatValue: FC<{
} catch (ex: any) { } catch (ex: any) {
return "-"; return "-";
} }
} else if (mode === "date") {
if (!value || isEmptyString(value)) return "-";
try {
return formatDate(dayjs(value), "DD MMMM YYYY");
} catch (ex: any) {
return "-";
}
}else if (mode === "timeago") { }else if (mode === "timeago") {
if (!value || isEmptyString(value)) return "-"; if (!value || isEmptyString(value)) return "-";
try { try {