1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
10 } from 'components/data-table/data-column';
14 DataTableRequestState,
15 } from './data-explorer-action';
19 } from 'components/data-table/data-table';
20 import { DataTableFilters } from 'components/data-table-filters/data-table-filters-tree';
22 export interface DataExplorer {
23 fetchMode: DataTableFetchMode;
24 columns: DataColumns<any, any>;
26 itemsAvailable: number;
29 rowsPerPageOptions: number[];
32 requestState: DataTableRequestState;
36 export const initialDataExplorer: DataExplorer = {
37 fetchMode: DataTableFetchMode.PAGINATED,
43 rowsPerPageOptions: [10, 20, 50, 100, 200, 500],
45 requestState: DataTableRequestState.IDLE,
49 export type DataExplorerState = Record<string, DataExplorer>;
51 export const dataExplorerReducer = (
52 state: DataExplorerState = {},
53 action: DataExplorerAction
55 return dataExplorerActions.match(action, {
57 update(state, id, (explorer) => ({
64 RESET_PAGINATION: ({ id }) =>
65 update(state, id, (explorer) => ({ ...explorer, page: 0 })),
67 SET_FETCH_MODE: ({ id, fetchMode }) =>
68 update(state, id, (explorer) => ({ ...explorer, fetchMode })),
70 SET_COLUMNS: ({ id, columns }) => update(state, id, setColumns(columns)),
72 SET_FILTERS: ({ id, columnName, filters }) =>
73 update(state, id, mapColumns(setFilters(columnName, filters))),
75 SET_ITEMS: ({ id, items, itemsAvailable, page, rowsPerPage }) => (
76 update(state, id, (explorer) => {
77 // Reject updates to pages other than current,
78 // DataExplorer middleware should retry
79 const updatedPage = page || 0;
80 if (explorer.page === updatedPage) {
94 APPEND_ITEMS: ({ id, items, itemsAvailable, page, rowsPerPage }) =>
95 update(state, id, (explorer) => ({
97 items: state[id].items.concat(items),
98 itemsAvailable: state[id].itemsAvailable + itemsAvailable,
103 SET_PAGE: ({ id, page }) =>
104 update(state, id, (explorer) => ({ ...explorer, page })),
106 SET_ROWS_PER_PAGE: ({ id, rowsPerPage }) =>
107 update(state, id, (explorer) => ({ ...explorer, rowsPerPage })),
109 SET_EXPLORER_SEARCH_VALUE: ({ id, searchValue }) =>
110 update(state, id, (explorer) => ({ ...explorer, searchValue })),
112 RESET_EXPLORER_SEARCH_VALUE: ({ id }) =>
113 update(state, id, (explorer) => ({ ...explorer, searchValue: '' })),
115 SET_REQUEST_STATE: ({ id, requestState }) =>
116 update(state, id, (explorer) => ({ ...explorer, requestState })),
118 TOGGLE_SORT: ({ id, columnName }) =>
119 update(state, id, mapColumns(toggleSort(columnName))),
121 TOGGLE_COLUMN: ({ id, columnName }) =>
122 update(state, id, mapColumns(toggleColumn(columnName))),
124 SET_IS_NOT_FOUND: ({ id, isNotFound }) =>
125 update(state, id, (explorer) => ({ ...explorer, isNotFound })),
127 default: () => state,
130 export const getDataExplorer = (state: DataExplorerState, id: string) => {
131 const returnValue = state[id] || initialDataExplorer;
135 export const getSortColumn = <R>(dataExplorer: DataExplorer): DataColumn<any, R> | undefined =>
136 dataExplorer.columns.find(
137 (c: DataColumn<any, R>) => !!c.sort && c.sort.direction !== SortDirection.NONE
141 state: DataExplorerState,
143 updateFn: (dataExplorer: DataExplorer) => DataExplorer
144 ) => ({ ...state, [id]: updateFn(getDataExplorer(state, id)) });
146 const canUpdateColumns = (
147 prevColumns: DataColumns<any, any>,
148 nextColumns: DataColumns<any, any>
150 if (prevColumns.length !== nextColumns.length) {
153 for (let i = 0; i < nextColumns.length; i++) {
154 const pc = prevColumns[i];
155 const nc = nextColumns[i];
156 if (pc.key !== nc.key || pc.name !== nc.name) {
164 (columns: DataColumns<any, any>) => (dataExplorer: DataExplorer) => ({
166 columns: canUpdateColumns(dataExplorer.columns, columns)
168 : dataExplorer.columns,
172 (mapFn: (column: DataColumn<any, any>) => DataColumn<any, any>) =>
173 (dataExplorer: DataExplorer) => ({
175 columns: dataExplorer.columns.map(mapFn),
178 const toggleSort = (columnName: string) => (column: DataColumn<any, any>) =>
179 column.name === columnName
180 ? toggleSortDirection(column)
181 : resetSortDirection(column);
183 const toggleColumn = (columnName: string) => (column: DataColumn<any, any>) =>
184 column.name === columnName
185 ? { ...column, selected: !column.selected }
189 (columnName: string, filters: DataTableFilters) =>
190 (column: DataColumn<any, any>) =>
191 column.name === columnName ? { ...column, filters } : column;