Skip to content

Commit 00586ed

Browse files
committed
Merge remote-tracking branch 'origin/candidate-9.2.x' into candidate-9.4.x
Signed-off-by: Gordon Smith <[email protected]> # Conflicts: # helm/hpcc/Chart.yaml # helm/hpcc/templates/_helpers.tpl # version.cmake
2 parents 6a70854 + b2c9fae commit 00586ed

13 files changed

+192
-119
lines changed

esp/src/eclwatch/LFDetailsWidget.js

-10
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ define([
7171
contentWidget: null,
7272
dataPatternsWidget: null,
7373
sourceWidget: null,
74-
defWidget: null,
7574
xmlWidget: null,
7675
filePartsWidget: null,
7776
queriesWidget: null,
@@ -95,7 +94,6 @@ define([
9594
this.contentWidget = registry.byId(this.id + "_Content");
9695
this.dataPatternsWidget = registry.byId(this.id + "_DataPatterns");
9796
this.sourceWidget = registry.byId(this.id + "_Source");
98-
this.defWidget = registry.byId(this.id + "_DEF");
9997
this.xmlWidget = registry.byId(this.id + "_XML");
10098
this.filePartsWidget = registry.byId(this.id + "_FileParts");
10199
this.queriesWidget = registry.byId(this.id + "_Queries");
@@ -306,13 +304,6 @@ define([
306304
this.sourceWidget.init({
307305
ECL: this.logicalFile.Ecl
308306
});
309-
} else if (currSel.id === this.defWidget.id) {
310-
var context = this;
311-
this.logicalFile.fetchDEF(function (response) {
312-
context.defWidget.init({
313-
ECL: response
314-
});
315-
});
316307
} else if (currSel.id === this.xmlWidget.id) {
317308
var context = this;
318309
this.logicalFile.fetchXML(function (response) {
@@ -403,7 +394,6 @@ define([
403394
}
404395
this.contentWidget.reset();
405396
this.sourceWidget.reset();
406-
this.defWidget.reset();
407397
this.xmlWidget.reset();
408398
this.filePartsWidget.reset();
409399
this.widget._Queries.reset();

esp/src/eclwatch/templates/LFDetailsWidget.html

-2
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,6 @@ <h2>
246246
</div>
247247
<div id="${id}_Source" title="${i18n.ECL}" data-dojo-props="delayWidget: 'ECLSourceWidget', disabled: true" data-dojo-type="DelayLoadWidget">
248248
</div>
249-
<div id="${id}_DEF" title="${i18n.DEF}" data-dojo-props="delayWidget: 'ECLSourceWidget', disabled: true" data-dojo-type="DelayLoadWidget">
250-
</div>
251249
<div id="${id}_XML" title="${i18n.XML}" data-dojo-props="delayProps: {WUXml: true}, delayWidget: 'ECLSourceWidget', disabled: true" data-dojo-type="DelayLoadWidget">
252250
</div>
253251
<div id="${id}_FileBelongs" title="${i18n.Superfiles}" data-dojo-props="delayWidget: 'FileBelongsToWidget', disabled: true" data-dojo-type="DelayLoadWidget">

esp/src/package-lock.json

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

esp/src/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"@hpcc-js/chart": "2.86.0",
4848
"@hpcc-js/codemirror": "2.65.0",
4949
"@hpcc-js/common": "2.73.0",
50-
"@hpcc-js/comms": "2.99.0",
50+
"@hpcc-js/comms": "2.99.1",
5151
"@hpcc-js/dataflow": "8.1.7",
5252
"@hpcc-js/eclwatch": "2.76.1",
5353
"@hpcc-js/graph": "2.87.0",

esp/src/src-react/components/ECLArchiveTree.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from "react";
22
import { FlatTree, useHeadlessFlatTree_unstable, HeadlessFlatTreeItemProps, TreeItem, TreeItemLayout, CounterBadge } from "@fluentui/react-components";
33
import { FluentIconsProps, FolderOpen20Regular, Folder20Regular, FolderOpen20Filled, Folder20Filled, Document20Regular, Document20Filled, Important16Regular } from "@fluentui/react-icons";
4-
import { Archive, isAttribute } from "../util/metricArchive";
4+
import { Archive, isAttribute, UNNAMED_QUERY } from "../util/metricArchive";
55

66
type FlatItem = HeadlessFlatTreeItemProps & { fileTimePct?: number, content: string };
77

@@ -57,6 +57,9 @@ export const ECLArchiveTree: React.FunctionComponent<ECLArchiveTreeProps> = ({
5757
fileTimePct: isAttribute(modAttr) && Math.round((archive?.sourcePathTime(modAttr.sourcePath) / archive?.timeTotalExecute) * 100),
5858
});
5959
});
60+
if (archive?.query.content) {
61+
flatTreeItems.push({ value: UNNAMED_QUERY, parentValue: undefined, content: UNNAMED_QUERY });
62+
}
6063
setFlatTreeItems(flatTreeItems.sort((a, b) => a.value.toString().localeCompare(b.value.toString(), undefined, { sensitivity: "base" })));
6164
}, [archive, archive?.modAttrs, archive?.timeTotalExecute]);
6265

@@ -65,6 +68,8 @@ export const ECLArchiveTree: React.FunctionComponent<ECLArchiveTreeProps> = ({
6568
const modAttr = archive?.modAttrs.find(modAttr => modAttr.id === attrId);
6669
if (modAttr?.type === "Attribute") {
6770
setSelectedItem(attrId, archive.metricIDs(attrId));
71+
} else if (attrId === UNNAMED_QUERY) {
72+
setSelectedItem(attrId, []);
6873
}
6974
}, [archive, setSelectedItem]);
7075

esp/src/src-react/components/FileDetails.tsx

-7
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ export const FileDetails: React.FunctionComponent<FileDetailsProps> = ({
4848
replaceUrl(`/files/${file.NodeGroup}/${logicalFile}`);
4949
}
5050
}, [cluster, file?.NodeGroup, file?.isSuperfile, logicalFile]);
51-
const [defFile] = useDefFile(cluster, logicalFile, WsDfu.DFUDefFileFormat.def);
5251
const [xmlFile] = useDefFile(cluster, logicalFile, WsDfu.DFUDefFileFormat.xml);
5352

5453
const onTabSelect = React.useCallback((tab: TabInfo) => {
@@ -69,9 +68,6 @@ export const FileDetails: React.FunctionComponent<FileDetailsProps> = ({
6968
}, {
7069
id: "ecl",
7170
label: nlsHPCC.ECL,
72-
}, {
73-
id: "def",
74-
label: nlsHPCC.DEF,
7571
}, {
7672
id: "xml",
7773
label: nlsHPCC.XML,
@@ -130,9 +126,6 @@ export const FileDetails: React.FunctionComponent<FileDetailsProps> = ({
130126
<DelayLoadedPanel visible={tab === "ecl"} size={size}>
131127
<SourceEditor text={file?.Ecl} mode="ecl" readonly={true} />
132128
</DelayLoadedPanel>
133-
<DelayLoadedPanel visible={tab === "def"} size={size}>
134-
<XMLSourceEditor text={defFile} readonly={true} />
135-
</DelayLoadedPanel>
136129
<DelayLoadedPanel visible={tab === "xml"} size={size}>
137130
<XMLSourceEditor text={xmlFile} readonly={true} />
138131
</DelayLoadedPanel>

esp/src/src-react/components/MetricsPropertiesTables.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import * as React from "react";
22
import { useConst } from "@fluentui/react-hooks";
33
import { Palette } from "@hpcc-js/common";
4-
import { IScope } from "@hpcc-js/comms";
54
import { ColumnFormat, Table } from "@hpcc-js/dgrid";
65
import { formatDecimal } from "src/Utility";
6+
import { formatTwoDigits } from "src/Session";
77
import nlsHPCC from "src/nlsHPCC";
8+
import { IScopeEx } from "../hooks/metrics";
89
import { AutosizeHpccJSComponent } from "../layouts/HpccJSAdapter";
910

1011
Palette.rainbow("StdDevs", ["white", "white", "#fff0f0", "#ffC0C0", "#ff8080", "#ff0000", "#ff0000"]);
1112

1213
export interface MetricsPropertiesTablesProps {
1314
scopesTableColumns?: string[];
14-
scopes?: IScope[];
15+
scopes?: IScopeEx[];
1516
}
1617

1718
export const MetricsPropertiesTables: React.FunctionComponent<MetricsPropertiesTablesProps> = ({
@@ -44,6 +45,9 @@ export const MetricsPropertiesTables: React.FunctionComponent<MetricsPropertiesT
4445
const props = [];
4546
scopes.forEach((item, idx) => {
4647
const scopeProps = [];
48+
for (const exception of item.__exceptions ?? []) {
49+
scopeProps.push([exception.Severity, exception.Message, `${formatTwoDigits(+exception.Priority / 1000)}s`, "", "", "", "", "", "", "", "", 6]);
50+
}
4751
for (const key in item.__groupedProps) {
4852
const row = item.__groupedProps[key];
4953
scopeProps.push([row.Key, row.Value, row.Avg, row.Min, row.Max, row.Delta, row.StdDev === undefined ? "" : `${row.StdDev} (${formatDecimal(row.StdDevs)}σ)`, row.SkewMin, row.SkewMax, row.NodeMin, row.NodeMax, row.StdDevs]);

esp/src/src-react/components/MetricsScopes.tsx

+6-4
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,16 @@ export class ScopesTable extends Table {
4141
field = filter.substring(0, colonIdx);
4242
}
4343
if (field) {
44-
const value: string = !matchCase ? row[field]?.toString().toLowerCase() : row[field]?.toString();
44+
const rawValue: string = !matchCase ? row[field]?.toString().toLowerCase() : row[field]?.toString();
45+
const formattedValue: string = !matchCase ? row.__formattedProps[field]?.toString().toLowerCase() : row.__formattedProps[field]?.toString();
4546
const filterValue: string = !matchCase ? filter.toLowerCase() : filter;
46-
return value?.indexOf(filterValue.substring(colonIdx + 1)) >= 0 ?? false;
47+
return (rawValue?.indexOf(filterValue.substring(colonIdx + 1)) >= 0 || formattedValue?.indexOf(filterValue.substring(colonIdx + 1)) >= 0) ?? false;
4748
}
4849
for (const field in row) {
49-
const value: string = !matchCase ? row[field].toString().toLowerCase() : row[field].toString();
50+
const rawValue: string = !matchCase ? row[field]?.toString().toLowerCase() : row[field]?.toString();
51+
const formattedValue: string = !matchCase ? row.__formattedProps[field]?.toString().toLowerCase() : row.__formattedProps[field]?.toString();
5052
const filterValue: string = !matchCase ? filter.toLowerCase() : filter;
51-
return value?.indexOf(filterValue) >= 0 ?? false;
53+
return (rawValue?.indexOf(filterValue) >= 0 || formattedValue?.indexOf(filterValue) >= 0) ?? false;
5254
}
5355
return false;
5456
}

esp/src/src-react/components/controls/Grid.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ const gridStyles = (height: string): Partial<IDetailsListStyles> => {
123123
selectors: {
124124
".ms-DetailsHeader-cellName": { fontSize: "13.5px" },
125125
".ms-DetailsRow": { userSelect: "text", borderBottom: "1px solid var(--colorNeutralBackground5)" },
126+
".ms-DetailsRow-cell": { borderRight: "1px solid var(--colorNeutralBackground5)" },
126127
".ms-DetailsRow-cell:has(.bgFilled)": { color: "white", boxShadow: "inset 1px 0 var(--colorNeutralBackground1), inset -1px 1px var(--colorNeutralBackground1)" },
127128
".ms-DetailsRow-cell:has(.bgGreen)": { background: "green" },
128129
".ms-DetailsRow-cell:has(.bgOrange)": { background: "orange" },

esp/src/src-react/hooks/metrics.ts

+53-31
Original file line numberDiff line numberDiff line change
@@ -263,14 +263,18 @@ export interface useMetricsResult {
263263
refresh: () => void;
264264
}
265265

266+
export interface IScopeEx extends IScope {
267+
__exceptions?: WsWorkunits.ECLException[],
268+
}
269+
266270
export function useWorkunitMetrics(
267271
wuid: string,
268272
scopeFilter: Partial<WsWorkunits.ScopeFilter> = scopeFilterDefault,
269273
nestedFilter: WsWorkunits.NestedFilter = nestedFilterDefault
270274
): useMetricsResult {
271275

272276
const [workunit, state] = useWorkunit(wuid);
273-
const [data, setData] = React.useState<IScope[]>([]);
277+
const [data, setData] = React.useState<IScopeEx[]>([]);
274278
const [columns, setColumns] = React.useState<{ [id: string]: any }>([]);
275279
const [activities, setActivities] = React.useState<WsWorkunits.Activity2[]>([]);
276280
const [properties, setProperties] = React.useState<WsWorkunits.Property2[]>([]);
@@ -281,40 +285,58 @@ export function useWorkunitMetrics(
281285

282286
React.useEffect(() => {
283287
if (wuid && workunit) {
288+
const fetchInfo = singletonDebounce(workunit, "fetchInfo");
284289
const fetchDetailsNormalized = singletonDebounce(workunit, "fetchDetailsNormalized");
285290
setStatus(FetchStatus.STARTED);
286-
fetchDetailsNormalized({
287-
ScopeFilter: scopeFilter,
288-
NestedFilter: nestedFilter,
289-
PropertiesToReturn: {
290-
AllScopes: true,
291-
AllAttributes: true,
292-
AllProperties: true,
293-
AllNotes: true,
294-
AllStatistics: true,
295-
AllHints: true
296-
},
297-
ScopeOptions: {
298-
IncludeId: true,
299-
IncludeScope: true,
300-
IncludeScopeType: true,
301-
IncludeMatchedScopesInResults: true
302-
},
303-
PropertyOptions: {
304-
IncludeName: true,
305-
IncludeRawValue: true,
306-
IncludeFormatted: true,
307-
IncludeMeasure: true,
308-
IncludeCreator: false,
309-
IncludeCreatorType: false
291+
Promise.all([
292+
fetchInfo({ IncludeExceptions: true }),
293+
fetchDetailsNormalized({
294+
ScopeFilter: scopeFilter,
295+
NestedFilter: nestedFilter,
296+
PropertiesToReturn: {
297+
AllScopes: true,
298+
AllAttributes: true,
299+
AllProperties: true,
300+
AllNotes: true,
301+
AllStatistics: true,
302+
AllHints: true
303+
},
304+
ScopeOptions: {
305+
IncludeId: true,
306+
IncludeScope: true,
307+
IncludeScopeType: true,
308+
IncludeMatchedScopesInResults: true
309+
},
310+
PropertyOptions: {
311+
IncludeName: true,
312+
IncludeRawValue: true,
313+
IncludeFormatted: true,
314+
IncludeMeasure: true,
315+
IncludeCreator: false,
316+
IncludeCreatorType: false
317+
}
318+
})
319+
]).then(([info, response]) => {
320+
const exceptionsMap: { [scope: string]: WsWorkunits.ECLException[] } = {};
321+
for (const exception of info?.Workunit?.Exceptions?.ECLException ?? []) {
322+
if (exception.Scope) {
323+
if (!exceptionsMap[exception.Scope]) {
324+
exceptionsMap[exception.Scope] = [];
325+
}
326+
exceptionsMap[exception.Scope].push(exception);
327+
}
310328
}
311-
}).then(response => {
312-
setData(response?.data);
329+
setData(response?.data.map(row => {
330+
if (exceptionsMap[row.name]) {
331+
row.__exceptions = exceptionsMap[row.name];
332+
}
333+
return row;
334+
}));
313335
setColumns(response?.columns);
314-
setActivities(response?.meta?.Activities?.Activity || []);
315-
setProperties(response?.meta?.Properties?.Property || []);
316-
setMeasures(response?.meta?.Measures?.Measure || []);
317-
setScopeTypes(response?.meta?.ScopeTypes?.ScopeType || []);
336+
setActivities(response?.meta?.Activities?.Activity ?? []);
337+
setProperties(response?.meta?.Properties?.Property ?? []);
338+
setMeasures(response?.meta?.Measures?.Measure ?? []);
339+
setScopeTypes(response?.meta?.ScopeTypes?.ScopeType ?? []);
318340
}).catch(e => {
319341
logger.error(e);
320342
}).finally(() => {

esp/src/src-react/util/metricArchive.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { IScope } from "@hpcc-js/comms";
22
import { XMLNode, xml2json } from "@hpcc-js/util";
33
import nlsHPCC from "src/nlsHPCC";
44

5+
export const UNNAMED_QUERY = "<unnamed query>";
6+
57
export class Archive {
68
build: string = "";
79
eclVersion: string = "";
@@ -125,7 +127,7 @@ export class Archive {
125127
}
126128

127129
content(attrId: string) {
128-
const attr = this.attribute(attrId);
130+
const attr = attrId === UNNAMED_QUERY ? this.query : this.attribute(attrId);
129131
return attr?.content ?? "";
130132
}
131133

0 commit comments

Comments
 (0)