fix table list
This commit is contained in:
parent
66ce2ab145
commit
52105ef69c
|
|
@ -0,0 +1,113 @@
|
|||
import { FC } from "react";
|
||||
import { Skeleton } from "../ui/skeleton";
|
||||
import { OnRowClick } from "./utils/type";
|
||||
import { Sticker } from "lucide-react";
|
||||
|
||||
export const TLList: FC<{
|
||||
local: Record<string, any> & {
|
||||
el: null | HTMLDivElement;
|
||||
render: () => void;
|
||||
};
|
||||
data: any[];
|
||||
PassProp: any;
|
||||
row_click: OnRowClick;
|
||||
mode_child: any;
|
||||
dataGridStyle: (local: { el: null | HTMLDivElement }) => string;
|
||||
}> = ({ local, data, dataGridStyle, mode_child, PassProp, row_click }) => {
|
||||
return (
|
||||
<div
|
||||
className={cx(
|
||||
"c-w-full c-h-full c-flex-1 c-relative c-overflow-hidden",
|
||||
dataGridStyle(local)
|
||||
)}
|
||||
ref={(el) => {
|
||||
if (!local.el && el) {
|
||||
local.el = el;
|
||||
}
|
||||
}}
|
||||
>
|
||||
{local.status !== "ready" ? (
|
||||
<div className="c-flex c-flex-col c-space-y-2 c-m-4 c-absolute c-left-0 c-top-0">
|
||||
<Skeleton className={cx("c-w-[200px] c-h-[11px]")} />
|
||||
<Skeleton className={cx("c-w-[170px] c-h-[11px]")} />
|
||||
<Skeleton className={cx("c-w-[180px] c-h-[11px]")} />
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className={cx(
|
||||
"c-absolute c-inset-0",
|
||||
!isEditor &&
|
||||
css`
|
||||
@keyframes flasher {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
.list-row {
|
||||
animation: flasher 0.5s;
|
||||
}
|
||||
`
|
||||
)}
|
||||
>
|
||||
<>
|
||||
{Array.isArray(data) && data.length > 0 ? (
|
||||
<div
|
||||
className="w-full h-full overflow-y-auto c-flex-col"
|
||||
ref={(e) => {
|
||||
local.grid_ref = e;
|
||||
}}
|
||||
onScroll={(e) => local.paging.scroll(e.currentTarget)}
|
||||
>
|
||||
{data.map((e, idx) => {
|
||||
return (
|
||||
<div
|
||||
className={cx("list-row c-flex-grow c-flex")}
|
||||
onClick={(ev) => {
|
||||
if (!isEditor && typeof row_click === "function") {
|
||||
row_click({
|
||||
event: ev,
|
||||
idx: idx,
|
||||
row: e,
|
||||
rows: local.data,
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
<PassProp idx={idx} row={e} col={{}} rows={local.data}>
|
||||
{mode_child}
|
||||
</PassProp>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
) : (
|
||||
<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} />
|
||||
<div className="c-pt-1 c-text-center">
|
||||
No Data
|
||||
<br />
|
||||
{local.filtering && (
|
||||
<div
|
||||
className={css`
|
||||
color: gray;
|
||||
font-style: italic;
|
||||
font-size: 90%;
|
||||
`}
|
||||
>
|
||||
{local.filtering}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
import { FC } from "react";
|
||||
import { Skeleton } from "../ui/skeleton";
|
||||
import { OnRowClick } from "./utils/type";
|
||||
import { Sticker } from "lucide-react";
|
||||
|
||||
export const TLSlider: FC<{
|
||||
local: Record<string, any> & {
|
||||
el: null | HTMLDivElement;
|
||||
render: () => void;
|
||||
};
|
||||
data: any[];
|
||||
PassProp: any;
|
||||
row_click: OnRowClick;
|
||||
mode_child: any;
|
||||
item_w: string;
|
||||
dataGridStyle: (local: { el: null | HTMLDivElement }) => string;
|
||||
}> = ({
|
||||
local,
|
||||
data,
|
||||
dataGridStyle,
|
||||
item_w,
|
||||
mode_child,
|
||||
PassProp,
|
||||
row_click,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
{local.status !== "ready" ? (
|
||||
<div className="c-flex c-flex-col c-space-y-2 c-m-4 c-absolute c-left-0 c-top-0">
|
||||
<Skeleton className={cx("c-w-[200px] c-h-[11px]")} />
|
||||
<Skeleton className={cx("c-w-[170px] c-h-[11px]")} />
|
||||
<Skeleton className={cx("c-w-[180px] c-h-[11px]")} />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{Array.isArray(data) && data.length > 0 ? (
|
||||
<div
|
||||
className={cx(
|
||||
"c-overflow-x-auto c-snap-x c-h-full c-w-full c-flex",
|
||||
css`
|
||||
padding-right: 50px;
|
||||
`
|
||||
)}
|
||||
ref={(e) => {
|
||||
local.grid_ref = e;
|
||||
}}
|
||||
onScroll={(e) => local.paging.scroll(e.currentTarget)}
|
||||
>
|
||||
{data.map((e, idx) => {
|
||||
return (
|
||||
<div
|
||||
className={cx(
|
||||
"list-item c-snap-start c-flex c-shrink-0",
|
||||
css`
|
||||
width: ${item_w}px;
|
||||
`
|
||||
)}
|
||||
onClick={(ev) => {
|
||||
if (!isEditor && typeof row_click === "function") {
|
||||
row_click({
|
||||
event: ev,
|
||||
idx: idx,
|
||||
row: e,
|
||||
rows: local.data,
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
<PassProp
|
||||
idx={idx}
|
||||
item_w={item_w}
|
||||
is_last={idx == data.length - 1}
|
||||
row={e}
|
||||
col={{}}
|
||||
rows={local.data}
|
||||
>
|
||||
{mode_child}
|
||||
</PassProp>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
) : (
|
||||
<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} />
|
||||
<div className="c-pt-1 c-text-center">
|
||||
No Data
|
||||
<br />
|
||||
{local.filtering && (
|
||||
<div
|
||||
className={css`
|
||||
color: gray;
|
||||
font-style: italic;
|
||||
font-size: 90%;
|
||||
`}
|
||||
>
|
||||
{local.filtering}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
@ -36,19 +36,17 @@ import { MDLocal } from "../md/utils/typings";
|
|||
import { Skeleton } from "../ui/skeleton";
|
||||
import { toast } from "../ui/toast";
|
||||
import { sortTree } from "./utils/sort-tree";
|
||||
import { TLList } from "./TLList";
|
||||
import { OnRowClick } from "./utils/type";
|
||||
import { TLSlider } from "./TLSlider";
|
||||
|
||||
type OnRowClick = (arg: {
|
||||
row: any;
|
||||
rows: any[];
|
||||
idx: any;
|
||||
event: React.MouseEvent<HTMLDivElement>;
|
||||
}) => void;
|
||||
let EMPTY_SET = new Set() as ReadonlySet<any>;
|
||||
|
||||
type SelectedRow = (arg: { row: any; rows: any[]; idx: any }) => boolean;
|
||||
type TableListProp = {
|
||||
child: any;
|
||||
PassProp: any;
|
||||
list: { type: string; item_w: string };
|
||||
name: string;
|
||||
value?: any[];
|
||||
on_load?: (arg: {
|
||||
|
|
@ -75,7 +73,6 @@ type TableListProp = {
|
|||
tbl: any;
|
||||
child: any;
|
||||
}) => ReactNode;
|
||||
softdel_field?: string;
|
||||
gen_table?: string;
|
||||
softdel_type?: string;
|
||||
paging?: boolean;
|
||||
|
|
@ -110,6 +107,7 @@ export const TableList: FC<TableListProp> = ({
|
|||
row_height: rowHeight,
|
||||
render_col,
|
||||
show_header,
|
||||
list,
|
||||
value,
|
||||
paging,
|
||||
cache_row,
|
||||
|
|
@ -163,6 +161,7 @@ export const TableList: FC<TableListProp> = ({
|
|||
last_length: 0,
|
||||
scroll: (currentTarget: HTMLDivElement) => {
|
||||
if (
|
||||
isEditor ||
|
||||
local.data.length < local.paging.take ||
|
||||
local.data.length === 0 ||
|
||||
local.status !== "ready" ||
|
||||
|
|
@ -259,7 +258,11 @@ export const TableList: FC<TableListProp> = ({
|
|||
}
|
||||
const result = on_load({ ...load_args, mode: "query" });
|
||||
const callback = (data: any[]) => {
|
||||
if (!local.paging || (local.paging && !local.paging.take)) {
|
||||
if (
|
||||
id_parent ||
|
||||
!local.paging ||
|
||||
(local.paging && !local.paging.take)
|
||||
) {
|
||||
local.data = data;
|
||||
} else {
|
||||
local.data = [...local.data, ...data];
|
||||
|
|
@ -414,6 +417,9 @@ export const TableList: FC<TableListProp> = ({
|
|||
useEffect(() => {
|
||||
if (isEditor || value) {
|
||||
on_init(local);
|
||||
if (isEditor && local.data.length === 0 && local.status === "ready") {
|
||||
reload();
|
||||
}
|
||||
return;
|
||||
}
|
||||
(async () => {
|
||||
|
|
@ -935,107 +941,35 @@ export const TableList: FC<TableListProp> = ({
|
|||
);
|
||||
} else if (mode === "list") {
|
||||
return (
|
||||
<div
|
||||
className={cx(
|
||||
"c-w-full c-h-full c-flex-1 c-relative c-overflow-hidden",
|
||||
dataGridStyle(local)
|
||||
)}
|
||||
ref={(el) => {
|
||||
if (!local.el && el) {
|
||||
local.el = el;
|
||||
}
|
||||
}}
|
||||
>
|
||||
<>
|
||||
{toaster_el &&
|
||||
createPortal(
|
||||
<Toaster position={toast.position} cn={cn} />,
|
||||
toaster_el
|
||||
)}
|
||||
|
||||
{local.status !== "ready" ? (
|
||||
<div className="c-flex c-flex-col c-space-y-2 c-m-4 c-absolute c-left-0 c-top-0">
|
||||
<Skeleton className={cx("c-w-[200px] c-h-[11px]")} />
|
||||
<Skeleton className={cx("c-w-[170px] c-h-[11px]")} />
|
||||
<Skeleton className={cx("c-w-[180px] c-h-[11px]")} />
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className={cx(
|
||||
"c-absolute c-inset-0",
|
||||
css`
|
||||
@keyframes flasher {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
.list-row {
|
||||
animation: flasher 0.5s;
|
||||
}
|
||||
`
|
||||
)}
|
||||
>
|
||||
<>
|
||||
{Array.isArray(data) && data.length > 0 ? (
|
||||
<div
|
||||
className="w-full h-full overflow-y-auto c-flex-col"
|
||||
ref={(e) => {
|
||||
local.grid_ref = e;
|
||||
}}
|
||||
onScroll={(e) => local.paging.scroll(e.currentTarget)}
|
||||
>
|
||||
{data.map((e, idx) => {
|
||||
return (
|
||||
<div
|
||||
className={cx("list-row c-flex-grow c-flex")}
|
||||
onClick={(ev) => {
|
||||
if (!isEditor && typeof row_click === "function") {
|
||||
row_click({
|
||||
event: ev,
|
||||
idx: idx,
|
||||
row: e,
|
||||
rows: local.data,
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
<PassProp idx={idx} row={e} col={{}} rows={local.data}>
|
||||
{mode_child}
|
||||
</PassProp>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
) : (
|
||||
<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} />
|
||||
<div className="c-pt-1 c-text-center">
|
||||
No Data
|
||||
<br />
|
||||
{local.filtering && (
|
||||
<div
|
||||
className={css`
|
||||
color: gray;
|
||||
font-style: italic;
|
||||
font-size: 90%;
|
||||
`}
|
||||
>
|
||||
{local.filtering}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
{list.type !== "slider" && list.type !== "grid" && (
|
||||
<TLList
|
||||
row_click={row_click}
|
||||
PassProp={PassProp}
|
||||
local={local}
|
||||
mode_child={mode_child}
|
||||
data={data}
|
||||
dataGridStyle={dataGridStyle}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{list.type === "slider" && (
|
||||
<TLSlider
|
||||
row_click={row_click}
|
||||
PassProp={PassProp}
|
||||
local={local}
|
||||
mode_child={mode_child}
|
||||
data={data}
|
||||
item_w={list.item_w}
|
||||
dataGridStyle={dataGridStyle}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
}
|
||||
};
|
||||
const CheckboxList: FC<{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
export type OnRowClick = (arg: {
|
||||
row: any;
|
||||
rows: any[];
|
||||
idx: any;
|
||||
event: React.MouseEvent<HTMLDivElement>;
|
||||
}) => void;
|
||||
|
|
@ -16,7 +16,7 @@ export const generateTableList = async (
|
|||
let table = "" as string;
|
||||
try {
|
||||
table = eval(data.gen__table.value);
|
||||
} catch (e) {
|
||||
} catch (e) {
|
||||
table = data.gen__table?.value;
|
||||
}
|
||||
const raw_fields = JSON.parse(data.gen__fields.value) as (
|
||||
|
|
@ -129,11 +129,11 @@ const genList = async (opt: GenOpt) => {
|
|||
},
|
||||
adv: {
|
||||
js: `\
|
||||
<div {...props} className={cx(props.className, \`s-\${_item?.edit?.parent?.item?.id}\` , "list-field")}>
|
||||
<div {...props} className={cx(props.className, _item?.edit?.parent?.item?.id && \`s-\${_item?.edit?.parent?.item?.id}\` , "list-field")}>
|
||||
<FormatValue value={_get(row, name)} name={name} gen_fields={gen__fields} />
|
||||
</div>`,
|
||||
jsBuilt: `\
|
||||
render(React.createElement("div", Object.assign({}, props, { className: cx(props.className, \`s-\${_item?.edit?.parent?.item?.id}\` , "") }),React.createElement(FormatValue, { value: _get(row, name), name: name, gen_fields: gen__fields })));
|
||||
render(React.createElement("div", Object.assign({}, props, { className: cx(props.className, _item?.edit?.parent?.item?.id && \`s-\${_item?.edit?.parent?.item?.id}\` , "") }),React.createElement(FormatValue, { value: _get(row, name), name: name, gen_fields: gen__fields })));
|
||||
`,
|
||||
},
|
||||
}),
|
||||
|
|
@ -189,25 +189,25 @@ const genTable = async (opt: GenOpt) => {
|
|||
title: formatName(e.name),
|
||||
child: createItem({
|
||||
name: "cell",
|
||||
"layout": {
|
||||
"dir": "col",
|
||||
"align": "left",
|
||||
"gap": 0,
|
||||
"wrap": "flex-nowrap"
|
||||
layout: {
|
||||
dir: "col",
|
||||
align: "left",
|
||||
gap: 0,
|
||||
wrap: "flex-nowrap",
|
||||
},
|
||||
padding: {
|
||||
l: 8,
|
||||
l: 8,
|
||||
b: 0,
|
||||
t: 0,
|
||||
r: 8,
|
||||
},
|
||||
adv: {
|
||||
js: `\
|
||||
<div {...props} className={cx(props.className, \`s-\${_item?.edit?.parent?.item?.id}\` , "table-col")}>
|
||||
<div {...props} className={cx(props.className, _item?.edit?.parent?.item?.id && \`s-\${_item?.edit?.parent?.item?.id}\` , "table-col")}>
|
||||
<FormatValue value={col.value} name={col.name} gen_fields={gen__fields} />
|
||||
</div>`,
|
||||
jsBuilt: `\
|
||||
render(React.createElement("div", Object.assign({}, props, { className: cx(props.className, \`s-\${_item?.edit?.parent?.item?.id}\` , "") }),React.createElement(FormatValue, { value: col.value, name: col.name, gen_fields: gen__fields })));
|
||||
render(React.createElement("div", Object.assign({}, props, { className: cx(props.className, _item?.edit?.parent?.item?.id && \`s-\${_item?.edit?.parent?.item?.id}\` , "") }),React.createElement(FormatValue, { value: col.value, name: col.name, gen_fields: gen__fields })));
|
||||
`,
|
||||
},
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ async (arg: TableOnLoad) => {
|
|||
if (isEditor)
|
||||
return [${JSON.stringify(sample)}];
|
||||
|
||||
let where = arg.where;
|
||||
let where = arg.where as Prisma.${table}WhereInput;
|
||||
if (arg.mode === "count") {
|
||||
return await db.${table}.count({
|
||||
where: {
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ export const Layout: FC<LYTChild> = (props) => {
|
|||
const newurl = new URL(`${url.protocol}//${url.host}${_href}`);
|
||||
const pathname = newurl.pathname;
|
||||
|
||||
_href = baseurl(_href);
|
||||
if (params) {
|
||||
const prefix: LinkParam["prefix"] =
|
||||
params.breads?.map((e) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue