fix category
This commit is contained in:
parent
362cfdff27
commit
ad86c97c9a
|
|
@ -13,7 +13,7 @@ export const FilterField: FC<{
|
||||||
name?: string;
|
name?: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
type: FilterFieldType;
|
type: FilterFieldType;
|
||||||
modifiers?: any[]
|
modifiers?: any[];
|
||||||
}> = ({ filter, name, label, type, modifiers }) => {
|
}> = ({ filter, name, label, type, modifiers }) => {
|
||||||
const internal = useLocal({ render_timeout: null as any });
|
const internal = useLocal({ render_timeout: null as any });
|
||||||
if (!name) return <>No Name</>;
|
if (!name) return <>No Name</>;
|
||||||
|
|
@ -85,7 +85,7 @@ export const FilterField: FC<{
|
||||||
prop={{
|
prop={{
|
||||||
type: "input",
|
type: "input",
|
||||||
sub_type: "search",
|
sub_type: "search",
|
||||||
placeholder: "Search...",
|
placeholder: field.field.label,
|
||||||
onBlur(e) {
|
onBlur(e) {
|
||||||
filter.form?.submit();
|
filter.form?.submit();
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,8 @@ export const Field: FC<FieldProp> = (arg) => {
|
||||||
{...props}
|
{...props}
|
||||||
className={cx(
|
className={cx(
|
||||||
"field",
|
"field",
|
||||||
|
field.type,
|
||||||
|
sub_type,
|
||||||
"c-flex c-relative",
|
"c-flex c-relative",
|
||||||
editorClassName,
|
editorClassName,
|
||||||
field.type === "single-option" && sub_type === "checkbox"
|
field.type === "single-option" && sub_type === "checkbox"
|
||||||
|
|
|
||||||
|
|
@ -290,3 +290,47 @@ const getFileName = (url: string) => {
|
||||||
const extension = fileName.substring(dotIndex + 1);
|
const extension = fileName.substring(dotIndex + 1);
|
||||||
return { name, extension, fullname };
|
return { name, extension, fullname };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ImgThumb = ({
|
||||||
|
className,
|
||||||
|
url,
|
||||||
|
w,
|
||||||
|
h,
|
||||||
|
}: {
|
||||||
|
className?: string;
|
||||||
|
url: string;
|
||||||
|
w: number;
|
||||||
|
h: number;
|
||||||
|
}) => {
|
||||||
|
const local = useLocal({ error: false });
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
"img-thumb",
|
||||||
|
className,
|
||||||
|
css`
|
||||||
|
width: ${w}px;
|
||||||
|
height: ${h}px;
|
||||||
|
background-image: linear-gradient(45deg, #ccc 25%, transparent 25%),
|
||||||
|
linear-gradient(135deg, #ccc 25%, transparent 25%),
|
||||||
|
linear-gradient(45deg, transparent 75%, #ccc 75%),
|
||||||
|
linear-gradient(135deg, transparent 75%, #ccc 75%);
|
||||||
|
background-size: 25px 25px; /* Must be a square */
|
||||||
|
background-position: 0 0, 12.5px 0, 12.5px -12.5px, 0px 12.5px; /* Must be half of one side of the square */
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{!local.error && (
|
||||||
|
<img
|
||||||
|
onError={() => {
|
||||||
|
local.error = true;
|
||||||
|
local.render();
|
||||||
|
}}
|
||||||
|
src={siteurl(
|
||||||
|
`/_img/${url.substring("_file/".length)}?w=${w}&h=${h}&fit=cover`
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ export const FieldUploadMulti: FC<{
|
||||||
<div className="c-flex c-pt-1">
|
<div className="c-flex c-pt-1">
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(
|
||||||
"c-flex c-border c-rounded c-cursor-pointer hover:c-bg-blue-50",
|
"button c-flex c-border c-rounded c-cursor-pointer hover:c-bg-blue-50",
|
||||||
css`
|
css`
|
||||||
&:hover {
|
&:hover {
|
||||||
border: 1px solid #1c4ed8;
|
border: 1px solid #1c4ed8;
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,9 @@ import { filterWhere } from "../filter/parser/filter-where";
|
||||||
import { getFilter } from "../filter/utils/get-filter";
|
import { getFilter } from "../filter/utils/get-filter";
|
||||||
import { MDLocal } from "../md/utils/typings";
|
import { MDLocal } from "../md/utils/typings";
|
||||||
import { Skeleton } from "../ui/skeleton";
|
import { Skeleton } from "../ui/skeleton";
|
||||||
import { sortTree } from "./utils/sort-tree";
|
|
||||||
import { toast } from "../ui/toast";
|
import { toast } from "../ui/toast";
|
||||||
import { Arrow } from "../custom/Datepicker/components/utils";
|
import { sortTree } from "./utils/sort-tree";
|
||||||
|
import { getPathname } from "lib/exports";
|
||||||
|
|
||||||
type OnRowClick = (arg: {
|
type OnRowClick = (arg: {
|
||||||
row: any;
|
row: any;
|
||||||
|
|
@ -176,6 +176,104 @@ export const TableList: FC<TableListProp> = ({
|
||||||
collapsed: new Set<number>(),
|
collapsed: new Set<number>(),
|
||||||
cached_row: new WeakMap<any, ReactElement>(),
|
cached_row: new WeakMap<any, ReactElement>(),
|
||||||
filtering: "" as ReactNode | string | true,
|
filtering: "" as ReactNode | string | true,
|
||||||
|
reload: (arg?: { toast: boolean }) => {
|
||||||
|
return new Promise<void>((done) => {
|
||||||
|
let should_toast = true;
|
||||||
|
if (arg?.toast === false) should_toast = false;
|
||||||
|
local.should_toast = should_toast;
|
||||||
|
|
||||||
|
local.filtering = "";
|
||||||
|
if (typeof on_load === "function") {
|
||||||
|
local.status = "loading";
|
||||||
|
local.render();
|
||||||
|
|
||||||
|
const orderBy = local.sort.orderBy || undefined;
|
||||||
|
const where = filterWhere(filter_name, __props);
|
||||||
|
|
||||||
|
if (where?.OR?.length > 0) {
|
||||||
|
const key = Object.keys(where.OR[0])[0];
|
||||||
|
if (key && where.OR[0][key]) {
|
||||||
|
let filtering = where.OR[0][key].contains;
|
||||||
|
if (typeof local.filtering === "string") {
|
||||||
|
filtering = filtering.slice(1, -1);
|
||||||
|
} else {
|
||||||
|
filtering = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filtering) {
|
||||||
|
local.filtering = (
|
||||||
|
<div className="c-pt-2">
|
||||||
|
Searching for: <pre>"{filtering.trim()}"</pre>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (md) {
|
||||||
|
const last = md.params.links[md.params.links.length - 1];
|
||||||
|
|
||||||
|
if (last && last.where) {
|
||||||
|
for (const [k, v] of Object.entries(last.where)) {
|
||||||
|
where[k] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
call_prasi_events("tablelist", "where", [__props?.gen__table, where]);
|
||||||
|
|
||||||
|
const load_args: any = {
|
||||||
|
async reload() {},
|
||||||
|
orderBy,
|
||||||
|
where,
|
||||||
|
paging: {
|
||||||
|
take: local.paging.take > 0 ? local.paging.take : undefined,
|
||||||
|
skip: local.paging.skip,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (id_parent) {
|
||||||
|
load_args.paging = {};
|
||||||
|
}
|
||||||
|
const result = on_load({ ...load_args, mode: "query" });
|
||||||
|
const callback = (data: any[]) => {
|
||||||
|
if (local.paging.skip === 0) {
|
||||||
|
local.data = data;
|
||||||
|
} else {
|
||||||
|
local.data = [...local.data, ...data];
|
||||||
|
}
|
||||||
|
|
||||||
|
local.status = "ready";
|
||||||
|
local.render();
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (result instanceof Promise) {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
callback(await result);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
local.status = "error";
|
||||||
|
toast.dismiss();
|
||||||
|
toast.error(
|
||||||
|
<div className="c-flex c-text-red-600 c-items-center">
|
||||||
|
<AlertTriangle className="c-h-4 c-w-4 c-mr-1" />
|
||||||
|
Failed to load data
|
||||||
|
</div>,
|
||||||
|
{
|
||||||
|
dismissible: true,
|
||||||
|
className: css`
|
||||||
|
background: #ffecec;
|
||||||
|
border: 2px solid red;
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
} else callback(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
sort: {
|
sort: {
|
||||||
columns: (ls_sort?.columns || []) as SortColumn[],
|
columns: (ls_sort?.columns || []) as SortColumn[],
|
||||||
on_change: (cols: SortColumn[]) => {
|
on_change: (cols: SortColumn[]) => {
|
||||||
|
|
@ -255,104 +353,7 @@ export const TableList: FC<TableListProp> = ({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const reload = useCallback(
|
const reload = local.reload;
|
||||||
(arg?: { toast: boolean }) => {
|
|
||||||
let should_toast = true;
|
|
||||||
if (arg?.toast === false) should_toast = false;
|
|
||||||
local.should_toast = should_toast;
|
|
||||||
|
|
||||||
local.filtering = "";
|
|
||||||
if (typeof on_load === "function") {
|
|
||||||
local.status = "loading";
|
|
||||||
local.render();
|
|
||||||
|
|
||||||
const orderBy = local.sort.orderBy || undefined;
|
|
||||||
const where = filterWhere(filter_name, __props);
|
|
||||||
|
|
||||||
if (where?.OR?.length > 0) {
|
|
||||||
const key = Object.keys(where.OR[0])[0];
|
|
||||||
if (key && where.OR[0][key]) {
|
|
||||||
let filtering = where.OR[0][key].contains;
|
|
||||||
if (typeof local.filtering === "string") {
|
|
||||||
filtering = filtering.slice(1, -1);
|
|
||||||
} else {
|
|
||||||
filtering = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filtering) {
|
|
||||||
local.filtering = (
|
|
||||||
<div className="c-pt-2">
|
|
||||||
Searching for: <pre>"{filtering.trim()}"</pre>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (md) {
|
|
||||||
const last = md.params.links[md.params.links.length - 1];
|
|
||||||
if (last && last.where) {
|
|
||||||
for (const [k, v] of Object.entries(last.where)) {
|
|
||||||
where[k] = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
call_prasi_events("tablelist", "where", [__props?.gen__table, where]);
|
|
||||||
|
|
||||||
const load_args: any = {
|
|
||||||
async reload() {},
|
|
||||||
orderBy,
|
|
||||||
where,
|
|
||||||
paging: {
|
|
||||||
take: local.paging.take > 0 ? local.paging.take : undefined,
|
|
||||||
skip: local.paging.skip,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if (id_parent) {
|
|
||||||
load_args.paging = {};
|
|
||||||
}
|
|
||||||
const result = on_load({ ...load_args, mode: "query" });
|
|
||||||
const callback = (data: any[]) => {
|
|
||||||
if (local.paging.skip === 0) {
|
|
||||||
local.data = data;
|
|
||||||
} else {
|
|
||||||
local.data = [...local.data, ...data];
|
|
||||||
}
|
|
||||||
|
|
||||||
local.status = "ready";
|
|
||||||
local.render();
|
|
||||||
};
|
|
||||||
|
|
||||||
if (result instanceof Promise) {
|
|
||||||
(async () => {
|
|
||||||
try {
|
|
||||||
callback(await result);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
local.status = "error";
|
|
||||||
toast.dismiss();
|
|
||||||
toast.error(
|
|
||||||
<div className="c-flex c-text-red-600 c-items-center">
|
|
||||||
<AlertTriangle className="c-h-4 c-w-4 c-mr-1" />
|
|
||||||
Failed to load data
|
|
||||||
</div>,
|
|
||||||
{
|
|
||||||
dismissible: true,
|
|
||||||
className: css`
|
|
||||||
background: #ffecec;
|
|
||||||
border: 2px solid red;
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
} else callback(result);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[on_load, local.sort.orderBy, local.paging.take, local.paging.skip]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (md) {
|
if (md) {
|
||||||
md.master.reload = reload;
|
md.master.reload = reload;
|
||||||
}
|
}
|
||||||
|
|
@ -366,6 +367,7 @@ export const TableList: FC<TableListProp> = ({
|
||||||
|
|
||||||
// code ini digunakan untuk mengambil nama dari pk yang akan digunakan sebagai key untuk id
|
// code ini digunakan untuk mengambil nama dari pk yang akan digunakan sebagai key untuk id
|
||||||
const pk = local.pk?.name || "id";
|
const pk = local.pk?.name || "id";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isEditor || value) {
|
if (isEditor || value) {
|
||||||
on_init(local);
|
on_init(local);
|
||||||
|
|
@ -373,7 +375,10 @@ export const TableList: FC<TableListProp> = ({
|
||||||
}
|
}
|
||||||
(async () => {
|
(async () => {
|
||||||
on_init(local);
|
on_init(local);
|
||||||
if (local.status === "reload" && typeof on_load === "function") {
|
if (
|
||||||
|
(local.status === "init" || local.status === "reload") &&
|
||||||
|
typeof on_load === "function"
|
||||||
|
) {
|
||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
@ -703,33 +708,22 @@ export const TableList: FC<TableListProp> = ({
|
||||||
if (columns.length > 1) columns = columns.slice(0, 0 + 1);
|
if (columns.length > 1) columns = columns.slice(0, 0 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local.status === "resizing" && !isEditor) {
|
|
||||||
local.status = "ready";
|
|
||||||
local.render();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isEditor) {
|
|
||||||
if (local.status === "loading") {
|
if (local.status === "loading") {
|
||||||
if (local.should_toast) {
|
|
||||||
toast.dismiss();
|
toast.dismiss();
|
||||||
toast.loading(
|
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 {local.paging.skip === 0 ? "Data" : "more rows"} ...
|
Loading Data ...
|
||||||
</>,
|
</>
|
||||||
{
|
|
||||||
dismissible: true,
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
local.should_toast = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (local.status !== "error") {
|
|
||||||
toast.dismiss();
|
toast.dismiss();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (local.status === "resizing" && !isEditor) {
|
||||||
|
local.status = "ready";
|
||||||
|
local.render();
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.getElementsByClassName("prasi-toaster").length === 0) {
|
if (document.getElementsByClassName("prasi-toaster").length === 0) {
|
||||||
|
|
@ -908,32 +902,16 @@ export const TableList: FC<TableListProp> = ({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="c-absolute c-inset-0">
|
|
||||||
{toaster_el && createPortal(<Toaster cn={cn} />, toaster_el)}
|
{toaster_el && createPortal(<Toaster cn={cn} />, toaster_el)}
|
||||||
{local.status === "init" ? (
|
|
||||||
<DataGrid
|
{local.status !== "ready" ? (
|
||||||
style={{ opacity: 0 }}
|
<div className="c-flex c-flex-col c-space-y-2 c-m-4 c-absolute c-left-0 c-top-0">
|
||||||
columns={[
|
<Skeleton className={cx("c-w-[200px] c-h-[11px]")} />
|
||||||
{
|
<Skeleton className={cx("c-w-[170px] c-h-[11px]")} />
|
||||||
key: "_",
|
<Skeleton className={cx("c-w-[180px] c-h-[11px]")} />
|
||||||
name: "",
|
</div>
|
||||||
renderCell({ rowIdx }) {
|
|
||||||
if (local.paging.take < rowIdx) {
|
|
||||||
local.paging.take = rowIdx;
|
|
||||||
}
|
|
||||||
clearTimeout(local.paging.timeout);
|
|
||||||
local.paging.timeout = setTimeout(() => {
|
|
||||||
local.status = "reload";
|
|
||||||
local.paging.take = local.paging.take * 5;
|
|
||||||
local.render();
|
|
||||||
}, 100);
|
|
||||||
return <></>;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
rows={genRows(200)}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
|
<div className="c-absolute c-inset-0">
|
||||||
<>
|
<>
|
||||||
{Array.isArray(data) && data.length > 0 ? (
|
{Array.isArray(data) && data.length > 0 ? (
|
||||||
<div
|
<div
|
||||||
|
|
@ -965,7 +943,7 @@ export const TableList: FC<TableListProp> = ({
|
||||||
) : (
|
) : (
|
||||||
<div className="c-flex c-items-center c-justify-center c-flex-1 w-full h-full c-flex-col ">
|
<div className="c-flex c-items-center c-justify-center c-flex-1 w-full h-full c-flex-col ">
|
||||||
<Sticker size={35} strokeWidth={1} />
|
<Sticker size={35} strokeWidth={1} />
|
||||||
<div className="c-pt-1">
|
<div className="c-pt-1 c-text-center">
|
||||||
No Data
|
No Data
|
||||||
<br />
|
<br />
|
||||||
{local.filtering && (
|
{local.filtering && (
|
||||||
|
|
@ -983,8 +961,8 @@ export const TableList: FC<TableListProp> = ({
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,51 @@
|
||||||
import { FC, useState } from "react";
|
import { FC, ReactNode, useEffect, useState } from "react";
|
||||||
import { breadcrumbPrefix } from "../utils/md-hash";
|
import { breadcrumbPrefix } from "../utils/md-hash";
|
||||||
import { MDLocal, MDRef } from "../utils/typings";
|
import { MDLocal, MDRef } from "../utils/typings";
|
||||||
|
import { BreadItem } from "lib/comps/custom/Breadcrumb";
|
||||||
|
import { useLocal } from "lib/utils/use-local";
|
||||||
|
|
||||||
export const MDHeader: FC<{ md: MDLocal; mdr: MDRef }> = ({ md, mdr }) => {
|
export const MDHeader: FC<{ md: MDLocal; mdr: MDRef }> = ({ md, mdr }) => {
|
||||||
const [_, set] = useState({});
|
const local = useLocal({ breads_length: 0 });
|
||||||
const head = mdr.item.edit.props?.header.value;
|
const head = mdr.item.edit.props?.header.value;
|
||||||
const PassProp = mdr.PassProp;
|
const PassProp = mdr.PassProp;
|
||||||
md.header.render = () => set({});
|
md.header.render = local.render;
|
||||||
|
|
||||||
const prefix = breadcrumbPrefix(md);
|
const prefix = breadcrumbPrefix(md);
|
||||||
|
let breads: (BreadItem & { url: string })[] = [];
|
||||||
if (md.selected && md.header.child.breadcrumb) {
|
if (md.selected && md.header.child.breadcrumb) {
|
||||||
md.header.breadcrumb = [...prefix, ...md.header.child.breadcrumb()];
|
breads = [...prefix, ...md.header.child.breadcrumb()] as any;
|
||||||
} else if (!md.selected && md.header.master.breadcrumb) {
|
} else if (!md.selected && md.header.master.breadcrumb) {
|
||||||
md.header.breadcrumb = [...prefix, ...md.header.master.breadcrumb()];
|
breads = [...prefix, ...md.header.master.breadcrumb()] as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
md.header.breadcrumb = [];
|
||||||
|
let overrideLabel = "" as ReactNode;
|
||||||
|
for (const v of breads) {
|
||||||
|
if (v.label === "--reset--") {
|
||||||
|
md.header.breadcrumb = [];
|
||||||
|
overrideLabel = "";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v.url === "--override--") {
|
||||||
|
overrideLabel = v.label;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overrideLabel) {
|
||||||
|
v.label = overrideLabel;
|
||||||
|
overrideLabel = "";
|
||||||
|
}
|
||||||
|
md.header.breadcrumb.push(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (local.breads_length !== md.header.breadcrumb.length) {
|
||||||
|
local.breads_length = md.header.breadcrumb.length;
|
||||||
|
if (!md.selected && md.master.reload) md.master.reload();
|
||||||
|
}
|
||||||
|
}, [md.header.breadcrumb.length]);
|
||||||
|
|
||||||
if (md.internal.reset_detail) return null;
|
if (md.internal.reset_detail) return null;
|
||||||
return <PassProp md={md}>{head}</PassProp>;
|
return <PassProp md={md}>{head}</PassProp>;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ export const masterDetailApplyParams = (md: MDLocal) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const breadcrumbPrefix = (md: MDLocal) => {
|
export const breadcrumbPrefix = (md: MDLocal) => {
|
||||||
const prefix: BreadItem[] = [];
|
let prefix: (BreadItem & { url: string })[] = [];
|
||||||
if (md.params.links && md.params.links.length > 0) {
|
if (md.params.links && md.params.links.length > 0) {
|
||||||
const hashes: string[] = [];
|
const hashes: string[] = [];
|
||||||
for (const link of md.params.links) {
|
for (const link of md.params.links) {
|
||||||
|
|
@ -93,6 +93,7 @@ export const breadcrumbPrefix = (md: MDLocal) => {
|
||||||
for (const p of link.prefix) {
|
for (const p of link.prefix) {
|
||||||
prefix.push({
|
prefix.push({
|
||||||
label: p.label,
|
label: p.label,
|
||||||
|
url: p.url || link.url,
|
||||||
onClick(ev) {
|
onClick(ev) {
|
||||||
let url = "";
|
let url = "";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ export const toast = {
|
||||||
sonner.dismiss();
|
sonner.dismiss();
|
||||||
} else {
|
} else {
|
||||||
clearTimeout(timer.timeout);
|
clearTimeout(timer.timeout);
|
||||||
|
timer.timeout = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
loading: (
|
loading: (
|
||||||
|
|
@ -41,6 +42,8 @@ export const toast = {
|
||||||
clearTimeout(timer.timeout);
|
clearTimeout(timer.timeout);
|
||||||
timer.timeout = setTimeout(() => {
|
timer.timeout = setTimeout(() => {
|
||||||
sonner.error(el, props);
|
sonner.error(el, props);
|
||||||
|
clearTimeout(timer.timeout);
|
||||||
|
|
||||||
timer.timeout = null;
|
timer.timeout = null;
|
||||||
}, timer.limit);
|
}, timer.limit);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ export const Typeahead = lazify(
|
||||||
async () => (await import("@/comps/ui/typeahead")).Typeahead
|
async () => (await import("@/comps/ui/typeahead")).Typeahead
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const ImgThumb = lazify(
|
||||||
|
async () => (await import("@/comps/form/field/type/FilePreview")).ImgThumb
|
||||||
|
);
|
||||||
|
|
||||||
/** Master - Detail - List - Form */
|
/** Master - Detail - List - Form */
|
||||||
export const MasterDetail = lazify(
|
export const MasterDetail = lazify(
|
||||||
async () => (await import("@/comps/md/MasterDetail")).MasterDetail
|
async () => (await import("@/comps/md/MasterDetail")).MasterDetail
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue