Skip to content

Commit 8853198

Browse files
aarthy-dkclaude
andcommitted
feat(journeys): polish autodiscovery UI and fix DAG node positioning
- Separate pattern fields into "Component Autodiscovery" card/panel - Replace single-line inputs with textareas for multi-pattern entry - Add hint text explaining pattern syntax and matching behavior - Shorten labels, button text, and empty state message - Style preview list without bullets and smaller font - Fix DAG alignFloatingNodes to position new nodes after stored ones instead of overlapping them Ref: OBS-1996 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7705fc1 commit 8853198

File tree

5 files changed

+126
-35
lines changed

5 files changed

+126
-35
lines changed

observability_ui/apps/shell/src/app/projects/journeys/add-journey-dialog/add-journey-dialog.component.html

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,34 +22,47 @@
2222
rows="2"></textarea>
2323
</mat-form-field>
2424

25-
<text-field formControlName="component_include_patterns"
26-
label="Component include patterns"
27-
placeholder="Component include patterns">
28-
</text-field>
29-
30-
<text-field formControlName="component_exclude_patterns"
31-
label="Component exclude patterns"
32-
placeholder="Component exclude patterns">
33-
</text-field>
34-
35-
<div class="pattern-preview">
36-
<button mat-stroked-button
37-
type="button"
38-
(click)="previewComponents()"
39-
[disabled]="previewing">
40-
{{ previewing ? 'Previewing...' : 'Preview matching components' }}
41-
</button>
25+
<mat-expansion-panel class="mat-elevation-z0">
26+
<mat-expansion-panel-header>
27+
<mat-panel-title>
28+
Component Autodiscovery
29+
</mat-panel-title>
30+
</mat-expansion-panel-header>
4231

43-
<div *ngIf="previewResults !== null"
44-
class="preview-results">
45-
<span *ngIf="previewResults.length === 0"
46-
class="text--secondary">No components match the current patterns.</span>
47-
<ul *ngIf="previewResults.length > 0"
48-
class="preview-list">
49-
<li *ngFor="let c of previewResults">{{ c.key }}</li>
50-
</ul>
32+
<mat-form-field>
33+
<mat-label>Include patterns</mat-label>
34+
<textarea formControlName="component_include_patterns"
35+
placeholder="e.g. prod_*, staging_*"
36+
rows="2"
37+
matInput></textarea>
38+
<mat-hint>Matched against component keys. Comma or newline-separated. Wildcards: * ? [abc]</mat-hint>
39+
</mat-form-field>
40+
<mat-form-field>
41+
<mat-label>Exclude patterns</mat-label>
42+
<textarea formControlName="component_exclude_patterns"
43+
placeholder="e.g. test_*, dev_*"
44+
rows="2"
45+
matInput></textarea>
46+
<mat-hint>Components matching these are excluded even if they match an include pattern.</mat-hint>
47+
</mat-form-field>
48+
<div class="pattern-preview">
49+
<button mat-stroked-button
50+
type="button"
51+
(click)="previewComponents()"
52+
[disabled]="previewing">
53+
{{ previewing ? 'Previewing...' : 'Preview' }}
54+
</button>
55+
<div *ngIf="previewResults !== null"
56+
class="preview-results">
57+
<span *ngIf="previewResults.length === 0"
58+
class="text--secondary">No components found matching patterns.</span>
59+
<ul *ngIf="previewResults.length > 0"
60+
class="preview-list">
61+
<li *ngFor="let c of previewResults">{{ c.key }}</li>
62+
</ul>
63+
</div>
5164
</div>
52-
</div>
65+
</mat-expansion-panel>
5366

5467
<mat-expansion-panel class="mat-elevation-z0">
5568
<mat-expansion-panel-header>

observability_ui/apps/shell/src/app/projects/journeys/add-journey-dialog/add-journey-dialog.component.scss

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ textarea {
3636
max-height: 150px;
3737
overflow-y: auto;
3838
margin: 4px 0 0;
39-
padding-left: 20px;
39+
padding-left: 0;
40+
list-style: none;
41+
font-size: 13px;
4042
}
4143
}
4244

@@ -52,4 +54,8 @@ mat-expansion-panel {
5254
@include mixins.font-color(primary);
5355
}
5456
}
57+
58+
& + mat-expansion-panel {
59+
margin-top: 12px;
60+
}
5561
}

observability_ui/apps/shell/src/app/projects/journeys/journey-settings/journey-settings.component.html

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,62 @@
7272

7373
</mat-card-edit>
7474

75+
<mat-card-edit
76+
#patternsEditor
77+
title="Component Autodiscovery"
78+
[formGroup]="form"
79+
(save)="saveInfo(journey)"
80+
(cancel)="cancelInfoChanges(journey)"
81+
[saving]="saving$ | async"
82+
iconTooltip="Edit component autodiscovery"
83+
>
84+
<ng-container *ngIf="!patternsEditor.editing">
85+
<div class="text--secondary mb-1">Include patterns</div>
86+
<div class="pattern-value">{{ journey.component_include_patterns || '—' }}</div>
87+
88+
<div class="text--secondary mb-1 mt-3">Exclude patterns</div>
89+
<div class="pattern-value">{{ journey.component_exclude_patterns || '—' }}</div>
90+
</ng-container>
91+
92+
<ng-container *ngIf="patternsEditor.editing">
93+
<form [formGroup]="$any(form)">
94+
<mat-form-field>
95+
<mat-label>Include patterns</mat-label>
96+
<textarea formControlName="component_include_patterns"
97+
placeholder="e.g. prod_*, staging_*"
98+
rows="2"
99+
matInput></textarea>
100+
<mat-hint>Matched against component keys. Comma or newline-separated. Wildcards: * ? [abc]</mat-hint>
101+
</mat-form-field>
102+
<mat-form-field>
103+
<mat-label>Exclude patterns</mat-label>
104+
<textarea formControlName="component_exclude_patterns"
105+
placeholder="e.g. test_*, dev_*"
106+
rows="2"
107+
matInput></textarea>
108+
<mat-hint>Components matching these are excluded even if they match an include pattern.</mat-hint>
109+
</mat-form-field>
110+
<div class="pattern-preview">
111+
<button mat-stroked-button
112+
type="button"
113+
(click)="previewComponents()"
114+
[disabled]="previewing">
115+
{{ previewing ? 'Previewing...' : 'Preview' }}
116+
</button>
117+
<div *ngIf="previewResults !== null"
118+
class="preview-results">
119+
<span *ngIf="previewResults.length === 0"
120+
class="text--secondary">No components found matching patterns.</span>
121+
<ul *ngIf="previewResults.length > 0"
122+
class="preview-list">
123+
<li *ngFor="let c of previewResults">{{ c.key }}</li>
124+
</ul>
125+
</div>
126+
</div>
127+
</form>
128+
</ng-container>
129+
</mat-card-edit>
130+
75131
<mat-card-edit
76132
#conditionsEditor
77133
title="Instance Conditions"

observability_ui/apps/shell/src/app/projects/journeys/journey-settings/journey-settings.component.scss

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ mat-card-content {
3333
width: 100%;
3434
}
3535

36+
.pattern-value {
37+
white-space: pre-line;
38+
}
39+
3640
.pattern-preview {
3741
margin-top: 8px;
3842

@@ -44,6 +48,8 @@ mat-card-content {
4448
max-height: 150px;
4549
overflow-y: auto;
4650
margin: 4px 0 0;
47-
padding-left: 20px;
51+
padding-left: 0;
52+
list-style: none;
53+
font-size: 13px;
4854
}
4955
}

observability_ui/libs/ui/src/lib/dag/dag.component.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -566,23 +566,33 @@ export class DagComponent implements AfterViewInit {
566566

567567
const isHorizontal = orientation === DagOrientation.Horizontal;
568568

569+
// Phase 1: Restore stored positions and find the furthest extent
570+
const newNodes: DagNodeDirective[] = [];
569571
for (const node of looseNodes) {
570572
if (!node) continue;
571573

572-
// check if node has stored position
573574
const storedPosition = this.getStoredPosition(node);
574575
if (storedPosition) {
575576
node.x = storedPosition.x;
576577
node.y = storedPosition.y;
578+
if (isHorizontal) {
579+
previuoPosition.y = Math.max(previuoPosition.y, node.y);
580+
} else {
581+
previuoPosition.x = Math.max(previuoPosition.x, node.x);
582+
}
577583
} else {
578-
node.x = isHorizontal ? startingX : previuoPosition.x + node.width + 50;
579-
node.y = isHorizontal ? previuoPosition.y + node.height + 50 : startingY;
580-
581-
previuoPosition.y = node.y;
582-
previuoPosition.x = node.x;
583-
this.storeNodePosition(node);
584+
newNodes.push(node);
584585
}
586+
}
587+
588+
// Phase 2: Position new nodes after all existing ones
589+
for (const node of newNodes) {
590+
node.x = isHorizontal ? startingX : previuoPosition.x + node.width + 50;
591+
node.y = isHorizontal ? previuoPosition.y + node.height + 50 : startingY;
585592

593+
previuoPosition.y = node.y;
594+
previuoPosition.x = node.x;
595+
this.storeNodePosition(node);
586596
}
587597

588598
}

0 commit comments

Comments
 (0)