Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-select Filter #109

Merged
merged 4 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@patternfly/react-table": "^5.2.4",
"@reduxjs/toolkit": "^2.2.3",
"axios": "^1.6.8",
"lodash": "^4.17.21",
"plotly.js": "^2.32.0",
"react": "^18.2.0",
"react-date-picker": "^10.6.0",
Expand Down
70 changes: 53 additions & 17 deletions frontend/src/actions/commonActions.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as TYPES from "@/actions/types.js";

import { setCatFilters, sliceTableRows } from "./homeActions";
import { setOCPCatFilters, sliceOCPTableRows } from "./ocpActions";

import { DEFAULT_PER_PAGE } from "@/assets/constants/paginationConstants";
import { sliceTableRows } from "./homeActions";
import { cloneDeep } from "lodash";

const getSortableRowValues = (result, tableColumns) => {
const tableKeys = tableColumns.map((item) => item.value);
Expand Down Expand Up @@ -75,7 +76,8 @@ export const calculateMetrics = (results) => {
};

export const buildFilterData = (currState) => (dispatch, getState) => {
const results = [...getState()[currState].results];
const results = [...getState()[currState].filteredResults];
const categoryFilterValue = getState()[currState].categoryFilterValue;

const tableFilters = [...getState()[currState].tableFilters];

Expand All @@ -85,11 +87,19 @@ export const buildFilterData = (currState) => (dispatch, getState) => {
let obj = {
name: filter.name,
key,
value: [...new Set(results.map((item) => item[key]))],
value: [
...new Set(results.map((item) => item[key]?.toString()?.toLowerCase())),
],
};
filterData.push(obj);
}
dispatch(setFilterData(filterData, currState, tableFilters[0].name));
dispatch(
setFilterData(
filterData,
currState,
categoryFilterValue || tableFilters[0].name
)
);
};

const setFilterData = (filterData, currState, activeFilter) => (dispatch) => {
Expand All @@ -99,6 +109,12 @@ const setFilterData = (filterData, currState, activeFilter) => (dispatch) => {
payload: filterData,
});
dispatch(setOCPCatFilters(activeFilter));
} else if (currState === "cpt") {
dispatch({
type: TYPES.SET_CPT_FILTER_DATA,
payload: filterData,
});
dispatch(setCatFilters(activeFilter));
}
};

Expand All @@ -111,10 +127,10 @@ export const getFilteredData = (appliedFilters, results) => {
if (isFilterApplied) {
filtered = results.filter((el) => {
for (const key in appliedFilters) {
if (
el[key]?.toString()?.toLowerCase() !==
appliedFilters[key]?.toString()?.toLowerCase()
) {
const valueMap = appliedFilters[key]?.map((i) =>
i?.toString()?.toLowerCase()
);
if (!valueMap.includes(el[key]?.toString()?.toLowerCase())) {
return false;
}
}
Expand All @@ -124,15 +140,35 @@ export const getFilteredData = (appliedFilters, results) => {
return filtered;
};

export const getAppliedFilters =
(currState, selectedOption) => (dispatch, getState) => {
const { categoryFilterValue, filterData } = getState()[currState];
const appliedFilters = { ...getState()[currState].appliedFilters };
export const deleteAppliedFilters =
(filterKey, filterValue, currState) => (dispatch, getState) => {
const appliedFilters = cloneDeep(getState()[currState].appliedFilters);

const index = appliedFilters[filterKey].indexOf(
filterValue?.toString()?.toLowerCase()
);
if (index >= 0) {
appliedFilters[filterKey].splice(index, 1);
if (appliedFilters[filterKey].length === 0) {
delete appliedFilters[filterKey];
}
}
return appliedFilters;
};

const category = filterData.filter(
(item) => item.name === categoryFilterValue
)[0].key;
appliedFilters[category] = selectedOption;
export const getSelectedFilter =
(selectedCategory, selectedOption, currState) => (dispatch, getState) => {
const selectedFilters = cloneDeep(getState()[currState].selectedFilters);

return appliedFilters;
const obj = selectedFilters.find((i) => i.name === selectedCategory);
selectedOption = selectedOption?.toString()?.toLowerCase();
const objValue = obj.value.map((i) => i?.toString()?.toLowerCase());

if (objValue.includes(selectedOption)) {
const arr = objValue.filter((selection) => selection !== selectedOption);
obj.value = arr;
} else {
obj.value = [...obj.value, selectedOption];
}
return selectedFilters;
};
142 changes: 68 additions & 74 deletions frontend/src/actions/homeActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,17 @@ import {
START_PAGE,
} from "@/assets/constants/paginationConstants";
import { appendDateFilter, appendQueryString } from "@/utils/helper";
import { calculateMetrics, getFilteredData, sortTable } from "./commonActions";
import {
buildFilterData,
calculateMetrics,
deleteAppliedFilters,
getFilteredData,
getSelectedFilter,
sortTable,
} from "./commonActions";

import API from "@/utils/axiosInstance";
import { cloneDeep } from "lodash";
import { showFailureToast } from "@/actions/toastActions";

export const fetchOCPJobsData = () => async (dispatch, getState) => {
Expand All @@ -20,8 +28,6 @@ export const fetchOCPJobsData = () => async (dispatch, getState) => {
pretty: true,
...(start_date && { start_date }),
...(end_date && { end_date }),
// start_date: "2024-04-21",
// end_date: "2024-04-22",
},
});
if (response?.data?.results?.length > 0) {
Expand All @@ -43,10 +49,7 @@ export const fetchOCPJobsData = () => async (dispatch, getState) => {
});
dispatch(applyFilters());
dispatch(sortTable("cpt"));
dispatch(getCPTSummary());
dispatch(setPageOptions(START_PAGE, DEFAULT_PER_PAGE));
dispatch(sliceTableRows(0, DEFAULT_PER_PAGE));
dispatch(buildFilterData());
dispatch(tableReCalcValues());
}
} catch (error) {
dispatch(showFailureToast());
Expand All @@ -73,28 +76,6 @@ export const sliceTableRows = (startIdx, endIdx) => (dispatch, getState) => {
});
};

export const buildFilterData = () => (dispatch, getState) => {
const results = [...getState().cpt.results];

const tableFilters = [...getState().cpt.tableFilters];

const filterData = [];
for (const filter of tableFilters) {
const key = filter.value;
let obj = {
name: filter.name,
key,
value: [...new Set(results.map((item) => item[key]?.toLowerCase()))],
};
filterData.push(obj);
}
dispatch({
type: TYPES.SET_CPT_FILTER_DATA,
payload: filterData,
});
dispatch(setCatFilters(tableFilters[0].name));
};

export const setCatFilters = (category) => (dispatch, getState) => {
const filterData = [...getState().cpt.filterData];
const options = filterData.filter((item) => item.name === category)[0].value;
Expand All @@ -110,64 +91,70 @@ export const setCatFilters = (category) => (dispatch, getState) => {
});
};

export const setAppliedFilters =
(selectedOption, navigate) => (dispatch, getState) => {
const { categoryFilterValue, filterData, start_date, end_date } =
getState().cpt;
const appliedFilters = { ...getState().cpt.appliedFilters };

const category = filterData.filter(
(item) => item.name === categoryFilterValue
)[0].key;
appliedFilters[category] = selectedOption;

export const setSelectedFilterFromUrl = (params) => (dispatch, getState) => {
const selectedFilters = cloneDeep(getState().cpt.selectedFilters);
for (const key in params) {
selectedFilters.find((i) => i.name === key).value = params[key].split(",");
}
dispatch({
type: TYPES.SET_SELECTED_FILTERS,
payload: selectedFilters,
});
};
export const setSelectedFilter =
(selectedCategory, selectedOption) => (dispatch) => {
const selectedFilters = dispatch(
getSelectedFilter(selectedCategory, selectedOption, "cpt")
);
dispatch({
type: TYPES.SET_APPLIED_FILTERS,
payload: appliedFilters,
type: TYPES.SET_SELECTED_FILTERS,
payload: selectedFilters,
});
appendQueryString({ ...appliedFilters, start_date, end_date }, navigate);
dispatch(applyFilters());
};

export const filterFromSummary =
(category, value, navigate) => (dispatch, getState) => {
const { start_date, end_date } = getState().cpt;
const appliedFilters = { ...getState().cpt.appliedFilters };
appliedFilters[category] = value;
dispatch({
type: TYPES.SET_APPLIED_FILTERS,
payload: appliedFilters,
});
appendQueryString({ ...appliedFilters, start_date, end_date }, navigate);
dispatch(applyFilters());
};
export const setAppliedFilters = (navigate) => (dispatch, getState) => {
const { selectedFilters, start_date, end_date } = getState().cpt;

const appliedFilterArr = selectedFilters.filter((i) => i.value.length > 0);

const appliedFilters = {};
appliedFilterArr.forEach((item) => {
appliedFilters[item["name"]] = item.value;
});

dispatch({
type: TYPES.SET_APPLIED_FILTERS,
payload: appliedFilters,
});
appendQueryString({ ...appliedFilters, start_date, end_date }, navigate);
dispatch(applyFilters());
};

export const setOtherSummaryFilter = () => (dispatch, getState) => {
const filteredResults = [...getState().cpt.filteredResults];
const keyWordArr = ["SUCCESS", "FAILURE"];
const keyWordArr = ["success", "failure"];
const data = filteredResults.filter(
(item) => !keyWordArr.includes(item.jobStatus)
(item) => !keyWordArr.includes(item.jobStatus?.toLowerCase())
);
dispatch({
type: TYPES.SET_FILTERED_DATA,
payload: data,
});
dispatch(getCPTSummary());
dispatch(setPageOptions(START_PAGE, DEFAULT_PER_PAGE));
dispatch(sliceTableRows(0, DEFAULT_PER_PAGE));
dispatch(tableReCalcValues());
};
export const removeAppliedFilters =
(filterKey, navigate) => (dispatch, getState) => {
const appliedFilters = { ...getState().cpt.appliedFilters };
(filterKey, filterValue, navigate) => (dispatch, getState) => {
const { start_date, end_date } = getState().cpt;
const name = filterKey;
// eslint-disable-next-line no-unused-vars
const { [name]: removedProperty, ...remainingObject } = appliedFilters;

const appliedFilters = dispatch(
deleteAppliedFilters(filterKey, filterValue, "cpt")
);

dispatch({
type: TYPES.SET_APPLIED_FILTERS,
payload: remainingObject,
payload: appliedFilters,
});
appendQueryString({ ...remainingObject, start_date, end_date }, navigate);
appendQueryString({ ...appliedFilters, start_date, end_date }, navigate);
dispatch(applyFilters());
};

Expand All @@ -178,17 +165,18 @@ export const applyFilters = () => (dispatch, getState) => {

const isFilterApplied =
Object.keys(appliedFilters).length > 0 &&
!Object.values(appliedFilters).includes("");
Object.values(appliedFilters).flat().length > 0;

const filtered = getFilteredData(appliedFilters, results);
const filtered = isFilterApplied
? getFilteredData(appliedFilters, results)
: results;

dispatch({
type: TYPES.SET_FILTERED_DATA,
payload: isFilterApplied ? filtered : results,
payload: filtered,
});
dispatch(getCPTSummary());
dispatch(setPageOptions(START_PAGE, DEFAULT_PER_PAGE));
dispatch(sliceTableRows(0, DEFAULT_PER_PAGE));
dispatch(tableReCalcValues());
dispatch(buildFilterData("cpt"));
};

export const setFilterFromURL = (searchParams) => ({
Expand Down Expand Up @@ -232,3 +220,9 @@ export const getCPTSummary = () => (dispatch, getState) => {
payload: countObj,
});
};

export const tableReCalcValues = () => (dispatch) => {
dispatch(getCPTSummary());
dispatch(setPageOptions(START_PAGE, DEFAULT_PER_PAGE));
dispatch(sliceTableRows(0, DEFAULT_PER_PAGE));
};
Loading
Loading