Skip to content

Commit

Permalink
Multiple filter
Browse files Browse the repository at this point in the history
  • Loading branch information
MVarshini committed Jul 16, 2024
1 parent b84fa11 commit 2b6972b
Show file tree
Hide file tree
Showing 10 changed files with 287 additions and 96 deletions.
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
8 changes: 4 additions & 4 deletions frontend/src/actions/commonActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,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 Down
103 changes: 65 additions & 38 deletions frontend/src/actions/homeActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { appendDateFilter, appendQueryString } from "@/utils/helper";
import { calculateMetrics, getFilteredData, sortTable } from "./commonActions";

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

export const fetchOCPJobsData = () => async (dispatch, getState) => {
Expand Down Expand Up @@ -110,42 +111,59 @@ 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, getState) => {
const selectedFilters = cloneDeep(getState().cpt.selectedFilters);

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];
}
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,
Expand All @@ -156,18 +174,25 @@ export const setOtherSummaryFilter = () => (dispatch, getState) => {
dispatch(sliceTableRows(0, DEFAULT_PER_PAGE));
};
export const removeAppliedFilters =
(filterKey, navigate) => (dispatch, getState) => {
const appliedFilters = { ...getState().cpt.appliedFilters };
(filterKey, filterValue, navigate) => (dispatch, getState) => {
const appliedFilters = cloneDeep(getState().cpt.appliedFilters);
const { start_date, end_date } = getState().cpt;
const name = filterKey;
// eslint-disable-next-line no-unused-vars
const { [name]: removedProperty, ...remainingObject } = appliedFilters;

const index = appliedFilters[filterKey]
?.toString()
?.toLowerCase()
.indexOf(filterValue);
if (index >= 0) {
appliedFilters[filterKey].splice(index, 1);
if (appliedFilters[filterKey].length === 0) {
delete appliedFilters[filterKey];
}
}
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,9 +203,11 @@ 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,
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const SET_APPLIED_FILTERS = "SET_APPLIED_FILTERS";
export const SET_PAGE = "SET_PAGE";
export const SET_PAGE_OPTIONS = "SET_PAGE_OPTIONS";
export const SET_CPT_SUMMARY = "SET_CPT_SUMMARY";

export const SET_SELECTED_FILTERS = "SET_SELECTED_FILTERS";
/* OCP Jobs */
export const SET_OCP_JOBS_DATA = "SET_OCP_JOBS_DATA";
export const SET_OCP_DATE_FILTER = "SET_OCP_DATE_FILTER";
Expand Down
113 changes: 113 additions & 0 deletions frontend/src/components/molecules/MultiSelectBox/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import {
Chip,
ChipGroup,
MenuToggle,
Select,
SelectList,
SelectOption,
TextInputGroup,
TextInputGroupMain,
} from "@patternfly/react-core";

import PropTypes from "prop-types";
import { useState } from "react";

const MultiSelectBox = (props) => {
const [isOpen, setIsOpen] = useState(false);
const [isDirty, setIsDirty] = useState(false);
const onSelect = (value) => {
console.log("selected", value);
setIsDirty(true);
props.onChange(props.currCategory, value);
};

const onToggleClick = () => {
setIsOpen(!isOpen);
};

const closeMenu = () => {
setIsOpen(false);
if (isDirty) {
props.applyMethod();
}
setIsDirty(false);
};
const toggle = (toggleRef) => {
console.log(props.selected);
return (
<MenuToggle
variant="typeahead"
aria-label="Multi typeahead menu toggle"
onClick={onToggleClick}
innerRef={toggleRef}
isExpanded={isOpen}
style={{
width: "300px",
height: "36px",
}}
>
{Array.isArray(props.selected.value) &&
props.selected.value.length > 0 ? (
<ChipGroup numChips={2}>
{props.selected.value.map((selection, index) => (
<Chip
key={index}
readOnly
// onClick={(ev) => {
// ev.stopPropagation();
// onSelect(selection);
// }}
>
{selection}
</Chip>
))}
</ChipGroup>
) : (
<TextInputGroup>
<TextInputGroupMain value={"Select a value"} />
</TextInputGroup>
)}
</MenuToggle>
);
};
const createItemId = (value) =>
`select-multi-typeahead-${value.replace(" ", "-")}`;
return (
<>
<Select
id="multi-typeahead-select"
isOpen={isOpen}
selected={props.selected?.value}
onSelect={(_event, selection) => onSelect(selection)}
onOpenChange={(isOpen) => {
!isOpen && closeMenu();
}}
toggle={toggle}
shouldFocusFirstItemOnOpen={false}
>
<SelectList isAriaMultiselectable id="select-multi-typeahead-listbox">
{props.options.map((option) => (
<SelectOption
key={option.value}
className={option.className}
id={createItemId(option.value)}
{...option}
ref={null}
>
{option.name}
</SelectOption>
))}
</SelectList>
</Select>
</>
);
};

MultiSelectBox.propTypes = {
options: PropTypes.array,
onChange: PropTypes.func,
selected: PropTypes.array,
applyMethod: PropTypes.func,
currCategory: PropTypes.string,
};
export default MultiSelectBox;
1 change: 1 addition & 0 deletions frontend/src/components/molecules/SelectBox/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const SelectBox = (props) => {
isExpanded={isOpen}
style={{
width: props.width,
height: "36px",
}}
>
{props.selected}
Expand Down
Loading

0 comments on commit 2b6972b

Please sign in to comment.