fix lib
This commit is contained in:
parent
d1174741b4
commit
913f1dc942
|
|
@ -43,11 +43,11 @@ const Week: React.FC<Props> = ({style}) => {
|
||||||
>
|
>
|
||||||
{style === "google" ? dayjs(`2022-11-${6 + (item + startDateModifier)}`)
|
{style === "google" ? dayjs(`2022-11-${6 + (item + startDateModifier)}`)
|
||||||
.locale(i18n)
|
.locale(i18n)
|
||||||
.format("dddd") : ucFirst(
|
.format(isMobile ? "dd" :"dddd") : ucFirst(
|
||||||
shortString(
|
shortString(
|
||||||
dayjs(`2022-11-${6 + (item + startDateModifier)}`)
|
dayjs(`2022-11-${6 + (item + startDateModifier)}`)
|
||||||
.locale(i18n)
|
.locale(i18n)
|
||||||
.format("dddd")
|
.format(isMobile ? "dd" :"dddd")
|
||||||
),
|
),
|
||||||
|
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -377,15 +377,6 @@ const Calendar: React.FC<Props> = ({
|
||||||
return onMark(day, date)
|
return onMark(day, date)
|
||||||
}
|
}
|
||||||
return <></>
|
return <></>
|
||||||
if (new Date().getDate() === day)
|
|
||||||
return (
|
|
||||||
<div className="c-absolute c-inset-y-0 c-left-0 -c-translate-y-1/2 -c-translate-x-1/2">
|
|
||||||
<div className="c-w-full c-h-full c-flex c-flex-row c-items-center c-justif-center c-px-0.5">
|
|
||||||
!
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
return <></>
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,6 @@ export function getNumberOfDay(
|
||||||
let number = 0;
|
let number = 0;
|
||||||
|
|
||||||
let startDateModifier = 0;
|
let startDateModifier = 0;
|
||||||
|
|
||||||
if (startWeekOn) {
|
if (startWeekOn) {
|
||||||
switch (startWeekOn) {
|
switch (startWeekOn) {
|
||||||
case "mon":
|
case "mon":
|
||||||
|
|
@ -173,16 +172,7 @@ export function getNumberOfDay(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const days = [
|
||||||
isMobile ? [
|
|
||||||
"S",
|
|
||||||
"M",
|
|
||||||
"T",
|
|
||||||
"W",
|
|
||||||
"T",
|
|
||||||
"F",
|
|
||||||
"S",
|
|
||||||
]: [
|
|
||||||
"Sunday",
|
"Sunday",
|
||||||
"Monday",
|
"Monday",
|
||||||
"Tuesday",
|
"Tuesday",
|
||||||
|
|
@ -190,7 +180,8 @@ export function getNumberOfDay(
|
||||||
"Thursday",
|
"Thursday",
|
||||||
"Friday",
|
"Friday",
|
||||||
"Saturday",
|
"Saturday",
|
||||||
].forEach((item, index) => {
|
]
|
||||||
|
days.forEach((item, index) => {
|
||||||
if (item.includes(dayString)) {
|
if (item.includes(dayString)) {
|
||||||
number = (index + startDateModifier) % 7;
|
number = (index + startDateModifier) % 7;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
|
import { Toaster } from "lib/exports";
|
||||||
import { ReactNode, useEffect, useRef, useState } from "react";
|
import { ReactNode, useEffect, useRef, useState } from "react";
|
||||||
import { createPortal } from "react-dom";
|
import { createPortal } from "react-dom";
|
||||||
import { editorFormWidth } from "../Form";
|
|
||||||
import { FMLocal } from "../typings";
|
import { FMLocal } from "../typings";
|
||||||
import { createFm } from "./utils/create-fm";
|
import { createFm } from "./utils/create-fm";
|
||||||
import { DivForm } from "./utils/DivForm";
|
import { DivForm } from "./utils/DivForm";
|
||||||
import { Toaster } from "lib/exports";
|
import { editorFormWidth } from "../Form";
|
||||||
|
|
||||||
export type BaseFormProps<T> = {
|
export type BaseFormProps<T> = {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,6 @@ export const FieldInput: FC<{
|
||||||
child: get(_item, "edit.props.child.value") as PrasiItem,
|
child: get(_item, "edit.props.child.value") as PrasiItem,
|
||||||
bottom: childsTableEdit.find((e) => e.name === "bottom") as PrasiItem,
|
bottom: childsTableEdit.find((e) => e.name === "bottom") as PrasiItem,
|
||||||
};
|
};
|
||||||
console.log({ tableEdit });
|
|
||||||
table_edit = (
|
table_edit = (
|
||||||
<TableEdit
|
<TableEdit
|
||||||
on_init={() => {
|
on_init={() => {
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,6 @@ export const Label: FC<{ field: FieldLocal; fm: FMLocal; arg: FieldProp }> = ({
|
||||||
const errors = fm.error.get(field.name);
|
const errors = fm.error.get(field.name);
|
||||||
const disabled =
|
const disabled =
|
||||||
typeof field.disabled === "function" ? field.disabled() : field.disabled;
|
typeof field.disabled === "function" ? field.disabled() : field.disabled;
|
||||||
useEffect(() => {
|
|
||||||
if (field.name === "complete_description")
|
|
||||||
console.log("log", field.required);
|
|
||||||
}, []);
|
|
||||||
const required =
|
const required =
|
||||||
typeof arg.required === "string"
|
typeof arg.required === "string"
|
||||||
? arg.required === "y"
|
? arg.required === "y"
|
||||||
|
|
@ -30,12 +26,12 @@ export const Label: FC<{ field: FieldLocal; fm: FMLocal; arg: FieldProp }> = ({
|
||||||
"c-mt-3 c-w-full c-justify-between"
|
"c-mt-3 c-w-full c-justify-between"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="c-flex c-items-center">
|
<div className="c-flex c-flex-row c-items-center">
|
||||||
<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>
|
||||||
{required && !disabled && (
|
{required && !disabled && (
|
||||||
<span className="c-text-red-600 c-mb-2 c-ml-1">
|
<span className="c-text-red-600 c-ml-1">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="12"
|
width="12"
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,7 @@ export const TableEdit: FC<{
|
||||||
<BaseForm is_form={false} data={row}>
|
<BaseForm is_form={false} data={row}>
|
||||||
{(form) => {
|
{(form) => {
|
||||||
return (
|
return (
|
||||||
<tr>
|
<tr className={cx("c-border-b ", idx !== value.length -1 ? "c-border-gray-300" : "" )}>
|
||||||
{columns.map((header) => {
|
{columns.map((header) => {
|
||||||
return (
|
return (
|
||||||
<td
|
<td
|
||||||
|
|
@ -322,10 +322,11 @@ export const TableEdit: FC<{
|
||||||
ext_fm={{
|
ext_fm={{
|
||||||
add: (e: any) => {
|
add: (e: any) => {
|
||||||
if (Array.isArray(fm.data[name])) {
|
if (Array.isArray(fm.data[name])) {
|
||||||
fm.data[name].push({});
|
fm.data[name].push({...e});
|
||||||
} else {
|
} else {
|
||||||
fm.data[name] = [{}];
|
fm.data[name] = [{...e}];
|
||||||
}
|
}
|
||||||
|
console.log("CEKK")
|
||||||
fm.render();
|
fm.render();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const last = Array.from(
|
const last = Array.from(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { FC } from "react"
|
||||||
|
import { FilePreview } from "./FilePreview";
|
||||||
|
import { Trash2 } from "lucide-react";
|
||||||
|
import { FMLocal } from "lib/exports";
|
||||||
|
|
||||||
|
|
||||||
|
export const PreviewAfterUpload: FC<{
|
||||||
|
fm: FMLocal, fieldName: string, local: any
|
||||||
|
}> = ({ fm, fieldName, local }) => {
|
||||||
|
return (
|
||||||
|
<div className="c-flex-grow c-flex-row c-flex c-w-full c-h-full c-items-stretch">
|
||||||
|
<div className="c-flex c-justify-between c-flex-1 c-p-1">
|
||||||
|
<FilePreview url={fm.data[fieldName] || ""} />
|
||||||
|
|
||||||
|
<div
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
if (confirm("Clear this file ?")) {
|
||||||
|
fm.data[fieldName] = null;
|
||||||
|
local.attachment = "";
|
||||||
|
local.render();
|
||||||
|
fm.render();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className={cx(
|
||||||
|
"c-flex c-flex-row c-items-center c-border c-px-2 c-rounded c-cursor-pointer hover:c-bg-red-100"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Trash2 className="c-text-red-500 c-h-4 c-w-4" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -242,7 +242,7 @@ export const navigateLink = async (
|
||||||
if (prev_link) prev_link = prev_link + "+";
|
if (prev_link) prev_link = prev_link + "+";
|
||||||
}
|
}
|
||||||
|
|
||||||
navigate(`${link.url}#lnk=${prev_link + vhash}${prm}`);
|
navigate(`${link.url}#lnk=${prev_link + vhash}${prm ? prm : ""}`);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ export const FieldRadio: FC<{
|
||||||
list: [] as any[],
|
list: [] as any[],
|
||||||
value: [] as any[],
|
value: [] as any[],
|
||||||
});
|
});
|
||||||
|
const disabled =
|
||||||
|
typeof field.disabled === "function" ? field.disabled() : field.disabled;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const callback = (res: any[]) => {
|
const callback = (res: any[]) => {
|
||||||
local.list = res;
|
local.list = res;
|
||||||
|
|
@ -40,6 +42,7 @@ export const FieldRadio: FC<{
|
||||||
<div
|
<div
|
||||||
className="flex items-center mb-4"
|
className="flex items-center mb-4"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
if(!disabled)
|
||||||
arg.opt_set_value({
|
arg.opt_set_value({
|
||||||
fm,
|
fm,
|
||||||
name: field.name,
|
name: field.name,
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
|
||||||
</div>
|
</div>
|
||||||
</div>,
|
</div>,
|
||||||
{
|
{
|
||||||
duration:3000,
|
duration: 3000,
|
||||||
className: css`
|
className: css`
|
||||||
background: #e4ffed;
|
background: #e4ffed;
|
||||||
border: 2px solid green;
|
border: 2px solid green;
|
||||||
|
|
@ -134,7 +134,7 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
|
||||||
</div>
|
</div>
|
||||||
</div>,
|
</div>,
|
||||||
{
|
{
|
||||||
duration:3000,
|
duration: 3000,
|
||||||
className: css`
|
className: css`
|
||||||
background: #e4ffed;
|
background: #e4ffed;
|
||||||
border: 2px solid green;
|
border: 2px solid green;
|
||||||
|
|
@ -147,10 +147,10 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
|
||||||
fm.reload = async () => {
|
fm.reload = async () => {
|
||||||
fm.status = isEditor ? "ready" : "loading";
|
fm.status = isEditor ? "ready" : "loading";
|
||||||
fm.render();
|
fm.render();
|
||||||
|
let toastId = null as any;
|
||||||
if (sonar === "on" && !isEditor) {
|
if (sonar === "on" && !isEditor) {
|
||||||
toast.dismiss();
|
toast.dismiss();
|
||||||
toast.loading(
|
toastId = toast.loading(
|
||||||
<>
|
<>
|
||||||
<Loader2 className="c-h-4 c-w-4 c-animate-spin" />
|
<Loader2 className="c-h-4 c-w-4 c-animate-spin" />
|
||||||
Loading data...
|
Loading data...
|
||||||
|
|
@ -158,7 +158,6 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
|
||||||
{ dismissible: true }
|
{ dismissible: true }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let should_load = true;
|
let should_load = true;
|
||||||
if (isEditor) {
|
if (isEditor) {
|
||||||
const item_id = props.item.id;
|
const item_id = props.item.id;
|
||||||
|
|
@ -204,7 +203,6 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toast.dismiss();
|
toast.dismiss();
|
||||||
|
|
||||||
if (fm.is_newly_created) {
|
if (fm.is_newly_created) {
|
||||||
|
|
@ -214,6 +212,11 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
|
||||||
|
|
||||||
fm.status = "ready";
|
fm.status = "ready";
|
||||||
fm.render();
|
fm.render();
|
||||||
|
setTimeout(() => {
|
||||||
|
|
||||||
|
toast.dismiss();
|
||||||
|
|
||||||
|
}, 2000)
|
||||||
};
|
};
|
||||||
|
|
||||||
fm.submit = async () => {
|
fm.submit = async () => {
|
||||||
|
|
@ -289,7 +292,6 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
toastSuccess({ addNewText: lang.t("Add New") });
|
toastSuccess({ addNewText: lang.t("Add New") });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,5 @@ export const useField = (
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
field.prop = arg as any;
|
field.prop = arg as any;
|
||||||
|
|
||||||
return field;
|
return field;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import {
|
||||||
Plus,
|
Plus,
|
||||||
QrCode,
|
QrCode,
|
||||||
Rocket,
|
Rocket,
|
||||||
Settings,
|
Settings,
|
||||||
Ship,
|
Ship,
|
||||||
Siren,
|
Siren,
|
||||||
StickyNote,
|
StickyNote,
|
||||||
|
|
|
||||||
|
|
@ -95,12 +95,12 @@ export const Import: FC<{
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
resolve([]);
|
resolve([]);
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 50);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await task(list[n], n);
|
await task(list[n], n);
|
||||||
await sleep(100);
|
await sleep(50);
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ export const TLList: FC<{
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(
|
||||||
"c-absolute c-inset-0",
|
"list-inner c-absolute c-inset-0",
|
||||||
!isEditor &&
|
!isEditor &&
|
||||||
css`
|
css`
|
||||||
@keyframes flasher {
|
@keyframes flasher {
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,13 @@ import { OnRowClick } from "./utils/type";
|
||||||
|
|
||||||
let EMPTY_SET = new Set() as ReadonlySet<any>;
|
let EMPTY_SET = new Set() as ReadonlySet<any>;
|
||||||
|
|
||||||
type SelectedRow = (arg: { row: any; rows: any[]; idx: any }) => boolean;
|
type SelectedRow = (arg: {
|
||||||
|
row: any;
|
||||||
|
rows: any[];
|
||||||
|
idx: any;
|
||||||
|
select?: boolean;
|
||||||
|
data?: any[];
|
||||||
|
}) => boolean;
|
||||||
type TableListProp = {
|
type TableListProp = {
|
||||||
child: any;
|
child: any;
|
||||||
PassProp: any;
|
PassProp: any;
|
||||||
|
|
@ -137,6 +143,7 @@ export const TableList: FC<TableListProp> = ({
|
||||||
el: null as null | HTMLDivElement,
|
el: null as null | HTMLDivElement,
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
|
selectedAllRows: false as boolean,
|
||||||
selectedRowIds: [] as (string | number)[],
|
selectedRowIds: [] as (string | number)[],
|
||||||
pk: null as null | GFCol,
|
pk: null as null | GFCol,
|
||||||
scrolled: false,
|
scrolled: false,
|
||||||
|
|
@ -468,9 +475,11 @@ export const TableList: FC<TableListProp> = ({
|
||||||
rows: data,
|
rows: data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
local.selectedAllRows = true;
|
||||||
local.render();
|
local.render();
|
||||||
} else {
|
} else {
|
||||||
// jika tidak, maka local selected rows akan dikosongkan
|
// jika tidak, maka local selected rows akan dikosongkan
|
||||||
|
local.selectedAllRows = false;
|
||||||
local.selectedRows = [];
|
local.selectedRows = [];
|
||||||
local.render();
|
local.render();
|
||||||
}
|
}
|
||||||
|
|
@ -494,6 +503,7 @@ export const TableList: FC<TableListProp> = ({
|
||||||
local.selectedRows = local.selectedRows.filter(
|
local.selectedRows = local.selectedRows.filter(
|
||||||
(data) => data.pk !== rowId
|
(data) => data.pk !== rowId
|
||||||
);
|
);
|
||||||
|
local.selectedAllRows = false;
|
||||||
local.render();
|
local.render();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -610,8 +620,24 @@ export const TableList: FC<TableListProp> = ({
|
||||||
frozen: true,
|
frozen: true,
|
||||||
renderHeaderCell(props) {
|
renderHeaderCell(props) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div
|
||||||
{/* <CheckboxList value={false} on_click={on_click} /> */}
|
className={cx(
|
||||||
|
css`
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
`,
|
||||||
|
"c-flex c-items-center c-justify-center"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{isCheckbox ? (
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={local.selectedAllRows}
|
||||||
|
onChange={headerCheckboxClick}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
@ -622,7 +648,29 @@ export const TableList: FC<TableListProp> = ({
|
||||||
tbl: local,
|
tbl: local,
|
||||||
child,
|
child,
|
||||||
});
|
});
|
||||||
|
if (isCheckbox) {
|
||||||
|
const isChecked = local.selectedRows.some(
|
||||||
|
(checked) => checked.pk === props.row.id
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
onClick={checkboxClick(props.row.id)}
|
||||||
|
className={cx(
|
||||||
|
css`
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
`,
|
||||||
|
"c-flex c-items-center c-justify-center"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
className="c-pointer-events-none"
|
||||||
|
type="checkbox"
|
||||||
|
checked={local.selectedAllRows ? true : isChecked}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<PassProp
|
<PassProp
|
||||||
idx={props.rowIdx}
|
idx={props.rowIdx}
|
||||||
|
|
@ -908,10 +956,20 @@ export const TableList: FC<TableListProp> = ({
|
||||||
) {
|
) {
|
||||||
return local.cached_row.get(props.row);
|
return local.cached_row.get(props.row);
|
||||||
}
|
}
|
||||||
const isSelect = selected({
|
const isSelect = local.selectedAllRows
|
||||||
|
? true
|
||||||
|
: selected({
|
||||||
idx: props.rowIdx,
|
idx: props.rowIdx,
|
||||||
row: props.row,
|
row: props.row,
|
||||||
rows: local.data,
|
rows: local.data,
|
||||||
|
select: local.selectedAllRows
|
||||||
|
? true
|
||||||
|
: local.selectedRows.some(
|
||||||
|
(checked) => checked.pk === props.row.id
|
||||||
|
),
|
||||||
|
data: local.selectedAllRows
|
||||||
|
? local.data
|
||||||
|
: local.selectedRows,
|
||||||
});
|
});
|
||||||
const child_row = (
|
const child_row = (
|
||||||
<Row
|
<Row
|
||||||
|
|
@ -1008,23 +1066,29 @@ export const TableList: FC<TableListProp> = ({
|
||||||
};
|
};
|
||||||
const CheckboxList: FC<{
|
const CheckboxList: FC<{
|
||||||
on_click: (e: any) => void;
|
on_click: (e: any) => void;
|
||||||
|
checked?: boolean;
|
||||||
value?: boolean;
|
value?: boolean;
|
||||||
}> = ({ value, on_click }) => {
|
}> = ({ value, checked, on_click }) => {
|
||||||
const local = useLocal({
|
const local = useLocal({
|
||||||
|
checked: false as any,
|
||||||
value: false as boolean,
|
value: false as boolean,
|
||||||
});
|
});
|
||||||
|
useEffect(() => {
|
||||||
|
local.checked = checked;
|
||||||
|
local.render();
|
||||||
|
}, []);
|
||||||
return (
|
return (
|
||||||
<div className={cx("c-flex c-items-center c-w-full c-flex-row")}>
|
<div className={cx("c-flex c-items-center c-w-full c-flex-row")}>
|
||||||
<div className={cx(`c-flex c-flex-col c-space-y-1 c-p-0.5`)}>
|
<div className={cx(`c-flex c-flex-col c-space-y-1 c-p-0.5`)}>
|
||||||
<div
|
<div
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
local.value = !local.value;
|
local.checked = !local.checked;
|
||||||
on_click(local.value);
|
on_click(typeof value === "boolean" ? !local.checked : value);
|
||||||
local.render();
|
local.render();
|
||||||
}}
|
}}
|
||||||
className="c-flex c-flex-row c-space-x-1 cursor-pointer c-items-center rounded-full p-0.5"
|
className="c-flex c-flex-row c-space-x-1 cursor-pointer c-items-center rounded-full p-0.5"
|
||||||
>
|
>
|
||||||
{local.value ? (
|
{local.checked ? (
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="24"
|
width="24"
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ export const toast = {
|
||||||
sonner.dismiss(t.id);
|
sonner.dismiss(t.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sonner.dismiss()
|
||||||
} else {
|
} else {
|
||||||
clearTimeout(timer.timeout);
|
clearTimeout(timer.timeout);
|
||||||
timer.timeout = null;
|
timer.timeout = null;
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,6 @@ export { get_user } from "./utils/get_user";
|
||||||
export { range_date } from "./utils/ranged_date";
|
export { range_date } from "./utils/ranged_date";
|
||||||
export const _sum = sum;
|
export const _sum = sum;
|
||||||
export const _get = __get;
|
export const _get = __get;
|
||||||
|
|
||||||
/** Generator */
|
/** Generator */
|
||||||
export { generateFilter as generateFilter } from "lib/comps/filter/gen/gen-filter";
|
export { generateFilter as generateFilter } from "lib/comps/filter/gen/gen-filter";
|
||||||
export { generateRelation } from "lib/comps/form/gen/gen-rel";
|
export { generateRelation } from "lib/comps/form/gen/gen-rel";
|
||||||
|
|
@ -197,7 +196,7 @@ export * from "lib/comps/ui/input";
|
||||||
export { ButtonUpload } from "lib/preset/profile/ButtonUpload";
|
export { ButtonUpload } from "lib/preset/profile/ButtonUpload";
|
||||||
export { Profile } from "lib/preset/profile/Profile";
|
export { Profile } from "lib/preset/profile/Profile";
|
||||||
export { generateProfile } from "lib/preset/profile/utils/generate";
|
export { generateProfile } from "lib/preset/profile/utils/generate";
|
||||||
export { formatTime, longDate, shortDate, timeAgo } from "lib/utils/date";
|
export { formatTime, longDate, shortDate, timeAgo, formatDay } from "lib/utils/date";
|
||||||
export { getBasename, getPathname } from "lib/utils/pathname";
|
export { getBasename, getPathname } from "lib/utils/pathname";
|
||||||
|
|
||||||
export { formatMoney } from "lib/comps/form/field/type/TypeMoney";
|
export { formatMoney } from "lib/comps/form/field/type/TypeMoney";
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ import { useLocal } from "lib/utils/use-local";
|
||||||
import get from "lodash.get";
|
import get from "lodash.get";
|
||||||
import { FC, useEffect, useRef } from "react";
|
import { FC, useEffect, useRef } from "react";
|
||||||
import { IMenu, MenuProp } from "./utils/type-menu";
|
import { IMenu, MenuProp } from "./utils/type-menu";
|
||||||
|
import { icons } from "app/icons";
|
||||||
|
import { FieldLoading } from "lib/exports";
|
||||||
// import { icon } from "../../..";
|
// import { icon } from "../../..";
|
||||||
|
|
||||||
const local_default = {
|
const local_default = {
|
||||||
|
|
@ -14,19 +16,19 @@ const local_default = {
|
||||||
pathname: "",
|
pathname: "",
|
||||||
loading: false,
|
loading: false,
|
||||||
init: false,
|
init: false,
|
||||||
|
ready: false,
|
||||||
|
menu: [] as any[],
|
||||||
};
|
};
|
||||||
type MLocal = typeof local_default & { render: () => void };
|
type MLocal = typeof local_default & { render: () => void };
|
||||||
|
|
||||||
export const Menu: FC<MenuProp> = (props) => {
|
export const Menu: FC<MenuProp> = (props) => {
|
||||||
const imenu = props.menu;
|
|
||||||
let role = props.role;
|
|
||||||
role = props.on_init();
|
|
||||||
let menu = get(imenu, role) || [];
|
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
const local = useLocal({ ...local_default }, ({ setDelayedRender }) => {
|
const local = useLocal({ ...local_default }, ({ setDelayedRender }) => {
|
||||||
setDelayedRender(true);
|
setDelayedRender(true);
|
||||||
});
|
});
|
||||||
|
const imenu = props.menu;
|
||||||
|
// useEffect(() => {
|
||||||
|
// }, []);
|
||||||
if (local.pathname !== getPathname()) {
|
if (local.pathname !== getPathname()) {
|
||||||
local.pathname = getPathname();
|
local.pathname = getPathname();
|
||||||
}
|
}
|
||||||
|
|
@ -37,9 +39,30 @@ export const Menu: FC<MenuProp> = (props) => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
local.mode = props.mode;
|
local.mode = props.mode;
|
||||||
|
local.ready = false;
|
||||||
|
local.render();
|
||||||
|
if (typeof imenu === "function") {
|
||||||
|
const res = imenu();
|
||||||
|
if (res instanceof Promise) {
|
||||||
|
res.then((e) => {
|
||||||
|
local.menu = e;
|
||||||
|
local.render();
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
local.menu = res;
|
||||||
|
local.render();
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let role = props.role;
|
||||||
|
role = props.on_init();
|
||||||
|
let menu = get(imenu, role) || [];
|
||||||
|
local.menu = menu;
|
||||||
|
}
|
||||||
|
local.ready = true;
|
||||||
local.render();
|
local.render();
|
||||||
}, [props.mode]);
|
}, [props.mode]);
|
||||||
|
if (!local.ready) return <FieldLoading />;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx("c-overflow-y-auto c-relative c-h-full c-w-full c-flex-1")}
|
className={cx("c-overflow-y-auto c-relative c-h-full c-w-full c-flex-1")}
|
||||||
|
|
@ -47,7 +70,7 @@ export const Menu: FC<MenuProp> = (props) => {
|
||||||
>
|
>
|
||||||
<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={local.menu}
|
||||||
local={local}
|
local={local}
|
||||||
pm={props}
|
pm={props}
|
||||||
depth={0}
|
depth={0}
|
||||||
|
|
@ -88,6 +111,9 @@ export const SideBar: FC<{
|
||||||
pm,
|
pm,
|
||||||
};
|
};
|
||||||
const data: IMenu[] = (typeof _data[0] === "string" ? [_data] : _data) as any;
|
const data: IMenu[] = (typeof _data[0] === "string" ? [_data] : _data) as any;
|
||||||
|
if (!data.length) {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
data.map((item) => {
|
data.map((item) => {
|
||||||
const menu = {
|
const menu = {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ export type IMenu = [string, any, string | IMenu[]];
|
||||||
export type MenuProp = {
|
export type MenuProp = {
|
||||||
role: string;
|
role: string;
|
||||||
on_init: () => string;
|
on_init: () => string;
|
||||||
menu: Array<Record<string, IMenu[]>>;
|
menu: Array<Record<string, IMenu[]>> | (() => Promise<any>);
|
||||||
PassProp: any;
|
PassProp: any;
|
||||||
child: ReactNode;
|
child: ReactNode;
|
||||||
mode: "full" | "mini";
|
mode: "full" | "mini";
|
||||||
|
|
@ -12,7 +12,9 @@ export type MenuProp = {
|
||||||
style: "navbar" | "sidebar";
|
style: "navbar" | "sidebar";
|
||||||
layout?: { current_menu: string; render: () => void };
|
layout?: { current_menu: string; render: () => void };
|
||||||
on_load?: (on_done: (exec: () => void) => void) => void;
|
on_load?: (on_done: (exec: () => void) => void) => void;
|
||||||
get_menu?: (mn: Array<Record<string, IMenu[]>>) => Array<Record<string, IMenu[]>>
|
get_menu?: (
|
||||||
|
mn: Array<Record<string, IMenu[]>>
|
||||||
|
) => Array<Record<string, IMenu[]>>;
|
||||||
};
|
};
|
||||||
export type MenuActive = {
|
export type MenuActive = {
|
||||||
data: any;
|
data: any;
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,6 @@ export const useServerRouter = <T extends ReturnType<typeof newServerRouter>>(
|
||||||
async handle(arg: ServerContext | SessionContext<any>) {
|
async handle(arg: ServerContext | SessionContext<any>) {
|
||||||
const { url, req, handle } = arg;
|
const { url, req, handle } = arg;
|
||||||
const found = findRoute(rou, undefined, url.pathname);
|
const found = findRoute(rou, undefined, url.pathname);
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
const route = found.data;
|
const route = found.data;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,13 @@ import relative from "dayjs/plugin/relativeTime";
|
||||||
|
|
||||||
day.extend(relative);
|
day.extend(relative);
|
||||||
|
|
||||||
|
export const formatDay = (date: string | Date, mode: string) => {
|
||||||
|
if (date instanceof Date || typeof date === "string") {
|
||||||
|
return day(date).format(mode);
|
||||||
|
}
|
||||||
|
return "-";
|
||||||
|
};
|
||||||
|
|
||||||
export const longDate = (date: string | Date) => {
|
export const longDate = (date: string | Date) => {
|
||||||
if (date instanceof Date || typeof date === "string") {
|
if (date instanceof Date || typeof date === "string") {
|
||||||
return day(date).format("DD MMM YYYY - hh:mm");
|
return day(date).format("DD MMM YYYY - hh:mm");
|
||||||
|
|
@ -23,6 +30,7 @@ export const timeAgo = (date: string | Date) => {
|
||||||
}
|
}
|
||||||
return "-";
|
return "-";
|
||||||
};
|
};
|
||||||
|
|
||||||
export const formatTime = (date: string | Date) => {
|
export const formatTime = (date: string | Date) => {
|
||||||
if (date instanceof Date || typeof date === "string") {
|
if (date instanceof Date || typeof date === "string") {
|
||||||
return day(date).format("hh:mm");
|
return day(date).format("hh:mm");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue