@acorex-platform/module-system-insight-client 0.0.38 → 0.0.48
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/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-alert-rule.mjs +13 -0
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-alert-rule.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-audit-log.mjs +14 -0
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-audit-log.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-dashboard-widget-config.mjs +12 -0
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-dashboard-widget-config.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-error-event.mjs +14 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-error-event.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-http-request-log.mjs +14 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-http-request-log.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-job-execution-log.mjs +14 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-job-execution-log.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-log-entry.mjs +4 -4
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-log-entry.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-metric-point.mjs +13 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-metric-point.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-observability-data-source.mjs +11 -0
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-observability-data-source.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-retention-policy.mjs +13 -0
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-retention-policy.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-saved-view.mjs +12 -0
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-saved-view.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-slow-request.mjs +14 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-slow-request.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-trace-entry.mjs +4 -4
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-trace-entry.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-trace-span.mjs +18 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entities-trace-span.mjs.map +1 -1
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-acorex-platform-module-system-insight-client-contracts-entity-catalog-L_KQ_ZRS.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-acorex-platform-module-system-insight-client-contracts-entity-catalog-Bcovlxhp.mjs} +15 -15
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-acorex-platform-module-system-insight-client-contracts-entity-catalog-L_KQ_ZRS.mjs.map → acorex-platform-module-system-insight-client-contracts-entity-catalog-acorex-platform-module-system-insight-client-contracts-entity-catalog-Bcovlxhp.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-alert-rule.entity-CVQ8zi2n.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-alert-rule.entity-DuUn71Sz.mjs} +15 -2
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-alert-rule.entity-DuUn71Sz.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-audit-log.entity-DUUbh-K4.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-audit-log.entity-DZ1CmaFi.mjs} +16 -2
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-audit-log.entity-DZ1CmaFi.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-dashboard-widget-config.entity-CQPGHj3-.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-dashboard-widget-config.entity-BQak4AZc.mjs} +14 -2
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-dashboard-widget-config.entity-BQak4AZc.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-error-event.entity-41bQET9n.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-error-event.entity-DaZislZB.mjs} +16 -3
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-error-event.entity-DaZislZB.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-http-request-log.entity-DuUG39be.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-http-request-log.entity-DbLd4t7F.mjs} +16 -3
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-http-request-log.entity-DbLd4t7F.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-job-execution-log.entity-DjScVny4.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-job-execution-log.entity-sX-AHmPB.mjs} +16 -3
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-job-execution-log.entity-sX-AHmPB.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-log-entry.entity-KhwOnohn.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-log-entry.entity-76GPKu4M.mjs} +6 -6
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-log-entry.entity-76GPKu4M.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-metric-point.entity-kfxxSxvp.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-metric-point.entity-DJFXCRCy.mjs} +15 -3
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-metric-point.entity-DJFXCRCy.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-observability-data-source.entity-BM0wTN3C.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-observability-data-source.entity-Bd3Bvtgl.mjs} +13 -2
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-observability-data-source.entity-Bd3Bvtgl.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-queries.keys-C768fZe1.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-queries.keys-8eqBvMRF.mjs} +2 -2
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-queries.keys-8eqBvMRF.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-retention-policy.entity-BU_FXy6_.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-retention-policy.entity-C4ipn2nR.mjs} +15 -2
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-retention-policy.entity-C4ipn2nR.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-saved-view.entity-BhhIVSRT.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-saved-view.entity-HevCnSJO.mjs} +14 -2
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-saved-view.entity-HevCnSJO.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-slow-request.entity-CdQongZo.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-slow-request.entity-kdw-SNYp.mjs} +16 -3
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-slow-request.entity-kdw-SNYp.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-trace-entry.entity-B_B8zT6c.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-trace-entry.entity-D3HM0Fbw.mjs} +6 -6
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-trace-entry.entity-D3HM0Fbw.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-system-insight-client-contracts-entity-catalog-trace-span.entity-BJGn3-6F.mjs → acorex-platform-module-system-insight-client-contracts-entity-catalog-trace-span.entity-DqvCcxQO.mjs} +20 -3
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-trace-span.entity-DqvCcxQO.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog.mjs +1 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts.mjs +22 -2
- package/fesm2022/acorex-platform-module-system-insight-client-contracts.mjs.map +1 -1
- package/fesm2022/{acorex-platform-module-system-insight-client-index-CeO40uWE.mjs → acorex-platform-module-system-insight-client-index-B-pPInVq.mjs} +168 -42
- package/fesm2022/acorex-platform-module-system-insight-client-index-B-pPInVq.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-system-insight-client.mjs +4 -26
- package/fesm2022/acorex-platform-module-system-insight-client.mjs.map +1 -1
- package/package.json +1 -1
- package/types/acorex-platform-module-system-insight-client-contracts.d.ts +9 -2
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-alert-rule.entity-CVQ8zi2n.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-audit-log.entity-DUUbh-K4.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-dashboard-widget-config.entity-CQPGHj3-.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-error-event.entity-41bQET9n.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-http-request-log.entity-DuUG39be.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-job-execution-log.entity-DjScVny4.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-log-entry.entity-KhwOnohn.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-metric-point.entity-kfxxSxvp.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-observability-data-source.entity-BM0wTN3C.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-queries.keys-C768fZe1.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-retention-policy.entity-BU_FXy6_.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-saved-view.entity-BhhIVSRT.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-slow-request.entity-CdQongZo.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-trace-entry.entity-B_B8zT6c.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-contracts-entity-catalog-trace-span.entity-BJGn3-6F.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-system-insight-client-index-CeO40uWE.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TRACE_TIMELINE_PAGE_COMPONENT_KEY, TRACE_FLOW_PAGE_COMPONENT_KEY } from '@acorex-platform/module-system-insight-client/contracts';
|
|
1
|
+
import { TRACE_TIMELINE_PAGE_COMPONENT_KEY, TRACE_FLOW_PAGE_COMPONENT_KEY, AXMSystemInsightQueryKeys } from '@acorex-platform/module-system-insight-client/contracts';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
3
|
import { Injectable, inject, input, signal, computed, effect, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
4
|
import { convertArrayToDataSource } from '@acorex/cdk/common';
|
|
@@ -115,7 +115,7 @@ class AXMTraceTimelinePageComponent extends AXPPageLayoutBaseComponent {
|
|
|
115
115
|
}
|
|
116
116
|
this.loading.set(true);
|
|
117
117
|
try {
|
|
118
|
-
const result = await this.queryExecutor.fetch(
|
|
118
|
+
const result = await this.queryExecutor.fetch(AXMSystemInsightQueryKeys.TraceTimeline.Get, traceId);
|
|
119
119
|
const timeline = runtimeQueryPayloadData(result) ?? null;
|
|
120
120
|
const rows = this.buildSpanRows(timeline);
|
|
121
121
|
this.timeline.set(timeline);
|
|
@@ -434,24 +434,84 @@ function sortSpans(spans) {
|
|
|
434
434
|
return (a.order ?? 0) - (b.order ?? 0);
|
|
435
435
|
});
|
|
436
436
|
}
|
|
437
|
+
function resolveRootOpSpanId(spans) {
|
|
438
|
+
const ops = spans.filter((span) => span.spanKind === 'op');
|
|
439
|
+
const rootOp = ops.find((span) => !span.parentSpanId);
|
|
440
|
+
return rootOp?.spanId ?? ops[0]?.spanId;
|
|
441
|
+
}
|
|
442
|
+
function hasChildSpans(spans, parentSpanId) {
|
|
443
|
+
return spans.some((span) => span.parentSpanId === parentSpanId);
|
|
444
|
+
}
|
|
445
|
+
function childrenByParent(spans) {
|
|
446
|
+
const map = new Map();
|
|
447
|
+
for (const span of spans) {
|
|
448
|
+
const parentId = span.parentSpanId;
|
|
449
|
+
if (!parentId) {
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
const siblings = map.get(parentId);
|
|
453
|
+
if (siblings) {
|
|
454
|
+
siblings.push(span);
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
map.set(parentId, [span]);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
for (const [parentId, siblings] of map) {
|
|
461
|
+
map.set(parentId, sortSpans(siblings));
|
|
462
|
+
}
|
|
463
|
+
return map;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Current layer under a focused op:
|
|
467
|
+
* - flatten onion middleware/backend descendants
|
|
468
|
+
* - stop at nested `op` spans (those stay one drill-in step)
|
|
469
|
+
*/
|
|
470
|
+
function layerSpansForFocus(spans, focusSpanId) {
|
|
471
|
+
const childrenOf = childrenByParent(spans);
|
|
472
|
+
const layer = [];
|
|
473
|
+
const visit = (parentId) => {
|
|
474
|
+
const children = childrenOf.get(parentId) ?? [];
|
|
475
|
+
for (const child of children) {
|
|
476
|
+
layer.push(child);
|
|
477
|
+
if (child.spanKind !== 'op') {
|
|
478
|
+
visit(child.spanId);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
visit(focusSpanId);
|
|
483
|
+
return layer;
|
|
484
|
+
}
|
|
437
485
|
//#endregion
|
|
438
486
|
//#region ---- Builder ----
|
|
439
|
-
function buildTraceFlowDiagram(timeline) {
|
|
487
|
+
function buildTraceFlowDiagram(timeline, focusSpanId) {
|
|
440
488
|
if (!timeline?.spans?.length) {
|
|
441
489
|
return null;
|
|
442
490
|
}
|
|
443
491
|
const spans = sortSpans(timeline.spans);
|
|
444
|
-
const
|
|
492
|
+
const activeOpId = focusSpanId ?? resolveRootOpSpanId(spans);
|
|
493
|
+
if (!activeOpId) {
|
|
494
|
+
return null;
|
|
495
|
+
}
|
|
496
|
+
const layerSpans = layerSpansForFocus(spans, activeOpId);
|
|
497
|
+
if (!layerSpans.length) {
|
|
498
|
+
return null;
|
|
499
|
+
}
|
|
500
|
+
const nodes = layerSpans.map((span, index) => {
|
|
445
501
|
const colors = statusColors(span.status);
|
|
502
|
+
const isNestedOp = span.spanKind === 'op';
|
|
503
|
+
const drillable = isNestedOp && hasChildSpans(spans, span.spanId);
|
|
446
504
|
return {
|
|
447
505
|
id: span.spanId,
|
|
448
506
|
type: span.spanKind ?? 'span',
|
|
449
507
|
title: spanTitle(span),
|
|
450
|
-
icon:
|
|
451
|
-
? 'fa-light fa-
|
|
452
|
-
: span.spanKind === '
|
|
453
|
-
? 'fa-light fa-
|
|
454
|
-
:
|
|
508
|
+
icon: isNestedOp
|
|
509
|
+
? 'fa-light fa-diagram-project'
|
|
510
|
+
: span.spanKind === 'middleware'
|
|
511
|
+
? 'fa-light fa-layer-group'
|
|
512
|
+
: span.spanKind === 'backend'
|
|
513
|
+
? 'fa-light fa-database'
|
|
514
|
+
: 'fa-light fa-play',
|
|
455
515
|
shape: 'rounded-rectangle',
|
|
456
516
|
position: { x: index * 280, y: 40 },
|
|
457
517
|
size: { width: DEFAULT_NODE_W, height: DEFAULT_NODE_H },
|
|
@@ -463,34 +523,25 @@ function buildTraceFlowDiagram(timeline) {
|
|
|
463
523
|
data: {
|
|
464
524
|
subtitle: spanSubtitle(span),
|
|
465
525
|
span,
|
|
526
|
+
drillable,
|
|
527
|
+
drillTarget: drillable ? span.spanId : undefined,
|
|
466
528
|
},
|
|
467
529
|
};
|
|
468
530
|
});
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
for (let i = 0; i < nodes.length - 1; i += 1) {
|
|
484
|
-
connectors.push({
|
|
485
|
-
id: `${nodes[i].id}->${nodes[i + 1].id}`,
|
|
486
|
-
sourceNodeId: nodes[i].id,
|
|
487
|
-
sourcePortId: `${nodes[i].id}:out`,
|
|
488
|
-
targetNodeId: nodes[i + 1].id,
|
|
489
|
-
targetPortId: `${nodes[i + 1].id}:in`,
|
|
490
|
-
readonly: true,
|
|
491
|
-
borderColor: 'primary',
|
|
492
|
-
});
|
|
493
|
-
}
|
|
531
|
+
const connectors = [];
|
|
532
|
+
for (let i = 0; i < nodes.length - 1; i += 1) {
|
|
533
|
+
const source = nodes[i];
|
|
534
|
+
const target = nodes[i + 1];
|
|
535
|
+
const sourceSpan = layerSpans[i];
|
|
536
|
+
connectors.push({
|
|
537
|
+
id: `${source.id}->${target.id}`,
|
|
538
|
+
sourceNodeId: source.id,
|
|
539
|
+
sourcePortId: `${source.id}:out`,
|
|
540
|
+
targetNodeId: target.id,
|
|
541
|
+
targetPortId: `${target.id}:in`,
|
|
542
|
+
readonly: true,
|
|
543
|
+
borderColor: (sourceSpan.status === 'error' ? 'danger' : 'primary'),
|
|
544
|
+
});
|
|
494
545
|
}
|
|
495
546
|
return arrangeWorkflowDiagram({
|
|
496
547
|
nodes,
|
|
@@ -499,6 +550,7 @@ function buildTraceFlowDiagram(timeline) {
|
|
|
499
550
|
traceId: timeline.traceId,
|
|
500
551
|
kind: timeline.kind,
|
|
501
552
|
operation: timeline.operation,
|
|
553
|
+
focusSpanId: activeOpId,
|
|
502
554
|
},
|
|
503
555
|
}, { direction: 'horizontal' });
|
|
504
556
|
}
|
|
@@ -579,8 +631,45 @@ class AXMTraceFlowPageComponent extends AXPPageLayoutBaseComponent {
|
|
|
579
631
|
...(ngDevMode ? [{ debugName: "timeline" }] : /* istanbul ignore next */ []));
|
|
580
632
|
this.selectedSpan = signal(null, /* @ts-ignore */
|
|
581
633
|
...(ngDevMode ? [{ debugName: "selectedSpan" }] : /* istanbul ignore next */ []));
|
|
582
|
-
this.
|
|
634
|
+
this.focusSpanStack = signal([], /* @ts-ignore */
|
|
635
|
+
...(ngDevMode ? [{ debugName: "focusSpanStack" }] : /* istanbul ignore next */ []));
|
|
636
|
+
this.#suppressNodeDrill = false;
|
|
637
|
+
this.focusSpanId = computed(() => {
|
|
638
|
+
const stack = this.focusSpanStack();
|
|
639
|
+
if (stack.length) {
|
|
640
|
+
return stack[stack.length - 1];
|
|
641
|
+
}
|
|
642
|
+
const spans = this.timeline()?.spans;
|
|
643
|
+
return spans?.length ? resolveRootOpSpanId(spans) : undefined;
|
|
644
|
+
}, /* @ts-ignore */
|
|
645
|
+
...(ngDevMode ? [{ debugName: "focusSpanId" }] : /* istanbul ignore next */ []));
|
|
646
|
+
this.diagram = computed(() => buildTraceFlowDiagram(this.timeline(), this.focusSpanId()), /* @ts-ignore */
|
|
583
647
|
...(ngDevMode ? [{ debugName: "diagram" }] : /* istanbul ignore next */ []));
|
|
648
|
+
this.drillBreadcrumbs = computed(() => {
|
|
649
|
+
const timeline = this.timeline();
|
|
650
|
+
if (!timeline?.spans?.length) {
|
|
651
|
+
return [];
|
|
652
|
+
}
|
|
653
|
+
const spans = timeline.spans;
|
|
654
|
+
const rootId = resolveRootOpSpanId(spans);
|
|
655
|
+
if (!rootId) {
|
|
656
|
+
return [];
|
|
657
|
+
}
|
|
658
|
+
const items = [];
|
|
659
|
+
const rootSpan = spans.find((span) => span.spanId === rootId);
|
|
660
|
+
items.push({
|
|
661
|
+
spanId: rootId,
|
|
662
|
+
label: rootSpan?.operationName ?? timeline.operation ?? rootId,
|
|
663
|
+
});
|
|
664
|
+
for (const spanId of this.focusSpanStack()) {
|
|
665
|
+
const span = spans.find((item) => item.spanId === spanId);
|
|
666
|
+
if (span) {
|
|
667
|
+
items.push({ spanId, label: span.operationName });
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
return items;
|
|
671
|
+
}, /* @ts-ignore */
|
|
672
|
+
...(ngDevMode ? [{ debugName: "drillBreadcrumbs" }] : /* istanbul ignore next */ []));
|
|
584
673
|
this.highlightedNodeIds = computed(() => {
|
|
585
674
|
const id = this.selectedSpan()?.spanId;
|
|
586
675
|
return id ? [id] : [];
|
|
@@ -604,6 +693,7 @@ class AXMTraceFlowPageComponent extends AXPPageLayoutBaseComponent {
|
|
|
604
693
|
}, /* @ts-ignore */
|
|
605
694
|
...(ngDevMode ? [{ debugName: "#loadEffect" }] : /* istanbul ignore next */ []));
|
|
606
695
|
}
|
|
696
|
+
#suppressNodeDrill;
|
|
607
697
|
//#endregion
|
|
608
698
|
//#region ---- Lifecycle ----
|
|
609
699
|
#loadEffect;
|
|
@@ -618,7 +708,29 @@ class AXMTraceFlowPageComponent extends AXPPageLayoutBaseComponent {
|
|
|
618
708
|
const nodeId = event.node.id;
|
|
619
709
|
const fromData = event.node.data?.['span'];
|
|
620
710
|
const fromTimeline = this.timeline()?.spans?.find((span) => span.spanId === nodeId || span.id === nodeId);
|
|
621
|
-
|
|
711
|
+
const span = fromData ?? fromTimeline ?? null;
|
|
712
|
+
this.selectedSpan.set(span);
|
|
713
|
+
const drillTarget = event.node.data?.['drillTarget'];
|
|
714
|
+
if (!this.#suppressNodeDrill &&
|
|
715
|
+
typeof drillTarget === 'string' &&
|
|
716
|
+
drillTarget &&
|
|
717
|
+
!this.focusSpanStack().includes(drillTarget)) {
|
|
718
|
+
this.#suppressNodeDrill = true;
|
|
719
|
+
this.focusSpanStack.update((stack) => [...stack, drillTarget]);
|
|
720
|
+
this.#releaseDrillSuppress();
|
|
721
|
+
}
|
|
722
|
+
this.recompute();
|
|
723
|
+
}
|
|
724
|
+
onBreadcrumbClick(index) {
|
|
725
|
+
this.#suppressNodeDrill = true;
|
|
726
|
+
if (index <= 0) {
|
|
727
|
+
this.focusSpanStack.set([]);
|
|
728
|
+
}
|
|
729
|
+
else {
|
|
730
|
+
this.focusSpanStack.set(this.focusSpanStack().slice(0, index));
|
|
731
|
+
}
|
|
732
|
+
this.selectedSpan.set(null);
|
|
733
|
+
this.#releaseDrillSuppress();
|
|
622
734
|
this.recompute();
|
|
623
735
|
}
|
|
624
736
|
hasValue(value) {
|
|
@@ -655,21 +767,34 @@ class AXMTraceFlowPageComponent extends AXPPageLayoutBaseComponent {
|
|
|
655
767
|
}
|
|
656
768
|
}
|
|
657
769
|
//#endregion
|
|
770
|
+
//#region ---- Drill-in ----
|
|
771
|
+
#releaseDrillSuppress() {
|
|
772
|
+
queueMicrotask(() => {
|
|
773
|
+
setTimeout(() => {
|
|
774
|
+
this.#suppressNodeDrill = false;
|
|
775
|
+
}, 250);
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
//#endregion
|
|
658
779
|
//#region ---- Data Loading ----
|
|
659
780
|
async loadTimeline(traceId) {
|
|
660
781
|
if (!traceId) {
|
|
661
782
|
this.timeline.set(null);
|
|
662
783
|
this.selectedSpan.set(null);
|
|
784
|
+
this.focusSpanStack.set([]);
|
|
663
785
|
this.loading.set(false);
|
|
664
786
|
return;
|
|
665
787
|
}
|
|
666
788
|
this.loading.set(true);
|
|
667
789
|
try {
|
|
668
|
-
const result = await this.queryExecutor.fetch(
|
|
790
|
+
const result = await this.queryExecutor.fetch(AXMSystemInsightQueryKeys.TraceTimeline.Get, traceId);
|
|
669
791
|
const timeline = runtimeQueryPayloadData(result) ?? null;
|
|
792
|
+
this.#suppressNodeDrill = true;
|
|
670
793
|
this.timeline.set(timeline);
|
|
671
|
-
this.
|
|
794
|
+
this.focusSpanStack.set([]);
|
|
795
|
+
this.selectedSpan.set(null);
|
|
672
796
|
this.recompute();
|
|
797
|
+
this.#releaseDrillSuppress();
|
|
673
798
|
}
|
|
674
799
|
finally {
|
|
675
800
|
this.loading.set(false);
|
|
@@ -681,13 +806,14 @@ class AXMTraceFlowPageComponent extends AXPPageLayoutBaseComponent {
|
|
|
681
806
|
provide: AXPPageLayoutBase,
|
|
682
807
|
useExisting: AXMTraceFlowPageComponent,
|
|
683
808
|
},
|
|
684
|
-
], usesInheritance: true, ngImport: i0, template: "<!-- ----- Trace flow chart page ----- -->\n<div class=\"axm-trace-flow flex flex-col gap-4 p-4 w-full min-h-0 h-full\">\n @if (loading()) {\n <!-- ----- Loading indicator while timeline is fetched ----- -->\n <div class=\"flex justify-center py-10\">\n <ax-loading />\n </div>\n }\n <!-- ----- Empty state when timeline is missing ----- -->\n @else if (!timeline()) {\n <p class=\"typo-caption text-muted\">\n {{ '@system-insight:pages.trace-flow.not-found' | translate | async }}\n </p>\n }\n <!-- ----- Flow chart + span details ----- -->\n @else {\n <div class=\"flex flex-wrap items-center gap-2\">\n @if (timeline()?.kind; as kind) {\n <ax-badge [text]=\"kind\" color=\"primary\" size=\"sm\"></ax-badge>\n }\n @if (timeline()?.operation; as operation) {\n <span class=\"text-sm\">{{ operation }}</span>\n }\n <span class=\"text-sm text-muted ms-auto\">\n {{ '@system-insight:pages.trace-flow.duration' | translate | async }}:\n {{ timeline()?.duration }} ms\n </span>\n </div>\n\n <div class=\"axm-trace-flow__canvas border border-lightest rounded-md overflow-hidden min-h-[360px] flex-1\">\n @if (diagram(); as model) {\n <!-- ----- Readonly span flow chart ----- -->\n <axp-workflow-designer\n [model]=\"model\"\n [readonly]=\"true\"\n [showPortLabels]=\"false\"\n [highlightedNodeIds]=\"highlightedNodeIds()\"\n (nodeClick)=\"onNodeClick($event)\"\n />\n }\n <!-- ----- Empty diagram fallback ----- -->\n @else {\n <p class=\"typo-caption text-muted p-4\">\n {{ '@system-insight:pages.trace-flow.empty' | translate | async }}\n </p>\n }\n </div>\n\n @if (selectedSpan(); as span) {\n <!-- ----- Selected span details (metadata + IO) ----- -->\n <div class=\"border border-lightest rounded-md p-4 flex flex-col gap-4\">\n <div class=\"flex flex-wrap items-center gap-2\">\n <strong class=\"text-base\">{{ span.operationName }}</strong>\n @if (span.spanKind) {\n <ax-badge [text]=\"span.spanKind\" color=\"primary\" size=\"sm\"></ax-badge>\n }\n @if (span.middlewareName) {\n <ax-badge [text]=\"span.middlewareName\" color=\"secondary\" size=\"sm\"></ax-badge>\n }\n @if (span.status) {\n <ax-badge\n [text]=\"span.status\"\n [color]=\"span.status === 'error' ? 'danger' : 'success'\"\n size=\"sm\"\n ></ax-badge>\n }\n </div>\n\n <!-- ----- Span metadata grid ----- -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-3 text-sm\">\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.span-id' | translate | async }}\n </div>\n <div class=\"font-mono break-all\">{{ span.spanId }}</div>\n </div>\n @if (span.parentSpanId) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.parent-span-id' | translate | async }}\n </div>\n <div class=\"font-mono break-all\">{{ span.parentSpanId }}</div>\n </div>\n }\n @if (span.serviceName) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.service-name' | translate | async }}\n </div>\n <div>{{ span.serviceName }}</div>\n </div>\n }\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.duration' | translate | async }}\n </div>\n <div>{{ span.duration ?? 0 }} ms</div>\n </div>\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.start-time' | translate | async }}\n </div>\n <div>{{ span.startTime }}</div>\n </div>\n @if (span.order != null) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.order' | translate | async }}\n </div>\n <div>{{ span.order }}</div>\n </div>\n }\n @if (span.nextMiddleware) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.next-middleware' | translate | async }}\n </div>\n <div>{{ span.nextMiddleware }}</div>\n </div>\n }\n </div>\n\n @if (span.error) {\n <!-- ----- Span error ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1 text-danger\">\n {{ '@system-insight:fields.error' | translate | async }}\n </div>\n <pre class=\"text-sm whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-40\">{{\n span.error\n }}</pre>\n </div>\n }\n\n <!-- ----- Input snapshot (always visible) ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.input' | translate | async }}\n </div>\n @if (hasValue(span.input)) {\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.input)\n }}</pre>\n }\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@system-insight:pages.trace-flow.no-input' | translate | async }}\n </p>\n }\n </div>\n\n <!-- ----- Output snapshot (always visible) ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.output' | translate | async }}\n </div>\n @if (hasValue(span.output)) {\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.output)\n }}</pre>\n }\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@system-insight:pages.trace-flow.no-output' | translate | async }}\n </p>\n }\n </div>\n\n @if (hasValue(span.tags)) {\n <!-- ----- Span tags / attributes ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.attributes' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.tags)\n }}</pre>\n </div>\n }\n\n @if (span.logs?.length) {\n <!-- ----- Span logs / events ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.events' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.logs)\n }}</pre>\n </div>\n }\n </div>\n }\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i4.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPWorkflowDesignerComponent, selector: "axp-workflow-designer", inputs: ["model", "readonly", "highlightedNodeIds", "gridSize", "snapToGrid", "connectionPreviewStyle", "backgroundPattern", "canConnect", "paletteItems", "showPortLabels", "nodeBodyTemplate"], outputs: ["modelChange", "zoomChange", "designerPointerDown", "designerClick", "designerDoubleClick", "nodePointerDown", "nodeClick", "nodeDoubleClick", "nodeContextMenu", "nodeDragStart", "nodeDragEnd", "portPointerDown", "linkDragStart", "linkDragMove", "linkDragEnd", "connectorClick", "connectorDoubleClick", "connectionCreated", "connectionRejected", "activationChange"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i7.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
809
|
+
], usesInheritance: true, ngImport: i0, template: "<!-- ----- Trace flow chart page ----- -->\n<div class=\"axm-trace-flow flex flex-col gap-4 p-4 w-full min-h-0 h-full\">\n @if (loading()) {\n <!-- ----- Loading indicator while timeline is fetched ----- -->\n <div class=\"flex justify-center py-10\">\n <ax-loading />\n </div>\n }\n <!-- ----- Empty state when timeline is missing ----- -->\n @else if (!timeline()) {\n <p class=\"typo-caption text-muted\">\n {{ '@system-insight:pages.trace-flow.not-found' | translate | async }}\n </p>\n }\n <!-- ----- Flow chart + span details ----- -->\n @else {\n <div class=\"flex flex-wrap items-center gap-2\">\n @if (timeline()?.kind; as kind) {\n <ax-badge [text]=\"kind\" color=\"primary\" size=\"sm\"></ax-badge>\n }\n @if (timeline()?.operation; as operation) {\n <span class=\"text-sm\">{{ operation }}</span>\n }\n <span class=\"text-sm text-muted ms-auto\">\n {{ '@system-insight:pages.trace-flow.duration' | translate | async }}:\n {{ timeline()?.duration }} ms\n </span>\n </div>\n\n @if (drillBreadcrumbs().length > 1) {\n <!-- ----- Breadcrumb drill-in path ----- -->\n <nav class=\"flex flex-wrap items-center gap-1 text-sm\" aria-label=\"Trace flow layers\">\n @for (item of drillBreadcrumbs(); track item.spanId; let i = $index) {\n @if (i > 0) {\n <span class=\"text-muted px-1\">/</span>\n }\n @if (i < drillBreadcrumbs().length - 1) {\n <button\n type=\"button\"\n class=\"text-primary hover:underline truncate max-w-[240px]\"\n (click)=\"onBreadcrumbClick(i)\"\n >\n {{ item.label }}\n </button>\n }\n <!-- ----- Current layer label (not clickable) ----- -->\n @else {\n <span class=\"font-medium truncate max-w-[320px]\">{{ item.label }}</span>\n }\n }\n </nav>\n }\n\n <div class=\"axm-trace-flow__canvas border border-lightest rounded-md overflow-hidden min-h-[360px] flex-1\">\n @if (diagram(); as model) {\n <!-- ----- Readonly span flow chart ----- -->\n <axp-workflow-designer\n [model]=\"model\"\n [readonly]=\"true\"\n [showPortLabels]=\"false\"\n [highlightedNodeIds]=\"highlightedNodeIds()\"\n (nodeClick)=\"onNodeClick($event)\"\n />\n }\n <!-- ----- Empty diagram fallback ----- -->\n @else {\n <p class=\"typo-caption text-muted p-4\">\n {{ '@system-insight:pages.trace-flow.empty' | translate | async }}\n </p>\n }\n </div>\n\n @if (selectedSpan(); as span) {\n <!-- ----- Selected span details (metadata + IO) ----- -->\n <div class=\"border border-lightest rounded-md p-4 flex flex-col gap-4\">\n <div class=\"flex flex-wrap items-center gap-2\">\n <strong class=\"text-base\">{{ span.operationName }}</strong>\n @if (span.spanKind) {\n <ax-badge [text]=\"span.spanKind\" color=\"primary\" size=\"sm\"></ax-badge>\n }\n @if (span.middlewareName) {\n <ax-badge [text]=\"span.middlewareName\" color=\"secondary\" size=\"sm\"></ax-badge>\n }\n @if (span.status) {\n <ax-badge\n [text]=\"span.status\"\n [color]=\"span.status === 'error' ? 'danger' : 'success'\"\n size=\"sm\"\n ></ax-badge>\n }\n </div>\n\n <!-- ----- Span metadata grid ----- -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-3 text-sm\">\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.span-id' | translate | async }}\n </div>\n <div class=\"font-mono break-all\">{{ span.spanId }}</div>\n </div>\n @if (span.parentSpanId) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.parent-span-id' | translate | async }}\n </div>\n <div class=\"font-mono break-all\">{{ span.parentSpanId }}</div>\n </div>\n }\n @if (span.serviceName) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.service-name' | translate | async }}\n </div>\n <div>{{ span.serviceName }}</div>\n </div>\n }\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.duration' | translate | async }}\n </div>\n <div>{{ span.duration ?? 0 }} ms</div>\n </div>\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.start-time' | translate | async }}\n </div>\n <div>{{ span.startTime }}</div>\n </div>\n @if (span.order != null) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.order' | translate | async }}\n </div>\n <div>{{ span.order }}</div>\n </div>\n }\n @if (span.nextMiddleware) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.next-middleware' | translate | async }}\n </div>\n <div>{{ span.nextMiddleware }}</div>\n </div>\n }\n </div>\n\n @if (span.error) {\n <!-- ----- Span error ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1 text-danger\">\n {{ '@system-insight:fields.error' | translate | async }}\n </div>\n <pre class=\"text-sm whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-40\">{{\n span.error\n }}</pre>\n </div>\n }\n\n <!-- ----- Input snapshot (always visible) ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.input' | translate | async }}\n </div>\n @if (hasValue(span.input)) {\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.input)\n }}</pre>\n }\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@system-insight:pages.trace-flow.no-input' | translate | async }}\n </p>\n }\n </div>\n\n <!-- ----- Output snapshot (always visible) ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.output' | translate | async }}\n </div>\n @if (hasValue(span.output)) {\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.output)\n }}</pre>\n }\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@system-insight:pages.trace-flow.no-output' | translate | async }}\n </p>\n }\n </div>\n\n @if (hasValue(span.tags)) {\n <!-- ----- Span tags / attributes ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.attributes' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.tags)\n }}</pre>\n </div>\n }\n\n @if (span.logs?.length) {\n <!-- ----- Span logs / events ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.events' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.logs)\n }}</pre>\n </div>\n }\n </div>\n }\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i4.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPWorkflowDesignerComponent, selector: "axp-workflow-designer", inputs: ["model", "readonly", "highlightedNodeIds", "gridSize", "snapToGrid", "connectionPreviewStyle", "connectorStub", "backgroundPattern", "canConnect", "paletteItems", "showPortLabels", "showPorts", "showConnectorLabels", "canvasPadding", "minCanvasSize", "nodeBodyTemplate"], outputs: ["modelChange", "zoomChange", "designerPointerDown", "designerClick", "designerDoubleClick", "nodePointerDown", "nodeClick", "nodeDoubleClick", "nodeContextMenu", "nodeDragStart", "nodeDragEnd", "portPointerDown", "linkDragStart", "linkDragMove", "linkDragEnd", "connectorClick", "connectorDoubleClick", "connectionCreated", "connectionRejected", "activationChange"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i7.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
685
810
|
}
|
|
686
811
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMTraceFlowPageComponent, decorators: [{
|
|
687
812
|
type: Component,
|
|
688
813
|
args: [{ selector: 'axm-trace-flow-page', standalone: true, imports: [
|
|
689
814
|
CommonModule,
|
|
690
815
|
AXBadgeModule,
|
|
816
|
+
AXButtonModule,
|
|
691
817
|
AXLoadingModule,
|
|
692
818
|
AXTranslationModule,
|
|
693
819
|
AXPWorkflowDesignerComponent,
|
|
@@ -696,7 +822,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
696
822
|
provide: AXPPageLayoutBase,
|
|
697
823
|
useExisting: AXMTraceFlowPageComponent,
|
|
698
824
|
},
|
|
699
|
-
], host: { class: 'axm-trace-flow-page block w-full min-h-0' }, template: "<!-- ----- Trace flow chart page ----- -->\n<div class=\"axm-trace-flow flex flex-col gap-4 p-4 w-full min-h-0 h-full\">\n @if (loading()) {\n <!-- ----- Loading indicator while timeline is fetched ----- -->\n <div class=\"flex justify-center py-10\">\n <ax-loading />\n </div>\n }\n <!-- ----- Empty state when timeline is missing ----- -->\n @else if (!timeline()) {\n <p class=\"typo-caption text-muted\">\n {{ '@system-insight:pages.trace-flow.not-found' | translate | async }}\n </p>\n }\n <!-- ----- Flow chart + span details ----- -->\n @else {\n <div class=\"flex flex-wrap items-center gap-2\">\n @if (timeline()?.kind; as kind) {\n <ax-badge [text]=\"kind\" color=\"primary\" size=\"sm\"></ax-badge>\n }\n @if (timeline()?.operation; as operation) {\n <span class=\"text-sm\">{{ operation }}</span>\n }\n <span class=\"text-sm text-muted ms-auto\">\n {{ '@system-insight:pages.trace-flow.duration' | translate | async }}:\n {{ timeline()?.duration }} ms\n </span>\n </div>\n\n <div class=\"axm-trace-flow__canvas border border-lightest rounded-md overflow-hidden min-h-[360px] flex-1\">\n @if (diagram(); as model) {\n <!-- ----- Readonly span flow chart ----- -->\n <axp-workflow-designer\n [model]=\"model\"\n [readonly]=\"true\"\n [showPortLabels]=\"false\"\n [highlightedNodeIds]=\"highlightedNodeIds()\"\n (nodeClick)=\"onNodeClick($event)\"\n />\n }\n <!-- ----- Empty diagram fallback ----- -->\n @else {\n <p class=\"typo-caption text-muted p-4\">\n {{ '@system-insight:pages.trace-flow.empty' | translate | async }}\n </p>\n }\n </div>\n\n @if (selectedSpan(); as span) {\n <!-- ----- Selected span details (metadata + IO) ----- -->\n <div class=\"border border-lightest rounded-md p-4 flex flex-col gap-4\">\n <div class=\"flex flex-wrap items-center gap-2\">\n <strong class=\"text-base\">{{ span.operationName }}</strong>\n @if (span.spanKind) {\n <ax-badge [text]=\"span.spanKind\" color=\"primary\" size=\"sm\"></ax-badge>\n }\n @if (span.middlewareName) {\n <ax-badge [text]=\"span.middlewareName\" color=\"secondary\" size=\"sm\"></ax-badge>\n }\n @if (span.status) {\n <ax-badge\n [text]=\"span.status\"\n [color]=\"span.status === 'error' ? 'danger' : 'success'\"\n size=\"sm\"\n ></ax-badge>\n }\n </div>\n\n <!-- ----- Span metadata grid ----- -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-3 text-sm\">\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.span-id' | translate | async }}\n </div>\n <div class=\"font-mono break-all\">{{ span.spanId }}</div>\n </div>\n @if (span.parentSpanId) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.parent-span-id' | translate | async }}\n </div>\n <div class=\"font-mono break-all\">{{ span.parentSpanId }}</div>\n </div>\n }\n @if (span.serviceName) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.service-name' | translate | async }}\n </div>\n <div>{{ span.serviceName }}</div>\n </div>\n }\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.duration' | translate | async }}\n </div>\n <div>{{ span.duration ?? 0 }} ms</div>\n </div>\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.start-time' | translate | async }}\n </div>\n <div>{{ span.startTime }}</div>\n </div>\n @if (span.order != null) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.order' | translate | async }}\n </div>\n <div>{{ span.order }}</div>\n </div>\n }\n @if (span.nextMiddleware) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.next-middleware' | translate | async }}\n </div>\n <div>{{ span.nextMiddleware }}</div>\n </div>\n }\n </div>\n\n @if (span.error) {\n <!-- ----- Span error ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1 text-danger\">\n {{ '@system-insight:fields.error' | translate | async }}\n </div>\n <pre class=\"text-sm whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-40\">{{\n span.error\n }}</pre>\n </div>\n }\n\n <!-- ----- Input snapshot (always visible) ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.input' | translate | async }}\n </div>\n @if (hasValue(span.input)) {\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.input)\n }}</pre>\n }\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@system-insight:pages.trace-flow.no-input' | translate | async }}\n </p>\n }\n </div>\n\n <!-- ----- Output snapshot (always visible) ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.output' | translate | async }}\n </div>\n @if (hasValue(span.output)) {\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.output)\n }}</pre>\n }\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@system-insight:pages.trace-flow.no-output' | translate | async }}\n </p>\n }\n </div>\n\n @if (hasValue(span.tags)) {\n <!-- ----- Span tags / attributes ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.attributes' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.tags)\n }}</pre>\n </div>\n }\n\n @if (span.logs?.length) {\n <!-- ----- Span logs / events ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.events' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.logs)\n }}</pre>\n </div>\n }\n </div>\n }\n }\n</div>\n" }]
|
|
825
|
+
], host: { class: 'axm-trace-flow-page block w-full min-h-0' }, template: "<!-- ----- Trace flow chart page ----- -->\n<div class=\"axm-trace-flow flex flex-col gap-4 p-4 w-full min-h-0 h-full\">\n @if (loading()) {\n <!-- ----- Loading indicator while timeline is fetched ----- -->\n <div class=\"flex justify-center py-10\">\n <ax-loading />\n </div>\n }\n <!-- ----- Empty state when timeline is missing ----- -->\n @else if (!timeline()) {\n <p class=\"typo-caption text-muted\">\n {{ '@system-insight:pages.trace-flow.not-found' | translate | async }}\n </p>\n }\n <!-- ----- Flow chart + span details ----- -->\n @else {\n <div class=\"flex flex-wrap items-center gap-2\">\n @if (timeline()?.kind; as kind) {\n <ax-badge [text]=\"kind\" color=\"primary\" size=\"sm\"></ax-badge>\n }\n @if (timeline()?.operation; as operation) {\n <span class=\"text-sm\">{{ operation }}</span>\n }\n <span class=\"text-sm text-muted ms-auto\">\n {{ '@system-insight:pages.trace-flow.duration' | translate | async }}:\n {{ timeline()?.duration }} ms\n </span>\n </div>\n\n @if (drillBreadcrumbs().length > 1) {\n <!-- ----- Breadcrumb drill-in path ----- -->\n <nav class=\"flex flex-wrap items-center gap-1 text-sm\" aria-label=\"Trace flow layers\">\n @for (item of drillBreadcrumbs(); track item.spanId; let i = $index) {\n @if (i > 0) {\n <span class=\"text-muted px-1\">/</span>\n }\n @if (i < drillBreadcrumbs().length - 1) {\n <button\n type=\"button\"\n class=\"text-primary hover:underline truncate max-w-[240px]\"\n (click)=\"onBreadcrumbClick(i)\"\n >\n {{ item.label }}\n </button>\n }\n <!-- ----- Current layer label (not clickable) ----- -->\n @else {\n <span class=\"font-medium truncate max-w-[320px]\">{{ item.label }}</span>\n }\n }\n </nav>\n }\n\n <div class=\"axm-trace-flow__canvas border border-lightest rounded-md overflow-hidden min-h-[360px] flex-1\">\n @if (diagram(); as model) {\n <!-- ----- Readonly span flow chart ----- -->\n <axp-workflow-designer\n [model]=\"model\"\n [readonly]=\"true\"\n [showPortLabels]=\"false\"\n [highlightedNodeIds]=\"highlightedNodeIds()\"\n (nodeClick)=\"onNodeClick($event)\"\n />\n }\n <!-- ----- Empty diagram fallback ----- -->\n @else {\n <p class=\"typo-caption text-muted p-4\">\n {{ '@system-insight:pages.trace-flow.empty' | translate | async }}\n </p>\n }\n </div>\n\n @if (selectedSpan(); as span) {\n <!-- ----- Selected span details (metadata + IO) ----- -->\n <div class=\"border border-lightest rounded-md p-4 flex flex-col gap-4\">\n <div class=\"flex flex-wrap items-center gap-2\">\n <strong class=\"text-base\">{{ span.operationName }}</strong>\n @if (span.spanKind) {\n <ax-badge [text]=\"span.spanKind\" color=\"primary\" size=\"sm\"></ax-badge>\n }\n @if (span.middlewareName) {\n <ax-badge [text]=\"span.middlewareName\" color=\"secondary\" size=\"sm\"></ax-badge>\n }\n @if (span.status) {\n <ax-badge\n [text]=\"span.status\"\n [color]=\"span.status === 'error' ? 'danger' : 'success'\"\n size=\"sm\"\n ></ax-badge>\n }\n </div>\n\n <!-- ----- Span metadata grid ----- -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-3 text-sm\">\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.span-id' | translate | async }}\n </div>\n <div class=\"font-mono break-all\">{{ span.spanId }}</div>\n </div>\n @if (span.parentSpanId) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.parent-span-id' | translate | async }}\n </div>\n <div class=\"font-mono break-all\">{{ span.parentSpanId }}</div>\n </div>\n }\n @if (span.serviceName) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.service-name' | translate | async }}\n </div>\n <div>{{ span.serviceName }}</div>\n </div>\n }\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.duration' | translate | async }}\n </div>\n <div>{{ span.duration ?? 0 }} ms</div>\n </div>\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.start-time' | translate | async }}\n </div>\n <div>{{ span.startTime }}</div>\n </div>\n @if (span.order != null) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.order' | translate | async }}\n </div>\n <div>{{ span.order }}</div>\n </div>\n }\n @if (span.nextMiddleware) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.next-middleware' | translate | async }}\n </div>\n <div>{{ span.nextMiddleware }}</div>\n </div>\n }\n </div>\n\n @if (span.error) {\n <!-- ----- Span error ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1 text-danger\">\n {{ '@system-insight:fields.error' | translate | async }}\n </div>\n <pre class=\"text-sm whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-40\">{{\n span.error\n }}</pre>\n </div>\n }\n\n <!-- ----- Input snapshot (always visible) ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.input' | translate | async }}\n </div>\n @if (hasValue(span.input)) {\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.input)\n }}</pre>\n }\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@system-insight:pages.trace-flow.no-input' | translate | async }}\n </p>\n }\n </div>\n\n <!-- ----- Output snapshot (always visible) ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.output' | translate | async }}\n </div>\n @if (hasValue(span.output)) {\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.output)\n }}</pre>\n }\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@system-insight:pages.trace-flow.no-output' | translate | async }}\n </p>\n }\n </div>\n\n @if (hasValue(span.tags)) {\n <!-- ----- Span tags / attributes ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.attributes' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.tags)\n }}</pre>\n </div>\n }\n\n @if (span.logs?.length) {\n <!-- ----- Span logs / events ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.events' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.logs)\n }}</pre>\n </div>\n }\n </div>\n }\n }\n</div>\n" }]
|
|
700
826
|
}], propDecorators: { rootContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "rootContext", required: false }] }], pageConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageConfig", required: false }] }] } });
|
|
701
827
|
|
|
702
828
|
var traceFlowPage_component = /*#__PURE__*/Object.freeze({
|
|
@@ -704,5 +830,5 @@ var traceFlowPage_component = /*#__PURE__*/Object.freeze({
|
|
|
704
830
|
AXMTraceFlowPageComponent: AXMTraceFlowPageComponent
|
|
705
831
|
});
|
|
706
832
|
|
|
707
|
-
export { AXMTraceFlowPageComponent, AXMTraceTimelinePageComponent, AXMTraceTimelinePageComponentProvider, buildTraceFlowDiagram, normalizeTraceDisplayValue };
|
|
708
|
-
//# sourceMappingURL=acorex-platform-module-system-insight-client-index-
|
|
833
|
+
export { AXMTraceFlowPageComponent, AXMTraceTimelinePageComponent, AXMTraceTimelinePageComponentProvider, buildTraceFlowDiagram, hasChildSpans, normalizeTraceDisplayValue, resolveRootOpSpanId };
|
|
834
|
+
//# sourceMappingURL=acorex-platform-module-system-insight-client-index-B-pPInVq.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acorex-platform-module-system-insight-client-index-B-pPInVq.mjs","sources":["../../../../libs/modules/system-insight/client/src/lib/features/traces/trace-timeline-page-component.provider.ts","../../../../libs/modules/system-insight/client/src/lib/features/traces/trace-timeline-page.component.ts","../../../../libs/modules/system-insight/client/src/lib/features/traces/trace-flow-diagram.utils.ts","../../../../libs/modules/system-insight/client/src/lib/features/traces/trace-flow-display.util.ts","../../../../libs/modules/system-insight/client/src/lib/features/traces/trace-flow-page.component.ts","../../../../libs/modules/system-insight/client/src/lib/features/traces/trace-flow-page.component.html"],"sourcesContent":["import { AXPPageComponentDefinition, AXPPageComponentProvider } from '@acorex-platform/framework-client/layout/components';\r\nimport {\r\n TRACE_FLOW_PAGE_COMPONENT_KEY,\r\n TRACE_TIMELINE_PAGE_COMPONENT_KEY,\r\n} from '@acorex-platform/module-system-insight-client/contracts';\r\nimport { Injectable } from '@angular/core';\r\n\r\n//#region ---- Trace page providers ----\r\n\r\n@Injectable()\r\nexport class AXMTraceTimelinePageComponentProvider implements AXPPageComponentProvider {\r\n async components(): Promise<AXPPageComponentDefinition[]> {\r\n return [\r\n {\r\n key: TRACE_TIMELINE_PAGE_COMPONENT_KEY,\r\n loader: () =>\r\n import('./trace-timeline-page.component').then((m) => m.AXMTraceTimelinePageComponent),\r\n },\r\n {\r\n key: TRACE_FLOW_PAGE_COMPONENT_KEY,\r\n loader: () => import('./trace-flow-page.component').then((m) => m.AXMTraceFlowPageComponent),\r\n },\r\n ];\r\n }\r\n}\r\n\r\n//#endregion\r\n","import { convertArrayToDataSource } from '@acorex/cdk/common';\nimport { AXBadgeModule } from '@acorex/components/badge';\nimport { AXButtonModule } from '@acorex/components/button';\nimport { AXDataTableModule } from '@acorex/components/data-table';\nimport { AXLoadingModule } from '@acorex/components/loading';\nimport { AXProgressBarModule } from '@acorex/components/progress-bar';\nimport { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';\nimport {\n AXPPageLayoutBase,\n AXPPageLayoutBaseComponent,\n} from '@acorex-platform/framework-client/layout/views';\nimport { AXPQueryExecutor } from '@acorex-platform/framework-client/runtime';\nimport { runtimeQueryPayloadData } from '@acorex-platform/framework-shared/core';\nimport {\n AXMSystemInsightQueryKeys,\n type TraceSpanDto,\n type TraceTimelineDto,\n} from '@acorex-platform/module-system-insight-client/contracts';\nimport { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n signal,\n} from '@angular/core';\n\n//#region ---- Types ----\n\ntype TimelineSpanRow = TraceSpanDto & {\n offsetPercent: number;\n widthPercent: number;\n durationShare: number;\n};\n\n//#endregion\n\n/**\n * TraceEntry detail tab — same hosting pattern as workflow Activities / RuleSet Simulate.\n * Chrome comes from entity details; content uses ACOREX controls only.\n */\n@Component({\n selector: 'axm-trace-timeline-page',\n standalone: true,\n imports: [\n CommonModule,\n AXBadgeModule,\n AXButtonModule,\n AXDataTableModule,\n AXLoadingModule,\n AXProgressBarModule,\n AXTranslationModule,\n ],\n template: `\n <div class=\"axm-trace-timeline flex flex-col gap-4 p-4 w-full min-h-0\">\n @if (loading()) {\n <div class=\"flex justify-center py-10\">\n <ax-loading />\n </div>\n } @else if (timeline(); as data) {\n <div class=\"flex flex-wrap items-center gap-2\">\n <ax-badge [text]=\"spanCountBadge()\" color=\"primary\" size=\"sm\"></ax-badge>\n @for (service of data.services; track service) {\n <ax-badge [text]=\"service\" color=\"secondary\" size=\"sm\"></ax-badge>\n }\n <span class=\"text-sm text-muted ms-auto\">\n {{ '@system-insight:pages.trace-timeline.duration' | translate | async }}:\n {{ data.duration }} ms\n </span>\n <ax-button\n look=\"outline\"\n color=\"primary\"\n [text]=\"('@system-insight:pages.trace-timeline.view-logs' | translate | async) || ''\"\n (onClick)=\"goToRelatedLogs()\"\n ></ax-button>\n </div>\n\n <ax-data-table\n class=\"w-full border border-lightest rounded-md overflow-hidden\"\n [paging]=\"false\"\n [dataSource]=\"dataSource()\"\n >\n <ax-text-column\n dataField=\"operationName\"\n [caption]=\"'@system-insight:fields.operation' | translate | async\"\n [width]=\"'200px'\"\n [allowResizing]=\"true\"\n ></ax-text-column>\n <ax-text-column\n dataField=\"serviceName\"\n [caption]=\"'@system-insight:fields.service-name' | translate | async\"\n [width]=\"'140px'\"\n [allowResizing]=\"true\"\n ></ax-text-column>\n <ax-text-column\n dataField=\"status\"\n [caption]=\"'@system-insight:fields.status' | translate | async\"\n [width]=\"'100px'\"\n [cellTemplate]=\"statusTpl\"\n [allowResizing]=\"true\"\n ></ax-text-column>\n <ax-text-column\n dataField=\"duration\"\n [caption]=\"'@system-insight:fields.duration' | translate | async\"\n [width]=\"'110px'\"\n [cellTemplate]=\"durationTpl\"\n [allowResizing]=\"true\"\n ></ax-text-column>\n <ax-text-column\n dataField=\"durationShare\"\n [caption]=\"'@system-insight:pages.trace-timeline.timeline' | translate | async\"\n [width]=\"'280px'\"\n [cellTemplate]=\"timelineTpl\"\n [allowResizing]=\"true\"\n ></ax-text-column>\n <ax-text-column\n dataField=\"spanId\"\n [caption]=\"'@system-insight:fields.span-id' | translate | async\"\n [width]=\"'180px'\"\n [allowResizing]=\"true\"\n ></ax-text-column>\n </ax-data-table>\n } @else {\n <p class=\"text-sm text-muted p-2\">\n {{ '@system-insight:pages.trace-timeline.not-found' | translate | async }}\n </p>\n }\n </div>\n\n <ng-template #statusTpl let-item>\n <ax-badge\n [text]=\"item.data?.status || 'ok'\"\n [color]=\"item.data?.status === 'error' ? 'danger' : 'success'\"\n size=\"sm\"\n ></ax-badge>\n </ng-template>\n\n <ng-template #durationTpl let-item>{{ item.data?.duration ?? 0 }} ms</ng-template>\n\n <ng-template #timelineTpl let-item>\n <div class=\"flex w-full items-center gap-0 py-1\">\n <div class=\"shrink-0\" [style.width.%]=\"item.data?.offsetPercent ?? 0\"></div>\n <div class=\"min-w-0\" [style.width.%]=\"item.data?.widthPercent ?? 3\">\n <ax-progress-bar\n [progress]=\"100\"\n [color]=\"item.data?.status === 'error' ? 'danger' : 'primary'\"\n [style.height.px]=\"10\"\n ></ax-progress-bar>\n </div>\n </div>\n </ng-template>\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: AXPPageLayoutBase,\n useExisting: AXMTraceTimelinePageComponent,\n },\n ],\n host: { class: 'axm-trace-timeline-page block w-full min-h-0' },\n})\nexport class AXMTraceTimelinePageComponent extends AXPPageLayoutBaseComponent {\n private readonly queryExecutor = inject(AXPQueryExecutor);\n private readonly translationService = inject(AXTranslationService);\n\n /** Entity record from TraceEntry detail host. */\n rootContext = input<Record<string, unknown>>();\n pageConfig = input<Record<string, unknown>>();\n\n readonly loading = signal(true);\n readonly timeline = signal<TraceTimelineDto | null>(null);\n readonly spanRows = signal<TimelineSpanRow[]>([]);\n readonly spansLabel = signal('Spans');\n\n readonly spanCountBadge = computed(() => `${this.spanRows().length} ${this.spansLabel()}`);\n\n readonly dataSource = signal(convertArrayToDataSource<TimelineSpanRow>([], { key: 'id', pageSize: 100 }));\n\n readonly traceId = computed(() => {\n const ctx = this.rootContext() ?? {};\n const fromTraceId = typeof ctx['traceId'] === 'string' ? ctx['traceId'].trim() : '';\n if (fromTraceId) {\n return fromTraceId;\n }\n const fromId = typeof ctx['id'] === 'string' ? ctx['id'].trim() : '';\n return fromId;\n });\n\n #loadEffect = effect(() => {\n const id = this.traceId();\n void this.loadTimeline(id);\n });\n\n constructor() {\n super();\n void this.translationService\n .translateAsync('@system-insight:pages.trace-timeline.spans')\n .then((label) => this.spansLabel.set(label));\n }\n\n override async getPageTitle(): Promise<string> {\n return this.translationService.translateAsync('@system-insight:pages.trace-timeline.title');\n }\n\n goToRelatedLogs(): void {\n const traceId = this.timeline()?.traceId ?? this.traceId();\n if (!traceId) {\n return;\n }\n const app = this.sessionService.application?.name;\n if (!app) {\n return;\n }\n void this.router.navigate([`/${app}/m/SystemInsight/e/LogEntry/list`], {\n queryParams: { traceId },\n });\n }\n\n private async loadTimeline(traceId: string): Promise<void> {\n if (!traceId) {\n this.timeline.set(null);\n this.spanRows.set([]);\n this.dataSource.set(convertArrayToDataSource<TimelineSpanRow>([], { key: 'id', pageSize: 100 }));\n this.loading.set(false);\n return;\n }\n\n this.loading.set(true);\n try {\n const result = await this.queryExecutor.fetch<string, TraceTimelineDto>(\n AXMSystemInsightQueryKeys.TraceTimeline.Get,\n traceId,\n );\n const timeline = runtimeQueryPayloadData(result) ?? null;\n const rows = this.buildSpanRows(timeline);\n this.timeline.set(timeline);\n this.spanRows.set(rows);\n this.dataSource.set(convertArrayToDataSource(rows, { key: 'id', pageSize: 100 }));\n this.recompute();\n } finally {\n this.loading.set(false);\n }\n }\n\n private buildSpanRows(timeline: TraceTimelineDto | null | undefined): TimelineSpanRow[] {\n if (!timeline?.spans?.length) {\n return [];\n }\n\n const spanStarts = timeline.spans\n .map((span) => Date.parse(span.startTime))\n .filter((value) => Number.isFinite(value));\n const rootStart = spanStarts.length ? Math.min(...spanStarts) : Date.parse(timeline.startTime) || 0;\n const maxEnd = Math.max(\n ...timeline.spans.map((span) => {\n const start = Date.parse(span.startTime);\n const startMs = Number.isFinite(start) ? start : rootStart;\n return startMs + (span.duration || 0);\n }),\n rootStart + (timeline.duration || 0),\n );\n const total = Math.max(maxEnd - rootStart, timeline.duration || 1, 1);\n\n return timeline.spans.map((span) => {\n const start = Date.parse(span.startTime);\n const offsetMs = Number.isFinite(start) ? Math.max(0, start - rootStart) : 0;\n const widthPercent = Math.max(3, Math.min(100, ((span.duration || 0) / total) * 100));\n const offsetPercent = Math.max(0, Math.min(100 - widthPercent, (offsetMs / total) * 100));\n return {\n ...span,\n offsetPercent,\n widthPercent,\n durationShare: span.duration ?? 0,\n };\n });\n }\n}\n","//#region ---- Imports ----\n\nimport {\n arrangeWorkflowDiagram,\n type AXPWorkflowDiagramModel,\n type AXPWorkflowNode,\n type AXPWorkflowSemanticColor,\n} from '@acorex-platform/module-platform-management-client';\nimport type { TraceSpanDto, TraceTimelineDto } from '@acorex-platform/module-system-insight-client/contracts';\n\n//#endregion\n\n//#region ---- Constants ----\n\nconst DEFAULT_NODE_W = 220;\nconst DEFAULT_NODE_H = 88;\n\n//#endregion\n\n//#region ---- Helpers ----\n\nfunction spanTitle(span: TraceSpanDto): string {\n if (span.middlewareName) {\n return span.middlewareName;\n }\n return span.operationName;\n}\n\nfunction spanSubtitle(span: TraceSpanDto): string {\n const parts: string[] = [];\n if (span.spanKind) {\n parts.push(span.spanKind);\n }\n if (span.duration != null) {\n parts.push(`${span.duration} ms`);\n }\n if (span.nextMiddleware) {\n parts.push(`→ ${span.nextMiddleware}`);\n }\n return parts.join(' · ');\n}\n\nfunction statusColors(status: string | undefined): {\n color?: AXPWorkflowSemanticColor;\n borderColor?: AXPWorkflowSemanticColor;\n} {\n if (status === 'error') {\n return { color: 'danger', borderColor: 'danger' };\n }\n if (status === 'running') {\n return { color: 'warning', borderColor: 'warning' };\n }\n return { borderColor: 'success' };\n}\n\nfunction sortSpans(spans: TraceSpanDto[]): TraceSpanDto[] {\n return [...spans].sort((a, b) => {\n const aStart = Date.parse(a.startTime) || 0;\n const bStart = Date.parse(b.startTime) || 0;\n if (aStart !== bStart) {\n return aStart - bStart;\n }\n return (a.order ?? 0) - (b.order ?? 0);\n });\n}\n\nexport function resolveRootOpSpanId(spans: TraceSpanDto[]): string | undefined {\n const ops = spans.filter((span) => span.spanKind === 'op');\n const rootOp = ops.find((span) => !span.parentSpanId);\n return rootOp?.spanId ?? ops[0]?.spanId;\n}\n\nexport function hasChildSpans(spans: TraceSpanDto[], parentSpanId: string): boolean {\n return spans.some((span) => span.parentSpanId === parentSpanId);\n}\n\nfunction childrenByParent(spans: TraceSpanDto[]): Map<string, TraceSpanDto[]> {\n const map = new Map<string, TraceSpanDto[]>();\n for (const span of spans) {\n const parentId = span.parentSpanId;\n if (!parentId) {\n continue;\n }\n const siblings = map.get(parentId);\n if (siblings) {\n siblings.push(span);\n } else {\n map.set(parentId, [span]);\n }\n }\n for (const [parentId, siblings] of map) {\n map.set(parentId, sortSpans(siblings));\n }\n return map;\n}\n\n/**\n * Current layer under a focused op:\n * - flatten onion middleware/backend descendants\n * - stop at nested `op` spans (those stay one drill-in step)\n */\nfunction layerSpansForFocus(spans: TraceSpanDto[], focusSpanId: string): TraceSpanDto[] {\n const childrenOf = childrenByParent(spans);\n const layer: TraceSpanDto[] = [];\n\n const visit = (parentId: string): void => {\n const children = childrenOf.get(parentId) ?? [];\n for (const child of children) {\n layer.push(child);\n if (child.spanKind !== 'op') {\n visit(child.spanId);\n }\n }\n };\n\n visit(focusSpanId);\n return layer;\n}\n\n//#endregion\n\n//#region ---- Builder ----\n\nexport function buildTraceFlowDiagram(\n timeline: TraceTimelineDto | null | undefined,\n focusSpanId?: string | null,\n): AXPWorkflowDiagramModel | null {\n if (!timeline?.spans?.length) {\n return null;\n }\n\n const spans = sortSpans(timeline.spans);\n const activeOpId = focusSpanId ?? resolveRootOpSpanId(spans);\n if (!activeOpId) {\n return null;\n }\n\n const layerSpans = layerSpansForFocus(spans, activeOpId);\n if (!layerSpans.length) {\n return null;\n }\n\n const nodes: AXPWorkflowNode[] = layerSpans.map((span, index) => {\n const colors = statusColors(span.status);\n const isNestedOp = span.spanKind === 'op';\n const drillable = isNestedOp && hasChildSpans(spans, span.spanId);\n\n return {\n id: span.spanId,\n type: span.spanKind ?? 'span',\n title: spanTitle(span),\n icon: isNestedOp\n ? 'fa-light fa-diagram-project'\n : span.spanKind === 'middleware'\n ? 'fa-light fa-layer-group'\n : span.spanKind === 'backend'\n ? 'fa-light fa-database'\n : 'fa-light fa-play',\n shape: 'rounded-rectangle',\n position: { x: index * 280, y: 40 },\n size: { width: DEFAULT_NODE_W, height: DEFAULT_NODE_H },\n inboundPorts: [{ id: `${span.spanId}:in`, kind: 'inbound', side: 'left', ratio: 0.5 }],\n outboundPorts: [{ id: `${span.spanId}:out`, kind: 'outbound', side: 'right', ratio: 0.5 }],\n readonly: true,\n color: colors.color as AXPWorkflowSemanticColor | undefined,\n borderColor: colors.borderColor as AXPWorkflowSemanticColor | undefined,\n data: {\n subtitle: spanSubtitle(span),\n span,\n drillable,\n drillTarget: drillable ? span.spanId : undefined,\n },\n };\n });\n\n const connectors = [];\n for (let i = 0; i < nodes.length - 1; i += 1) {\n const source = nodes[i];\n const target = nodes[i + 1];\n const sourceSpan = layerSpans[i];\n connectors.push({\n id: `${source.id}->${target.id}`,\n sourceNodeId: source.id,\n sourcePortId: `${source.id}:out`,\n targetNodeId: target.id,\n targetPortId: `${target.id}:in`,\n readonly: true,\n borderColor: (sourceSpan.status === 'error' ? 'danger' : 'primary') as AXPWorkflowSemanticColor,\n });\n }\n\n return arrangeWorkflowDiagram(\n {\n nodes,\n connectors,\n data: {\n traceId: timeline.traceId,\n kind: timeline.kind,\n operation: timeline.operation,\n focusSpanId: activeOpId,\n },\n },\n { direction: 'horizontal' },\n );\n}\n\n//#endregion\n","//#region ---- Trace flow display normalization ----\n\n/**\n * Prepares a value for the Trace Flow detail viewer:\n * - plain string → unchanged\n * - JSON string → parsed object/array (recursively)\n * - object/array → nested JSON strings expanded\n */\nexport function normalizeTraceDisplayValue(value: unknown, depth = 0): unknown {\n if (depth > 8) {\n return value;\n }\n\n if (typeof value === 'string') {\n return tryParseJsonString(value, depth);\n }\n\n if (Array.isArray(value)) {\n return value.map((entry) => normalizeTraceDisplayValue(entry, depth + 1));\n }\n\n if (value && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {\n result[key] = normalizeTraceDisplayValue(entry, depth + 1);\n }\n return result;\n }\n\n return value;\n}\n\nfunction tryParseJsonString(value: string, depth: number): unknown {\n const trimmed = value.trim();\n if (!trimmed) {\n return value;\n }\n\n const looksLikeJson =\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']')) ||\n ((trimmed.startsWith('\"') && trimmed.endsWith('\"')) && trimmed.length > 1);\n\n if (!looksLikeJson) {\n return value;\n }\n\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n return normalizeTraceDisplayValue(parsed, depth + 1);\n } catch {\n return value;\n }\n}\n\n//#endregion\n","//#region ---- Imports ----\n\nimport { AXBadgeModule } from '@acorex/components/badge';\nimport { AXButtonModule } from '@acorex/components/button';\nimport { AXLoadingModule } from '@acorex/components/loading';\nimport { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';\nimport {\n AXPPageLayoutBase,\n AXPPageLayoutBaseComponent,\n} from '@acorex-platform/framework-client/layout/views';\nimport { AXPQueryExecutor } from '@acorex-platform/framework-client/runtime';\nimport { runtimeQueryPayloadData } from '@acorex-platform/framework-shared/core';\nimport {\n AXMSystemInsightQueryKeys,\n type TraceSpanDto,\n type TraceTimelineDto,\n} from '@acorex-platform/module-system-insight-client/contracts';\nimport {\n AXPWorkflowDesignerComponent,\n type AXPWorkflowDiagramModel,\n type AXPWorkflowNode,\n} from '@acorex-platform/module-platform-management-client';\nimport { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport {\n buildTraceFlowDiagram,\n resolveRootOpSpanId,\n} from './trace-flow-diagram.utils';\nimport { normalizeTraceDisplayValue } from './trace-flow-display.util';\n\n//#endregion\n\n//#region ---- Types ----\n\ninterface TraceFlowBreadcrumbItem {\n spanId: string;\n label: string;\n}\n\n//#endregion\n\n//#region ---- Component ----\n\n/**\n * TraceEntry detail tab — readonly flow chart of spans (middleware chain),\n * same hosting pattern as Timeline / workflow history Visual.\n */\n@Component({\n selector: 'axm-trace-flow-page',\n standalone: true,\n imports: [\n CommonModule,\n AXBadgeModule,\n AXButtonModule,\n AXLoadingModule,\n AXTranslationModule,\n AXPWorkflowDesignerComponent,\n ],\n templateUrl: './trace-flow-page.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: AXPPageLayoutBase,\n useExisting: AXMTraceFlowPageComponent,\n },\n ],\n host: { class: 'axm-trace-flow-page block w-full min-h-0' },\n})\nexport class AXMTraceFlowPageComponent extends AXPPageLayoutBaseComponent {\n //#region ---- Services & Dependencies ----\n\n private readonly queryExecutor = inject(AXPQueryExecutor);\n private readonly translationService = inject(AXTranslationService);\n\n //#endregion\n\n //#region ---- Inputs ----\n\n /** Entity record from TraceEntry detail host. */\n rootContext = input<Record<string, unknown>>();\n pageConfig = input<Record<string, unknown>>();\n\n //#endregion\n\n //#region ---- State Signals ----\n\n readonly loading = signal(true);\n readonly timeline = signal<TraceTimelineDto | null>(null);\n readonly selectedSpan = signal<TraceSpanDto | null>(null);\n readonly focusSpanStack = signal<string[]>([]);\n #suppressNodeDrill = false;\n\n readonly focusSpanId = computed(() => {\n const stack = this.focusSpanStack();\n if (stack.length) {\n return stack[stack.length - 1];\n }\n const spans = this.timeline()?.spans;\n return spans?.length ? resolveRootOpSpanId(spans) : undefined;\n });\n\n readonly diagram = computed<AXPWorkflowDiagramModel | null>(() =>\n buildTraceFlowDiagram(this.timeline(), this.focusSpanId()),\n );\n\n readonly drillBreadcrumbs = computed<TraceFlowBreadcrumbItem[]>(() => {\n const timeline = this.timeline();\n if (!timeline?.spans?.length) {\n return [];\n }\n\n const spans = timeline.spans;\n const rootId = resolveRootOpSpanId(spans);\n if (!rootId) {\n return [];\n }\n\n const items: TraceFlowBreadcrumbItem[] = [];\n const rootSpan = spans.find((span) => span.spanId === rootId);\n items.push({\n spanId: rootId,\n label: rootSpan?.operationName ?? timeline.operation ?? rootId,\n });\n\n for (const spanId of this.focusSpanStack()) {\n const span = spans.find((item) => item.spanId === spanId);\n if (span) {\n items.push({ spanId, label: span.operationName });\n }\n }\n\n return items;\n });\n\n readonly highlightedNodeIds = computed(() => {\n const id = this.selectedSpan()?.spanId;\n return id ? [id] : [];\n });\n\n readonly traceId = computed(() => {\n const ctx = this.rootContext() ?? {};\n const fromTraceId = typeof ctx['traceId'] === 'string' ? ctx['traceId'].trim() : '';\n if (fromTraceId) {\n return fromTraceId;\n }\n const fromId = typeof ctx['id'] === 'string' ? ctx['id'].trim() : '';\n return fromId;\n });\n\n //#endregion\n\n //#region ---- Lifecycle ----\n\n #loadEffect = effect(() => {\n const id = this.traceId();\n void this.loadTimeline(id);\n });\n\n //#endregion\n\n //#region ---- Page metadata ----\n\n override async getPageTitle(): Promise<string> {\n return this.translationService.translateAsync('@system-insight:pages.trace-flow.title');\n }\n\n //#endregion\n\n //#region ---- Event Handlers ----\n\n onNodeClick(event: { node: AXPWorkflowNode }): void {\n const nodeId = event.node.id;\n const fromData = event.node.data?.['span'] as TraceSpanDto | undefined;\n const fromTimeline = this.timeline()?.spans?.find(\n (span) => span.spanId === nodeId || span.id === nodeId,\n );\n const span = fromData ?? fromTimeline ?? null;\n this.selectedSpan.set(span);\n\n const drillTarget = event.node.data?.['drillTarget'];\n if (\n !this.#suppressNodeDrill &&\n typeof drillTarget === 'string' &&\n drillTarget &&\n !this.focusSpanStack().includes(drillTarget)\n ) {\n this.#suppressNodeDrill = true;\n this.focusSpanStack.update((stack) => [...stack, drillTarget]);\n this.#releaseDrillSuppress();\n }\n\n this.recompute();\n }\n\n onBreadcrumbClick(index: number): void {\n this.#suppressNodeDrill = true;\n if (index <= 0) {\n this.focusSpanStack.set([]);\n } else {\n this.focusSpanStack.set(this.focusSpanStack().slice(0, index));\n }\n this.selectedSpan.set(null);\n this.#releaseDrillSuppress();\n this.recompute();\n }\n\n hasValue(value: unknown): boolean {\n if (value === undefined || value === null) {\n return false;\n }\n if (typeof value === 'string') {\n return value.trim().length > 0;\n }\n if (Array.isArray(value)) {\n return value.length > 0;\n }\n if (typeof value === 'object') {\n return Object.keys(value as Record<string, unknown>).length > 0;\n }\n return true;\n }\n\n /**\n * Display rules:\n * - plain string → as-is\n * - JSON string → parse, then pretty JSON\n * - object/array → pretty JSON (nested JSON strings also expanded)\n */\n formatJson(value: unknown): string {\n const normalized = normalizeTraceDisplayValue(value);\n if (typeof normalized === 'string') {\n return normalized;\n }\n try {\n return JSON.stringify(normalized, null, 2);\n } catch {\n return String(value);\n }\n }\n\n //#endregion\n\n //#region ---- Drill-in ----\n\n #releaseDrillSuppress(): void {\n queueMicrotask(() => {\n setTimeout(() => {\n this.#suppressNodeDrill = false;\n }, 250);\n });\n }\n\n //#endregion\n\n //#region ---- Data Loading ----\n\n private async loadTimeline(traceId: string): Promise<void> {\n if (!traceId) {\n this.timeline.set(null);\n this.selectedSpan.set(null);\n this.focusSpanStack.set([]);\n this.loading.set(false);\n return;\n }\n\n this.loading.set(true);\n try {\n const result = await this.queryExecutor.fetch<string, TraceTimelineDto>(\n AXMSystemInsightQueryKeys.TraceTimeline.Get,\n traceId,\n );\n const timeline = runtimeQueryPayloadData(result) ?? null;\n this.#suppressNodeDrill = true;\n this.timeline.set(timeline);\n this.focusSpanStack.set([]);\n this.selectedSpan.set(null);\n this.recompute();\n this.#releaseDrillSuppress();\n } finally {\n this.loading.set(false);\n }\n }\n\n //#endregion\n}\n\n//#endregion\n","<!-- ----- Trace flow chart page ----- -->\n<div class=\"axm-trace-flow flex flex-col gap-4 p-4 w-full min-h-0 h-full\">\n @if (loading()) {\n <!-- ----- Loading indicator while timeline is fetched ----- -->\n <div class=\"flex justify-center py-10\">\n <ax-loading />\n </div>\n }\n <!-- ----- Empty state when timeline is missing ----- -->\n @else if (!timeline()) {\n <p class=\"typo-caption text-muted\">\n {{ '@system-insight:pages.trace-flow.not-found' | translate | async }}\n </p>\n }\n <!-- ----- Flow chart + span details ----- -->\n @else {\n <div class=\"flex flex-wrap items-center gap-2\">\n @if (timeline()?.kind; as kind) {\n <ax-badge [text]=\"kind\" color=\"primary\" size=\"sm\"></ax-badge>\n }\n @if (timeline()?.operation; as operation) {\n <span class=\"text-sm\">{{ operation }}</span>\n }\n <span class=\"text-sm text-muted ms-auto\">\n {{ '@system-insight:pages.trace-flow.duration' | translate | async }}:\n {{ timeline()?.duration }} ms\n </span>\n </div>\n\n @if (drillBreadcrumbs().length > 1) {\n <!-- ----- Breadcrumb drill-in path ----- -->\n <nav class=\"flex flex-wrap items-center gap-1 text-sm\" aria-label=\"Trace flow layers\">\n @for (item of drillBreadcrumbs(); track item.spanId; let i = $index) {\n @if (i > 0) {\n <span class=\"text-muted px-1\">/</span>\n }\n @if (i < drillBreadcrumbs().length - 1) {\n <button\n type=\"button\"\n class=\"text-primary hover:underline truncate max-w-[240px]\"\n (click)=\"onBreadcrumbClick(i)\"\n >\n {{ item.label }}\n </button>\n }\n <!-- ----- Current layer label (not clickable) ----- -->\n @else {\n <span class=\"font-medium truncate max-w-[320px]\">{{ item.label }}</span>\n }\n }\n </nav>\n }\n\n <div class=\"axm-trace-flow__canvas border border-lightest rounded-md overflow-hidden min-h-[360px] flex-1\">\n @if (diagram(); as model) {\n <!-- ----- Readonly span flow chart ----- -->\n <axp-workflow-designer\n [model]=\"model\"\n [readonly]=\"true\"\n [showPortLabels]=\"false\"\n [highlightedNodeIds]=\"highlightedNodeIds()\"\n (nodeClick)=\"onNodeClick($event)\"\n />\n }\n <!-- ----- Empty diagram fallback ----- -->\n @else {\n <p class=\"typo-caption text-muted p-4\">\n {{ '@system-insight:pages.trace-flow.empty' | translate | async }}\n </p>\n }\n </div>\n\n @if (selectedSpan(); as span) {\n <!-- ----- Selected span details (metadata + IO) ----- -->\n <div class=\"border border-lightest rounded-md p-4 flex flex-col gap-4\">\n <div class=\"flex flex-wrap items-center gap-2\">\n <strong class=\"text-base\">{{ span.operationName }}</strong>\n @if (span.spanKind) {\n <ax-badge [text]=\"span.spanKind\" color=\"primary\" size=\"sm\"></ax-badge>\n }\n @if (span.middlewareName) {\n <ax-badge [text]=\"span.middlewareName\" color=\"secondary\" size=\"sm\"></ax-badge>\n }\n @if (span.status) {\n <ax-badge\n [text]=\"span.status\"\n [color]=\"span.status === 'error' ? 'danger' : 'success'\"\n size=\"sm\"\n ></ax-badge>\n }\n </div>\n\n <!-- ----- Span metadata grid ----- -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-3 text-sm\">\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.span-id' | translate | async }}\n </div>\n <div class=\"font-mono break-all\">{{ span.spanId }}</div>\n </div>\n @if (span.parentSpanId) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.parent-span-id' | translate | async }}\n </div>\n <div class=\"font-mono break-all\">{{ span.parentSpanId }}</div>\n </div>\n }\n @if (span.serviceName) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.service-name' | translate | async }}\n </div>\n <div>{{ span.serviceName }}</div>\n </div>\n }\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.duration' | translate | async }}\n </div>\n <div>{{ span.duration ?? 0 }} ms</div>\n </div>\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.start-time' | translate | async }}\n </div>\n <div>{{ span.startTime }}</div>\n </div>\n @if (span.order != null) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:fields.order' | translate | async }}\n </div>\n <div>{{ span.order }}</div>\n </div>\n }\n @if (span.nextMiddleware) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@system-insight:pages.trace-flow.next-middleware' | translate | async }}\n </div>\n <div>{{ span.nextMiddleware }}</div>\n </div>\n }\n </div>\n\n @if (span.error) {\n <!-- ----- Span error ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1 text-danger\">\n {{ '@system-insight:fields.error' | translate | async }}\n </div>\n <pre class=\"text-sm whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-40\">{{\n span.error\n }}</pre>\n </div>\n }\n\n <!-- ----- Input snapshot (always visible) ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.input' | translate | async }}\n </div>\n @if (hasValue(span.input)) {\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.input)\n }}</pre>\n }\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@system-insight:pages.trace-flow.no-input' | translate | async }}\n </p>\n }\n </div>\n\n <!-- ----- Output snapshot (always visible) ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.output' | translate | async }}\n </div>\n @if (hasValue(span.output)) {\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.output)\n }}</pre>\n }\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@system-insight:pages.trace-flow.no-output' | translate | async }}\n </p>\n }\n </div>\n\n @if (hasValue(span.tags)) {\n <!-- ----- Span tags / attributes ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.attributes' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.tags)\n }}</pre>\n </div>\n }\n\n @if (span.logs?.length) {\n <!-- ----- Span logs / events ----- -->\n <div>\n <div class=\"text-sm font-medium mb-1\">\n {{ '@system-insight:pages.trace-flow.events' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(span.logs)\n }}</pre>\n </div>\n }\n </div>\n }\n }\n</div>\n"],"names":["i2","i3","i4"],"mappings":"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"}
|
|
@@ -1,35 +1,15 @@
|
|
|
1
1
|
import { AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/auth';
|
|
2
|
-
import {
|
|
2
|
+
import { provideLazyProvider } from '@acorex-platform/framework-client/core';
|
|
3
3
|
import { AXP_PAGE_COMPONENT_PROVIDER } from '@acorex-platform/framework-client/layout/components';
|
|
4
4
|
import { AXPRuntimeModule, provideCommandSetups } from '@acorex-platform/framework-client/runtime';
|
|
5
5
|
import * as i0 from '@angular/core';
|
|
6
6
|
import { inject, Injectable, NgModule } from '@angular/core';
|
|
7
7
|
import { AXPSearchCommandProvider, AXP_MENU_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER, AXP_SEARCH_PROVIDER } from '@acorex-platform/framework-client/common';
|
|
8
|
-
import { RootConfig, AXPAdministrationPermissionKeys, AXMSystemInsightMenuKeys, AXPSystemInsightSettings } from '@acorex-platform/module-system-insight-client/contracts';
|
|
9
8
|
import { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';
|
|
10
9
|
import { AXPCommonMenuKeys, AXPCommonPermissionGroupKeys } from '@acorex-platform/module-common-client/contracts';
|
|
10
|
+
import { RootConfig, AXPAdministrationPermissionKeys, AXMSystemInsightMenuKeys, AXPSystemInsightSettings } from '@acorex-platform/module-system-insight-client/contracts';
|
|
11
11
|
import { AXPWidgetsList } from '@acorex-platform/framework-shared/core';
|
|
12
12
|
|
|
13
|
-
//#region ---- Imports ----
|
|
14
|
-
//#endregion
|
|
15
|
-
//#region ---- Manifest Definition ----
|
|
16
|
-
/**
|
|
17
|
-
* System Insight Module Manifest.
|
|
18
|
-
* Defines module metadata, features, and provider references.
|
|
19
|
-
*/
|
|
20
|
-
const SystemInsightManifest = {
|
|
21
|
-
name: RootConfig.module.name,
|
|
22
|
-
version: '1.0.0',
|
|
23
|
-
title: RootConfig.module.title,
|
|
24
|
-
icon: RootConfig.module.icon,
|
|
25
|
-
i18n: RootConfig.config.i18n,
|
|
26
|
-
type: 'platform',
|
|
27
|
-
domain: 'platform',
|
|
28
|
-
// Module dependencies
|
|
29
|
-
dependencies: ['ReportManagement'],
|
|
30
|
-
};
|
|
31
|
-
//#endregion
|
|
32
|
-
|
|
33
13
|
//#region ---- Imports ----
|
|
34
14
|
//#endregion
|
|
35
15
|
class AXMSystemInsightMenuProvider {
|
|
@@ -329,8 +309,7 @@ class AXMSystemInsightModule {
|
|
|
329
309
|
command: () => import('./acorex-platform-module-system-insight-client-open-trace-timeline.command-DPbr-AYZ.mjs').then((m) => m.AXMOpenTraceTimelineCommand),
|
|
330
310
|
},
|
|
331
311
|
]),
|
|
332
|
-
provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-platform-module-system-insight-client-index-
|
|
333
|
-
{ provide: AXP_MODULE_MANIFEST_PROVIDER, useValue: SystemInsightManifest, multi: true },
|
|
312
|
+
provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-platform-module-system-insight-client-index-B-pPInVq.mjs').then((m) => m.AXMTraceTimelinePageComponentProvider)),
|
|
334
313
|
{ provide: AXP_PERMISSION_DEFINITION_PROVIDER, useClass: AXMSystemInsightPermissionDefinitionProvider, multi: true },
|
|
335
314
|
{ provide: AXP_MENU_PROVIDER, useClass: AXMSystemInsightMenuProvider, multi: true },
|
|
336
315
|
{ provide: AXP_SETTING_DEFINITION_PROVIDER, useClass: AXPSystemInsightSettingProvider, multi: true },
|
|
@@ -348,8 +327,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
348
327
|
command: () => import('./acorex-platform-module-system-insight-client-open-trace-timeline.command-DPbr-AYZ.mjs').then((m) => m.AXMOpenTraceTimelineCommand),
|
|
349
328
|
},
|
|
350
329
|
]),
|
|
351
|
-
provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-platform-module-system-insight-client-index-
|
|
352
|
-
{ provide: AXP_MODULE_MANIFEST_PROVIDER, useValue: SystemInsightManifest, multi: true },
|
|
330
|
+
provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-platform-module-system-insight-client-index-B-pPInVq.mjs').then((m) => m.AXMTraceTimelinePageComponentProvider)),
|
|
353
331
|
{ provide: AXP_PERMISSION_DEFINITION_PROVIDER, useClass: AXMSystemInsightPermissionDefinitionProvider, multi: true },
|
|
354
332
|
{ provide: AXP_MENU_PROVIDER, useClass: AXMSystemInsightMenuProvider, multi: true },
|
|
355
333
|
{ provide: AXP_SETTING_DEFINITION_PROVIDER, useClass: AXPSystemInsightSettingProvider, multi: true },
|