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

feat(ocpadvisor-123): functional filters with mockdata #629

Merged
merged 6 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 3 additions & 3 deletions src/AppConstants.js
Original file line number Diff line number Diff line change
Expand Up @@ -434,10 +434,10 @@ export const WORKLOADS_TABLE_CELL_OBJECTS = 3;
export const WORKLOADS_TABLE_CELL_LAST_SEEN = 4;

export const WORKLOADS_TABLE_FILTER_CATEGORIES = {
highest_severity: {
general_severity: {
type: 'checkbox',
title: 'Highest severity',
urlParam: 'highest_severity',
title: 'General severity',
urlParam: 'general_severity',
values: [
{ label: 'Critical', text: 'Critical', value: 'critical' },
{ label: 'Important', text: 'Important', value: 'important' },
Expand Down
33 changes: 33 additions & 0 deletions src/Components/Common/Tables.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import {
FILTER_CATEGORIES,
RULE_CATEGORIES,
} from '../../AppConstants';
import {
hasAnyValueGreaterThanZero,
remappingSeverity,
} from '../../Utilities/Workloads';

export const passFilters = (rule, filters) =>
Object.entries(filters).every(([filterKey, filterValue]) => {
Expand Down Expand Up @@ -275,3 +279,32 @@ export const addFilterParam = (currentFilters, updateFilters, param, values) =>
...{ [param]: values },
})
: removeFilterParam(currentFilters, updateFilters, param);

export const passFilterWorkloads = (workloads, filters) => {
const generalSeverityRemapped = remappingSeverity(
workloads.metadata.hits_by_severity,
'general'
);
return Object.entries(filters).every(([filterKey, filterValue]) => {
switch (filterKey) {
case 'cluster_name':
return workloads.cluster.display_name
.toLowerCase()
.includes(filterValue.toLowerCase());
case 'namespace_name':
return workloads.namespace.name
.toLowerCase()
.includes(filterValue.toLowerCase());
case 'general_severity':
return (
filterValue.length === 0 ||
hasAnyValueGreaterThanZero(
generalSeverityRemapped,
filters.general_severity
)
);
default:
return true;
}
});
};
14 changes: 1 addition & 13 deletions src/Components/HighestSeverityBadge/HighestSeverityBadge.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,9 @@ import { Tooltip } from '@patternfly/react-core';
import { TooltipPosition } from '@patternfly/react-core/dist/js/components/Tooltip';
import InsightsLabel from '@redhat-cloud-services/frontend-components/InsightsLabel';
import PropTypes from 'prop-types';
import { severityTypeToText } from '../../Utilities/Workloads';

export const HighestSeverityBadge = ({ highestSeverity, severities }) => {
const severityTypeToText = (value) => {
value = parseInt(value);
if (value === 1) {
return 'Low';
} else if (value === 2) {
return 'Moderate';
} else if (value === 3) {
return 'Important';
} else {
return 'Critical';
}
};

const severitiesToDisplay = Object.keys(severities)
.map((severityType) => {
return severities[severityType] > 0 ? (
Expand Down
3 changes: 2 additions & 1 deletion src/Components/ShieldSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import { SEVERITY_OPTIONS, remappingSeverity } from '../Utilities/Workloads';
const ShieldSet = (hits_by_severity) => {
const DISABLED_COLOR = 'var(--pf-global--disabled-color--200)';
const severitiesRemapped = remappingSeverity(
hits_by_severity.hits_by_severity
hits_by_severity.hits_by_severity,
'label'
);
return (
<div className="shield-set">
Expand Down
82 changes: 55 additions & 27 deletions src/Components/WorkloadsListTable/WorkloadsListTable.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import PrimaryToolbar from '@redhat-cloud-services/frontend-components/PrimaryToolbar';
import {
Expand All @@ -24,35 +24,67 @@ import {
updateWorkloadsListFilters,
} from '../../Services/Filters';
import isEqual from 'lodash/isEqual';
import { buildFilterChips } from '../Common/Tables';
import {
addFilterParam,
buildFilterChips,
passFilterWorkloads,
removeFilterParam as _removeFilterParam,
} from '../Common/Tables';
import { ErrorState, NoMatchingClusters } from '../MessageState/EmptyStates';
import Loading from '../Loading/Loading';
import mockdata from '../../../cypress/fixtures/api/insights-results-aggregator/v2/workloads.json';
import ShieldSet from '../ShieldSet';
import { noFiltersApplied } from '../../Utilities/Workloads';

const WorkloadsListTable = ({
query: { isError, isUninitialized, isFetching, isSuccess, data },
query: { isError, isUninitialized, isFetching, isSuccess, data, refetch },
}) => {
const dispatch = useDispatch();
const filters = useSelector(({ filters }) => filters.workloadsListState);
//const workloads = data?.workloads || [];
//to check all types of filters use the mockdata json
const workloads = mockdata;

const [rows, setRows] = React.useState([]);
const [rows, setRows] = useState([]);
const [filteredRows, setFilteredRows] = useState([]);
const [rowsFiltered, setRowsFiltered] = useState(false);
const [filtersApplied, setFiltersApplied] = useState(false);
const updateFilters = (payload) =>
dispatch(updateWorkloadsListFilters(payload));
const removeFilterParam = (param) =>
_removeFilterParam(filters, updateFilters, param);

const loadingState = isUninitialized || isFetching;
const loadingState = isUninitialized || isFetching || !rowsFiltered;
const errorState = isError;
const noMatch = rows.length === 0;
const successState = isSuccess;

useEffect(() => {
setRows(buildRows(workloads));
}, [data]);
setRows(buildFilteredRows(workloads));
//should be refactored to smth like setDisplayedRows(buildDisplayedRows(filteredRows));
//when we add pagination
setRowsFiltered(true);
setFiltersApplied(noFiltersApplied(filters).length > 0 ? true : false);
}, [data, filteredRows]);

useEffect(() => {
setFilteredRows(buildFilteredRows(workloads));
}, [
filters.namespace_name,
filters.cluster_name,
filters.general_severity,
filters.highest_severity,
filters.sortDirection,
filters.sortIndex,
]);

const buildRows = (items) => {
return items.map((item, index) => {
const buildFilteredRows = (items) => {
setRowsFiltered(false);
const filtered = items.filter((workloadData) => {
return passFilterWorkloads(workloadData, filters);
});

return filtered.map((item, index) => {
return {
entity: item,
cells: [
Expand All @@ -67,10 +99,6 @@ const WorkloadsListTable = ({
item.metadata.recommendations,
<span key={index}>
<ShieldSet hits_by_severity={item.metadata.hits_by_severity} />
{/* <HighestSeverityBadge
highestSeverity={item.metadata.highest_severity}
severities={item.metadata.hits_by_severity}
/> */}
</span>,
item.metadata.objects,
<span key={index}>
Expand Down Expand Up @@ -107,29 +135,29 @@ const WorkloadsListTable = ({
},
},
{
label: 'Highest severity',
label: 'Severity',
type: conditionalFilterType.checkbox,
id: WORKLOADS_TABLE_FILTER_CATEGORIES.highest_severity.urlParam,
value: `checkbox-${WORKLOADS_TABLE_FILTER_CATEGORIES.highest_severity.urlParam}`,
id: WORKLOADS_TABLE_FILTER_CATEGORIES.general_severity.urlParam,
value: `checkbox-${WORKLOADS_TABLE_FILTER_CATEGORIES.general_severity.urlParam}`,
filterValues: {
key: `${WORKLOADS_TABLE_FILTER_CATEGORIES.highest_severity.urlParam}-filter`,
key: `${WORKLOADS_TABLE_FILTER_CATEGORIES.general_severity.urlParam}-filter`,
onChange: (_event, value) =>
updateFilters({ ...filters, offset: 0, highest_severity: value }),
value: filters.highest_severity,
items: WORKLOADS_TABLE_FILTER_CATEGORIES.highest_severity.values,
placeholder: 'Filter by highest severity',
addFilterParam(filters, updateFilters, 'general_severity', value),
value: filters.general_severity,
items: WORKLOADS_TABLE_FILTER_CATEGORIES.general_severity.values,
placeholder: 'Filter by severity',
},
},
];

const activeFiltersConfig = {
showDeleteButton: true,
showDeleteButton: filtersApplied ? true : false,
deleteTitle: 'Reset filters',
filters: buildFilterChips(filters, WORKLOADS_TABLE_FILTER_CATEGORIES),
onDelete: (_event, itemsToRemove, isAll) => {
if (isAll) {
if (isEqual(filters, WORKLOADS_TABLE_INITIAL_STATE)) {
console.log('here should be a refetch!');
refetch();
} else {
resetFilters(filters, WORKLOADS_TABLE_INITIAL_STATE, updateFilters);
}
Expand All @@ -144,9 +172,7 @@ const WorkloadsListTable = ({
};
newFilter[item.urlParam].length > 0
? updateFilters({ ...filters, ...newFilter })
: console.log(
'here we should remove the filter parameter from a URL!'
);
: removeFilterParam(item.urlParam);
});
}
},
Expand All @@ -165,7 +191,9 @@ const WorkloadsListTable = ({
ouiaId: 'pager',
}}
filterConfig={{ items: filterConfigItems }}
activeFiltersConfig={activeFiltersConfig}
activeFiltersConfig={
isError ? { showDeleteButton: false } : activeFiltersConfig
}
/>
<Table
aria-label="Table of workloads"
Expand Down
2 changes: 1 addition & 1 deletion src/Services/Filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const WORKLOADS_TABLE_INITIAL_STATE = {
sortDirection: 'desc',
cluster_name: '',
namespace_name: '',
highest_severity: [],
general_severity: [],
};

const filtersInitialState = {
Expand Down
45 changes: 41 additions & 4 deletions src/Utilities/Workloads.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import _, { isEmpty } from 'lodash';

export const SEVERITY_OPTIONS = [
{
value: 'critical',
Expand Down Expand Up @@ -33,7 +35,7 @@ export const SEVERITY_OPTIONS = [
},
];

export const remappingSeverity = (obj) => {
export const remappingSeverity = (obj, mode) => {
const mapping = {
1: 'low',
2: 'moderate',
Expand All @@ -42,10 +44,45 @@ export const remappingSeverity = (obj) => {
};
let updatedObj = {};

for (const key in obj) {
if (key in mapping) {
updatedObj[mapping[key]] = obj[key];
if (mode === 'general' || mode === 'label') {
for (const key in obj) {
if (key in mapping) {
updatedObj[mapping[key]] = obj[key];
}
}
} else {
updatedObj = mapping[obj];
}

return updatedObj;
};

export const hasAnyValueGreaterThanZero = (obj, stringsToCheck) => {
for (const key of stringsToCheck) {
if (obj[key] > 0) {
return true; // Return true if any matching string has a value greater than 0
}
}
};

export const severityTypeToText = (value) => {
value = parseInt(value);
if (value === 1) {
return 'Low';
} else if (value === 2) {
return 'Moderate';
} else if (value === 3) {
return 'Important';
} else {
return 'Critical';
}
};

export const noFiltersApplied = (params) => {
const cleanedUpParams = _.cloneDeep(params);
delete cleanedUpParams.sortIndex;
delete cleanedUpParams.sortDirection;
delete cleanedUpParams.offset;
delete cleanedUpParams.limit;
return Object.values(cleanedUpParams).filter((value) => !isEmpty(value));
Copy link
Contributor

Choose a reason for hiding this comment

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

You could return this instead

Suggested change
return Object.values(cleanedUpParams).filter((value) => !isEmpty(value));
return (
Object.values(cleanedUpParams).filter((value) => !isEmpty(value)).length > 0
);

and then remove the filtersApplied state, since it's not used in any effect.

Used like this: showDeleteButton: noFiltersApplied(filters)

};