|
@@ -70,6 +70,8 @@ import {
|
|
|
OnRowClick,
|
|
|
DownloadAction,
|
|
|
getFormatFn,
|
|
|
+ getPageKey,
|
|
|
+ FilterDesc,
|
|
|
} from "./tableUtils";
|
|
|
import {
|
|
|
useClassNames,
|
|
@@ -80,7 +82,7 @@ import {
|
|
|
useFormatConfig,
|
|
|
useModule,
|
|
|
} from "../../utils/hooks";
|
|
|
-import TableFilter, { FilterDesc } from "./TableFilter";
|
|
|
+import TableFilter from "./TableFilter";
|
|
|
import { getSuffixedClassNames, getUpdateVar } from "./utils";
|
|
|
import { emptyArray } from "../../utils";
|
|
|
|
|
@@ -133,99 +135,98 @@ const PaginatedTable = (props: TaipyPaginatedTableProps) => {
|
|
|
const hover = useDynamicProperty(props.hoverText, props.defaultHoverText, undefined);
|
|
|
const baseColumns = useDynamicJsonProperty(props.columns, props.defaultColumns, defaultColumns);
|
|
|
|
|
|
- const [colsOrder, columns, styles, tooltips, formats, handleNan, filter, partialEditable, nbWidth] =
|
|
|
- useMemo(() => {
|
|
|
- let hNan = !!props.nanValue;
|
|
|
- if (baseColumns) {
|
|
|
- try {
|
|
|
- let filter = false;
|
|
|
- let partialEditable = editable;
|
|
|
- const newCols: Record<string, ColumnDesc> = {};
|
|
|
- Object.entries(baseColumns).forEach(([cId, cDesc]) => {
|
|
|
- const nDesc = (newCols[cId] = { ...cDesc });
|
|
|
- if (typeof nDesc.filter != "boolean") {
|
|
|
- nDesc.filter = !!props.filter;
|
|
|
- }
|
|
|
- filter = filter || nDesc.filter;
|
|
|
- if (typeof nDesc.notEditable == "boolean") {
|
|
|
- partialEditable = partialEditable || !nDesc.notEditable;
|
|
|
- } else {
|
|
|
- nDesc.notEditable = !editable;
|
|
|
- }
|
|
|
- if (nDesc.tooltip === undefined) {
|
|
|
- nDesc.tooltip = props.tooltip;
|
|
|
- }
|
|
|
- });
|
|
|
- addActionColumn(
|
|
|
- (active && partialEditable && (onAdd || onDelete) ? 1 : 0) +
|
|
|
- (active && filter ? 1 : 0) +
|
|
|
- (active && downloadable ? 1 : 0),
|
|
|
- newCols
|
|
|
- );
|
|
|
- const colsOrder = Object.keys(newCols).sort(getSortByIndex(newCols));
|
|
|
- let nbWidth = 0;
|
|
|
- const styTt = colsOrder.reduce<Record<string, Record<string, string>>>((pv, col) => {
|
|
|
- if (newCols[col].style) {
|
|
|
- pv.styles = pv.styles || {};
|
|
|
- pv.styles[newCols[col].dfid] = newCols[col].style;
|
|
|
- }
|
|
|
- hNan = hNan || !!newCols[col].nanValue;
|
|
|
- if (newCols[col].tooltip) {
|
|
|
- pv.tooltips = pv.tooltips || {};
|
|
|
- pv.tooltips[newCols[col].dfid] = newCols[col].tooltip;
|
|
|
- }
|
|
|
- if (newCols[col].formatFn) {
|
|
|
- pv.formats = pv.formats || {};
|
|
|
- pv.formats[newCols[col].dfid] = newCols[col].formatFn;
|
|
|
- }
|
|
|
- if (newCols[col].width !== undefined) {
|
|
|
- nbWidth ++;
|
|
|
- }
|
|
|
- return pv;
|
|
|
- }, {});
|
|
|
- nbWidth = colsOrder.length - nbWidth;
|
|
|
- if (props.lineStyle) {
|
|
|
- styTt.styles = styTt.styles || {};
|
|
|
- styTt.styles[LINE_STYLE] = props.lineStyle;
|
|
|
+ const [colsOrder, columns, styles, tooltips, formats, handleNan, filter, partialEditable, nbWidth] = useMemo(() => {
|
|
|
+ let hNan = !!props.nanValue;
|
|
|
+ if (baseColumns) {
|
|
|
+ try {
|
|
|
+ let filter = false;
|
|
|
+ let partialEditable = editable;
|
|
|
+ const newCols: Record<string, ColumnDesc> = {};
|
|
|
+ Object.entries(baseColumns).forEach(([cId, cDesc]) => {
|
|
|
+ const nDesc = (newCols[cId] = { ...cDesc });
|
|
|
+ if (typeof nDesc.filter != "boolean") {
|
|
|
+ nDesc.filter = !!props.filter;
|
|
|
+ }
|
|
|
+ filter = filter || nDesc.filter;
|
|
|
+ if (typeof nDesc.notEditable == "boolean") {
|
|
|
+ partialEditable = partialEditable || !nDesc.notEditable;
|
|
|
+ } else {
|
|
|
+ nDesc.notEditable = !editable;
|
|
|
+ }
|
|
|
+ if (nDesc.tooltip === undefined) {
|
|
|
+ nDesc.tooltip = props.tooltip;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ addActionColumn(
|
|
|
+ (active && partialEditable && (onAdd || onDelete) ? 1 : 0) +
|
|
|
+ (active && filter ? 1 : 0) +
|
|
|
+ (active && downloadable ? 1 : 0),
|
|
|
+ newCols
|
|
|
+ );
|
|
|
+ const colsOrder = Object.keys(newCols).sort(getSortByIndex(newCols));
|
|
|
+ let nbWidth = 0;
|
|
|
+ const styTt = colsOrder.reduce<Record<string, Record<string, string>>>((pv, col) => {
|
|
|
+ if (newCols[col].style) {
|
|
|
+ pv.styles = pv.styles || {};
|
|
|
+ pv.styles[newCols[col].dfid] = newCols[col].style;
|
|
|
+ }
|
|
|
+ hNan = hNan || !!newCols[col].nanValue;
|
|
|
+ if (newCols[col].tooltip) {
|
|
|
+ pv.tooltips = pv.tooltips || {};
|
|
|
+ pv.tooltips[newCols[col].dfid] = newCols[col].tooltip;
|
|
|
+ }
|
|
|
+ if (newCols[col].formatFn) {
|
|
|
+ pv.formats = pv.formats || {};
|
|
|
+ pv.formats[newCols[col].dfid] = newCols[col].formatFn;
|
|
|
}
|
|
|
- return [
|
|
|
- colsOrder,
|
|
|
- newCols,
|
|
|
- styTt.styles,
|
|
|
- styTt.tooltips,
|
|
|
- styTt.formats,
|
|
|
- hNan,
|
|
|
- filter,
|
|
|
- partialEditable,
|
|
|
- nbWidth,
|
|
|
- ];
|
|
|
- } catch (e) {
|
|
|
- console.info("PaginatedTable.columns: ", (e as Error).message || e);
|
|
|
+ if (newCols[col].width !== undefined) {
|
|
|
+ nbWidth++;
|
|
|
+ }
|
|
|
+ return pv;
|
|
|
+ }, {});
|
|
|
+ nbWidth = colsOrder.length - nbWidth;
|
|
|
+ if (props.lineStyle) {
|
|
|
+ styTt.styles = styTt.styles || {};
|
|
|
+ styTt.styles[LINE_STYLE] = props.lineStyle;
|
|
|
}
|
|
|
+ return [
|
|
|
+ colsOrder,
|
|
|
+ newCols,
|
|
|
+ styTt.styles,
|
|
|
+ styTt.tooltips,
|
|
|
+ styTt.formats,
|
|
|
+ hNan,
|
|
|
+ filter,
|
|
|
+ partialEditable,
|
|
|
+ nbWidth,
|
|
|
+ ];
|
|
|
+ } catch (e) {
|
|
|
+ console.info("PaginatedTable.columns: ", (e as Error).message || e);
|
|
|
}
|
|
|
- return [
|
|
|
- [] as string[],
|
|
|
- {} as Record<string, ColumnDesc>,
|
|
|
- {} as Record<string, string>,
|
|
|
- {} as Record<string, string>,
|
|
|
- {} as Record<string, string>,
|
|
|
- hNan,
|
|
|
- false,
|
|
|
- false,
|
|
|
- 0,
|
|
|
- ];
|
|
|
- }, [
|
|
|
- active,
|
|
|
- editable,
|
|
|
- onAdd,
|
|
|
- onDelete,
|
|
|
- baseColumns,
|
|
|
- props.lineStyle,
|
|
|
- props.tooltip,
|
|
|
- props.nanValue,
|
|
|
- props.filter,
|
|
|
- downloadable,
|
|
|
- ]);
|
|
|
+ }
|
|
|
+ return [
|
|
|
+ [] as string[],
|
|
|
+ {} as Record<string, ColumnDesc>,
|
|
|
+ {} as Record<string, string>,
|
|
|
+ {} as Record<string, string>,
|
|
|
+ {} as Record<string, string>,
|
|
|
+ hNan,
|
|
|
+ false,
|
|
|
+ false,
|
|
|
+ 0,
|
|
|
+ ];
|
|
|
+ }, [
|
|
|
+ active,
|
|
|
+ editable,
|
|
|
+ onAdd,
|
|
|
+ onDelete,
|
|
|
+ baseColumns,
|
|
|
+ props.lineStyle,
|
|
|
+ props.tooltip,
|
|
|
+ props.nanValue,
|
|
|
+ props.filter,
|
|
|
+ downloadable,
|
|
|
+ ]);
|
|
|
|
|
|
useDispatchRequestUpdateOnFirstRender(dispatch, id, module, updateVars);
|
|
|
|
|
@@ -252,19 +253,9 @@ const PaginatedTable = (props: TaipyPaginatedTableProps) => {
|
|
|
|
|
|
useEffect(() => {
|
|
|
const endIndex = showAll ? -1 : startIndex + rowsPerPage - 1;
|
|
|
- const agg = aggregates.length
|
|
|
- ? colsOrder.reduce((pv, col, idx) => {
|
|
|
- if (aggregates.includes(columns[col].dfid)) {
|
|
|
- return pv + "-" + idx;
|
|
|
- }
|
|
|
- return pv;
|
|
|
- }, "-agg")
|
|
|
- : "";
|
|
|
const cols = colsOrder.map((col) => columns[col].dfid).filter((c) => c != EDIT_COL);
|
|
|
const afs = appliedFilters.filter((fd) => Object.values(columns).some((cd) => cd.dfid === fd.col));
|
|
|
- pageKey.current = `${startIndex}-${endIndex}-${cols.join()}-${orderBy}-${order}${agg}${afs.map(
|
|
|
- (af) => `${af.col}${af.action}${af.value}`
|
|
|
- )}`;
|
|
|
+ pageKey.current = getPageKey(columns, `${startIndex}-${endIndex}`, cols, orderBy, order, afs, aggregates, styles, tooltips, formats);
|
|
|
if (refresh || !props.data || props.data[pageKey.current] === undefined) {
|
|
|
setLoading(true);
|
|
|
const applies = aggregates.length
|
|
@@ -514,7 +505,7 @@ const PaginatedTable = (props: TaipyPaginatedTableProps) => {
|
|
|
columns[col].width
|
|
|
? { width: columns[col].width }
|
|
|
: nbWidth
|
|
|
- ? { width: `${100/nbWidth}%`, maxWidth: 0 }
|
|
|
+ ? { width: `${100 / nbWidth}%`, maxWidth: 0 }
|
|
|
: undefined
|
|
|
}
|
|
|
>
|