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

Improve and document the TableFilter component #163

Merged
merged 7 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from 4 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
13 changes: 13 additions & 0 deletions frontend/src/components/molecules/ColumnMenuFilter/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ import TableColumnIcon from "@/components/atoms/TableColumnIcon";
import { uid } from "@/utils/helper";
import { useSelector } from "react-redux";

/**
* A component that displays a list of columns available for the project
* ID type, and allows the user to select or deselect them.
* Selection changes are communicated through the callback.
*
* @param {*} props
* - type: The project ID type within the CPT Dashboard as used in
* the commonActions action file.
* - setColumns: A callback with two inputs, `value` and `isAdding`:
* - value: The column to modify
* - isAdding: `true` if adding the column, `false` if removing it.
*/
const ColumnMenuFilter = (props) => {
const [isOpen, setIsOpen] = React.useState(false);

Expand Down Expand Up @@ -73,6 +85,7 @@ const ColumnMenuFilter = (props) => {
);
};


ColumnMenuFilter.propTypes = {
type: PropTypes.string,
setColumns: PropTypes.func,
Expand Down
20 changes: 19 additions & 1 deletion frontend/src/components/molecules/MultiSelectBox/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,22 @@ import {
import PropTypes from "prop-types";
import { useState } from "react";

/**
* A multi-select box that allows selecting values for a category.
*
* @param {*} props:
* - options: an array of options that can be selected.
* - onChange: a callback function that is called with inputs `category` and `value`
* - `category`: The value from currCategory.
* - `value`: The value that was selected.
* - selected: The currently selected options in the form of an object with fields `name` and `value`
* - `name`: The name of the category.
* - `value`: An array of all selected values as strings.
* - applyMethod: A callback that is called when it is time to apply the changes (like when
* the multi-select is closed). Takes no parameters.
* - currCategory: A string specifying the current category.
* - width: the CSS value for the width of the outer sub-component.
*/
const MultiSelectBox = (props) => {
const [isOpen, setIsOpen] = useState(false);
const [isDirty, setIsDirty] = useState(false);
Expand All @@ -31,6 +47,8 @@ const MultiSelectBox = (props) => {
}
setIsDirty(false);
};
const message = props.options.length > 0 ? "Select a value" : "No values present";

const toggle = (toggleRef) => {
return (
<MenuToggle
Expand Down Expand Up @@ -66,7 +84,7 @@ const MultiSelectBox = (props) => {
</TextInputGroup>
) : (
<TextInputGroup>
<TextInputGroupMain value={"Select a value"} />
<TextInputGroupMain value={message} />
</TextInputGroup>
)}
</MenuToggle>
Expand Down
94 changes: 66 additions & 28 deletions frontend/src/components/organisms/TableFilters/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import "react-calendar/dist/Calendar.css";
import "./index.less";

import {
Banner,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You added the Banner import, but I don't see it being used. Ah, well. I see you merged, so someone can clean it up later. I'll bet ESLint will catch it.

Chip,
ChipGroup,
Toolbar,
Expand All @@ -24,12 +25,37 @@ import PropTypes from "prop-types";
import SelectBox from "@/components/molecules/SelectBox";
import { formatDate } from "@/utils/helper";

/**
* A component that provides an all-in-one toolbar for the tables in this project.
*
* Includes a filter selector, a date selector, a column selector, and navigation components.
* This component utilizes filterActions to modify the data store.
*
* @param {*} props:
* - tableFilters: A array of name-value pairs mapping the name of the filter category
* to the ID of the filter category.
* - categoryFilterValue: The ID of the currently selected category. See filterActions.setCatFilters
* for relevant code that can influence this input.
* - filterOptions: The array of options for the selected category. Used in the multi-select box.
* See filterActions.setCatFilters for relevant code that can influence this input.
* - appliedFilters: A map/object key-value pairs of the filters that are active.
* - start_date: The filter start date
* - end_date: The filter end date
* - navigation: The react navigate function.
* - type: A string that corresponds with the ID used in the commonActions action file.
* - showColumnMenu: When true, a toolbar item will display the selectable columns. Requires setColumns.
* - setColumns: A callback to set the column with inputs `value`, and `isAdding`. Allows setting
* which columns are shown. See ColumnMenuFilter for more information.
* - selectedFilters: An array of objects with fields `name` and `value`. `name` is the ID of
* the category, and `value` is an array of selected filters within the category.
* - updateSelectedFilter: A callback function with inputs `key`, `value`, and `selected` that takes a
* key and value for a filter, followed by whether the filter is selected. Used for a multi-select box.
*/
const TableFilter = (props) => {
const {
tableFilters,
categoryFilterValue,
filterOptions,
filterData,
appliedFilters,
start_date,
end_date,
Expand All @@ -41,10 +67,16 @@ const TableFilter = (props) => {
updateSelectedFilter,
} = props;

const category =
filterData?.length > 0 &&
categoryFilterValue &&
filterData.filter((item) => item.name === categoryFilterValue)?.[0]?.key;
const getFilterID = (name) => {
if (!(tableFilters?.length > 0)) {
return "";
}
const filterResults = tableFilters.filter((item) => item.name === name);
if (filterResults.length == 0) {
return "";
}
return filterResults[0].value
}

const getFilterName = (key) => {
const filter =
Expand All @@ -53,6 +85,8 @@ const TableFilter = (props) => {
return filter.name;
};

const category = getFilterID(categoryFilterValue);

const onCategoryChange = (_event, value) => {
setCatFilters(value, type);
};
Expand All @@ -72,28 +106,33 @@ const TableFilter = (props) => {
return (
<>
<Toolbar id="filter-toolbar">
{filterData?.length > 0 && (
<ToolbarContent className="field-filter">
<ToolbarItem style={{ marginInlineEnd: 0 }}>
<SelectBox
options={filterData}
onChange={onCategoryChange}
selected={categoryFilterValue}
icon={<FilterIcon />}
width={"200px"}
/>
</ToolbarItem>
<ToolbarItem>
<MultiSelectBox
options={filterOptions}
onChange={updateSelectedFilter}
applyMethod={onOptionsChange}
currCategory={category}
selected={selectedFilters?.find((i) => i.name === category)}
width={"300px"}
/>
</ToolbarItem>
</ToolbarContent>
{tableFilters != null && filterOptions != null && updateSelectedFilter != null && (
tableFilters.length > 0 ? (
<ToolbarContent className="field-filter">
<ToolbarItem style={{ marginInlineEnd: 0 }}>
<SelectBox
options={tableFilters}
onChange={onCategoryChange}
selected={categoryFilterValue}
icon={<FilterIcon />}
width={"200px"}
/>
</ToolbarItem>
<ToolbarItem>
<MultiSelectBox
options={filterOptions}
onChange={updateSelectedFilter}
applyMethod={onOptionsChange}
currCategory={category}
selected={selectedFilters?.find((i) => i.name === category)}
width={"300px"}
/>
</ToolbarItem>
</ToolbarContent>
) :
<ToolbarContent>
<ToolbarItem variant="label">No filters present</ToolbarItem>
</ToolbarContent>
)}

<ToolbarContent className="date-filter">
Expand Down Expand Up @@ -143,7 +182,6 @@ TableFilter.propTypes = {
tableFilters: PropTypes.array,
categoryFilterValue: PropTypes.string,
filterOptions: PropTypes.array,
filterData: PropTypes.array,
appliedFilters: PropTypes.object,
start_date: PropTypes.string,
end_date: PropTypes.string,
Expand Down
1 change: 0 additions & 1 deletion frontend/src/components/templates/Home/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ const Home = () => {
tableFilters={tableFilters}
filterOptions={filterOptions}
categoryFilterValue={categoryFilterValue}
filterData={filterData}
appliedFilters={appliedFilters}
start_date={start_date}
end_date={end_date}
Expand Down
1 change: 0 additions & 1 deletion frontend/src/components/templates/OCP/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ const OCP = () => {
tableFilters={modifidedTableFilters}
filterOptions={filterOptions}
categoryFilterValue={categoryFilterValue}
filterData={filterData}
appliedFilters={appliedFilters}
start_date={start_date}
end_date={end_date}
Expand Down
1 change: 0 additions & 1 deletion frontend/src/components/templates/Quay/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ const Quay = () => {
tableFilters={modifidedTableFilters}
filterOptions={filterOptions}
categoryFilterValue={categoryFilterValue}
filterData={filterData}
appliedFilters={appliedFilters}
start_date={start_date}
end_date={end_date}
Expand Down
1 change: 0 additions & 1 deletion frontend/src/components/templates/Telco/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ const Telco = () => {
tableFilters={modifidedTableFilters}
filterOptions={filterOptions}
categoryFilterValue={categoryFilterValue}
filterData={filterData}
appliedFilters={appliedFilters}
start_date={start_date}
end_date={end_date}
Expand Down
Loading