querysub 0.399.0 → 0.401.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/0-path-value-core/PathValueController.ts +0 -3
- package/src/0-path-value-core/pathValueCore.ts +1 -7
- package/src/diagnostics/logs/errorNotifications2/ErrorNotificationPage.tsx +1 -1
- package/src/diagnostics/logs/lifeCycleAnalysis/LifeCycleEntryEditor.tsx +1 -1
- package/src/diagnostics/logs/lifeCycleAnalysis/LifeCycleInstanceTableView.tsx +62 -0
- package/src/diagnostics/logs/lifeCycleAnalysis/LifeCyclePage.tsx +9 -5
- package/src/diagnostics/logs/lifeCycleAnalysis/LifeCycleRenderer.tsx +33 -14
- package/src/diagnostics/logs/lifeCycleAnalysis/lifeCycleSearch.tsx +7 -1
package/package.json
CHANGED
|
@@ -87,9 +87,6 @@ class PathValueControllerBase {
|
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
console.info("Received PathValues via forwardWrites", { valueCount: values.length, callerId, });
|
|
90
|
-
for (let value of values) {
|
|
91
|
-
console.info("Received PathValue for path", { path: value.path, time: value.time.time, callerId });
|
|
92
|
-
}
|
|
93
90
|
|
|
94
91
|
if (isCoreQuiet) {
|
|
95
92
|
await pathValueCommitter.ingestRemoteValues({
|
|
@@ -1567,11 +1567,6 @@ class PathWatcher {
|
|
|
1567
1567
|
callback(changes, parentPaths ?? []);
|
|
1568
1568
|
}
|
|
1569
1569
|
} else {
|
|
1570
|
-
if (isDiskAudit()) {
|
|
1571
|
-
for (let change of changes) {
|
|
1572
|
-
auditLog("non-local TRIGGER", { path: change.path, time: change.time.time, watcher });
|
|
1573
|
-
}
|
|
1574
|
-
}
|
|
1575
1570
|
if (!isCoreQuiet) {
|
|
1576
1571
|
console.log(`(${Date.now()}) Sending values to client: ${changes.length} (${watcher})`);
|
|
1577
1572
|
}
|
|
@@ -1584,9 +1579,8 @@ class PathWatcher {
|
|
|
1584
1579
|
stripSource: !allowSource,
|
|
1585
1580
|
});
|
|
1586
1581
|
|
|
1587
|
-
if (
|
|
1582
|
+
if (isDiskAudit()) {
|
|
1588
1583
|
for (let pathValue of changes) {
|
|
1589
|
-
|
|
1590
1584
|
auditLog("SEND VALUE", { path: pathValue.path, time: pathValue.time.time, watcher, nodeId: debugNodeId(watcher), transparent: pathValue.isTransparent, canGC: pathValue.canGCValue });
|
|
1591
1585
|
}
|
|
1592
1586
|
}
|
|
@@ -426,7 +426,7 @@ class SuppressionItem extends qreact.Component<{
|
|
|
426
426
|
<Button
|
|
427
427
|
hue={0}
|
|
428
428
|
onClick={() => {
|
|
429
|
-
if (!confirm(`Delete this suppression?`)) return;
|
|
429
|
+
if (!confirm(`Delete this suppression "${suppression.pattern}"?`)) return;
|
|
430
430
|
|
|
431
431
|
Querysub.onCommitFinished(async () => {
|
|
432
432
|
await this.manager.deleteSuppression(suppression.id);
|
|
@@ -57,7 +57,7 @@ export class LifeCycleEntryEditor extends qreact.Component<{
|
|
|
57
57
|
<Button
|
|
58
58
|
hue={0}
|
|
59
59
|
onClick={() => {
|
|
60
|
-
if (!confirm(
|
|
60
|
+
if (!confirm(`Delete this entry "${entry.matchPattern}"?`)) return;
|
|
61
61
|
|
|
62
62
|
let updatedLifeCycle = deepCloneJSON(lifeCycle);
|
|
63
63
|
updatedLifeCycle.entries.splice(entryIndex, 1);
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { qreact } from "../../../4-dom/qreact";
|
|
2
|
+
import { Table } from "../../../5-diagnostics/Table";
|
|
3
|
+
import { formatValue } from "../../../5-diagnostics/GenericFormat";
|
|
4
|
+
import { LifeCycle, getVariables } from "./lifeCycles";
|
|
5
|
+
import { LifecycleInstance } from "./lifeCycleSearch";
|
|
6
|
+
|
|
7
|
+
export class LifeCycleInstanceTableView extends qreact.Component<{
|
|
8
|
+
lifeCycle: LifeCycle;
|
|
9
|
+
instance: LifecycleInstance;
|
|
10
|
+
}> {
|
|
11
|
+
render() {
|
|
12
|
+
let { lifeCycle, instance } = this.props;
|
|
13
|
+
|
|
14
|
+
let columnKeyToTitle = new Map<string, string>();
|
|
15
|
+
let allColumnKeys = new Set<string>();
|
|
16
|
+
|
|
17
|
+
for (let entryData of instance.entries) {
|
|
18
|
+
let entry = lifeCycle.entries.find(e => e.matchPattern === entryData.matchPattern);
|
|
19
|
+
if (!entry) continue;
|
|
20
|
+
|
|
21
|
+
// ONLY variables, as the group by values will be the same for all entries in this instance!
|
|
22
|
+
for (let [key, value] of Object.entries(entry.variables)) {
|
|
23
|
+
let title = value.title || key;
|
|
24
|
+
allColumnKeys.add(key);
|
|
25
|
+
if (!columnKeyToTitle.has(key)) {
|
|
26
|
+
columnKeyToTitle.set(key, title);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let rows = instance.entries.map((entryData) => {
|
|
32
|
+
let entry = lifeCycle.entries.find(e => e.matchPattern === entryData.matchPattern);
|
|
33
|
+
let entryTitle = entry && (entry.description || entry.matchPattern) || entryData.matchPattern;
|
|
34
|
+
|
|
35
|
+
let row: { entryTitle: string;[key: string]: unknown } = {
|
|
36
|
+
entryTitle: entryTitle,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
if (entry) {
|
|
40
|
+
let variables = getVariables(entry);
|
|
41
|
+
for (let variable of variables) {
|
|
42
|
+
row[variable.key] = entryData.datum[variable.key];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return row;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
let columns: any = {
|
|
50
|
+
entryTitle: { title: "Entry" },
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
for (let columnKey of allColumnKeys) {
|
|
54
|
+
columns[columnKey] = {
|
|
55
|
+
title: columnKeyToTitle.get(columnKey) || columnKey,
|
|
56
|
+
formatter: (value: unknown) => formatValue(value),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return <Table rows={rows} columns={columns} />;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { qreact } from "../../../4-dom/qreact";
|
|
2
2
|
import { t } from "../../../2-proxy/schema2";
|
|
3
3
|
import { css } from "typesafecss";
|
|
4
|
-
import { deepCloneJSON, nextId } from "socket-function/src/misc";
|
|
4
|
+
import { deepCloneJSON, nextId, sort } from "socket-function/src/misc";
|
|
5
5
|
import { Querysub } from "../../../4-querysub/QuerysubController";
|
|
6
6
|
import { InputLabel } from "../../../library-components/InputLabel";
|
|
7
7
|
import { Button } from "../../../library-components/Button";
|
|
@@ -32,6 +32,7 @@ import { isPublic } from "../../../config";
|
|
|
32
32
|
export let lifecycleIdURL = new URLParam("lifecycleid", "");
|
|
33
33
|
export let limitURL = new URLParam("lifecyclelimit", 16);
|
|
34
34
|
export let additionalSearchURL = new URLParam("lifecyclesearch", "");
|
|
35
|
+
export let lifecycleTableViewURL = new URLParam("lifecycletable", false);
|
|
35
36
|
|
|
36
37
|
export class LifeCyclePage extends qreact.Component {
|
|
37
38
|
controller = LifeCyclesController(SocketFunction.browserNodeId());
|
|
@@ -69,9 +70,10 @@ export class LifeCyclePage extends qreact.Component {
|
|
|
69
70
|
<div>Loading...</div>
|
|
70
71
|
</div>;
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
+
lifeCycles = deepCloneJSON(lifeCycles);
|
|
74
|
+
sort(lifeCycles, x => -x.id.split("_")[0]);
|
|
73
75
|
|
|
74
|
-
let filteredLifeCycles =
|
|
76
|
+
let filteredLifeCycles = lifeCycles.filter(x =>
|
|
75
77
|
matchFilter({ value: this.state.filterText }, JSON.stringify(x))
|
|
76
78
|
);
|
|
77
79
|
|
|
@@ -83,6 +85,7 @@ export class LifeCyclePage extends qreact.Component {
|
|
|
83
85
|
filteredLifeCycles = filteredLifeCycles.filter(lc => lc.id === this.state.searchingLifeCycleId);
|
|
84
86
|
}
|
|
85
87
|
|
|
88
|
+
|
|
86
89
|
return <div className={css.vbox(16).pad2(16).fillWidth}>
|
|
87
90
|
<style>{`
|
|
88
91
|
.LifeCycleInstanceRenderer:has(.LifeCycleEntryEditor:hover) {
|
|
@@ -112,6 +115,7 @@ export class LifeCyclePage extends qreact.Component {
|
|
|
112
115
|
fillWidth
|
|
113
116
|
onKeyDown={(e) => {
|
|
114
117
|
if (e.key === "Enter" && lifecycleIdURL.value) {
|
|
118
|
+
additionalSearchURL.value = e.currentTarget.value;
|
|
115
119
|
void this.searchLifeCycle(lifecycleIdURL.value);
|
|
116
120
|
}
|
|
117
121
|
}}
|
|
@@ -149,7 +153,7 @@ export class LifeCyclePage extends qreact.Component {
|
|
|
149
153
|
}}
|
|
150
154
|
className={css.width(500)}
|
|
151
155
|
/>
|
|
152
|
-
<span>({filteredLifeCycles.length} / {
|
|
156
|
+
<span>({filteredLifeCycles.length} / {lifeCycles.length})</span>
|
|
153
157
|
{this.state.searchingLifeCycleId && (
|
|
154
158
|
<Button
|
|
155
159
|
hue={120}
|
|
@@ -264,7 +268,7 @@ export class LifeCyclePage extends qreact.Component {
|
|
|
264
268
|
)}
|
|
265
269
|
|
|
266
270
|
{this.state.lifecycleInstances.length > 0 && (() => {
|
|
267
|
-
let searchedLifeCycle =
|
|
271
|
+
let searchedLifeCycle = lifeCycles.find(lc => lc.id === this.state.searchingLifeCycleId);
|
|
268
272
|
if (!searchedLifeCycle) return <div>Cannot find life cycle instance {this.state.searchingLifeCycleId}</div>;
|
|
269
273
|
|
|
270
274
|
let lc = searchedLifeCycle;
|
|
@@ -13,9 +13,10 @@ import { niceStringify } from "../../../niceStringify";
|
|
|
13
13
|
import { getPathStr } from "../../../path";
|
|
14
14
|
import { MachineThreadInfo } from "../../MachineThreadInfo";
|
|
15
15
|
import { LifeCycleEntryEditor } from "./LifeCycleEntryEditor";
|
|
16
|
-
import { lifecycleIdURL } from "./LifeCyclePage";
|
|
16
|
+
import { lifecycleIdURL, lifecycleTableViewURL } from "./LifeCyclePage";
|
|
17
17
|
import { LifecycleInstance } from "./lifeCycleSearch";
|
|
18
18
|
import { LifeCycle, LifeCyclesController, LifeCycleEntry } from "./lifeCycles";
|
|
19
|
+
import { LifeCycleInstanceTableView } from "./LifeCycleInstanceTableView";
|
|
19
20
|
|
|
20
21
|
export class LifeCycleRenderer extends qreact.Component<{
|
|
21
22
|
lifeCycle: LifeCycle;
|
|
@@ -200,7 +201,7 @@ export class LifeCycleInstanceRenderer extends qreact.Component<{
|
|
|
200
201
|
}
|
|
201
202
|
title={statusTitle}
|
|
202
203
|
onClick={(e) => {
|
|
203
|
-
if ((e.target as HTMLElement).closest(".
|
|
204
|
+
if ((e.target as HTMLElement).closest(".LifeCycleRenderer-contents")) {
|
|
204
205
|
return;
|
|
205
206
|
}
|
|
206
207
|
this.state.expanded = !this.state.expanded;
|
|
@@ -270,19 +271,37 @@ export class LifeCycleInstanceRenderer extends qreact.Component<{
|
|
|
270
271
|
</div>
|
|
271
272
|
|
|
272
273
|
{this.state.expanded && (
|
|
273
|
-
<div className={css.vbox(8)}>
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
274
|
+
<div className={css.vbox(8) + "LifeCycleRenderer-contents"}>
|
|
275
|
+
<Button
|
|
276
|
+
hue={200}
|
|
277
|
+
onClick={() => {
|
|
278
|
+
lifecycleTableViewURL.value = !lifecycleTableViewURL.value;
|
|
279
|
+
}}
|
|
280
|
+
>
|
|
281
|
+
{lifecycleTableViewURL.value && "List View" || "Table View"}
|
|
282
|
+
</Button>
|
|
283
|
+
|
|
284
|
+
{lifecycleTableViewURL.value && (
|
|
285
|
+
<LifeCycleInstanceTableView
|
|
279
286
|
lifeCycle={lifeCycle}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
287
|
+
instance={instance}
|
|
288
|
+
/>
|
|
289
|
+
) || (
|
|
290
|
+
<div className={css.vbox(8)}>
|
|
291
|
+
{instance.entries.map((entryData, idx) => {
|
|
292
|
+
let entryIndex = lifeCycle.entries.findIndex(e => e.matchPattern === entryData.matchPattern);
|
|
293
|
+
let entry = lifeCycle.entries[entryIndex];
|
|
294
|
+
return <LifeCycleEntryEditor
|
|
295
|
+
key={idx}
|
|
296
|
+
lifeCycle={lifeCycle}
|
|
297
|
+
entry={entry}
|
|
298
|
+
entryIndex={entryIndex}
|
|
299
|
+
defaultEditMode={false}
|
|
300
|
+
datum={entryData.datum}
|
|
301
|
+
/>;
|
|
302
|
+
})}
|
|
303
|
+
</div>
|
|
304
|
+
)}
|
|
286
305
|
</div>
|
|
287
306
|
)}
|
|
288
307
|
</div>;
|
|
@@ -564,7 +564,13 @@ export function createLifeCycleSearch(
|
|
|
564
564
|
}
|
|
565
565
|
}
|
|
566
566
|
|
|
567
|
-
|
|
567
|
+
let range = Querysub.localRead(() => getTimeRange());
|
|
568
|
+
|
|
569
|
+
if (range.searchFromStart) {
|
|
570
|
+
sort(allInstances, x => x.startTime);
|
|
571
|
+
} else {
|
|
572
|
+
sort(allInstances, x => -x.startTime);
|
|
573
|
+
}
|
|
568
574
|
|
|
569
575
|
return allInstances;
|
|
570
576
|
};
|