fix
This commit is contained in:
parent
4a3374701c
commit
1d5cb53360
|
|
@ -14,7 +14,7 @@ export const filterWhere = (filter_name: string, p: any) => {
|
||||||
}
|
}
|
||||||
for (const pf of Object.values(f.filter.ref)) {
|
for (const pf of Object.values(f.filter.ref)) {
|
||||||
if (pf.mode === "raw") {
|
if (pf.mode === "raw") {
|
||||||
const data = pf.data?._where ? pf.data?._where : pf.data
|
const data = pf.data?._where ? pf.data?._where : pf.data;
|
||||||
for (const [k, v] of Object.entries(data)) {
|
for (const [k, v] of Object.entries(data)) {
|
||||||
where[k] = v;
|
where[k] = v;
|
||||||
}
|
}
|
||||||
|
|
@ -34,6 +34,5 @@ export const filterWhere = (filter_name: string, p: any) => {
|
||||||
type: p.sft__type,
|
type: p.sft__type,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
console.log({where})
|
|
||||||
return where;
|
return where;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -286,171 +286,6 @@ export const TableEdit: FC<{
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="c-w-full c-h-full c-flex c-flex-col">
|
|
||||||
<div
|
|
||||||
className={cx(
|
|
||||||
"c-w-full",
|
|
||||||
css`
|
|
||||||
.rdg {
|
|
||||||
overflow-y: hidden !important;
|
|
||||||
height: var(--rdg-scroll-height) !important;
|
|
||||||
}
|
|
||||||
.rdg-cell > div {
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
padding-right: 5px;
|
|
||||||
.field {
|
|
||||||
flex: 1;
|
|
||||||
padding-top: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.field-error {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.rdg-header-row {
|
|
||||||
border-top-right-radius: 5px;
|
|
||||||
border-top-left-radius: 5px;
|
|
||||||
}
|
|
||||||
.table-list-inner {
|
|
||||||
position: relative !important;
|
|
||||||
}
|
|
||||||
.typeahead-arrow {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
value.length === 0 &&
|
|
||||||
(show_header === "n"
|
|
||||||
? css`
|
|
||||||
display: none;
|
|
||||||
`
|
|
||||||
: css`
|
|
||||||
min-height: 35px;
|
|
||||||
`),
|
|
||||||
show_header === "n" &&
|
|
||||||
css`
|
|
||||||
.rdg-header-row {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
ref={ref}
|
|
||||||
>
|
|
||||||
<TableList
|
|
||||||
row_height={(row) => {
|
|
||||||
let h = 50;
|
|
||||||
if (local.tbl) {
|
|
||||||
const data = local.tbl.data;
|
|
||||||
const el = local.tbl.el as HTMLDivElement;
|
|
||||||
let idx = 0;
|
|
||||||
if (Array.isArray(data)) {
|
|
||||||
for (let k = 0; k < data.length; k++) {
|
|
||||||
if (data[k] === row) {
|
|
||||||
idx = k;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const rowdiv = el.querySelectorAll(`.rdg-row`)[
|
|
||||||
idx
|
|
||||||
] as HTMLDivElement;
|
|
||||||
if (rowdiv) {
|
|
||||||
rowdiv.querySelectorAll(".field").forEach((field) => {
|
|
||||||
const div = field as HTMLDivElement;
|
|
||||||
h = Math.max(h, div.offsetHeight + 10);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return h;
|
|
||||||
}}
|
|
||||||
feature={[]}
|
|
||||||
child={child}
|
|
||||||
PassProp={PassProp}
|
|
||||||
name={""}
|
|
||||||
value={value}
|
|
||||||
on_init={(tbl) => {
|
|
||||||
local.tbl = tbl;
|
|
||||||
local.render();
|
|
||||||
}}
|
|
||||||
mode={"table"}
|
|
||||||
_item={item}
|
|
||||||
gen_fields={[]}
|
|
||||||
row_click={({ event }) => {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
}}
|
|
||||||
show_header={show_header === "y"}
|
|
||||||
selected={() => {
|
|
||||||
return false;
|
|
||||||
}}
|
|
||||||
filter_name={""}
|
|
||||||
render_col={(arg) => {
|
|
||||||
const { props, tbl, child } = arg;
|
|
||||||
const fm_row = { ...fm, render: local.render };
|
|
||||||
fm_row.data = props.row;
|
|
||||||
local.tbl = tbl;
|
|
||||||
const key = props.column.key;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PassProp
|
|
||||||
idx={props.rowIdx}
|
|
||||||
row={props.row}
|
|
||||||
col={{
|
|
||||||
name: key,
|
|
||||||
value: props.row[props.column.key],
|
|
||||||
depth: props.row.__depth || 0,
|
|
||||||
}}
|
|
||||||
rows={tbl.data}
|
|
||||||
fm={fm_row}
|
|
||||||
fm_parent={parent}
|
|
||||||
ext_fm={{
|
|
||||||
idx: props.rowIdx,
|
|
||||||
change: () => {},
|
|
||||||
remove: () => {
|
|
||||||
fm.data[name] = tbl.data.filter(
|
|
||||||
(e: any) => e !== props.row
|
|
||||||
);
|
|
||||||
fm.render();
|
|
||||||
},
|
|
||||||
add: (e: any) => {
|
|
||||||
tbl.data.push(e ? e : {});
|
|
||||||
fm.render();
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{child}
|
|
||||||
</PassProp>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<PassProp
|
|
||||||
ext_fm={{
|
|
||||||
add: (e: any) => {
|
|
||||||
local.tbl.data.push(e ? e : {});
|
|
||||||
fm.render();
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
const last = Array.from(
|
|
||||||
ref.current?.querySelectorAll(".rdg-row") || []
|
|
||||||
).pop();
|
|
||||||
const input = last?.querySelector("input");
|
|
||||||
if (input) {
|
|
||||||
input.focus();
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
fm_parent={parent}
|
|
||||||
>
|
|
||||||
{bottom}
|
|
||||||
</PassProp>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function getProp(child: any, name: string, defaultValue?: any) {
|
function getProp(child: any, name: string, defaultValue?: any) {
|
||||||
|
|
|
||||||
|
|
@ -50,13 +50,6 @@ export const genTableEdit = async (
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
let tree_depth = "";
|
|
||||||
let tree_depth_built = "";
|
|
||||||
if (first) {
|
|
||||||
tree_depth = `tree_depth={col.depth}`;
|
|
||||||
tree_depth_built = `tree_depth:col.depth`;
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
childs.push({
|
childs.push({
|
||||||
component: {
|
component: {
|
||||||
id: "297023a4-d552-464a-971d-f40dcd940b77",
|
id: "297023a4-d552-464a-971d-f40dcd940b77",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,13 @@ import { fields_map } from "@/utils/format-value";
|
||||||
import { useLocal } from "@/utils/use-local";
|
import { useLocal } from "@/utils/use-local";
|
||||||
import { set } from "lib/utils/set";
|
import { set } from "lib/utils/set";
|
||||||
import get from "lodash.get";
|
import get from "lodash.get";
|
||||||
import { AlertTriangle, Loader2, Sticker } from "lucide-react";
|
import {
|
||||||
|
AlertTriangle,
|
||||||
|
ChevronDown,
|
||||||
|
ChevronRight,
|
||||||
|
Loader2,
|
||||||
|
Sticker,
|
||||||
|
} from "lucide-react";
|
||||||
import {
|
import {
|
||||||
ChangeEvent,
|
ChangeEvent,
|
||||||
FC,
|
FC,
|
||||||
|
|
@ -31,6 +37,7 @@ import { MDLocal } from "../md/utils/typings";
|
||||||
import { Skeleton } from "../ui/skeleton";
|
import { Skeleton } from "../ui/skeleton";
|
||||||
import { sortTree } from "./utils/sort-tree";
|
import { sortTree } from "./utils/sort-tree";
|
||||||
import { toast } from "../ui/toast";
|
import { toast } from "../ui/toast";
|
||||||
|
import { Arrow } from "../custom/Datepicker/components/utils";
|
||||||
|
|
||||||
type OnRowClick = (arg: {
|
type OnRowClick = (arg: {
|
||||||
row: any;
|
row: any;
|
||||||
|
|
@ -150,6 +157,7 @@ export const TableList: FC<TableListProp> = ({
|
||||||
| "init"
|
| "init"
|
||||||
| "error",
|
| "error",
|
||||||
where: null as any,
|
where: null as any,
|
||||||
|
firstKey: "",
|
||||||
should_toast: true,
|
should_toast: true,
|
||||||
paging: {
|
paging: {
|
||||||
take: 0,
|
take: 0,
|
||||||
|
|
@ -165,6 +173,7 @@ export const TableList: FC<TableListProp> = ({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
collapsed: new Set<number>(),
|
||||||
cached_row: new WeakMap<any, ReactElement>(),
|
cached_row: new WeakMap<any, ReactElement>(),
|
||||||
sort: {
|
sort: {
|
||||||
columns: (ls_sort?.columns || []) as SortColumn[],
|
columns: (ls_sort?.columns || []) as SortColumn[],
|
||||||
|
|
@ -421,10 +430,73 @@ export const TableList: FC<TableListProp> = ({
|
||||||
}
|
}
|
||||||
let columns: ColumnOrColumnGroup<any>[] = [];
|
let columns: ColumnOrColumnGroup<any>[] = [];
|
||||||
let isCheckbox = false;
|
let isCheckbox = false;
|
||||||
|
let isTree = false;
|
||||||
try {
|
try {
|
||||||
if (feature?.find((e) => e === "checkbox")) isCheckbox = true;
|
if (feature?.find((e) => e === "checkbox")) isCheckbox = true;
|
||||||
|
if (feature?.find((e) => e === "tree")) isTree = true;
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
|
if (local.status === "init") {
|
||||||
|
const fields = parseGenField(gen_fields);
|
||||||
|
for (const field of fields) {
|
||||||
|
if (field.is_pk) {
|
||||||
|
local.pk = field;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value !== "undefined") {
|
||||||
|
local.data = value;
|
||||||
|
local.status = "ready" as any;
|
||||||
|
} else {
|
||||||
|
if (isEditor && local.status !== "ready") {
|
||||||
|
if (local.data.length === 0) {
|
||||||
|
const load_args: any = {
|
||||||
|
async reload() {},
|
||||||
|
where: {},
|
||||||
|
paging: {
|
||||||
|
take: local.paging.take > 0 ? local.paging.take : undefined,
|
||||||
|
skip: local.paging.skip,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (id_parent) load_args.paging = {};
|
||||||
|
if (typeof on_load === "function") {
|
||||||
|
let res = on_load({ ...load_args, mode: "query" }) as any;
|
||||||
|
if (typeof res === "object" && res instanceof Promise) {
|
||||||
|
res.then((e) => {
|
||||||
|
local.data = e;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
local.data = res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
local.status = "ready";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let data = Array.isArray(local.data) ? local.data : [];
|
||||||
|
if (typeof local.data === "string") console.error(local.data);
|
||||||
|
|
||||||
|
if (isEditor) {
|
||||||
|
if (data.length > 0) {
|
||||||
|
w.prasi_table_list_temp_data = data;
|
||||||
|
} else if (
|
||||||
|
w.prasi_table_list_temp_data &&
|
||||||
|
w.prasi_table_list_temp_data.length > 0
|
||||||
|
) {
|
||||||
|
data = w.prasi_table_list_temp_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTree && id_parent && local.pk && local.sort.columns.length === 0) {
|
||||||
|
data = sortTree(local.data, id_parent, local.pk.name).filter((e) => {
|
||||||
|
if (local.pk && local.collapsed.has(e?.__parent?.[local.pk.name])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (childs.length && isCheckbox) {
|
if (childs.length && isCheckbox) {
|
||||||
columns.push({
|
columns.push({
|
||||||
key: SELECT_COLUMN_KEY,
|
key: SELECT_COLUMN_KEY,
|
||||||
|
|
@ -466,13 +538,14 @@ export const TableList: FC<TableListProp> = ({
|
||||||
cellClass: selectCellClassname,
|
cellClass: selectCellClassname,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let first = true;
|
||||||
for (const child of childs) {
|
for (const child of childs) {
|
||||||
let key = getProp(child, "name", {});
|
let key = getProp(child, "name", {});
|
||||||
const name = getProp(child, "title", "");
|
const name = getProp(child, "title", "");
|
||||||
const type = getProp(child, "type", "");
|
const type = getProp(child, "type", "");
|
||||||
const width = parseInt(getProp(child, "width", {}));
|
const width = parseInt(getProp(child, "width", {}));
|
||||||
if (type === "checkbox") {
|
if (type === "checkbox") {
|
||||||
const on_click = getProp(child, "opt__on_click", "");
|
|
||||||
columns.push({
|
columns.push({
|
||||||
key,
|
key,
|
||||||
name,
|
name,
|
||||||
|
|
@ -528,6 +601,58 @@ export const TableList: FC<TableListProp> = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{isTree && local.firstKey === key && local.pk && (
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
css`
|
||||||
|
padding-left: ${3 + props.row.__depth * 8}px;
|
||||||
|
`,
|
||||||
|
"c-flex c-items-center c-cursor-pointer"
|
||||||
|
)}
|
||||||
|
onClick={(e) => {
|
||||||
|
if (!local.pk) return;
|
||||||
|
if (props?.row?.__children?.length > 0) {
|
||||||
|
e.stopPropagation();
|
||||||
|
if (!local.collapsed.has(props.row?.[local.pk.name])) {
|
||||||
|
local.collapsed.add(props.row?.[local.pk.name]);
|
||||||
|
} else {
|
||||||
|
local.collapsed.delete(props.row?.[local.pk.name]);
|
||||||
|
}
|
||||||
|
local.render();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
css`
|
||||||
|
width: 16px;
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{props.row?.__children?.length > 0 && (
|
||||||
|
<>
|
||||||
|
{local.collapsed.has(props.row?.[local.pk.name]) ? (
|
||||||
|
<ChevronRight size={16} />
|
||||||
|
) : (
|
||||||
|
<ChevronDown size={16} />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{props.row?.__parent &&
|
||||||
|
props.row?.__children?.length === 0 && (
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
" c-border-l c-border-b c-border-black c-w-[10px] c-h-[15px]",
|
||||||
|
css`
|
||||||
|
margin-top: -10px;
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
></div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<PassProp
|
<PassProp
|
||||||
idx={props.rowIdx}
|
idx={props.rowIdx}
|
||||||
row={props.row}
|
row={props.row}
|
||||||
|
|
@ -540,9 +665,15 @@ export const TableList: FC<TableListProp> = ({
|
||||||
>
|
>
|
||||||
{child}
|
{child}
|
||||||
</PassProp>
|
</PassProp>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
local.firstKey = key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mode === "list") {
|
if (mode === "list") {
|
||||||
|
|
@ -585,63 +716,6 @@ export const TableList: FC<TableListProp> = ({
|
||||||
}
|
}
|
||||||
const toaster_el = document.getElementsByClassName("prasi-toaster")[0];
|
const toaster_el = document.getElementsByClassName("prasi-toaster")[0];
|
||||||
|
|
||||||
if (local.status === "init") {
|
|
||||||
const fields = parseGenField(gen_fields);
|
|
||||||
for (const field of fields) {
|
|
||||||
if (field.is_pk) {
|
|
||||||
local.pk = field;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof value !== "undefined") {
|
|
||||||
local.data = value;
|
|
||||||
local.status = "ready" as any;
|
|
||||||
} else {
|
|
||||||
if (isEditor && local.status !== "ready") {
|
|
||||||
if (local.data.length === 0) {
|
|
||||||
const load_args: any = {
|
|
||||||
async reload() {},
|
|
||||||
where: {},
|
|
||||||
paging: {
|
|
||||||
take: local.paging.take > 0 ? local.paging.take : undefined,
|
|
||||||
skip: local.paging.skip,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if (id_parent) load_args.paging = {};
|
|
||||||
if (typeof on_load === "function") {
|
|
||||||
let res = on_load({ ...load_args, mode: "query" }) as any;
|
|
||||||
if (typeof res === "object" && res instanceof Promise) {
|
|
||||||
res.then((e) => {
|
|
||||||
local.data = e;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
local.data = res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
local.status = "ready";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = Array.isArray(local.data) ? local.data : [];
|
|
||||||
if (typeof local.data === "string") console.error(local.data);
|
|
||||||
|
|
||||||
if (isEditor) {
|
|
||||||
if (data.length > 0) {
|
|
||||||
w.prasi_table_list_temp_data = data;
|
|
||||||
} else if (
|
|
||||||
w.prasi_table_list_temp_data &&
|
|
||||||
w.prasi_table_list_temp_data.length > 0
|
|
||||||
) {
|
|
||||||
data = w.prasi_table_list_temp_data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (id_parent && local.pk && local.sort.columns.length === 0) {
|
|
||||||
data = sortTree(local.data, id_parent, local.pk.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode === "table") {
|
if (mode === "table") {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
@ -651,6 +725,17 @@ export const TableList: FC<TableListProp> = ({
|
||||||
css`
|
css`
|
||||||
.rdg {
|
.rdg {
|
||||||
display: grid !important;
|
display: grid !important;
|
||||||
|
|
||||||
|
.rdg-cell,
|
||||||
|
.rdg-header-sort-name {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: stretch;
|
||||||
|
|
||||||
|
&.rdg-header-sort-name {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -42,158 +42,53 @@ export const treePrefix = (props: any) => {
|
||||||
}
|
}
|
||||||
return prefix;
|
return prefix;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sortTree = (list: any[], parent_key: string, pk: string) => {
|
export const sortTree = (list: any[], parent_key: string, pk: string) => {
|
||||||
const nodes: { [id: string]: any } = {};
|
const nodes: { [id: string]: any } = {};
|
||||||
const result: any[] = [];
|
|
||||||
|
|
||||||
// First pass: Create nodes
|
// First pass: Create nodes
|
||||||
list.forEach((node) => {
|
list.forEach((node) => {
|
||||||
const id = node[pk];
|
const id = node[pk];
|
||||||
nodes[id] = { ...node, __depth: 0, __children: [] };
|
nodes[id] = { ...node, __depth: 0, __children: [], __parent: null };
|
||||||
});
|
});
|
||||||
|
|
||||||
// Second pass: Build the tree structure
|
// Second pass: Build relationships
|
||||||
list.forEach((node) => {
|
list.forEach((node) => {
|
||||||
const id = node[pk];
|
const id = node[pk];
|
||||||
const parentId = node[parent_key];
|
const parentId = node[parent_key];
|
||||||
if (parentId === null || parentId === undefined) {
|
|
||||||
result.push(nodes[id]);
|
if (parentId && parentId !== id && nodes[parentId]) {
|
||||||
} else {
|
nodes[id].__parent = nodes[parentId];
|
||||||
if (nodes[parentId]) {
|
|
||||||
nodes[parentId].__children.push(nodes[id]);
|
nodes[parentId].__children.push(nodes[id]);
|
||||||
} else {
|
|
||||||
// Handle the case where a parent is missing
|
|
||||||
result.push(nodes[id]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Function to flatten the tree
|
// Function to calculate depth
|
||||||
function flattenTree(node: any, depth: number = 0): any[] {
|
const calculateDepth = (node: any, visited: Set<string> = new Set()): number => {
|
||||||
node.__depth = depth;
|
if (visited.has(node.id)) return 0; // Prevent cycles
|
||||||
const children = node.__children || [];
|
visited.add(node.id);
|
||||||
delete node.__children;
|
|
||||||
return [
|
if (!node.__parent) return 0;
|
||||||
node,
|
return 1 + calculateDepth(node.__parent, visited);
|
||||||
...children
|
};
|
||||||
.sort((a: any, b: any) => {
|
|
||||||
if (
|
// Calculate depths
|
||||||
a.__children.length === 0 &&
|
Object.values(nodes).forEach((node: any) => {
|
||||||
b.__children.length === 0 &&
|
node.__depth = calculateDepth(node);
|
||||||
a.name &&
|
});
|
||||||
b.name
|
|
||||||
) {
|
// Sort nodes
|
||||||
|
const sortedNodes = Object.values(nodes).sort((a: any, b: any) => {
|
||||||
|
if (a.__depth !== b.__depth) return a.__depth - b.__depth;
|
||||||
|
if (a.__children.length !== b.__children.length) {
|
||||||
|
return b.__children.length - a.__children.length;
|
||||||
|
}
|
||||||
return a.name.localeCompare(b.name);
|
return a.name.localeCompare(b.name);
|
||||||
}
|
});
|
||||||
|
|
||||||
return (b.__children?.length || 0) - (a.__children?.length || 0);
|
// Assign indices
|
||||||
})
|
sortedNodes.forEach((node: any, index: number) => {
|
||||||
.flatMap((child: any) => flattenTree(child, depth + 1)),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flatten and assign indices
|
|
||||||
const flatResult = result.flatMap((node) => flattenTree(node));
|
|
||||||
flatResult.forEach((node, index) => {
|
|
||||||
node.idx = index;
|
node.idx = index;
|
||||||
});
|
});
|
||||||
|
|
||||||
return flatResult;
|
return sortedNodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
// export const sortTree = (list: any[], parent_key: string, pk: string) => {
|
|
||||||
// let meta = {} as Record<
|
|
||||||
// string,
|
|
||||||
// { item: any; idx: string; depth: number; id_parent: any }
|
|
||||||
// >;
|
|
||||||
|
|
||||||
// let mode = "" as "" | "str" | "num";
|
|
||||||
// let _list = list.sort((a, b) => {
|
|
||||||
// if (!mode) {
|
|
||||||
// mode = typeof a[pk] === "string" ? "str" : "num";
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (mode === "str") return b[pk].toLocaleString(a[pk]);
|
|
||||||
|
|
||||||
// return a[pk] - b[pk];
|
|
||||||
// });
|
|
||||||
|
|
||||||
// if (_list.length > 0 && !isEditor) {
|
|
||||||
// const new_list = [];
|
|
||||||
// const unlisted = {} as Record<string, any>;
|
|
||||||
// for (const item of _list) {
|
|
||||||
// if (item[parent_key] === null) {
|
|
||||||
// if (!meta[item[pk]]) {
|
|
||||||
// meta[item[pk]] = {
|
|
||||||
// item,
|
|
||||||
// idx: new_list.length + "",
|
|
||||||
// depth: 0,
|
|
||||||
// id_parent: null,
|
|
||||||
// };
|
|
||||||
// item.__depth = 0;
|
|
||||||
// new_list.push(item);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// unlisted[item[pk]] = item;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let cyclic = {} as Record<string, number>;
|
|
||||||
// while (Object.values(unlisted).length > 0) {
|
|
||||||
// for (const item of Object.values(unlisted)) {
|
|
||||||
// const parent = meta[item[parent_key]];
|
|
||||||
// if (!cyclic[item[pk]]) {
|
|
||||||
// cyclic[item[pk]] = 1;
|
|
||||||
// } else {
|
|
||||||
// cyclic[item[pk]]++;
|
|
||||||
// }
|
|
||||||
// if (cyclic[item[pk]] > 5) {
|
|
||||||
// item.__depth = 0;
|
|
||||||
// meta[item[pk]] = {
|
|
||||||
// item,
|
|
||||||
// depth: 0,
|
|
||||||
// idx: new_list.length + "",
|
|
||||||
// id_parent: null,
|
|
||||||
// };
|
|
||||||
// new_list.push(item);
|
|
||||||
// delete unlisted[item[pk]];
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (item[parent_key] === item[pk]) {
|
|
||||||
// item.__depth = 0;
|
|
||||||
|
|
||||||
// meta[item[pk]] = {
|
|
||||||
// item,
|
|
||||||
// depth: 0,
|
|
||||||
// idx: new_list.length + "",
|
|
||||||
// id_parent: null,
|
|
||||||
// };
|
|
||||||
// new_list.push(item);
|
|
||||||
// delete unlisted[item[pk]];
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (parent) {
|
|
||||||
// item.__depth = parent.depth + 1;
|
|
||||||
|
|
||||||
// meta[item[pk]] = {
|
|
||||||
// item,
|
|
||||||
// depth: parent.depth + 1,
|
|
||||||
// idx: parent.idx + ".",
|
|
||||||
// id_parent: item[parent_key],
|
|
||||||
// };
|
|
||||||
// delete unlisted[item[pk]];
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// const sorted = Object.values(meta)
|
|
||||||
// .sort((a, b) => a.idx.localeCompare(b.idx))
|
|
||||||
// .map((e) => e.item);
|
|
||||||
|
|
||||||
// return sorted;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return _list;
|
|
||||||
// };
|
|
||||||
|
|
|
||||||
|
|
@ -181,13 +181,6 @@ const genTable = async (opt: GenOpt) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e.is_pk && (arg.mode === "table" || arg.mode === "auto")) return;
|
if (e.is_pk && (arg.mode === "table" || arg.mode === "auto")) return;
|
||||||
let tree_depth = "";
|
|
||||||
let tree_depth_built = "";
|
|
||||||
if (first) {
|
|
||||||
tree_depth = `tree_depth={col.depth}`;
|
|
||||||
tree_depth_built = `tree_depth:col.depth`;
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
component: {
|
component: {
|
||||||
id: "297023a4-d552-464a-971d-f40dcd940b77",
|
id: "297023a4-d552-464a-971d-f40dcd940b77",
|
||||||
|
|
@ -211,10 +204,10 @@ const genTable = async (opt: GenOpt) => {
|
||||||
adv: {
|
adv: {
|
||||||
js: `\
|
js: `\
|
||||||
<div {...props} className={cx(props.className, \`s-\${_item?.edit?.parent?.item?.id}\` , "table-col")}>
|
<div {...props} className={cx(props.className, \`s-\${_item?.edit?.parent?.item?.id}\` , "table-col")}>
|
||||||
<FormatValue value={col.value} name={col.name} gen_fields={gen__fields} ${tree_depth} />
|
<FormatValue value={col.value} name={col.name} gen_fields={gen__fields} />
|
||||||
</div>`,
|
</div>`,
|
||||||
jsBuilt: `\
|
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, ${tree_depth_built} })));
|
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 })));
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,10 @@ async (arg: TableOnLoad) => {
|
||||||
const fields = parseGenField(gen__fields);
|
const fields = parseGenField(gen__fields);
|
||||||
const gen = generateSelect(fields);
|
const gen = generateSelect(fields);
|
||||||
|
|
||||||
|
if (opt__feature.includes("tree") && opt__id_parent) {
|
||||||
|
gen.select[opt__id_parent] = true
|
||||||
|
}
|
||||||
|
|
||||||
const result = {items: []}
|
const result = {items: []}
|
||||||
result.items = await db.${table}.findMany({
|
result.items = await db.${table}.findMany({
|
||||||
select: gen.select,
|
select: gen.select,
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,9 @@ export const FormatValue: FC<{
|
||||||
value: any;
|
value: any;
|
||||||
name: string;
|
name: string;
|
||||||
gen_fields: string[];
|
gen_fields: string[];
|
||||||
tree_depth?: number;
|
|
||||||
mode?: "money" | "datetime" | "timeago" | "date";
|
mode?: "money" | "datetime" | "timeago" | "date";
|
||||||
}> = (prop) => {
|
}> = (prop) => {
|
||||||
const { value, gen_fields, name, tree_depth, mode } = prop;
|
const { value, gen_fields, name, mode } = prop;
|
||||||
if (gen_fields) {
|
if (gen_fields) {
|
||||||
const gf = JSON.stringify(gen_fields);
|
const gf = JSON.stringify(gen_fields);
|
||||||
if (!fields_map.has(gf)) {
|
if (!fields_map.has(gf)) {
|
||||||
|
|
@ -122,29 +121,28 @@ export const FormatValue: FC<{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let prefix = <></>;
|
// let prefix = <></>;
|
||||||
if (typeof tree_depth === "number" && tree_depth > 0) {
|
// if (typeof tree_depth === "number" && tree_depth > 0) {
|
||||||
prefix = (
|
// prefix = (
|
||||||
<div
|
// <div
|
||||||
className={css`
|
// className={css`
|
||||||
padding-left: ${tree_depth * 5}px;
|
// padding-left: ${tree_depth * 5}px;
|
||||||
`}
|
// `}
|
||||||
>
|
// >
|
||||||
<div
|
// <div
|
||||||
className={cx(
|
// className={cx(
|
||||||
" c-border-l c-border-b c-border-black c-w-[10px] c-h-[15px]",
|
// " c-border-l c-border-b c-border-black c-w-[10px] c-h-[15px]",
|
||||||
css`
|
// css`
|
||||||
margin-top: -10px;
|
// margin-top: -10px;
|
||||||
`
|
// `
|
||||||
)}
|
// )}
|
||||||
></div>
|
// ></div>
|
||||||
</div>
|
// </div>
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="c-flex c-space-x-2 c-items-center">
|
<div className="c-flex c-space-x-2 c-items-center">
|
||||||
{prefix}
|
|
||||||
<div>{value}</div>
|
<div>{value}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue