fix
This commit is contained in:
parent
15e1e983a5
commit
5022096c06
|
|
@ -41,6 +41,7 @@ export const BarChart: FC<{
|
||||||
datasetIdKey="id"
|
datasetIdKey="id"
|
||||||
options={{
|
options={{
|
||||||
responsive: true,
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
plugins:
|
plugins:
|
||||||
legend === "none"
|
legend === "none"
|
||||||
? {
|
? {
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ interface Props {
|
||||||
onClickNext: () => void;
|
onClickNext: () => void;
|
||||||
changeMonth: (month: number) => void;
|
changeMonth: (month: number) => void;
|
||||||
changeYear: (year: number) => void;
|
changeYear: (year: number) => void;
|
||||||
|
mode?: "monthly" | "daily";
|
||||||
}
|
}
|
||||||
|
|
||||||
const Calendar: React.FC<Props> = ({
|
const Calendar: React.FC<Props> = ({
|
||||||
|
|
@ -53,6 +54,7 @@ const Calendar: React.FC<Props> = ({
|
||||||
onClickNext,
|
onClickNext,
|
||||||
changeMonth,
|
changeMonth,
|
||||||
changeYear,
|
changeYear,
|
||||||
|
mode = "daily",
|
||||||
}) => {
|
}) => {
|
||||||
// Contexts
|
// Contexts
|
||||||
const {
|
const {
|
||||||
|
|
@ -73,6 +75,12 @@ const Calendar: React.FC<Props> = ({
|
||||||
const [showMonths, setShowMonths] = useState(false);
|
const [showMonths, setShowMonths] = useState(false);
|
||||||
const [showYears, setShowYears] = useState(false);
|
const [showYears, setShowYears] = useState(false);
|
||||||
const [year, setYear] = useState(date.year());
|
const [year, setYear] = useState(date.year());
|
||||||
|
useEffect(() => {
|
||||||
|
if (mode === "monthly") {
|
||||||
|
setShowMonths(true);
|
||||||
|
hideYears();
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
// Functions
|
// Functions
|
||||||
const previous = useCallback(() => {
|
const previous = useCallback(() => {
|
||||||
return getLastDaysInMonth(
|
return getLastDaysInMonth(
|
||||||
|
|
@ -104,7 +112,12 @@ const Calendar: React.FC<Props> = ({
|
||||||
(month: number) => {
|
(month: number) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
changeMonth(month);
|
changeMonth(month);
|
||||||
setShowMonths(!showMonths);
|
if (mode === "daily") {
|
||||||
|
setShowMonths(!showMonths);
|
||||||
|
} else {
|
||||||
|
hideDatepicker();
|
||||||
|
clickDay(1,month + 1, date.year() );
|
||||||
|
}
|
||||||
}, 250);
|
}, 250);
|
||||||
},
|
},
|
||||||
[changeMonth, showMonths]
|
[changeMonth, showMonths]
|
||||||
|
|
@ -115,6 +128,10 @@ const Calendar: React.FC<Props> = ({
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
changeYear(year);
|
changeYear(year);
|
||||||
setShowYears(!showYears);
|
setShowYears(!showYears);
|
||||||
|
if (mode === "monthly") {
|
||||||
|
setShowMonths(true);
|
||||||
|
clickDay(1,date.month() + 1, year );
|
||||||
|
}
|
||||||
}, 250);
|
}, 250);
|
||||||
},
|
},
|
||||||
[changeYear, showYears]
|
[changeYear, showYears]
|
||||||
|
|
@ -125,7 +142,6 @@ const Calendar: React.FC<Props> = ({
|
||||||
const fullDay = `${year}-${month}-${day}`;
|
const fullDay = `${year}-${month}-${day}`;
|
||||||
let newStart;
|
let newStart;
|
||||||
let newEnd = null;
|
let newEnd = null;
|
||||||
|
|
||||||
function chosePeriod(start: string, end: string) {
|
function chosePeriod(start: string, end: string) {
|
||||||
const ipt = input?.current;
|
const ipt = input?.current;
|
||||||
changeDatepickerValue(
|
changeDatepickerValue(
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ const Datepicker: React.FC<DatepickerType> = ({
|
||||||
startWeekOn = "sun",
|
startWeekOn = "sun",
|
||||||
classNames = undefined,
|
classNames = undefined,
|
||||||
popoverDirection = undefined,
|
popoverDirection = undefined,
|
||||||
|
mode="daily"
|
||||||
}) => {
|
}) => {
|
||||||
const local = useLocal({ open: false });
|
const local = useLocal({ open: false });
|
||||||
// Ref
|
// Ref
|
||||||
|
|
@ -95,6 +96,7 @@ const Datepicker: React.FC<DatepickerType> = ({
|
||||||
if (newDate.isSame(reformatDate) || newDate.isAfter(reformatDate)) {
|
if (newDate.isSame(reformatDate) || newDate.isAfter(reformatDate)) {
|
||||||
setSecondDate(nextMonth(date));
|
setSecondDate(nextMonth(date));
|
||||||
}
|
}
|
||||||
|
console.log(date)
|
||||||
setFirstDate(date);
|
setFirstDate(date);
|
||||||
},
|
},
|
||||||
[secondDate]
|
[secondDate]
|
||||||
|
|
@ -110,6 +112,7 @@ const Datepicker: React.FC<DatepickerType> = ({
|
||||||
|
|
||||||
const changeFirstMonth = useCallback(
|
const changeFirstMonth = useCallback(
|
||||||
(month: number) => {
|
(month: number) => {
|
||||||
|
console.log("HALOOO")
|
||||||
firstGotoDate(
|
firstGotoDate(
|
||||||
dayjs(`${firstDate.year()}-${month < 10 ? "0" : ""}${month}-01`)
|
dayjs(`${firstDate.year()}-${month < 10 ? "0" : ""}${month}-01`)
|
||||||
);
|
);
|
||||||
|
|
@ -148,6 +151,7 @@ const Datepicker: React.FC<DatepickerType> = ({
|
||||||
|
|
||||||
const changeSecondMonth = useCallback(
|
const changeSecondMonth = useCallback(
|
||||||
(month: number) => {
|
(month: number) => {
|
||||||
|
console.log("ALOO")
|
||||||
secondGotoDate(
|
secondGotoDate(
|
||||||
dayjs(`${secondDate.year()}-${month < 10 ? "0" : ""}${month}-01`)
|
dayjs(`${secondDate.year()}-${month < 10 ? "0" : ""}${month}-01`)
|
||||||
);
|
);
|
||||||
|
|
@ -323,8 +327,8 @@ const Datepicker: React.FC<DatepickerType> = ({
|
||||||
return typeof containerClassName === "function"
|
return typeof containerClassName === "function"
|
||||||
? containerClassName(defaultContainerClassName)
|
? containerClassName(defaultContainerClassName)
|
||||||
: typeof containerClassName === "string" && containerClassName !== ""
|
: typeof containerClassName === "string" && containerClassName !== ""
|
||||||
? containerClassName
|
? containerClassName
|
||||||
: defaultContainerClassName;
|
: defaultContainerClassName;
|
||||||
}, [containerClassName]);
|
}, [containerClassName]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -339,7 +343,9 @@ const Datepicker: React.FC<DatepickerType> = ({
|
||||||
open={local.open}
|
open={local.open}
|
||||||
content={
|
content={
|
||||||
<div
|
<div
|
||||||
className={cx("c-text-sm 2xl:c-text-sm")}
|
className={cx(
|
||||||
|
"c-text-sm 2xl:c-text-sm",
|
||||||
|
)}
|
||||||
ref={calendarContainerRef}
|
ref={calendarContainerRef}
|
||||||
>
|
>
|
||||||
<div className="c-flex c-flex-col lg:c-flex-row c-py-1">
|
<div className="c-flex c-flex-col lg:c-flex-row c-py-1">
|
||||||
|
|
@ -356,6 +362,7 @@ const Datepicker: React.FC<DatepickerType> = ({
|
||||||
onClickNext={nextMonthFirst}
|
onClickNext={nextMonthFirst}
|
||||||
changeMonth={changeFirstMonth}
|
changeMonth={changeFirstMonth}
|
||||||
changeYear={changeFirstYear}
|
changeYear={changeFirstYear}
|
||||||
|
mode={mode}
|
||||||
minDate={minDate}
|
minDate={minDate}
|
||||||
maxDate={maxDate}
|
maxDate={maxDate}
|
||||||
/>
|
/>
|
||||||
|
|
@ -372,6 +379,7 @@ const Datepicker: React.FC<DatepickerType> = ({
|
||||||
onClickNext={nextMonthSecond}
|
onClickNext={nextMonthSecond}
|
||||||
changeMonth={changeSecondMonth}
|
changeMonth={changeSecondMonth}
|
||||||
changeYear={changeSecondYear}
|
changeYear={changeSecondYear}
|
||||||
|
mode={mode}
|
||||||
minDate={minDate}
|
minDate={minDate}
|
||||||
maxDate={maxDate}
|
maxDate={maxDate}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ export interface DatepickerType {
|
||||||
disabledDates?: DateRangeType[] | null;
|
disabledDates?: DateRangeType[] | null;
|
||||||
startWeekOn?: string | null;
|
startWeekOn?: string | null;
|
||||||
popoverDirection?: PopoverDirectionType;
|
popoverDirection?: PopoverDirectionType;
|
||||||
|
mode?: "daily" | "monthly"
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ColorKeys = (typeof COLORS)[number]; // "blue" | "orange"
|
export type ColorKeys = (typeof COLORS)[number]; // "blue" | "orange"
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,7 @@ function PopoverArrow() {
|
||||||
top: arrowY != null ? `${arrowY}px` : "",
|
top: arrowY != null ? `${arrowY}px` : "",
|
||||||
[staticSide]: "-4px",
|
[staticSide]: "-4px",
|
||||||
transform: "rotate(45deg)",
|
transform: "rotate(45deg)",
|
||||||
|
cursor: "pointer"
|
||||||
}}
|
}}
|
||||||
className={cx(
|
className={cx(
|
||||||
"arrow",
|
"arrow",
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,16 @@ import { BaseForm } from "../form/base/BaseForm";
|
||||||
import { FilterLocal } from "./utils/types";
|
import { FilterLocal } from "./utils/types";
|
||||||
import { useLocal } from "lib/utils/use-local";
|
import { useLocal } from "lib/utils/use-local";
|
||||||
import { getFilter } from "./utils/get-filter";
|
import { getFilter } from "./utils/get-filter";
|
||||||
|
import { FMLocal } from "lib/exports";
|
||||||
|
|
||||||
export const FilterContent: FC<{
|
export const FilterContent: FC<{
|
||||||
mode: string;
|
mode: string;
|
||||||
filter: FilterLocal;
|
filter: FilterLocal;
|
||||||
|
onSubmit?: (form: FMLocal | null) => Promise<any>;
|
||||||
PassProp: any;
|
PassProp: any;
|
||||||
child: any;
|
child: any;
|
||||||
_item: PrasiItem;
|
_item: PrasiItem;
|
||||||
}> = ({ mode, filter, PassProp, child, _item }) => {
|
}> = ({ mode, filter, PassProp, child, _item, onSubmit }) => {
|
||||||
const internal = useLocal({});
|
const internal = useLocal({});
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
@ -97,9 +99,18 @@ export const FilterContent: FC<{
|
||||||
>
|
>
|
||||||
<BaseForm
|
<BaseForm
|
||||||
data={filter.data}
|
data={filter.data}
|
||||||
on_submit={(form) => {
|
on_submit={async (form) => {
|
||||||
const f = getFilter(filter.name);
|
if (typeof onSubmit === "function" && mode === "raw") {
|
||||||
|
const data = await onSubmit(form.fm);
|
||||||
|
if(typeof form.fm?.data === "object"){
|
||||||
|
form.fm.data = {
|
||||||
|
...form.fm.data,
|
||||||
|
_where: data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const f = getFilter(filter.name);
|
||||||
if (f) {
|
if (f) {
|
||||||
for (const list of Object.values(f.list.ref)) {
|
for (const list of Object.values(f.list.ref)) {
|
||||||
list.reload();
|
list.reload();
|
||||||
|
|
@ -113,7 +124,9 @@ export const FilterContent: FC<{
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!!(PassProp && child) && (
|
{!!(PassProp && child) && (
|
||||||
<PassProp filter={filter}>{child}</PassProp>
|
<PassProp filter={filter} fm={form.fm}>
|
||||||
|
{child}
|
||||||
|
</PassProp>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export const FilterField: FC<{
|
||||||
internal.render_timeout = setTimeout(() => {
|
internal.render_timeout = setTimeout(() => {
|
||||||
filter_window.prasiContext.render();
|
filter_window.prasiContext.render();
|
||||||
}, 500);
|
}, 500);
|
||||||
}, [filter.form?.data[name]]);
|
}, [filter.form]);
|
||||||
|
|
||||||
let show_modifier = filter.mode !== "inline";
|
let show_modifier = filter.mode !== "inline";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { useLocal } from "@/utils/use-local";
|
import { useLocal } from "@/utils/use-local";
|
||||||
import { FC, ReactNode } from "react";
|
import { FC, ReactNode } from "react";
|
||||||
import { createPortal } from "react-dom";
|
import { createPortal } from "react-dom";
|
||||||
import { GenField } from "../form/typings";
|
import { FMLocal, GenField } from "../form/typings";
|
||||||
import { FilterContent } from "./FilterContent";
|
import { FilterContent } from "./FilterContent";
|
||||||
import { getFilter } from "./utils/get-filter";
|
import { getFilter } from "./utils/get-filter";
|
||||||
import { default_filter_local } from "./utils/types";
|
import { default_filter_local } from "./utils/types";
|
||||||
|
|
@ -16,6 +16,7 @@ type FilterProps = {
|
||||||
mode: FilterMode;
|
mode: FilterMode;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
|
onSubmit?: (fm: FMLocal | null) => Promise<any>;
|
||||||
PassProp: any;
|
PassProp: any;
|
||||||
child: any;
|
child: any;
|
||||||
_item: PrasiItem;
|
_item: PrasiItem;
|
||||||
|
|
@ -31,6 +32,7 @@ export const MasterFilter: FC<FilterProps> = ({
|
||||||
child,
|
child,
|
||||||
onClose,
|
onClose,
|
||||||
_item,
|
_item,
|
||||||
|
onSubmit,
|
||||||
}): ReactNode => {
|
}): ReactNode => {
|
||||||
const filter = useLocal({ ...default_filter_local });
|
const filter = useLocal({ ...default_filter_local });
|
||||||
filter.name = name;
|
filter.name = name;
|
||||||
|
|
@ -74,6 +76,7 @@ export const MasterFilter: FC<FilterProps> = ({
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<FilterContent
|
<FilterContent
|
||||||
|
onSubmit={onSubmit}
|
||||||
PassProp={PassProp}
|
PassProp={PassProp}
|
||||||
child={child}
|
child={child}
|
||||||
mode={mode}
|
mode={mode}
|
||||||
|
|
@ -90,6 +93,7 @@ export const MasterFilter: FC<FilterProps> = ({
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FilterContent
|
<FilterContent
|
||||||
|
onSubmit={onSubmit}
|
||||||
PassProp={PassProp}
|
PassProp={PassProp}
|
||||||
_item={_item}
|
_item={_item}
|
||||||
child={child}
|
child={child}
|
||||||
|
|
|
||||||
|
|
@ -5,17 +5,24 @@ import { softDeleteFilter } from "./soft-delete-filter";
|
||||||
|
|
||||||
export const filterWhere = (filter_name: string, p: any) => {
|
export const filterWhere = (filter_name: string, p: any) => {
|
||||||
const f = getFilter(filter_name);
|
const f = getFilter(filter_name);
|
||||||
|
|
||||||
let where: any = {};
|
let where: any = {};
|
||||||
if (f) {
|
if (f) {
|
||||||
let fields: GFCol[] = [];
|
let fields: GFCol[] = [];
|
||||||
|
//
|
||||||
if (p.gen__fields) {
|
if (p.gen__fields) {
|
||||||
fields = parseGenField(p.gen__fields);
|
fields = parseGenField(p.gen__fields);
|
||||||
}
|
}
|
||||||
for (const pf of Object.values(f.filter.ref)) {
|
for (const pf of Object.values(f.filter.ref)) {
|
||||||
const w = parseSingleFilter(pf, fields);
|
if (pf.mode === "raw") {
|
||||||
for (const [k, v] of Object.entries(w)) {
|
const data = pf.data?._where ? pf.data?._where : pf.data
|
||||||
where[k] = v;
|
for (const [k, v] of Object.entries(data)) {
|
||||||
|
where[k] = v;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const w = parseSingleFilter(pf, fields);
|
||||||
|
for (const [k, v] of Object.entries(w)) {
|
||||||
|
where[k] = v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -27,6 +34,6 @@ export const filterWhere = (filter_name: string, p: any) => {
|
||||||
type: p.sft__type,
|
type: p.sft__type,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
console.log({where})
|
||||||
return where;
|
return where;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,9 @@ export const BaseForm = <T extends Record<string, any>>(
|
||||||
return prop;
|
return prop;
|
||||||
};
|
};
|
||||||
|
|
||||||
form.createFm = () => {
|
form.createFm = useCallback(() => {
|
||||||
if (form.fm) {
|
if (form.fm) {
|
||||||
form.fm.data = form.data;
|
form.fm.data = data;
|
||||||
return form.fm;
|
return form.fm;
|
||||||
}
|
}
|
||||||
let size = "full";
|
let size = "full";
|
||||||
|
|
@ -72,7 +72,7 @@ export const BaseForm = <T extends Record<string, any>>(
|
||||||
size = "half";
|
size = "half";
|
||||||
}
|
}
|
||||||
form.fm = {
|
form.fm = {
|
||||||
data: form.data,
|
data: data,
|
||||||
props: { label_mode: "vertical" },
|
props: { label_mode: "vertical" },
|
||||||
error: {
|
error: {
|
||||||
get: () => {
|
get: () => {
|
||||||
|
|
@ -84,7 +84,7 @@ export const BaseForm = <T extends Record<string, any>>(
|
||||||
render: form.render,
|
render: form.render,
|
||||||
} as any;
|
} as any;
|
||||||
return form.fm as any;
|
return form.fm as any;
|
||||||
};
|
}, [data]);
|
||||||
|
|
||||||
form.fieldProps = (arg) => {
|
form.fieldProps = (arg) => {
|
||||||
return {
|
return {
|
||||||
|
|
@ -95,8 +95,8 @@ export const BaseForm = <T extends Record<string, any>>(
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
form.data = data;
|
// form.data = data;
|
||||||
form.render();
|
// form.render();
|
||||||
|
|
||||||
if (form.internal.width === 0) {
|
if (form.internal.width === 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
@ -142,7 +142,9 @@ export const BaseForm = <T extends Record<string, any>>(
|
||||||
form.render();
|
form.render();
|
||||||
}, 50);
|
}, 50);
|
||||||
}
|
}
|
||||||
|
if (!form.fm) {
|
||||||
|
form.fm = form.createFm();
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
onSubmit={(e) => {
|
onSubmit={(e) => {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { FMLocal, FieldLocal, FieldProp } from "../typings";
|
||||||
|
|
||||||
export const default_base_form_local = {
|
export const default_base_form_local = {
|
||||||
status: "init" as "init" | "submitting" | "ready",
|
status: "init" as "init" | "submitting" | "ready",
|
||||||
data: {} as any,
|
// data: {} as any,
|
||||||
internal: {
|
internal: {
|
||||||
width: 0,
|
width: 0,
|
||||||
init_render: 0,
|
init_render: 0,
|
||||||
|
|
@ -23,7 +23,7 @@ type CreateFieldArg = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BaseFormLocal<T> = Omit<typeof default_base_form_local, "data"> & {
|
export type BaseFormLocal<T> = Omit<typeof default_base_form_local, "data"> & {
|
||||||
data: T;
|
// data: T;
|
||||||
createArg: (arg: CreateFieldArg) => FieldProp;
|
createArg: (arg: CreateFieldArg) => FieldProp;
|
||||||
createField: (arg: CreateFieldArg) => FieldLocal;
|
createField: (arg: CreateFieldArg) => FieldLocal;
|
||||||
createFm: () => FMLocal;
|
createFm: () => FMLocal;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ export const Field: FC<FieldProp> = (arg) => {
|
||||||
const { fm } = arg;
|
const { fm } = arg;
|
||||||
const field = useField(arg);
|
const field = useField(arg);
|
||||||
const name = field.name;
|
const name = field.name;
|
||||||
const local = useLocal({ prev_val: fm.data[name] });
|
const local = useLocal({ prev_val: fm.data?.[name] });
|
||||||
|
|
||||||
const w = field.width;
|
const w = field.width;
|
||||||
|
|
||||||
|
|
@ -29,14 +29,29 @@ 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){
|
||||||
|
fm.events = {
|
||||||
|
on_change(name, new_value) {
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fm.events.on_change(name, fm.data[name]);
|
fm.events.on_change(name, fm.data[name]);
|
||||||
fm.render();
|
fm.render();
|
||||||
}
|
}
|
||||||
}, [fm.data[name]]);
|
}, [fm.data[name]]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (typeof arg.on_init === "function") {
|
||||||
|
arg.on_init({ name, field });
|
||||||
|
}
|
||||||
|
}, [field]);
|
||||||
if (field.status === "init" && !isEditor) return null;
|
if (field.status === "init" && !isEditor) return null;
|
||||||
const errors = fm.error.get(name);
|
let errors = fm.error.get(name);
|
||||||
|
if(field.error){
|
||||||
|
errors = [field.error]
|
||||||
|
}
|
||||||
const props = { ...arg.props };
|
const props = { ...arg.props };
|
||||||
|
|
||||||
let editorClassName = "";
|
let editorClassName = "";
|
||||||
|
|
@ -45,6 +60,8 @@ export const Field: FC<FieldProp> = (arg) => {
|
||||||
props.className.split(" ").find((e: string) => e.startsWith("s-")) || "";
|
props.className.split(" ").find((e: string) => e.startsWith("s-")) || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const disabled =
|
||||||
|
typeof field.disabled === "function" ? field.disabled() : field.disabled;
|
||||||
if (field.hidden) return <></>;
|
if (field.hidden) return <></>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -72,7 +89,7 @@ export const Field: FC<FieldProp> = (arg) => {
|
||||||
"c-flex-col c-space-y-1",
|
"c-flex-col c-space-y-1",
|
||||||
css`
|
css`
|
||||||
.field-outer {
|
.field-outer {
|
||||||
border: 1px solid ${field.disabled ? "#ececeb" : "#cecece"};
|
border: 1px solid ${disabled ? "#ececeb" : "#cecece"};
|
||||||
|
|
||||||
&.focused {
|
&.focused {
|
||||||
border: 1px solid #1c4ed8;
|
border: 1px solid #1c4ed8;
|
||||||
|
|
@ -98,18 +115,18 @@ export const Field: FC<FieldProp> = (arg) => {
|
||||||
{field.desc}
|
{field.desc}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{errors.length > 0 && (
|
{errors.length ? (
|
||||||
<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"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{errors.map((err) => {
|
{errors.map((err) => {
|
||||||
return <div>{err}</div>;
|
return <div>{err}</div>;
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
) : <></>}
|
||||||
</div>
|
</div>
|
||||||
</LabelDiv>
|
</LabelDiv>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,14 @@ export const Label: FC<{ field: FieldLocal; fm: FMLocal }> = ({
|
||||||
fm,
|
fm,
|
||||||
}) => {
|
}) => {
|
||||||
const errors = fm.error.get(field.name);
|
const errors = fm.error.get(field.name);
|
||||||
|
const disabled =
|
||||||
|
typeof field.disabled === "function" ? field.disabled() : field.disabled;
|
||||||
return (
|
return (
|
||||||
<div className={cx("label c-text-sm c-flex c-items-center", "c-mt-3")}>
|
<div className={cx("label c-text-sm c-flex c-items-center", "c-mt-3")}>
|
||||||
<span className={cx(errors.length > 0 && `c-text-red-600`)}>
|
<span className={cx(errors.length > 0 && `c-text-red-600`)}>
|
||||||
{field.label}
|
{field.label}
|
||||||
</span>
|
</span>
|
||||||
{field.required && !field.disabled && (
|
{field.required && !disabled && (
|
||||||
<span className="c-text-red-600 c-mb-2 c-ml-1">
|
<span className="c-text-red-600 c-mb-2 c-ml-1">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|
|
||||||
|
|
@ -154,15 +154,10 @@ export const TableEdit: FC<{
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(
|
||||||
`c-w-full c-h-full c-flex c-flex-col`,
|
`c-w-full c-h-full c-flex c-flex-col`,
|
||||||
css`
|
css`
|
||||||
.rdg {
|
|
||||||
overflow-y: hidden !important;
|
|
||||||
height: var(--rdg-scroll-height) !important;
|
|
||||||
}
|
|
||||||
.rdg-cell > div {
|
.rdg-cell > div {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
@ -172,9 +167,6 @@ export const TableEdit: FC<{
|
||||||
padding-top: 0px;
|
padding-top: 0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.field-error {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.rdg-header-row {
|
.rdg-header-row {
|
||||||
border-top-right-radius: 5px;
|
border-top-right-radius: 5px;
|
||||||
border-top-left-radius: 5px;
|
border-top-left-radius: 5px;
|
||||||
|
|
@ -192,6 +184,7 @@ export const TableEdit: FC<{
|
||||||
className={cx(
|
className={cx(
|
||||||
"c-table-auto",
|
"c-table-auto",
|
||||||
css`
|
css`
|
||||||
|
height: 1px;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
table-layout: auto; /* Kolom akan menyesuaikan konten */
|
table-layout: auto; /* Kolom akan menyesuaikan konten */
|
||||||
`
|
`
|
||||||
|
|
@ -241,7 +234,7 @@ export const TableEdit: FC<{
|
||||||
{columns.map((header) => {
|
{columns.map((header) => {
|
||||||
return (
|
return (
|
||||||
<td>
|
<td>
|
||||||
<div className="c-flex c-flex-row c-py-2 c-w-full">
|
<div className="c-flex c-flex-row c-py-2 c-w-full c-h-full">
|
||||||
{header.renderCell({
|
{header.renderCell({
|
||||||
props: {
|
props: {
|
||||||
row: row,
|
row: row,
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,24 @@ export const TypeDropdown: FC<{
|
||||||
data: e.data,
|
data: e.data,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
let v = typeof arg.opt_get_value === "function"
|
||||||
|
? arg.opt_get_value({
|
||||||
|
fm,
|
||||||
|
name: field.name,
|
||||||
|
options: local.options,
|
||||||
|
type: field.type,
|
||||||
|
})
|
||||||
|
: fm.data[field.name];
|
||||||
|
let f = list.find((ex) => ex.value === v);
|
||||||
|
if(!f){
|
||||||
|
arg.opt_set_value({
|
||||||
|
fm,
|
||||||
|
name: field.name,
|
||||||
|
type: field.type,
|
||||||
|
options: local.options,
|
||||||
|
selected: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
local.options = list;
|
local.options = list;
|
||||||
} else {
|
} else {
|
||||||
local.options = res;
|
local.options = res;
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ export type PropTypeInput = {
|
||||||
| "file"
|
| "file"
|
||||||
| "search"
|
| "search"
|
||||||
| "password"
|
| "password"
|
||||||
| "import";
|
| "import"
|
||||||
|
| "monthly";
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
onFocus?: (e: FocusEvent<HTMLDivElement>) => void;
|
onFocus?: (e: FocusEvent<HTMLDivElement>) => void;
|
||||||
onBlur?: (e: FocusEvent<HTMLDivElement>) => void;
|
onBlur?: (e: FocusEvent<HTMLDivElement>) => void;
|
||||||
|
|
@ -168,7 +169,7 @@ export const FieldTypeInput: FC<{
|
||||||
case "upload":
|
case "upload":
|
||||||
return (
|
return (
|
||||||
<FieldUpload
|
<FieldUpload
|
||||||
arg={arg}
|
arg={arg}
|
||||||
field={field}
|
field={field}
|
||||||
fm={fm}
|
fm={fm}
|
||||||
prop={prop}
|
prop={prop}
|
||||||
|
|
@ -178,7 +179,7 @@ export const FieldTypeInput: FC<{
|
||||||
case "import":
|
case "import":
|
||||||
return (
|
return (
|
||||||
<FieldUpload
|
<FieldUpload
|
||||||
arg={arg}
|
arg={arg}
|
||||||
field={field}
|
field={field}
|
||||||
fm={fm}
|
fm={fm}
|
||||||
prop={prop}
|
prop={prop}
|
||||||
|
|
@ -199,11 +200,34 @@ export const FieldTypeInput: FC<{
|
||||||
value={{ startDate: value, endDate: value }}
|
value={{ startDate: value, endDate: value }}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
displayFormat="DD MMM YYYY"
|
displayFormat="DD MMM YYYY"
|
||||||
|
mode={"daily"}
|
||||||
maxDate={field.max_date instanceof Date ? field.max_date : null}
|
maxDate={field.max_date instanceof Date ? field.max_date : null}
|
||||||
minDate={field.min_date instanceof Date ? field.min_date : null}
|
minDate={field.min_date instanceof Date ? field.min_date : null}
|
||||||
asSingle={true}
|
asSingle={true}
|
||||||
useRange={false}
|
useRange={false}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
|
console.log({ value });
|
||||||
|
fm.data[field.name] = value?.startDate
|
||||||
|
? new Date(value?.startDate)
|
||||||
|
: null;
|
||||||
|
renderOnChange();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
case "monthly": {
|
||||||
|
return (
|
||||||
|
<Datepicker
|
||||||
|
value={{ startDate: value, endDate: value }}
|
||||||
|
disabled={disabled}
|
||||||
|
displayFormat="MMM YYYY"
|
||||||
|
mode={"monthly"}
|
||||||
|
maxDate={field.max_date instanceof Date ? field.max_date : null}
|
||||||
|
minDate={field.min_date instanceof Date ? field.min_date : null}
|
||||||
|
asSingle={true}
|
||||||
|
useRange={false}
|
||||||
|
onChange={(value) => {
|
||||||
|
console.log({ value });
|
||||||
fm.data[field.name] = value?.startDate
|
fm.data[field.name] = value?.startDate
|
||||||
? new Date(value?.startDate)
|
? new Date(value?.startDate)
|
||||||
: null;
|
: null;
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,10 @@ export type FieldProp = {
|
||||||
current: any;
|
current: any;
|
||||||
options: { value: string; label: string; item?: any }[];
|
options: { value: string; label: string; item?: any }[];
|
||||||
}) => boolean;
|
}) => boolean;
|
||||||
|
on_init: (arg: {
|
||||||
|
field: any,
|
||||||
|
name: string
|
||||||
|
}) => void;
|
||||||
pk: string;
|
pk: string;
|
||||||
sub_type: string;
|
sub_type: string;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
|
|
@ -188,6 +192,8 @@ export type FieldInternal<T extends FieldProp["type"]> = {
|
||||||
prop?: any;
|
prop?: any;
|
||||||
max_date?: FieldProp["max_date"];
|
max_date?: FieldProp["max_date"];
|
||||||
min_date?: FieldProp["min_date"];
|
min_date?: FieldProp["min_date"];
|
||||||
|
error?: any;
|
||||||
|
table_fields?: any[]
|
||||||
};
|
};
|
||||||
export type FieldLocal = FieldInternal<any> & {
|
export type FieldLocal = FieldInternal<any> & {
|
||||||
render: () => void;
|
render: () => void;
|
||||||
|
|
|
||||||
|
|
@ -16,35 +16,33 @@ export const useField = (
|
||||||
input: {},
|
input: {},
|
||||||
ref: null as any,
|
ref: null as any,
|
||||||
} as any);
|
} as any);
|
||||||
const ref = useRef(null as any);
|
const ref = useRef(null as any)
|
||||||
field.ref = ref;
|
field.ref = ref;
|
||||||
|
|
||||||
const name = typeof arg.name === "string" ? arg.name : arg.name();
|
const name = typeof arg.name === "string" ? arg.name : arg.name();
|
||||||
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 = {
|
||||||
|
name: name.replace(/\s*/gi, ""),
|
||||||
|
label: label,
|
||||||
|
type: arg.type,
|
||||||
|
desc: arg.desc,
|
||||||
|
prefix: arg.prefix,
|
||||||
|
suffix: arg.suffix,
|
||||||
|
width: arg.width,
|
||||||
|
custom: arg.custom,
|
||||||
|
required: required === "y",
|
||||||
|
required_msg: arg.required_msg,
|
||||||
|
disabled: typeof arg.disabled === "function" ? arg.disabled : arg.disabled === "y",
|
||||||
|
on_change: arg.on_change,
|
||||||
|
max_date: arg.max_date,
|
||||||
|
min_date: arg.min_date,
|
||||||
|
table_fields: []
|
||||||
|
};
|
||||||
|
|
||||||
if (field.status === "init" || isEditor) {
|
if (field.status === "init" || isEditor) {
|
||||||
for (const [k, v] of Object.entries({
|
for (const [k, v] of Object.entries(update_field)) {
|
||||||
name: name.replace(/\s*/gi, ""),
|
|
||||||
label: label,
|
|
||||||
type: arg.type,
|
|
||||||
desc: arg.desc,
|
|
||||||
prefix: arg.prefix,
|
|
||||||
suffix: arg.suffix,
|
|
||||||
width: arg.width,
|
|
||||||
custom: arg.custom,
|
|
||||||
required: required === "y",
|
|
||||||
required_msg: arg.required_msg,
|
|
||||||
disabled:
|
|
||||||
typeof arg.disabled === "function"
|
|
||||||
? arg.disabled
|
|
||||||
: arg.disabled === "y",
|
|
||||||
on_change: arg.on_change,
|
|
||||||
max_date: arg.max_date,
|
|
||||||
min_date: arg.min_date,
|
|
||||||
options: {},
|
|
||||||
reload_options: () => {},
|
|
||||||
})) {
|
|
||||||
(field as any)[k] = v;
|
(field as any)[k] = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -54,6 +52,9 @@ export const useField = (
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (field.status === "init" || !fm.fields[name]) {
|
if (field.status === "init" || !fm.fields[name]) {
|
||||||
field.status = "ready";
|
field.status = "ready";
|
||||||
|
if(!fm.fields){
|
||||||
|
fm.fields = {}
|
||||||
|
}
|
||||||
fm.fields[name] = field;
|
fm.fields[name] = field;
|
||||||
field.render();
|
field.render();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,6 @@ export const TableList: FC<TableListProp> = ({
|
||||||
let should_set = true;
|
let should_set = true;
|
||||||
const gf = JSON.stringify(gen_fields);
|
const gf = JSON.stringify(gen_fields);
|
||||||
const fields = fields_map.get(gf);
|
const fields = fields_map.get(gf);
|
||||||
|
|
||||||
if (fields) {
|
if (fields) {
|
||||||
const rel = fields?.find((e) => e.name === columnKey);
|
const rel = fields?.find((e) => e.name === columnKey);
|
||||||
if (rel && rel.checked) {
|
if (rel && rel.checked) {
|
||||||
|
|
@ -196,9 +195,7 @@ export const TableList: FC<TableListProp> = ({
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const field = rel.checked.find(
|
const field = rel.checked.find((e) => !e.is_pk);
|
||||||
(e) => !e.is_pk && !e.relation
|
|
||||||
);
|
|
||||||
if (field) {
|
if (field) {
|
||||||
local.sort.orderBy = {
|
local.sort.orderBy = {
|
||||||
[columnKey]: {
|
[columnKey]: {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
|
||||||
|
import { cn } from "@/utils"
|
||||||
|
const ScrollArea = React.forwardRef<
|
||||||
|
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<ScrollAreaPrimitive.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn("c-relative c-overflow-hidden", className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ScrollAreaPrimitive.Viewport className="c-h-full c-w-full c-rounded-[inherit]">
|
||||||
|
{children}
|
||||||
|
</ScrollAreaPrimitive.Viewport>
|
||||||
|
<ScrollBar />
|
||||||
|
<ScrollAreaPrimitive.Corner />
|
||||||
|
</ScrollAreaPrimitive.Root>
|
||||||
|
))
|
||||||
|
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
|
||||||
|
|
||||||
|
const ScrollBar = React.forwardRef<
|
||||||
|
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||||
|
>(({ className, orientation = "vertical", ...props }, ref) => (
|
||||||
|
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
||||||
|
ref={ref}
|
||||||
|
orientation={orientation}
|
||||||
|
className={cn(
|
||||||
|
"c-flex c-touch-none c-select-none c-transition-colors",
|
||||||
|
orientation === "vertical" &&
|
||||||
|
"c-h-full c-w-2.5 c-border-l c-border-l-transparent c-p-[1px]",
|
||||||
|
orientation === "horizontal" &&
|
||||||
|
"c-h-2.5 c-flex-col c-border-t c-border-t-transparent c-p-[1px]",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ScrollAreaPrimitive.ScrollAreaThumb className="c-relative c-flex-1 c-rounded-full c-bg-border" />
|
||||||
|
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||||
|
))
|
||||||
|
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
|
||||||
|
|
||||||
|
export { ScrollArea, ScrollBar }
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import * as React from "react";
|
||||||
|
import * as SheetPrimitive from "@radix-ui/react-dialog";
|
||||||
|
import { cva, type VariantProps } from "class-variance-authority";
|
||||||
|
|
||||||
|
import { cn } from "@/utils";
|
||||||
|
|
||||||
|
const Sheet = SheetPrimitive.Root;
|
||||||
|
|
||||||
|
const SheetTrigger = SheetPrimitive.Trigger;
|
||||||
|
|
||||||
|
const SheetClose = SheetPrimitive.Close;
|
||||||
|
|
||||||
|
const SheetPortal = SheetPrimitive.Portal;
|
||||||
|
|
||||||
|
const SheetOverlay = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SheetPrimitive.Overlay>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SheetPrimitive.Overlay
|
||||||
|
className={cn(
|
||||||
|
"c-fixed c-inset-0 c-z-50 c-bg-black/80 data-[state=open]:c-animate-in data-[state=closed]:c-animate-out data-[state=closed]:c-fade-out-0 data-[state=open]:c-fade-in-0",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
ref={ref}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
|
||||||
|
|
||||||
|
const sheetVariants = cva(
|
||||||
|
"c-fixed c-z-50 c-gap-4 c-bg-background c-p-6 c-shadow-lg c-transition c-ease-in-out data-[state=closed]:c-duration-300 data-[state=open]:c-duration-500 data-[state=open]:c-animate-in data-[state=closed]:c-animate-out",
|
||||||
|
{
|
||||||
|
variants: {
|
||||||
|
side: {
|
||||||
|
top: "c-inset-x-0 c-top-0 c-border-b data-[state=closed]:c-slide-out-to-top data-[state=open]:c-slide-in-from-top",
|
||||||
|
bottom:
|
||||||
|
"c-inset-x-0 c-bottom-0 c-border-t data-[state=closed]:c-slide-out-to-bottom data-[state=open]:c-slide-in-from-bottom",
|
||||||
|
left: "c-inset-y-0 c-left-0 c-h-full c-w-3/4 c-border-r data-[state=closed]:c-slide-out-to-left data-[state=open]:c-slide-in-from-left sm:c-max-w-sm",
|
||||||
|
right:
|
||||||
|
"c-inset-y-0 c-right-0 c-h-full c-w-3/4 c-border-l data-[state=closed]:c-slide-out-to-right data-[state=open]:c-slide-in-from-right sm:c-max-w-sm",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
side: "right",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
interface SheetContentProps
|
||||||
|
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
|
||||||
|
VariantProps<typeof sheetVariants> {}
|
||||||
|
|
||||||
|
const SheetContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SheetPrimitive.Content>,
|
||||||
|
SheetContentProps
|
||||||
|
>(({ side = "right", className, children, ...props }, ref) => (
|
||||||
|
<SheetPortal>
|
||||||
|
<SheetPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className={cn(sheetVariants({ side }), className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</SheetPrimitive.Content>
|
||||||
|
</SheetPortal>
|
||||||
|
));
|
||||||
|
SheetContent.displayName = SheetPrimitive.Content.displayName;
|
||||||
|
|
||||||
|
const SheetHeader = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"c-flex c-flex-col c-space-y-2 c-text-center sm:c-text-left",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
SheetHeader.displayName = "SheetHeader";
|
||||||
|
|
||||||
|
const SheetFooter = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"c-flex c-flex-col-reverse sm:c-flex-row sm:c-justify-end sm:c-space-x-2",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
SheetFooter.displayName = "SheetFooter";
|
||||||
|
|
||||||
|
const SheetTitle = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SheetPrimitive.Title>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SheetPrimitive.Title
|
||||||
|
ref={ref}
|
||||||
|
className={cn("c-text-lg c-font-semibold c-text-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
SheetTitle.displayName = SheetPrimitive.Title.displayName;
|
||||||
|
|
||||||
|
const SheetDescription = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SheetPrimitive.Description>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SheetPrimitive.Description
|
||||||
|
ref={ref}
|
||||||
|
className={cn("c-text-sm c-text-muted-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
SheetDescription.displayName = SheetPrimitive.Description.displayName;
|
||||||
|
|
||||||
|
export {
|
||||||
|
Sheet,
|
||||||
|
SheetPortal,
|
||||||
|
SheetOverlay,
|
||||||
|
SheetTrigger,
|
||||||
|
SheetClose,
|
||||||
|
SheetContent,
|
||||||
|
SheetHeader,
|
||||||
|
SheetFooter,
|
||||||
|
SheetTitle,
|
||||||
|
SheetDescription,
|
||||||
|
};
|
||||||
31
exports.tsx
31
exports.tsx
|
|
@ -1,10 +1,10 @@
|
||||||
export { FieldLoading } from "@/comps/ui/field-loading";
|
export { FieldLoading } from "@/comps/ui/field-loading";
|
||||||
|
export { fetchLinkParams } from "./comps/form/field/type/TypeLink";
|
||||||
|
export { prasi_gen } from "./gen/prasi_gen";
|
||||||
|
export { guessLabel } from "./utils/guess-label";
|
||||||
import { lazify, lazifyMany } from "@/utils/lazify";
|
import { lazify, lazifyMany } from "@/utils/lazify";
|
||||||
import __get from "lodash.get";
|
import __get from "lodash.get";
|
||||||
import { sum } from "./utils/sum";
|
import { sum } from "./utils/sum";
|
||||||
export { guessLabel } from "./utils/guess-label";
|
|
||||||
export { fetchLinkParams } from "./comps/form/field/type/TypeLink";
|
|
||||||
export { prasi_gen } from "./gen/prasi_gen";
|
|
||||||
|
|
||||||
export const _sum = sum;
|
export const _sum = sum;
|
||||||
export const _get = __get;
|
export const _get = __get;
|
||||||
|
|
@ -80,8 +80,8 @@ export const HeaderProfile = lazify(
|
||||||
);
|
);
|
||||||
|
|
||||||
/** charts */
|
/** charts */
|
||||||
export { PieChart } from "@/comps/charts/pie";
|
|
||||||
export { BarChart } from "@/comps/charts/bar";
|
export { BarChart } from "@/comps/charts/bar";
|
||||||
|
export { PieChart } from "@/comps/charts/pie";
|
||||||
// export { LineChart } from "@/comps/charts/line";
|
// export { LineChart } from "@/comps/charts/line";
|
||||||
|
|
||||||
/** Generator */
|
/** Generator */
|
||||||
|
|
@ -98,11 +98,9 @@ export { generateForm } from "@/comps/form/gen/gen-form";
|
||||||
export { validate as validateField } from "@/comps/form/utils/validate";
|
export { validate as validateField } from "@/comps/form/utils/validate";
|
||||||
export { sortTree, treePrefix } from "@/comps/list/utils/sort-tree";
|
export { sortTree, treePrefix } from "@/comps/list/utils/sort-tree";
|
||||||
|
|
||||||
|
export { getFilter } from "@/comps/filter/utils/get-filter";
|
||||||
export {
|
export {
|
||||||
FMLocal,
|
fieldType, FieldTypeCustom, FMLocal, formType
|
||||||
FieldTypeCustom,
|
|
||||||
fieldType,
|
|
||||||
formType,
|
|
||||||
} from "@/comps/form/typings";
|
} from "@/comps/form/typings";
|
||||||
export { TableListType } from "@/comps/list/utils/typings";
|
export { TableListType } from "@/comps/list/utils/typings";
|
||||||
export { generateTableList as generateTableList } from "@/comps/md/gen/gen-table-list";
|
export { generateTableList as generateTableList } from "@/comps/md/gen/gen-table-list";
|
||||||
|
|
@ -112,17 +110,15 @@ export { Button, FloatButton } from "@/comps/ui/button";
|
||||||
export { FormatValue } from "@/utils/format-value";
|
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 { call_prasi_events, 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";
|
||||||
export { logout } from "@/preset/login/utils/logout";
|
export { logout } from "@/preset/login/utils/logout";
|
||||||
export {
|
export {
|
||||||
RG,
|
registerSession, RG,
|
||||||
UserSession,
|
UserSession
|
||||||
registerSession,
|
|
||||||
} from "@/preset/login/utils/register";
|
} from "@/preset/login/utils/register";
|
||||||
|
|
||||||
export { Card } from "@/comps/custom/Card";
|
export { Card } from "@/comps/custom/Card";
|
||||||
|
|
@ -143,12 +139,15 @@ export { PanelTab } from "@/comps/tab/parts/PanelTab";
|
||||||
export { Popup } from "@/comps/popup/PopUp";
|
export { Popup } from "@/comps/popup/PopUp";
|
||||||
|
|
||||||
export { Detail } from "@/comps/custom/Detail";
|
export { Detail } from "@/comps/custom/Detail";
|
||||||
|
export * from "@/comps/ui/input";
|
||||||
export { ButtonUpload } from "@/preset/profile/ButtonUpload";
|
export { ButtonUpload } from "@/preset/profile/ButtonUpload";
|
||||||
export { Profile } from "@/preset/profile/Profile";
|
export { Profile } from "@/preset/profile/Profile";
|
||||||
export { generateProfile } from "@/preset/profile/utils/generate";
|
export { generateProfile } from "@/preset/profile/utils/generate";
|
||||||
export { formatTime, longDate, shortDate, timeAgo } from "@/utils/date";
|
export { formatTime, longDate, shortDate, timeAgo } from "@/utils/date";
|
||||||
export { getPathname, getBasename } from "@/utils/pathname";
|
export { getBasename, getPathname } from "@/utils/pathname";
|
||||||
|
|
||||||
export * from "@/comps/ui/input";
|
|
||||||
|
|
||||||
export { Flow } from "@/comps/ui/flow";
|
export { Flow } from "@/comps/ui/flow";
|
||||||
|
// format money
|
||||||
|
export { formatMoney } from "@/comps/form/field/type/TypeMoney";
|
||||||
|
|
||||||
|
export { ScrollArea } from "@/comps/ui/scroll-area";
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ export const FormatValue: FC<{
|
||||||
|
|
||||||
if (mode === "money") {
|
if (mode === "money") {
|
||||||
if (isEmptyString(value)) return "-";
|
if (isEmptyString(value)) return "-";
|
||||||
return formatMoney(Number(value) || 0);
|
return formatMoney(ceil_comma(Number(value) || 0));
|
||||||
} else if (mode === "datetime") {
|
} else if (mode === "datetime") {
|
||||||
if (!value || isEmptyString(value)) return "-";
|
if (!value || isEmptyString(value)) return "-";
|
||||||
try {
|
try {
|
||||||
|
|
@ -120,7 +120,7 @@ export const FormatValue: FC<{
|
||||||
}
|
}
|
||||||
} else if (["float"].includes(field?.type as string)) {
|
} else if (["float"].includes(field?.type as string)) {
|
||||||
if (!value || isEmptyString(value)) return "-";
|
if (!value || isEmptyString(value)) return "-";
|
||||||
return formatMoney(Number(value) || 0);
|
return formatMoney(ceil_comma(Number(value) || 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,12 +169,13 @@ const timeAgo = (date: any) => {
|
||||||
const daysPast = Math.floor(secondsPast / 86400);
|
const daysPast = Math.floor(secondsPast / 86400);
|
||||||
return `${daysPast} days ago`;
|
return `${daysPast} days ago`;
|
||||||
} else {
|
} else {
|
||||||
const year = date.getFullYear();
|
return formatDate(dayjs(date), "DD MMMM YYYY");
|
||||||
const month = (date.getMonth() + 1).toString().padStart(2, "0");
|
|
||||||
const day = date.getDate().toString().padStart(2, "0");
|
|
||||||
return `${day}-${month}-${year}`;
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const ceil_comma = (number: number) => {
|
||||||
|
if (!number) return 0;
|
||||||
|
return Math.ceil(number * 100) / 100;
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue