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

Toggle all params and all metrics on ManageColumnsPopover #105

2 changes: 1 addition & 1 deletion src/src/components/ChartPanel/ChartPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ const ChartPanel = React.forwardRef(function ChartPanel(
tooltipContent={props?.tooltip?.content || {}}
tooltipAppearance={props?.tooltip?.appearance}
focusedState={props.focusedState}
alignmentConfig={props.alignmentConfigs![0]}
alignmentConfig={props.alignmentConfigs?.[0]}
selectOptions={props.selectOptions}
onChangeTooltip={props.onChangeTooltip}
/>
Expand Down
4 changes: 4 additions & 0 deletions src/src/config/enums/tableEnums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,9 @@ enum HideColumnsEnum {
HideSystemMetrics = 'Hide System Metrics',
ShowSystemMetrics = 'Show System Metrics',
All = 'All',
HideMetrics = 'Hide Metrics',
ShowMetrics = 'Show Metrics',
HideParams = 'Hide Params',
ShowParams = 'Show Params',
}
export { RowHeightEnum, HideRowsEnum, ResizeModeEnum, HideColumnsEnum };
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function HideColumnsPopover({
}}
anchor={({ onAnchorClick, opened }) => (
<Tooltip
title='Toggle hiding unselected columns by default'
title='Improve table performance by automatically hiding unselected columns'
jescalada marked this conversation as resolved.
Show resolved Hide resolved
placement='top'
>
<div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable react-hooks/exhaustive-deps */
import React from 'react';
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
import { List, AutoSizer } from 'react-virtualized';
import _ from 'lodash-es';

import { Divider, InputBase } from '@material-ui/core';
Expand Down Expand Up @@ -54,6 +55,8 @@ function ManageColumnsPopover({
const [popoverWidth, setPopoverWidth] = React.useState(800);
const ref = React.useRef<HTMLDivElement | null>(null);

const VIRTUAL_COLUMN_THRESHOLD = 100; // If exceeded, use virtualized list

const onResize = _.debounce(() => {
onPopoverWidthChange();
}, 500);
Expand Down Expand Up @@ -245,6 +248,33 @@ function ManageColumnsPopover({
);
}, [appName, hiddenColumns, state]);

function generateRowRenderer(columnList: ITableColumn[]) {
const rowRenderer = ({ index, key }: { index: number; key: string }) => {
const column = columnList[index];
return (
<ColumnItem
key={`${column.key}-${index}`}
data={column.key}
label={column.label ?? column.key}
index={index}
popoverWidth={popoverWidth}
appName={appName}
isHidden={isColumnHidden(column.key)}
onClick={() => {
toggleSoftHidden(column.key);
onColumnsVisibilityChange(
hiddenColumns?.includes(column.key)
? hiddenColumns?.filter((col: string) => col !== column.key)
: hiddenColumns?.concat([column.key]),
);
}}
draggingItemId={draggingItemId}
/>
);
};
return rowRenderer;
}

return (
<ErrorBoundary>
<ControlPopover
Expand Down Expand Up @@ -344,31 +374,48 @@ function ManageColumnsPopover({
ref={provided.innerRef}
{...provided.droppableProps}
>
{state.columns.middle.list.map(
(column: ITableColumn, index: number) => (
<ColumnItem
key={`${column.key}-${index}`}
data={column.key}
label={column.label ?? column.key}
index={index}
appName={appName}
popoverWidth={popoverWidth}
hasSearchableItems
searchKey={searchKey}
isHidden={isColumnHidden(column.key)}
onClick={() => {
toggleSoftHidden(column.key);
onColumnsVisibilityChange(
hiddenColumns?.includes(column.key)
? hiddenColumns?.filter(
(col: string) => col !== column.key,
)
: hiddenColumns?.concat([column.key]),
);
}}
draggingItemId={draggingItemId}
/>
),
{state.columns.middle.list.length <
VIRTUAL_COLUMN_THRESHOLD ? (
state.columns.middle.list.map(
(column: ITableColumn, index: number) => (
<ColumnItem
key={`${column.key}-${index}`}
data={column.key}
label={column.label ?? column.key}
index={index}
appName={appName}
popoverWidth={popoverWidth}
hasSearchableItems
searchKey={searchKey}
isHidden={isColumnHidden(column.key)}
onClick={() => {
toggleSoftHidden(column.key);
onColumnsVisibilityChange(
hiddenColumns?.includes(column.key)
? hiddenColumns?.filter(
(col: string) => col !== column.key,
)
: hiddenColumns?.concat([column.key]),
);
}}
draggingItemId={draggingItemId}
/>
),
)
) : (
<AutoSizer>
{({ height, width }) => (
<List
height={height}
rowCount={state.columns.middle.list.length}
rowHeight={30}
width={width}
rowRenderer={generateRowRenderer(
state.columns.middle.list,
)}
/>
)}
</AutoSizer>
)}
{provided.placeholder}
</div>
Expand Down Expand Up @@ -470,7 +517,56 @@ function ManageColumnsPopover({
/>
</>
)}
<Button
variant='text'
size='xSmall'
onClick={() =>
onColumnsVisibilityChange(HideColumnsEnum.ShowParams)
}
>
<Icon name='eye-show-outline' color='#1473e6' />
<Text size={12} tint={100}>
{HideColumnsEnum.ShowParams}
</Text>
</Button>

<Button
variant='text'
size='xSmall'
onClick={() => {
onColumnsVisibilityChange(HideColumnsEnum.HideParams);
}}
>
<Icon name='eye-outline-hide' />
<Text size={12} tint={100}>
{HideColumnsEnum.HideParams}
</Text>
</Button>
<Button
variant='text'
size='xSmall'
onClick={() => {
onColumnsVisibilityChange(HideColumnsEnum.ShowMetrics);
}}
>
<Icon name='eye-show-outline' color='#1473e6' />
<Text size={12} tint={100}>
{HideColumnsEnum.ShowMetrics}
</Text>
</Button>

<Button
variant='text'
size='xSmall'
onClick={() => {
onColumnsVisibilityChange(HideColumnsEnum.HideMetrics);
}}
>
<Icon name='eye-outline-hide' />
<Text size={12} tint={100}>
{HideColumnsEnum.HideMetrics}
</Text>
</Button>
<Button
variant='text'
size='xSmall'
Expand Down
1 change: 1 addition & 0 deletions src/src/types/services/models/model.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface State {
params?: Record<string, any>;
sameValueColumns?: string[];
selectedRows?: any;
sortOptions?: Record<string, any>;
tooltip?: ITooltip;
selectFormData?: any;
}
Expand Down
65 changes: 55 additions & 10 deletions src/src/utils/app/onColumnsVisibilityChange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import { AVOID_COLUMNS_TO_HIDE_LIST } from 'config/table/tableConfigs';
import * as analytics from 'services/analytics';

import { IModel, State } from 'types/services/models/model';
import { IAppModelConfig } from 'types/services/models/explorer/createAppModel';
import {
IAppModelConfig,
ISelectOption,
} from 'types/services/models/explorer/createAppModel';
import { ITableColumn } from 'types/pages/metrics/components/TableColumns/TableColumns';

import { encode } from 'utils/encoder/encoder';
Expand All @@ -30,11 +33,14 @@ export default function onColumnsVisibilityChange<M extends State>({
shouldURLUpdate?: boolean,
) => void;
}): void {
const configData = model.getState()?.config;
const columnsData = model.getState()!.tableColumns!;
const modelState = model.getState();
const configData = modelState?.config;
const columnsData = modelState!.tableColumns!;
const systemMetrics: string[] = getSystemMetricsFromColumns(
columnsData as ITableColumn[],
);
let params: ISelectOption[] = [];
let metrics: ISelectOption[] = [];

let columnKeys: string[] = Array.isArray(hiddenColumns)
? [...hiddenColumns]
Expand All @@ -58,13 +64,52 @@ export default function onColumnsVisibilityChange<M extends State>({
hideSystemMetrics =
getFilteredSystemMetrics(columnKeys).length === systemMetrics.length;
}
columnKeys =
hiddenColumns === HideColumnsEnum.All
? columnsData.map(
(col) => !AVOID_COLUMNS_TO_HIDE_LIST.has(col.key) && col.key,
)
: columnKeys;

switch (hiddenColumns) {
case HideColumnsEnum.All:
columnKeys = columnsData.map((col) => {
if (!AVOID_COLUMNS_TO_HIDE_LIST.has(col.key)) {
return col.label ?? col.key;
}
return false;
});
break;
case HideColumnsEnum.HideMetrics:
metrics = modelState.sortOptions?.filter((option: ISelectOption) => {
return option.group === 'metrics';
});
// Set columnkeys to all metrics plus the already hidden columns from config.table.hiddencolumns
columnKeys = _.uniq([
...configData?.table.hiddenColumns,
...metrics.map((metric: ISelectOption) => metric.label),
]);
break;
case HideColumnsEnum.ShowMetrics:
columnKeys = configData?.table.hiddenColumns.filter((col: string) => {
return !modelState.sortOptions?.some(
(option: ISelectOption) => option.label === col,
);
});
break;
case HideColumnsEnum.HideParams:
params = modelState.sortOptions?.filter((option: any) => {
return option.group === 'run' && option.value?.includes('params');
});
columnKeys = _.uniq([
...configData?.table.hiddenColumns,
...params.map((param: ISelectOption) => param.label.split('.')[1]),
]);
break;
case HideColumnsEnum.ShowParams:
params = modelState.sortOptions?.filter((option: any) => {
return option.group === 'run' && option.value?.includes('params');
});
columnKeys = configData?.table.hiddenColumns.filter((col: string) => {
return !params.some(
(param: ISelectOption) => param.label.split('.')[1] === col,
);
});
break;
}
const table = {
...configData.table,
hiddenColumns: columnKeys,
Expand Down
Loading