Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export const columnChildrenMap = {
dataIndex: valueComp<string>(""),
hide: BoolControl,
sortable: BoolControl,
filterable: withDefault(BoolControl, false),
width: NumberControl,
autoWidth: dropdownControl(columnWidthOptions, "auto"),
render: RenderComp,
Expand Down Expand Up @@ -270,6 +271,9 @@ const ColumnPropertyView = React.memo(({
{comp.children.sortable.propertyView({
label: trans("table.sortable"),
})}
{comp.children.filterable.propertyView({
label: trans("table.filterable"),
})}
{comp.children.hide.propertyView({
label: trans("prop.hide"),
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ test("test table data transform", () => {
)
);
getAndExpectTableData(2, comp);
comp = evalAndReduce(comp.reduce(comp.changeChildAction("headerFilters", { name: ["gg2"] })));
({ transformedData } = getAndExpectTableData(1, comp));
expect(transformedData.map((d: any) => d["name"])).toEqual(["gg2"]);
comp = evalAndReduce(comp.reduce(comp.changeChildAction("headerFilters", {})));
// filter
comp = evalAndReduce(
comp.reduce(
Expand Down
19 changes: 17 additions & 2 deletions client/packages/lowcoder/src/comps/comps/tableComp/tableComp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getPageSize } from "comps/comps/tableComp/paginationControl";
import { EMPTY_ROW_KEY, TableCompView } from "comps/comps/tableComp/tableCompView";
import { TableFilter } from "comps/comps/tableComp/tableToolbarComp";
import {
applyHeaderFilters,
columnHide,
ColumnsAggrData,
COLUMN_CHILDREN_KEY,
Expand Down Expand Up @@ -357,12 +358,14 @@ export class TableImplComp extends TableInitComp implements IContainer {
data: this.sortDataNode(),
searchValue: this.children.searchText.node(),
filter: this.children.toolbar.children.filter.node(),
headerFilters: this.children.headerFilters.node(),
showFilter: this.children.toolbar.children.showFilter.node(),
};
let context = this;
const filteredDataNode = withFunction(fromRecord(nodes), (input) => {
const { data, searchValue, filter, showFilter } = input;
const filteredData = filterData(data, searchValue.value, filter, showFilter.value);
const { data, searchValue, filter, headerFilters, showFilter } = input;
const toolbarFilteredData = filterData(data, searchValue.value, filter, showFilter.value);
const filteredData = applyHeaderFilters(toolbarFilteredData, headerFilters);
// console.info("filterNode. data: ", data, " filter: ", filter, " filteredData: ", filteredData);
// if data is changed on search then trigger event
if(Boolean(searchValue.value) && data.length !== filteredData.length) {
Expand Down Expand Up @@ -1141,6 +1144,18 @@ export const TableComp = withExposingConfigs(TableTmpComp, [
},
trans("table.filterDesc")
),
new DepsConfig(
"headerFilters",
(children) => {
return {
headerFilters: children.headerFilters.node(),
};
},
(input) => {
return input.headerFilters;
},
trans("table.headerFiltersDesc")
),
new DepsConfig(
"selectedCell",
(children) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ export const TableCompView = React.memo((props: {
() => compChildren.dynamicColumnConfig.getView(),
[compChildren.dynamicColumnConfig]
);
const headerFilters = useMemo(() => compChildren.headerFilters.getView(), [compChildren.headerFilters]);
const columnsAggrData = comp.columnAggrData;
const expansion = useMemo(() => compChildren.expansion.getView(), [compChildren.expansion]);
const antdColumns = useMemo(
Expand All @@ -122,6 +123,7 @@ export const TableCompView = React.memo((props: {
columnsAggrData,
editModeClicks,
onEvent,
headerFilters,
),
[
columnViews,
Expand All @@ -132,6 +134,7 @@ export const TableCompView = React.memo((props: {
dynamicColumnConfig,
columnsAggrData,
editModeClicks,
headerFilters,
]
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ const tableChildrenMap = {
selection: SelectionControl,
pagination: PaginationControl,
sort: valueComp<Array<SortValue>>([]),
headerFilters: stateComp<Record<string, any[]>>({}),
toolbar: TableToolbarComp,
showSummary: BoolControl,
summaryRows: dropdownControl(summarRowsOptions, "1"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,31 @@ export function filterData(
return resultData;
}

export function applyHeaderFilters(
data: Array<RecordType>,
headerFilters: Record<string, any[]>
) {
if (!headerFilters || Object.keys(headerFilters).length === 0) {
return data;
}

return data.filter((row) =>
Object.entries(headerFilters).every(([columnKey, filterValues]) => {
if (!Array.isArray(filterValues) || filterValues.length === 0) {
return true;
}

const cellValue = row[columnKey];
return filterValues.some((filterValue) => {
if (cellValue == null) {
return filterValue == null;
}
return String(cellValue) === String(filterValue);
});
})
);
}

export function sortData(
data: Array<JSONObject>,
columns: Record<string, { sortable: boolean }>, // key: dataIndex
Expand Down Expand Up @@ -291,6 +316,14 @@ export function getColumnsAggr(
.uniqBy("text")
.value();
}

res.uniqueValues = _(oriDisplayData)
.map((row) => row[dataIndex])
.filter((value): value is JSONValue => value !== undefined && value !== null && value !== "")
.uniqWith(_.isEqual)
.slice(0, 100)
.value();

return res;
});
}
Expand Down Expand Up @@ -338,6 +371,27 @@ export type CustomColumnType<RecordType> = ColumnType<RecordType> & {
columnDataTestId?: string;
};

function buildHeaderFilterProps(
dataIndex: string,
filterable: boolean,
uniqueValues: any[],
headerFilters: Record<string, any[]> = {}
) {
if (!filterable || uniqueValues.length === 0) {
return {};
}

return {
filters: uniqueValues.map((value) => ({
text: String(value),
value,
})),
filteredValue: headerFilters[dataIndex] ?? null,
filterSearch: true,
filterMultiple: true,
} as const;
}

/**
* convert column in raw format into antd format
*/
Expand All @@ -351,6 +405,7 @@ export function columnsToAntdFormat(
columnsAggrData: ColumnsAggrData,
editMode: string,
onTableEvent: (eventName: any) => void,
headerFilters: Record<string, any[]> = {},
): Array<CustomColumnType<RecordType>> {
const customColumns = columns.filter(col => col.isCustom).map(col => col.dataIndex);
const initialColumns = getInitialColumns(columnsAggrData, customColumns);
Expand Down Expand Up @@ -393,10 +448,18 @@ export function columnsToAntdFormat(
text: string;
status: StatusType;
}[];
const uniqueValues = ((columnsAggrData[column.dataIndex] ?? {}).uniqueValues ?? []) as any[];
const columnKey = column.dataIndex || `custom-${mIndex}`;
const title = renderTitle({ title: column.title, tooltip: column.titleTooltip, editable: column.editable });
const filterProps = buildHeaderFilterProps(
column.dataIndex,
column.filterable,
uniqueValues,
headerFilters
);

return {
key: `${column.dataIndex}-${mIndex}`,
key: columnKey,
title: column.showTitle ? title : '',
titleText: column.title,
dataIndex: column.dataIndex,
Expand Down Expand Up @@ -468,6 +531,7 @@ export function columnsToAntdFormat(
showSorterTooltip: false,
}
: {}),
...filterProps,
};
});
}
Expand Down Expand Up @@ -504,6 +568,16 @@ export function onTableChange(
dispatch(changeChildAction("sort", sortValues, true));
onEvent("sortChange");
}

if (extra.action === "filter") {
const headerFilters = _(filters)
.pickBy((filterValues) => Array.isArray(filterValues) && filterValues.length > 0)
.mapValues((filterValues) => filterValues as any[])
.value();

dispatch(changeChildAction("headerFilters", headerFilters, true));
onEvent("filterChange");
}
}

export function calcColumnWidth(columnKey: string, data: Array<JSONObject>) {
Expand Down
2 changes: 2 additions & 0 deletions client/packages/lowcoder/src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2095,6 +2095,7 @@ export const en = {
"showTitle": "Show Title",
"showTitleTooltip": "Show/Hide column title in table header",
"sortable": "Sortable",
"filterable": "Filterable",
"align": "Alignment",
"fixedColumn": "Fixed Column",
"autoWidth": "Auto Width",
Expand Down Expand Up @@ -2170,6 +2171,7 @@ export const en = {
"displayDataDesc": "Data Displayed in the Current Table",
"selectedIndexDesc": "Selected Index in Display Data",
"filterDesc": "Table Filtering Parameters",
"headerFiltersDesc": "Header filter selections keyed by column name",
"dataDesc": "The JSON Data for the Table",
"saveChanges": "Save Changes",
"cancelChanges": "Cancel Changes",
Expand Down
Loading