Skip to content

Commit

Permalink
add an indicator with a clear button when there are column filters; i…
Browse files Browse the repository at this point in the history
…ndicate when no incidents match filters; stop polling when too many incidents
  • Loading branch information
martindstone committed Jun 6, 2024
1 parent 36e4ed2 commit c35128c
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 28 deletions.
55 changes: 31 additions & 24 deletions src/components/IncidentTable/IncidentTableComponent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
import {
selectIncidentTableRows as selectIncidentTableRowsConnected,
updateIncidentTableState as updateIncidentTableStateConnected,
CLEAR_INCIDENT_TABLE_FILTERS_COMPLETED,
} from 'src/redux/incident_table/actions';

import EmptyIncidentsComponent from './subcomponents/EmptyIncidentsComponent';
Expand Down Expand Up @@ -120,7 +121,7 @@ const doCsvExport = (tableData) => {

const IncidentTableComponent = () => {
const {
incidentTableState, incidentTableColumns,
incidentTableState, incidentTableColumns, status: incidentTableStatus,
} = useSelector((state) => state.incidentTable);
const {
status: incidentActionsStatus,
Expand Down Expand Up @@ -221,7 +222,8 @@ const IncidentTableComponent = () => {
// Debouncing for table state
const debouncedUpdateIncidentTableState = useDebouncedCallback((state, action) => {
// Only update store with sorted and column resizing state
if (action.type === 'toggleSortBy' || action.type === 'columnDoneResizing') {
// and filter state
if (action.type === 'toggleSortBy' || action.type === 'columnDoneResizing' || action.type === 'setFilter') {
updateIncidentTableState(state);
}
}, 100);
Expand Down Expand Up @@ -251,7 +253,7 @@ const IncidentTableComponent = () => {
// Set initial state from store
initialState: incidentTableState,
// Handle updates to table
stateReducer: (newState, action) => debouncedUpdateIncidentTableState(newState, action),
stateReducer: debouncedUpdateIncidentTableState,
},
// Plugins
useFilters,
Expand Down Expand Up @@ -327,19 +329,17 @@ const IncidentTableComponent = () => {
},
);

// save filters when the user changes them
useEffect(() => {
updateIncidentTableState({
...incidentTableState,
filters: tableInstance.state.filters,
});
}, [tableInstance.state.filters]);

// Update table filters when columns change
useEffect(() => {
tableInstance.setAllFilters(incidentTableState.filters);
}, [columns]);

useEffect(() => {
if (incidentTableStatus === CLEAR_INCIDENT_TABLE_FILTERS_COMPLETED) {
tableInstance.setAllFilters(incidentTableState.filters);
}
}, [incidentTableStatus]);

const {
getTableProps,
getTableBodyProps,
Expand Down Expand Up @@ -536,19 +536,26 @@ const IncidentTableComponent = () => {
</MenuItem>
</ContextMenu>
</Box>
<Box {...getTableBodyProps()}>
<FixedSizeList
className="incident-table-fixed-list"
height={tableHeight - 45}
itemCount={rows.length}
itemSize={60}
itemKey={(index) => rows[index].id}
itemData={rows}
width={totalColumnsWidth + scrollBarSize}
>
{MyIncidentRow}
</FixedSizeList>
</Box>
{ rows.length > 0 && (
<Box {...getTableBodyProps()}>
<FixedSizeList
className="incident-table-fixed-list"
height={tableHeight - 45}
itemCount={rows.length}
itemSize={60}
itemKey={(index) => rows[index].id}
itemData={rows}
width={totalColumnsWidth + scrollBarSize}
>
{MyIncidentRow}
</FixedSizeList>
</Box>
)}
{ rows.length === 0 && (
<EmptyIncidentsComponent
message={t('No incidents match your search criteria.')}
/>
)}
<GetAllModal
isOpen={displayGetAllModal}
onClose={() => setDisplayGetAllModal(false)}
Expand Down
22 changes: 20 additions & 2 deletions src/components/QuerySettings/QuerySettingsComponent.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React from 'react';
import React, {
useMemo,
} from 'react';

import {
useSelector, useDispatch,
Expand Down Expand Up @@ -28,6 +30,7 @@ import DatePickerComponent from './subcomponents/DatePickerComponent';
import StatusQueryComponent from './subcomponents/StatusQueryComponent';
import UrgencyQueryComponent from './subcomponents/UrgencyQueryComponent';
import PriorityQueryComponent from './subcomponents/PriorityQueryComponent';
import ColumnFilterIndicatorComponent from './subcomponents/ColumnFilterIndicatorComponent';

import './QuerySettingsComponent.scss';

Expand All @@ -52,6 +55,10 @@ const QuerySettingsComponent = () => {
} = useSelector(
(state) => state.querySettings,
);
const {
filters,
} = useSelector((state) => state.incidentTable.incidentTableState);

const dispatch = useDispatch();
const updateQuerySettingsServices = (newServiceIds) => {
dispatch(updateQuerySettingsServicesConnected(newServiceIds));
Expand All @@ -66,6 +73,13 @@ const QuerySettingsComponent = () => {
dispatch(updateQuerySettingsTeamsConnected(newTeamIds));
};

const filterCount = useMemo(() => {
if (filters instanceof Array) {
return filters.length;
}
return 0;
}, [filters]);

return (
<Box m={4}>
<Flex
Expand Down Expand Up @@ -117,7 +131,11 @@ const QuerySettingsComponent = () => {
isMulti
/>
</BoxForInput>
{/* <GlobalSearchComponent /> */}
{ filterCount > 0 && (
<BoxForInput label={`${t('Column Filters')}:`}>
<ColumnFilterIndicatorComponent />
</BoxForInput>
)}
</Flex>
</Box>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React, {
useMemo,
} from 'react';

import {
useSelector,
useDispatch,
} from 'react-redux';

import {
useTranslation,
} from 'react-i18next';

import {
Flex,
Button,
Tag,
} from '@chakra-ui/react';

import {
clearIncidentTableFilters as clearIncidentTableFiltersConnected,
} from 'src/redux/incident_table/actions';

const ColumnFilterIndicatorComponent = () => {
const {
t,
} = useTranslation();
const {
filters,
} = useSelector((state) => state.incidentTable.incidentTableState);

const dispatch = useDispatch();
const clearIncidentTableFilters = () => {
dispatch(clearIncidentTableFiltersConnected());
};

const filterCount = useMemo(() => {
if (filters instanceof Array) {
return filters.length;
}
return 0;
}, [filters]);

return (
<Flex>
<Tag colorScheme="blue">
{filterCount}
</Tag>
<Button
size="xs"
ml={1}
colorScheme="red"
aria-label="clear"
onClick={clearIncidentTableFilters}
>
{t('Clear')}
</Button>
</Flex>
);
};

export default ColumnFilterIndicatorComponent;
7 changes: 7 additions & 0 deletions src/redux/incident_table/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export const UPDATE_INCIDENT_TABLE_STATE_COMPLETED = 'UPDATE_INCIDENT_TABLE_STAT
export const SELECT_INCIDENT_TABLE_ROWS_REQUESTED = 'SELECT_INCIDENT_TABLE_ROWS_REQUESTED';
export const SELECT_INCIDENT_TABLE_ROWS_COMPLETED = 'SELECT_INCIDENT_TABLE_ROWS_COMPLETED';

export const CLEAR_INCIDENT_TABLE_FILTERS_REQUESTED = 'CLEAR_INCIDENT_TABLE_FILTERS_REQUESTED';
export const CLEAR_INCIDENT_TABLE_FILTERS_COMPLETED = 'CLEAR_INCIDENT_TABLE_FILTERS_COMPLETED';

// Define Actions

export const saveIncidentTable = (updatedIncidentTableColumns) => ({
Expand All @@ -35,3 +38,7 @@ export const selectIncidentTableRows = (allSelected, selectedCount, selectedRows
selectedCount,
selectedRows,
});

export const clearIncidentTableFilters = () => ({
type: CLEAR_INCIDENT_TABLE_FILTERS_REQUESTED,
});
14 changes: 14 additions & 0 deletions src/redux/incident_table/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
UPDATE_INCIDENT_TABLE_STATE_COMPLETED,
SELECT_INCIDENT_TABLE_ROWS_REQUESTED,
SELECT_INCIDENT_TABLE_ROWS_COMPLETED,
CLEAR_INCIDENT_TABLE_FILTERS_REQUESTED,
CLEAR_INCIDENT_TABLE_FILTERS_COMPLETED,
} from './actions';

const defaultColumns = [
Expand Down Expand Up @@ -70,6 +72,18 @@ const incidentTable = produce(
draft.status = SELECT_INCIDENT_TABLE_ROWS_COMPLETED;
break;

case CLEAR_INCIDENT_TABLE_FILTERS_REQUESTED:
draft.status = CLEAR_INCIDENT_TABLE_FILTERS_REQUESTED;
break;

case CLEAR_INCIDENT_TABLE_FILTERS_COMPLETED:
draft.incidentTableState = {
...draft.incidentTableState,
filters: [],
};
draft.status = CLEAR_INCIDENT_TABLE_FILTERS_COMPLETED;
break;

default:
break;
}
Expand Down
12 changes: 12 additions & 0 deletions src/redux/incident_table/sagas.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
UPDATE_INCIDENT_TABLE_STATE_COMPLETED,
SELECT_INCIDENT_TABLE_ROWS_REQUESTED,
SELECT_INCIDENT_TABLE_ROWS_COMPLETED,
CLEAR_INCIDENT_TABLE_FILTERS_REQUESTED,
CLEAR_INCIDENT_TABLE_FILTERS_COMPLETED,
} from './actions';

import selectIncidentTable from './selectors';
Expand Down Expand Up @@ -122,3 +124,13 @@ export function* selectIncidentTableRowsImpl(action) {
selectedRows,
});
}

export function* clearIncidentTableFilters() {
yield takeLatest(CLEAR_INCIDENT_TABLE_FILTERS_REQUESTED, clearIncidentTableFiltersImpl);
}

export function* clearIncidentTableFiltersImpl() {
yield put({
type: CLEAR_INCIDENT_TABLE_FILTERS_COMPLETED,
});
}
1 change: 1 addition & 0 deletions src/redux/incidents/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const incidents = produce(
case FETCH_INCIDENTS_REQUESTED:
draft.fetchingIncidents = true;
draft.status = FETCH_INCIDENTS_REQUESTED;
draft.error = null;
break;

case FETCH_INCIDENTS_COMPLETED:
Expand Down
12 changes: 10 additions & 2 deletions src/redux/log_entries/sagas.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,17 @@ export function* pollLogEntriesTask() {
},
incidents: {
fetchingIncidents,
error: incidentsError,
},
} = yield select();
if (userAuthorized && userAcceptedDisclaimer && !fetchingIncidents && !DEBUG_DISABLE_POLLING) {

const tooManyIncidentsError = (
incidentsError
&& typeof incidentsError === 'string'
&& incidentsError.startsWith('Too many records')
);

if (userAuthorized && userAcceptedDisclaimer && !fetchingIncidents && !DEBUG_DISABLE_POLLING && !tooManyIncidentsError) {
const lastPollStarted = new Date();
yield put({
type: UPDATE_LOG_ENTRIES_POLLING,
Expand Down Expand Up @@ -199,7 +207,7 @@ export function* pollLogEntriesTask() {
yield delay((LOG_ENTRIES_POLLING_INTERVAL_SECONDS * 1000) - timeTaken);
} else {
// eslint-disable-next-line no-console
console.log('skipping poll', { userAuthorized, userAcceptedDisclaimer, fetchingIncidents, DEBUG_DISABLE_POLLING });
console.log('skipping poll', { userAuthorized, userAcceptedDisclaimer, fetchingIncidents, DEBUG_DISABLE_POLLING, tooManyIncidentsError });
yield delay(LOG_ENTRIES_POLLING_INTERVAL_SECONDS * 1000);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/redux/rootSaga.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
updateIncidentTableColumns,
updateIncidentTableState,
selectIncidentTableRows,
clearIncidentTableFilters,
} from './incident_table/sagas';

import {
Expand Down Expand Up @@ -185,6 +186,7 @@ export default function* rootSaga() {
updateIncidentTableColumns(),
updateIncidentTableState(),
selectIncidentTableRows(),
clearIncidentTableFilters(),

// Incident Actions
doAction(),
Expand Down

0 comments on commit c35128c

Please sign in to comment.