mirror of https://github.com/apache/nifi.git
[NIFI-13974] - Improve UX of Status History dialog (select all nodes, scrolling left panel) (#9493)
This closes #9493
This commit is contained in:
parent
4e4ce6f470
commit
11cb2c56e2
|
@ -55,87 +55,103 @@
|
|||
@if (instances.length > 0 && fieldDescriptors.length > 0) {
|
||||
@if (componentDetails$ | async; as componentDetails) {
|
||||
<div class="flex flex-1 w-full gap-x-4">
|
||||
<div class="component-details flex flex-col gap-y-3">
|
||||
@for (detail of details; track detail) {
|
||||
@if (detail.key && detail.value) {
|
||||
<div class="component-details-panel relative h-full">
|
||||
<div
|
||||
class="component-details flex flex-col gap-y-3 overflow-y-auto absolute inset-0">
|
||||
@for (detail of details; track detail) {
|
||||
@if (detail.key && detail.value) {
|
||||
<div class="flex flex-col">
|
||||
<div>{{ detail.key }}</div>
|
||||
<div
|
||||
[title]="detail.value"
|
||||
class="tertiary-color overflow-ellipsis overflow-hidden whitespace-nowrap font-medium">
|
||||
{{ detail.value }}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
<div class="flex flex-col">
|
||||
<div>Start</div>
|
||||
<div class="tertiary-color font-medium">
|
||||
{{ minDate }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div>End</div>
|
||||
<div class="tertiary-color font-medium">
|
||||
{{ maxDate }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="detail-item">
|
||||
<div>Min / Max / Mean</div>
|
||||
<div class="tertiary-color font-medium">
|
||||
{{ clusterStats.min }} / {{ clusterStats.max }} /
|
||||
{{ clusterStats.mean }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="legend-entry flex justify-between items-center mr-1">
|
||||
<mat-label
|
||||
[ngStyle]="{
|
||||
color: getColor(
|
||||
nodeStats,
|
||||
NIFI_NODE_CONFIG.nifiInstanceId
|
||||
)
|
||||
}"
|
||||
>NiFi
|
||||
</mat-label>
|
||||
<mat-checkbox
|
||||
value="nifi-instance-id"
|
||||
(change)="selectNode($event)"
|
||||
[checked]="
|
||||
!!instanceVisibility['nifi-instance-id']
|
||||
"></mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
@if (!!nodes && nodes.length > 0) {
|
||||
<div class="flex flex-col">
|
||||
<div>{{ detail.key }}</div>
|
||||
<div
|
||||
[title]="detail.value"
|
||||
class="tertiary-color overflow-ellipsis overflow-hidden whitespace-nowrap font-medium">
|
||||
{{ detail.value }}
|
||||
<div class="flex justify-between items-center border-b mr-1">
|
||||
<mat-label class="font-bold secondary-color"
|
||||
>Nodes
|
||||
</mat-label>
|
||||
<mat-checkbox
|
||||
class="tertiary-checkbox"
|
||||
[checked]="areAllNodesSelected(instanceVisibility)"
|
||||
[indeterminate]="
|
||||
areAnyNodesSelected(instanceVisibility)
|
||||
"
|
||||
(change)="selectAllNodesChanged($event)"></mat-checkbox>
|
||||
</div>
|
||||
<div>
|
||||
<div>Min / Max / Mean</div>
|
||||
<div class="tertiary-color font-medium">
|
||||
{{ nodeStats.min }} / {{ nodeStats.max }} /
|
||||
{{ nodeStats.mean }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="legend-entry mr-1">
|
||||
@for (node of nodes; track node.id) {
|
||||
@if (node.snapshots?.length) {
|
||||
<div class="flex justify-between items-start">
|
||||
<mat-label
|
||||
[ngStyle]="{
|
||||
color: getColor(nodeStats, node.id)
|
||||
}"
|
||||
>{{ node.label }}
|
||||
</mat-label>
|
||||
<mat-checkbox
|
||||
[value]="node.id"
|
||||
(change)="selectNode($event)"
|
||||
[checked]="
|
||||
!!instanceVisibility[node.id]
|
||||
"></mat-checkbox>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
<div class="flex flex-col">
|
||||
<div>Start</div>
|
||||
<div class="tertiary-color font-medium">
|
||||
{{ minDate }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div>End</div>
|
||||
<div class="tertiary-color font-medium">
|
||||
{{ maxDate }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="font-bold">NiFi</div>
|
||||
<div class="detail-item">
|
||||
<div>Min / Max / Mean</div>
|
||||
<div class="tertiary-color font-medium">
|
||||
{{ clusterStats.min }} / {{ clusterStats.max }} /
|
||||
{{ clusterStats.mean }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="legend-entry">
|
||||
<mat-checkbox
|
||||
value="nifi-instance-id"
|
||||
(change)="selectNode($event)"
|
||||
[checked]="
|
||||
!!instanceVisibility['nifi-instance-id']
|
||||
"></mat-checkbox>
|
||||
<mat-label
|
||||
[ngStyle]="{
|
||||
color: getColor(nodeStats, NIFI_NODE_CONFIG.nifiInstanceId)
|
||||
}"
|
||||
>NiFi</mat-label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@if (!!nodes && nodes.length > 0) {
|
||||
<div class="flex flex-col">
|
||||
<div>Nodes</div>
|
||||
<div>
|
||||
<div>Min / Max / Mean</div>
|
||||
<div class="tertiary-color font-medium">
|
||||
{{ nodeStats.min }} / {{ nodeStats.max }} /
|
||||
{{ nodeStats.mean }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="legend-entry">
|
||||
@for (node of nodes; track node) {
|
||||
@if (node.snapshots?.length) {
|
||||
<div class="flex">
|
||||
<mat-checkbox
|
||||
[value]="node.id"
|
||||
(change)="selectNode($event)"
|
||||
[checked]="
|
||||
!!instanceVisibility[node.id]
|
||||
"></mat-checkbox>
|
||||
<mat-label
|
||||
[ngStyle]="{
|
||||
color: getColor(nodeStats, node.id)
|
||||
}"
|
||||
>{{ node.label }}</mat-label
|
||||
>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="chart-panel grow flex flex-col">
|
||||
@if (fieldDescriptors$ | async) {
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
min-width: 495px;
|
||||
}
|
||||
|
||||
.component-details-panel,
|
||||
.component-details {
|
||||
min-width: 300px;
|
||||
max-width: 300px;
|
||||
|
|
|
@ -244,6 +244,30 @@ export class StatusHistory extends CloseOnEscapeDialog implements OnInit, AfterV
|
|||
|
||||
protected readonly TextTip = TextTip;
|
||||
|
||||
areAllNodesSelected(instanceVisibility: any): boolean {
|
||||
const unChecked = Object.entries(instanceVisibility)
|
||||
.filter(([node, checked]) => node !== 'nifi-instance-id' && !checked)
|
||||
.map(([, checked]) => checked);
|
||||
return unChecked.length === 0;
|
||||
}
|
||||
|
||||
areAnyNodesSelected(instanceVisibility: any): boolean {
|
||||
const checked = Object.entries(instanceVisibility)
|
||||
.filter(([node, checked]) => node !== 'nifi-instance-id' && checked)
|
||||
.map(([, checked]) => checked);
|
||||
return checked.length > 0 && checked.length < this.nodes.length;
|
||||
}
|
||||
|
||||
selectAllNodesChanged(event: MatCheckboxChange) {
|
||||
const checked: boolean = event.checked;
|
||||
const tmpInstanceVisibility: any = {};
|
||||
this.nodes.forEach((node: Instance) => {
|
||||
tmpInstanceVisibility[node.id] = checked;
|
||||
});
|
||||
tmpInstanceVisibility['nifi-instance-id'] = this.instanceVisibility['nifi-instance-id'];
|
||||
this.instanceVisibility = tmpInstanceVisibility;
|
||||
}
|
||||
|
||||
selectNode(event: MatCheckboxChange) {
|
||||
const instanceId: string = event.source.value;
|
||||
const checked: boolean = event.checked;
|
||||
|
|
Loading…
Reference in New Issue