Skip to content

Commit

Permalink
PMM-11786 Fix for table filter (#630)
Browse files Browse the repository at this point in the history
* fix table filter and values for allcheckstab

* fix clear all

* open collapse when filter is set
  • Loading branch information
filipmikes1 committed Mar 13, 2023
1 parent a65b483 commit 088a114
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 24 deletions.
12 changes: 10 additions & 2 deletions public/app/percona/check/components/AllChecksTab/AllChecksTab.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { LoaderButton, logger } from '@percona/platform-core';
import React, { FC, useCallback, useMemo, useState } from 'react';

import { AppEvents } from '@grafana/data';
import { AppEvents, UrlQueryMap } from '@grafana/data';
import { locationService } from '@grafana/runtime';
import { useStyles2 } from '@grafana/ui';
import appEvents from 'app/core/app_events';
import { OldPage } from 'app/core/components/Page/Page';
import { useQueryParams } from 'app/core/hooks/useQueryParams';
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
import { CheckService } from 'app/percona/check/Check.service';
import { CheckDetails, Interval } from 'app/percona/check/types';
Expand Down Expand Up @@ -36,10 +37,11 @@ export const AllChecksTab: FC<GrafanaRouteComponentProps<{ category: string }>>
const { loading: advisorsPending } = useSelector(getAdvisors);
const categorizedAdvisors = useSelector(getCategorizedAdvisors);
const advisors = categorizedAdvisors[category];
const [queryParams] = useQueryParams();

if (navModel.main.id === 'not-found') {
locationService.push('/advisors');
}

const getCheckNamesListInCategory = () => {
return Object.values(advisors)
.map((advisor) => advisor.checks)
Expand Down Expand Up @@ -166,6 +168,10 @@ export const AllChecksTab: FC<GrafanaRouteComponentProps<{ category: string }>>
// eslint-disable-next-line react-hooks/exhaustive-deps
const featureSelector = useCallback(getPerconaSettingFlag('sttEnabled'), []);

const isFilterSet = (queryParams: UrlQueryMap, advisorName: string) => {
return Object.keys(queryParams).includes(advisorName);
};

return (
<OldPage navModel={navModel} tabsDataTestId="db-check-tabs-bar" data-testid="db-check-panel">
<OldPage.Contents dataTestId="db-check-tab-content">
Expand Down Expand Up @@ -198,13 +204,15 @@ export const AllChecksTab: FC<GrafanaRouteComponentProps<{ category: string }>>
mainLabel={summary}
content={advisors[summary].description}
sideLabel={advisors[summary].comment}
isInitOpen={isFilterSet(queryParams, advisors[summary].name)}
>
<Table
totalItems={advisors[summary].checks.length}
data={advisors[summary].checks}
columns={columns}
pendingRequest={advisorsPending}
emptyMessage={Messages.table.noData}
tableKey={advisors[summary].name}
showFilter
/>
{!!selectedCheck && checkIntervalModalVisible && (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unnecessary-type-assertion */
import { FormApi } from 'final-form';
import { debounce } from 'lodash';
import React, { useEffect, useMemo, useState } from 'react';
Expand All @@ -15,7 +15,7 @@ import { getStyles } from './Filter.styles';
import { FilterProps } from './Filter.types';
import {
buildEmptyValues,
buildObjForQueryParams,
buildParamsFromKey,
buildSearchOptions,
getQueryParams,
isInOptions,
Expand All @@ -27,24 +27,39 @@ import { SearchTextField } from './components/fields/SearchTextField';
import { SelectColumnField } from './components/fields/SelectColumnField';
import { SelectDropdownField } from './components/fields/SelectDropdownField';

export const Filter = ({ columns, rawData, setFilteredData, hasBackendFiltering = false }: FilterProps) => {
export const Filter = ({ columns, rawData, setFilteredData, hasBackendFiltering = false, tableKey }: FilterProps) => {
const [openCollapse, setOpenCollapse] = useState(false);
const [openSearchFields, setOpenSearchFields] = useState(false);
const styles = useStyles2(getStyles);
const [queryParams, setQueryParams] = useQueryParams();

const queryParamsByKey = useMemo(() => {
if (tableKey) {
// eslint-disable-next-line
const params = queryParams[tableKey] as any;

if (params) {
const paramsObj = JSON.parse(params);
return paramsObj;
} else {
return {};
}
}
return queryParams;
}, [queryParams, tableKey]);

const searchColumnsOptions = useMemo(() => buildSearchOptions(columns), [columns]);

const onFormChange = debounce(
(values: Record<string, any>) => setQueryParams(buildObjForQueryParams(columns, values)),
(values: Record<string, any>) => setQueryParams(buildParamsFromKey(tableKey, columns, values)),
DEBOUNCE_DELAY
);
const onSubmit = (values: Record<string, any>) => {
setQueryParams(buildObjForQueryParams(columns, values));
setQueryParams(buildParamsFromKey(tableKey, columns, values));
};

// eslint-disable-next-line react-hooks/exhaustive-deps
const initialValues = useMemo(() => getQueryParams(columns, queryParams), []);
const initialValues = useMemo(() => getQueryParams(columns, queryParamsByKey), []);
const onClearAll = (form: FormApi) => {
form.initialize(buildEmptyValues(columns));
setOpenCollapse(false);
Expand Down Expand Up @@ -72,8 +87,8 @@ export const Filter = ({ columns, rawData, setFilteredData, hasBackendFiltering
}, []);

useEffect(() => {
const queryParamsObj = getQueryParams(columns, queryParams);
if (Object.keys(queryParams).length > 0 && !hasBackendFiltering) {
const queryParamsObj = getQueryParams(columns, queryParamsByKey);
if (Object.keys(queryParamsByKey).length > 0 && !hasBackendFiltering) {
const dataArray = rawData.filter(
(filterValue) =>
isValueInTextColumn(columns, filterValue, queryParamsObj) &&
Expand All @@ -85,7 +100,7 @@ export const Filter = ({ columns, rawData, setFilteredData, hasBackendFiltering
setFilteredData(rawData);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [queryParams, rawData]);
}, [queryParamsByKey, rawData]);

const showAdvanceFilter = useMemo(
() => isOtherThanTextType(columns),
Expand All @@ -100,7 +115,6 @@ export const Filter = ({ columns, rawData, setFilteredData, hasBackendFiltering
render={({ handleSubmit, form }) => (
<form
onSubmit={handleSubmit}
role="form"
onKeyPress={(e) => {
e.key === 'Enter' && e.preventDefault();
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export interface FilterProps {
rawData: Object[];
setFilteredData: (data: Object[]) => void;
hasBackendFiltering: boolean;
tableKey?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,26 @@ export const buildObjForQueryParams = (columns: Array<ExtendedColumn<any>>, valu
}
}
});

return obj;
};

export const buildParamsFromKey = (
tableKey: string | undefined,
columns: Array<ExtendedColumn<any>>,
values: Record<string, any>
) => {
const params = buildObjForQueryParams(columns, values);
if (tableKey) {
const paramsResult = Object.values(params).some((value) => value !== undefined);
if (paramsResult) {
return { [tableKey]: JSON.stringify(params) };
}
return { [tableKey]: undefined };
}
return params;
};

export const buildSearchOptions = (columns: Array<ExtendedColumn<any>>) => {
const searchOptions = columns
.filter((value) => value.type === FilterFieldTypes.TEXT)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { css } from '@emotion/css';
import React, { FC, useMemo, useState } from 'react';
import { useTable, usePagination, useExpanded } from 'react-table';
import { useExpanded, usePagination, useTable } from 'react-table';

import { useStyles } from '@grafana/ui';
import { Overlay } from 'app/percona/shared/components/Elements/Overlay/Overlay';
Expand All @@ -9,7 +9,7 @@ import { Filter } from './Filter/Filter';
import { Pagination } from './Pagination';
import { PAGE_SIZES } from './Pagination/Pagination.constants';
import { getStyles } from './Table.styles';
import { TableProps, PaginatedTableOptions, PaginatedTableState } from './Table.types';
import { PaginatedTableOptions, PaginatedTableState, TableProps } from './Table.types';
import { TableContent } from './TableContent';

const defaultPropGetter = () => ({});
Expand Down Expand Up @@ -37,6 +37,7 @@ export const Table: FC<TableProps> = ({
showFilter = false,
hasBackendFiltering = false,
getRowId,
tableKey,
}) => {
const [filterData, setFilteredData] = useState<Object[]>([]);
const data = useMemo(() => (showFilter ? filterData : rawData), [showFilter, filterData, rawData]);
Expand Down Expand Up @@ -105,6 +106,7 @@ export const Table: FC<TableProps> = ({
rawData={rawData}
setFilteredData={setFilteredData}
hasBackendFiltering={hasBackendFiltering}
tableKey={tableKey}
/>
)}
<div className={style.tableWrap} data-testid="table-outer-wrapper">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import {
Cell,
Column,
TableInstance,
TableState,
ColumnInstance,
HeaderGroup,
Row,
TableOptions,
TableCellProps,
TableHeaderProps,
TableInstance,
TableOptions,
TableRowProps,
TableCellProps,
Cell,
ColumnInstance,
HeaderGroup,
TableState,
} from 'react-table';

import { SelectableValue } from '@grafana/data';
Expand Down Expand Up @@ -63,6 +63,7 @@ export interface TableProps {
getRowId?: (originalRow: any, relativeIndex: number, parent?: Row<any>) => string;
showFilter?: boolean;
hasBackendFiltering?: boolean;
tableKey?: string;
}

export interface PaginatedTableState extends TableState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const CustomCollapsableSection = ({
mainLabel,
content,
sideLabel,
isInitOpen,
}: CustomCollapsableSectionProps) => {
//used to automatically disable collapse when wrapping in UpgradePlanWrapper
const disabled = useContext(IsDisabledContext);
Expand All @@ -30,6 +31,7 @@ export const CustomCollapsableSection = ({
headerCustomClass={styles.collapsableHeader}
headerLabelCustomClass={styles.collapsableHeaderLabel}
disabled={disabled}
isOpen={isInitOpen}
>
{children}
</ControlledCollapse>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export interface CustomCollapsableSectionProps {
mainLabel: string;
content: string;
sideLabel: string;
isInitOpen: boolean;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { UrlQueryMap, UrlQueryValue } from '@grafana/data';

interface QueryParamTransform {
Expand All @@ -17,7 +18,6 @@ export const getValuesFromQueryParams = (queryParams: UrlQueryMap, keys: QueryPa

keys.forEach(({ key, transform = defaultTransform }) => {
const param = queryParams[key];

if (param !== undefined && param !== null) {
result = { ...result, [key]: transform(param) };
}
Expand Down
9 changes: 7 additions & 2 deletions public/app/percona/shared/services/advisors/Advisors.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@ export const groupAdvisorsIntoCategories = (advisors: Advisor[]): CategorizedAdv
const result: CategorizedAdvisor = {};

advisors.forEach((advisor) => {
const { category, summary } = advisor;
const { category, summary, checks } = advisor;

const modifiedChecks = checks.map((check) => ({
...check,
disabled: check.disabled ? true : false,
}));

if (!result[category]) {
result[category] = {};
}

if (!result[category][summary]) {
result[category][summary] = advisor;
result[category][summary] = { ...advisor, checks: [...modifiedChecks] };
}
});
return result;
Expand Down

0 comments on commit 088a114

Please sign in to comment.