Skip to content

Commit

Permalink
HPCC-32118 Default to case-insensitive metric filtering
Browse files Browse the repository at this point in the history
Introduced an option to toggle between case-sensitive and case-insensitive filtering

Signed-off-by: Gordon Smith <[email protected]>
  • Loading branch information
GordonSmith committed Jul 5, 2024
1 parent 9b7612b commit f765e83
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 26 deletions.
57 changes: 34 additions & 23 deletions esp/src/src-react/components/Metrics.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as React from "react";
import { CommandBar, ContextualMenuItemType, ICommandBarItemProps, IIconProps, SearchBox } from "@fluentui/react";
import { Label, Spinner } from "@fluentui/react-components";
import { CommandBar, ContextualMenuItemType, ICommandBarItemProps, IIconProps, SearchBox, Stack } from "@fluentui/react";
import { Label, Spinner, ToggleButton } from "@fluentui/react-components";
import { typographyStyles } from "@fluentui/react-theme";
import { useConst } from "@fluentui/react-hooks";
import { bundleIcon, Folder20Filled, Folder20Regular, FolderOpen20Filled, FolderOpen20Regular, } from "@fluentui/react-icons";
import { bundleIcon, Folder20Filled, Folder20Regular, FolderOpen20Filled, FolderOpen20Regular, TextCaseTitleRegular } from "@fluentui/react-icons";
import { Database } from "@hpcc-js/common";
import { WorkunitsServiceEx, IScope, splitMetric } from "@hpcc-js/comms";
import { DBStore, Table } from "@hpcc-js/dgrid";
Expand Down Expand Up @@ -55,7 +55,7 @@ class TableEx extends Table {
this._store = new DBStoreEx(this, this._db);
}

scopeFilterFunc(row: object, scopeFilter: string): boolean {
scopeFilterFunc(row: object, scopeFilter: string, matchCase: boolean): boolean {
const filter = scopeFilter.trim();
if (filter) {
let field = "";
Expand All @@ -67,8 +67,12 @@ class TableEx extends Table {
return row[field]?.indexOf && row[field]?.indexOf(filter.substring(colonIdx + 1)) >= 0;
}
for (const key in row) {
if (row[key]?.indexOf && row[key]?.indexOf(filter) >= 0) {
return true;
if (row[key]?.indexOf) {
const value = (!matchCase && row[key]?.toLowerCase) ? row[key]?.toLowerCase() : row[key];
const filterValue = (!matchCase && row[key]?.toLowerCase) ? filter.toLowerCase() : filter;
if (value.indexOf(filterValue) >= 0) {
return true;
}
}
}
return false;
Expand All @@ -77,12 +81,12 @@ class TableEx extends Table {
}

_rawDataMap: { [id: number]: string } = {};
metrics(metrics: any[], options: MetricsOptionsT, timelineFilter: string, scopeFilter: string): this {
metrics(metrics: any[], options: MetricsOptionsT, timelineFilter: string, scopeFilter: string, matchCase: boolean): this {
this
.columns(["##"]) // Reset hash to force recalculation of default widths
.columns(["##", nlsHPCC.Type, nlsHPCC.Scope, ...options.properties])
.data(metrics
.filter(m => this.scopeFilterFunc(m, scopeFilter))
.filter(m => this.scopeFilterFunc(m, scopeFilter, matchCase))
.filter(row => {
return (timelineFilter === "" || row.name?.indexOf(timelineFilter) === 0) &&
(options.scopeTypes.indexOf(row.type) >= 0);
Expand Down Expand Up @@ -170,6 +174,7 @@ export const Metrics: React.FunctionComponent<MetricsProps> = ({
const [isLayoutComplete, setIsLayoutComplete] = React.useState<boolean>(false);
const [isRenderComplete, setIsRenderComplete] = React.useState<boolean>(false);
const [dot, setDot] = React.useState<string>("");
const [matchCase, setMatchCase] = React.useState(false);

React.useEffect(() => {
const service = new WorkunitsServiceEx({ baseUrl: "" });
Expand Down Expand Up @@ -258,7 +263,7 @@ export const Metrics: React.FunctionComponent<MetricsProps> = ({

const scopesTable = useConst(() => new TableEx()
.multiSelect(true)
.metrics([], options, timelineFilter, scopeFilter)
.metrics([], options, timelineFilter, scopeFilter, matchCase)
.sortable(true)
.on("click", debounce((row, col, sel) => {
if (sel) {
Expand All @@ -269,10 +274,10 @@ export const Metrics: React.FunctionComponent<MetricsProps> = ({

React.useEffect(() => {
scopesTable
.metrics(metrics, options, timelineFilter, scopeFilter)
.metrics(metrics, options, timelineFilter, scopeFilter, matchCase)
.render()
;
}, [metrics, options, scopeFilter, scopesTable, timelineFilter]);
}, [matchCase, metrics, options, scopeFilter, scopesTable, timelineFilter]);

const updateScopesTable = React.useCallback((selection: IScope[]) => {
if (scopesTable?.renderCount() > 0) {
Expand Down Expand Up @@ -447,13 +452,13 @@ export const Metrics: React.FunctionComponent<MetricsProps> = ({
}, [lineage, selectedLineage]);

// Props Table ---
const propsTable2 = useConst(() => new Table()
const crossTabTable = useConst(() => new Table()
.columns([nlsHPCC.Property, nlsHPCC.Value])
.columnWidth("auto")
.sortable(true)
);

const updatePropsTable2 = React.useCallback((selection: IScope[]) => {
const updateCrossTabTable = React.useCallback((selection: IScope[]) => {
const columns = [];
const props = [];
selection.forEach(item => {
Expand All @@ -470,12 +475,13 @@ export const Metrics: React.FunctionComponent<MetricsProps> = ({
});
props.push(row);
});
propsTable2
?.columns(columns)
?.data(props)
?.lazyRender()
crossTabTable
.columns([])
.columns(columns)
.data(props)
.lazyRender()
;
}, [propsTable2]);
}, [crossTabTable]);

React.useEffect(() => {
const dot = metricGraph.graphTpl(selectedLineage ? [selectedLineage] : [], options);
Expand Down Expand Up @@ -503,7 +509,7 @@ export const Metrics: React.FunctionComponent<MetricsProps> = ({
React.useEffect(() => {
if (selectedMetrics) {
updateScopesTable(selectedMetrics);
updatePropsTable2(selectedMetrics);
updateCrossTabTable(selectedMetrics);
updateLineage(selectedMetrics);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down Expand Up @@ -607,13 +613,13 @@ export const Metrics: React.FunctionComponent<MetricsProps> = ({
const setShowMetricOptionsHook = React.useCallback((show: boolean) => {
setShowMetricOptions(show);
scopesTable
.metrics(metrics, options, timelineFilter, scopeFilter)
.metrics(metrics, options, timelineFilter, scopeFilter, matchCase)
.render(() => {
updateScopesTable(selectedMetrics);
})
;

}, [metrics, options, scopeFilter, scopesTable, selectedMetrics, timelineFilter, updateScopesTable]);
}, [matchCase, metrics, options, scopeFilter, scopesTable, selectedMetrics, timelineFilter, updateScopesTable]);

return <HolyGrail fullscreen={fullscreen}
header={<>
Expand All @@ -625,7 +631,12 @@ export const Metrics: React.FunctionComponent<MetricsProps> = ({
<DockPanel layout={options?.layout} onDockPanelCreate={setDockpanel}>
<DockPanelItem key="scopesTable" title={nlsHPCC.Metrics}>
<HolyGrail
header={<SearchBox value={scopeFilter} onChange={onChangeScopeFilter} iconProps={filterIcon} placeholder={nlsHPCC.Filter} />}
header={<Stack horizontal>
<Stack.Item grow>
<SearchBox value={scopeFilter} onChange={onChangeScopeFilter} iconProps={filterIcon} placeholder={nlsHPCC.Filter} />
</Stack.Item>
<ToggleButton appearance="subtle" icon={<TextCaseTitleRegular />} title={nlsHPCC.MatchCase} checked={matchCase} onClick={() => { setMatchCase(!matchCase); }} />
</Stack>}
main={<AutosizeHpccJSComponent widget={scopesTable} ></AutosizeHpccJSComponent>}
/>
</DockPanelItem>
Expand Down Expand Up @@ -655,7 +666,7 @@ export const Metrics: React.FunctionComponent<MetricsProps> = ({
<MetricsPropertiesTables scopesTableColumns={scopesTable.columns()} scopes={selectedMetrics}></MetricsPropertiesTables>
</DockPanelItem>
<DockPanelItem key="propsTable2" title={nlsHPCC.CrossTab} location="tab-after" relativeTo="propsTable" >
<AutosizeHpccJSComponent widget={propsTable2}></AutosizeHpccJSComponent>
<AutosizeHpccJSComponent widget={crossTabTable}></AutosizeHpccJSComponent>
</DockPanelItem>
</DockPanel>
<MetricsOptions show={showMetricOptions} setShow={setShowMetricOptionsHook} />
Expand Down
7 changes: 4 additions & 3 deletions esp/src/src-react/components/MetricsPropertiesTables.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export const MetricsPropertiesTables: React.FunctionComponent<MetricsPropertiesT
// Props Table ---
const propsTable = useConst(() => new Table()
.columns([nlsHPCC.Property, nlsHPCC.Value, "Avg", "Min", "Max", "Delta", "StdDev", "SkewMin", "SkewMax", "NodeMin", "NodeMax"])
.columnWidth("auto")
.sortable(true)
);

Expand Down Expand Up @@ -53,8 +52,10 @@ export const MetricsPropertiesTables: React.FunctionComponent<MetricsPropertiesT
});

propsTable
?.data(props)
?.lazyRender()
.columns([])
.columns([nlsHPCC.Property, nlsHPCC.Value, "Avg", "Min", "Max", "Delta", "StdDev", "SkewMin", "SkewMax", "NodeMin", "NodeMax"])
.data(props)
.lazyRender()
;
}, [propsTable, scopes, sortByColumns]);

Expand Down
1 change: 1 addition & 0 deletions esp/src/src/nls/hpcc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ export = {
ManualTreeSelection: "(Manual tree selection will be required)",
Mappings: "Mappings",
Mask: "Mask",
MatchCase: "Match Case",
Max: "Max",
MaxConnections: "Max Connections",
MaxNode: "Max Node",
Expand Down

0 comments on commit f765e83

Please sign in to comment.