mirror of https://github.com/apache/nifi.git
[NIFI-12615] - fix ExpressionChanged error on Counters page. (#8252)
* [NIFI-12615] - fix ExpressionChanged error on Counters page. * * refactor sorting for extension-creation.component * refactor sorting for controller-service-table.component * refactor sorting for reporting-task--table.component * refactor sorting for parameter-context-table.component This closes #8252
This commit is contained in:
parent
c6f5f534cb
commit
b47ca20f56
|
@ -44,6 +44,7 @@
|
|||
[dataSource]="dataSource"
|
||||
matSort
|
||||
matSortDisableClear
|
||||
(matSortChange)="sortData($event)"
|
||||
[matSortActive]="initialSortColumn"
|
||||
[matSortDirection]="initialSortDirection">
|
||||
<!-- Context column -->
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AfterViewInit, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
|
||||
import { AfterViewInit, Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { CounterEntity } from '../../../state/counter-listing';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import { Sort } from '@angular/material/sort';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { debounceTime } from 'rxjs';
|
||||
import { NiFiCommon } from '../../../../../service/nifi-common.service';
|
||||
|
@ -39,24 +39,14 @@ export class CounterTable implements AfterViewInit {
|
|||
dataSource: MatTableDataSource<CounterEntity> = new MatTableDataSource<CounterEntity>();
|
||||
filterForm: FormGroup;
|
||||
|
||||
@Input() initialSortColumn: 'context' | 'name' = 'context';
|
||||
@Input() initialSortColumn: 'context' | 'name' | 'value' = 'context';
|
||||
@Input() initialSortDirection: 'asc' | 'desc' = 'asc';
|
||||
|
||||
@Input() set counters(counterEntities: CounterEntity[]) {
|
||||
this.dataSource = new MatTableDataSource<CounterEntity>(counterEntities);
|
||||
this.dataSource.sort = this.sort;
|
||||
this.dataSource.sortingDataAccessor = (data: CounterEntity, displayColumn: string) => {
|
||||
switch (displayColumn) {
|
||||
case 'context':
|
||||
return this.formatContext(data);
|
||||
case 'name':
|
||||
return this.formatName(data);
|
||||
case 'value':
|
||||
return data.valueCount;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
this.dataSource.data = this.sortEntities(counterEntities, {
|
||||
active: this.initialSortColumn,
|
||||
direction: this.initialSortDirection
|
||||
});
|
||||
|
||||
this.dataSource.filterPredicate = (data: CounterEntity, filter: string) => {
|
||||
const { filterTerm, filterColumn } = JSON.parse(filter);
|
||||
|
@ -93,8 +83,6 @@ export class CounterTable implements AfterViewInit {
|
|||
|
||||
@Output() resetCounter: EventEmitter<CounterEntity> = new EventEmitter<CounterEntity>();
|
||||
|
||||
@ViewChild(MatSort) sort!: MatSort;
|
||||
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
private nifiCommon: NiFiCommon
|
||||
|
@ -103,8 +91,6 @@ export class CounterTable implements AfterViewInit {
|
|||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.dataSource.sort = this.sort;
|
||||
|
||||
this.filterForm
|
||||
.get('filterTerm')
|
||||
?.valueChanges.pipe(debounceTime(500))
|
||||
|
@ -140,4 +126,32 @@ export class CounterTable implements AfterViewInit {
|
|||
event.stopPropagation();
|
||||
this.resetCounter.next(counter);
|
||||
}
|
||||
|
||||
sortData(sort: Sort) {
|
||||
this.dataSource.data = this.sortEntities(this.dataSource.data, sort);
|
||||
}
|
||||
|
||||
private sortEntities(data: CounterEntity[], sort: Sort): CounterEntity[] {
|
||||
if (!data) {
|
||||
return [];
|
||||
}
|
||||
return data.slice().sort((a, b) => {
|
||||
const isAsc = sort.direction === 'asc';
|
||||
let retVal = 0;
|
||||
switch (sort.active) {
|
||||
case 'name':
|
||||
retVal = this.nifiCommon.compareString(this.formatName(a), this.formatName(b));
|
||||
break;
|
||||
case 'value':
|
||||
retVal = this.nifiCommon.compareNumber(a.valueCount, b.valueCount);
|
||||
break;
|
||||
case 'context':
|
||||
retVal = this.nifiCommon.compareString(this.formatContext(a), this.formatContext(b));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return retVal * (isAsc ? 1 : -1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,14 @@
|
|||
|
||||
<div class="relative h-full border">
|
||||
<div class="listing-table absolute inset-0 overflow-y-auto">
|
||||
<table mat-table [dataSource]="dataSource" matSort matSortDisableClear>
|
||||
<table
|
||||
mat-table
|
||||
[dataSource]="dataSource"
|
||||
matSort
|
||||
matSortDisableClear
|
||||
(matSortChange)="sortData($event)"
|
||||
[matSortActive]="initialSortColumn"
|
||||
[matSortDirection]="initialSortDirection">
|
||||
<!-- More Details Column -->
|
||||
<ng-container matColumnDef="moreDetails">
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
|
@ -35,12 +42,7 @@
|
|||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th>
|
||||
<td mat-cell *matCellDef="let item">
|
||||
<ng-container *ngIf="canRead(item); else nameNoPermissions">
|
||||
{{ formatName(item) }}
|
||||
</ng-container>
|
||||
<ng-template #nameNoPermissions>
|
||||
<div class="unset">{{ item.id }}</div>
|
||||
</ng-template>
|
||||
<div [ngClass]="{ unset: !canRead(item) }">{{ formatName(item) }}</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
@ -48,9 +50,7 @@
|
|||
<ng-container matColumnDef="provider">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Provider</th>
|
||||
<td mat-cell *matCellDef="let item">
|
||||
<ng-container *ngIf="canRead(item)">
|
||||
{{ formatProvider(item) }}
|
||||
</ng-container>
|
||||
{{ formatProvider(item) }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
@ -58,9 +58,7 @@
|
|||
<ng-container matColumnDef="description">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Description</th>
|
||||
<td mat-cell *matCellDef="let item">
|
||||
<ng-container *ngIf="canRead(item)">
|
||||
{{ formatDescription(item) }}
|
||||
</ng-container>
|
||||
{{ formatDescription(item) }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|||
|
||||
import { ParameterContextTable } from './parameter-context-table.component';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatSortModule } from '@angular/material/sort';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
|
||||
describe('ParameterContextTable', () => {
|
||||
let component: ParameterContextTable;
|
||||
|
@ -27,7 +29,7 @@ describe('ParameterContextTable', () => {
|
|||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ParameterContextTable],
|
||||
imports: [MatTableModule]
|
||||
imports: [MatTableModule, MatSortModule, NoopAnimationsModule]
|
||||
});
|
||||
fixture = TestBed.createComponent(ParameterContextTable);
|
||||
component = fixture.componentInstance;
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AfterViewInit, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import { Sort } from '@angular/material/sort';
|
||||
import { NiFiCommon } from '../../../../../service/nifi-common.service';
|
||||
import { ParameterContextEntity } from '../../../state/parameter-context-listing';
|
||||
import { FlowConfiguration } from '../../../../../state/flow-configuration';
|
||||
|
@ -28,22 +28,15 @@ import { CurrentUser } from '../../../../../state/current-user';
|
|||
templateUrl: './parameter-context-table.component.html',
|
||||
styleUrls: ['./parameter-context-table.component.scss', '../../../../../../assets/styles/listing-table.scss']
|
||||
})
|
||||
export class ParameterContextTable implements AfterViewInit {
|
||||
export class ParameterContextTable {
|
||||
@Input() initialSortColumn: 'name' | 'provider' | 'description' = 'name';
|
||||
@Input() initialSortDirection: 'asc' | 'desc' = 'asc';
|
||||
|
||||
@Input() set parameterContexts(parameterContextEntities: ParameterContextEntity[]) {
|
||||
this.dataSource = new MatTableDataSource<ParameterContextEntity>(parameterContextEntities);
|
||||
this.dataSource.sort = this.sort;
|
||||
this.dataSource.sortingDataAccessor = (data: ParameterContextEntity, displayColumn: string) => {
|
||||
if (this.canRead(data)) {
|
||||
if (displayColumn === 'name') {
|
||||
return this.formatName(data);
|
||||
} else if (displayColumn === 'type') {
|
||||
return this.formatProvider(data);
|
||||
} else if (displayColumn === 'bundle') {
|
||||
return this.formatDescription(data);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
this.dataSource.data = this.sortEntities(parameterContextEntities, {
|
||||
active: this.initialSortColumn,
|
||||
direction: this.initialSortDirection
|
||||
});
|
||||
}
|
||||
|
||||
@Input() selectedParameterContextId!: string;
|
||||
|
@ -57,14 +50,8 @@ export class ParameterContextTable implements AfterViewInit {
|
|||
displayedColumns: string[] = ['moreDetails', 'name', 'provider', 'description', 'actions'];
|
||||
dataSource: MatTableDataSource<ParameterContextEntity> = new MatTableDataSource<ParameterContextEntity>();
|
||||
|
||||
@ViewChild(MatSort) sort!: MatSort;
|
||||
|
||||
constructor(private nifiCommon: NiFiCommon) {}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.dataSource.sort = this.sort;
|
||||
}
|
||||
|
||||
canRead(entity: ParameterContextEntity): boolean {
|
||||
return entity.permissions.canRead;
|
||||
}
|
||||
|
@ -74,7 +61,7 @@ export class ParameterContextTable implements AfterViewInit {
|
|||
}
|
||||
|
||||
formatName(entity: ParameterContextEntity): string {
|
||||
return entity.component.name;
|
||||
return this.canRead(entity) ? entity.component.name : entity.id;
|
||||
}
|
||||
|
||||
formatProvider(entity: ParameterContextEntity): string {
|
||||
|
@ -82,7 +69,7 @@ export class ParameterContextTable implements AfterViewInit {
|
|||
}
|
||||
|
||||
formatDescription(entity: ParameterContextEntity): string {
|
||||
return entity.component.description;
|
||||
return this.canRead(entity) ? entity.component.description : '';
|
||||
}
|
||||
|
||||
editClicked(entity: ParameterContextEntity, event: MouseEvent): void {
|
||||
|
@ -120,4 +107,33 @@ export class ParameterContextTable implements AfterViewInit {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
sortData(sort: Sort) {
|
||||
this.dataSource.data = this.sortEntities(this.dataSource.data, sort);
|
||||
}
|
||||
|
||||
private sortEntities(data: ParameterContextEntity[], sort: Sort): ParameterContextEntity[] {
|
||||
if (!data) {
|
||||
return [];
|
||||
}
|
||||
return data.slice().sort((a, b) => {
|
||||
const isAsc = sort.direction === 'asc';
|
||||
let retVal = 0;
|
||||
|
||||
switch (sort.active) {
|
||||
case 'name':
|
||||
retVal = this.nifiCommon.compareString(this.formatName(a), this.formatName(b));
|
||||
break;
|
||||
case 'provider':
|
||||
retVal = this.nifiCommon.compareString(this.formatProvider(a), this.formatProvider(b));
|
||||
break;
|
||||
case 'description':
|
||||
retVal = this.nifiCommon.compareString(this.formatDescription(a), this.formatDescription(b));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return retVal * (isAsc ? 1 : -1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,14 @@
|
|||
|
||||
<div class="relative h-full border">
|
||||
<div class="reporting-task-table listing-table absolute inset-0 overflow-y-auto">
|
||||
<table mat-table [dataSource]="dataSource" matSort matSortDisableClear>
|
||||
<table
|
||||
mat-table
|
||||
[dataSource]="dataSource"
|
||||
matSort
|
||||
matSortDisableClear
|
||||
(matSortChange)="sortData($event)"
|
||||
[matSortActive]="initialSortColumn"
|
||||
[matSortDirection]="initialSortDirection">
|
||||
<!-- More Details Column -->
|
||||
<ng-container matColumnDef="moreDetails">
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
|
@ -59,12 +66,7 @@
|
|||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th>
|
||||
<td mat-cell *matCellDef="let item">
|
||||
<ng-container *ngIf="canRead(item); else nameNoPermissions">
|
||||
{{ item.component.name }}
|
||||
</ng-container>
|
||||
<ng-template #nameNoPermissions>
|
||||
<div class="unset">{{ item.id }}</div>
|
||||
</ng-template>
|
||||
<div [ngClass]="{ unset: !canRead(item) }">{{ formatName(item) }}</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
@ -72,9 +74,7 @@
|
|||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Type</th>
|
||||
<td mat-cell *matCellDef="let item">
|
||||
<ng-container *ngIf="canRead(item)">
|
||||
{{ formatType(item) }}
|
||||
</ng-container>
|
||||
{{ formatType(item) }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
@ -82,9 +82,7 @@
|
|||
<ng-container matColumnDef="bundle">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Bundle</th>
|
||||
<td mat-cell *matCellDef="let item">
|
||||
<ng-container *ngIf="canRead(item)">
|
||||
{{ formatBundle(item) }}
|
||||
</ng-container>
|
||||
{{ formatBundle(item) }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|||
|
||||
import { ReportingTaskTable } from './reporting-task-table.component';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatSortModule } from '@angular/material/sort';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
|
||||
describe('ReportingTaskTable', () => {
|
||||
let component: ReportingTaskTable;
|
||||
|
@ -27,7 +29,7 @@ describe('ReportingTaskTable', () => {
|
|||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ReportingTaskTable],
|
||||
imports: [MatTableModule]
|
||||
imports: [MatTableModule, MatSortModule, NoopAnimationsModule]
|
||||
});
|
||||
fixture = TestBed.createComponent(ReportingTaskTable);
|
||||
component = fixture.componentInstance;
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AfterViewInit, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
|
||||
import { AfterViewInit, Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import { Sort } from '@angular/material/sort';
|
||||
import { ReportingTaskEntity } from '../../../state/reporting-tasks';
|
||||
import { TextTip } from '../../../../../ui/common/tooltips/text-tip/text-tip.component';
|
||||
import { BulletinsTip } from '../../../../../ui/common/tooltips/bulletins-tip/bulletins-tip.component';
|
||||
|
@ -32,23 +32,17 @@ import { CurrentUser } from '../../../../../state/current-user';
|
|||
templateUrl: './reporting-task-table.component.html',
|
||||
styleUrls: ['./reporting-task-table.component.scss', '../../../../../../assets/styles/listing-table.scss']
|
||||
})
|
||||
export class ReportingTaskTable implements AfterViewInit {
|
||||
export class ReportingTaskTable {
|
||||
@Input() initialSortColumn: 'name' | 'type' | 'bundle' | 'state' = 'name';
|
||||
@Input() initialSortDirection: 'asc' | 'desc' = 'asc';
|
||||
|
||||
@Input() set reportingTasks(reportingTaskEntities: ReportingTaskEntity[]) {
|
||||
this.dataSource = new MatTableDataSource<ReportingTaskEntity>(reportingTaskEntities);
|
||||
this.dataSource.sort = this.sort;
|
||||
this.dataSource.sortingDataAccessor = (data: ReportingTaskEntity, displayColumn: string) => {
|
||||
if (displayColumn === 'name') {
|
||||
return this.formatType(data);
|
||||
} else if (displayColumn === 'type') {
|
||||
return this.formatType(data);
|
||||
} else if (displayColumn === 'bundle') {
|
||||
return this.formatBundle(data);
|
||||
} else if (displayColumn === 'state') {
|
||||
return this.formatState(data);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
this.dataSource.data = this.sortEntities(reportingTaskEntities, {
|
||||
active: this.initialSortColumn,
|
||||
direction: this.initialSortDirection
|
||||
});
|
||||
}
|
||||
|
||||
@Input() selectedReportingTaskId!: string;
|
||||
@Input() flowConfiguration!: FlowConfiguration;
|
||||
@Input() currentUser!: CurrentUser;
|
||||
|
@ -66,14 +60,8 @@ export class ReportingTaskTable implements AfterViewInit {
|
|||
displayedColumns: string[] = ['moreDetails', 'name', 'type', 'bundle', 'state', 'actions'];
|
||||
dataSource: MatTableDataSource<ReportingTaskEntity> = new MatTableDataSource<ReportingTaskEntity>();
|
||||
|
||||
@ViewChild(MatSort) sort!: MatSort;
|
||||
|
||||
constructor(private nifiCommon: NiFiCommon) {}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.dataSource.sort = this.sort;
|
||||
}
|
||||
|
||||
canRead(entity: ReportingTaskEntity): boolean {
|
||||
return entity.permissions.canRead;
|
||||
}
|
||||
|
@ -156,12 +144,16 @@ export class ReportingTaskTable implements AfterViewInit {
|
|||
return entity.status?.activeThreadCount > 0;
|
||||
}
|
||||
|
||||
formatName(entity: ReportingTaskEntity): string {
|
||||
return this.canRead(entity) ? entity.component.name : entity.id;
|
||||
}
|
||||
|
||||
formatType(entity: ReportingTaskEntity): string {
|
||||
return this.nifiCommon.formatType(entity.component);
|
||||
return this.canRead(entity) ? this.nifiCommon.formatType(entity.component) : '';
|
||||
}
|
||||
|
||||
formatBundle(entity: ReportingTaskEntity): string {
|
||||
return this.nifiCommon.formatBundle(entity.component.bundle);
|
||||
return this.canRead(entity) ? this.nifiCommon.formatBundle(entity.component.bundle) : '';
|
||||
}
|
||||
|
||||
isDisabled(entity: ReportingTaskEntity): boolean {
|
||||
|
@ -259,4 +251,36 @@ export class ReportingTaskTable implements AfterViewInit {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
sortData(sort: Sort) {
|
||||
this.dataSource.data = this.sortEntities(this.dataSource.data, sort);
|
||||
}
|
||||
|
||||
private sortEntities(data: ReportingTaskEntity[], sort: Sort): ReportingTaskEntity[] {
|
||||
if (!data) {
|
||||
return [];
|
||||
}
|
||||
return data.slice().sort((a, b) => {
|
||||
const isAsc = sort.direction === 'asc';
|
||||
let retVal = 0;
|
||||
|
||||
switch (sort.active) {
|
||||
case 'name':
|
||||
retVal = this.nifiCommon.compareString(this.formatName(a), this.formatName(b));
|
||||
break;
|
||||
case 'type':
|
||||
retVal = this.nifiCommon.compareString(this.formatType(a), this.formatType(b));
|
||||
break;
|
||||
case 'bundle':
|
||||
retVal = this.nifiCommon.compareString(this.formatBundle(a), this.formatBundle(b));
|
||||
break;
|
||||
case 'state':
|
||||
retVal = this.nifiCommon.compareString(this.formatState(a), this.formatState(b));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return retVal * (isAsc ? 1 : -1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,14 @@
|
|||
|
||||
<div class="relative h-full border">
|
||||
<div class="controller-service-table listing-table absolute inset-0 overflow-y-auto">
|
||||
<table mat-table [dataSource]="dataSource" matSort matSortDisableClear>
|
||||
<table
|
||||
mat-table
|
||||
[dataSource]="dataSource"
|
||||
matSort
|
||||
matSortDisableClear
|
||||
(matSortChange)="sortData($event)"
|
||||
[matSortActive]="initialSortColumn"
|
||||
[matSortDirection]="initialSortDirection">
|
||||
<!-- More Details Column -->
|
||||
<ng-container matColumnDef="moreDetails">
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
|
@ -64,12 +71,7 @@
|
|||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th>
|
||||
<td mat-cell *matCellDef="let item">
|
||||
<ng-container *ngIf="canRead(item); else nameNoPermissions">
|
||||
{{ item.component.name }}
|
||||
</ng-container>
|
||||
<ng-template #nameNoPermissions>
|
||||
<div class="unset">{{ item.id }}</div>
|
||||
</ng-template>
|
||||
<div [ngClass]="{ unset: !canRead(item) }">{{ formatName(item) }}</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
@ -77,9 +79,7 @@
|
|||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Type</th>
|
||||
<td mat-cell *matCellDef="let item">
|
||||
<ng-container *ngIf="canRead(item)">
|
||||
{{ formatType(item) }}
|
||||
</ng-container>
|
||||
{{ formatType(item) }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
@ -87,9 +87,7 @@
|
|||
<ng-container matColumnDef="bundle">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Bundle</th>
|
||||
<td mat-cell *matCellDef="let item">
|
||||
<ng-container *ngIf="canRead(item)">
|
||||
{{ formatBundle(item) }}
|
||||
</ng-container>
|
||||
{{ formatBundle(item) }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AfterViewInit, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
||||
import { NiFiCommon } from '../../../../service/nifi-common.service';
|
||||
import { MatSort, MatSortModule } from '@angular/material/sort';
|
||||
import { MatSortModule, Sort } from '@angular/material/sort';
|
||||
import { NgClass, NgIf } from '@angular/common';
|
||||
import {
|
||||
BulletinsTipInput,
|
||||
|
@ -52,25 +52,17 @@ import { CurrentUser } from '../../../../state/current-user';
|
|||
],
|
||||
styleUrls: ['./controller-service-table.component.scss', '../../../../../assets/styles/listing-table.scss']
|
||||
})
|
||||
export class ControllerServiceTable implements AfterViewInit {
|
||||
export class ControllerServiceTable {
|
||||
@Input() initialSortColumn: 'name' | 'type' | 'bundle' | 'state' | 'scope' = 'name';
|
||||
@Input() initialSortDirection: 'asc' | 'desc' = 'asc';
|
||||
|
||||
@Input() set controllerServices(controllerServiceEntities: ControllerServiceEntity[]) {
|
||||
this.dataSource = new MatTableDataSource<ControllerServiceEntity>(controllerServiceEntities);
|
||||
this.dataSource.sort = this.sort;
|
||||
this.dataSource.sortingDataAccessor = (data: ControllerServiceEntity, displayColumn: string) => {
|
||||
if (displayColumn == 'name') {
|
||||
return this.formatType(data);
|
||||
} else if (displayColumn == 'type') {
|
||||
return this.formatType(data);
|
||||
} else if (displayColumn == 'bundle') {
|
||||
return this.formatBundle(data);
|
||||
} else if (displayColumn == 'state') {
|
||||
return this.formatState(data);
|
||||
} else if (displayColumn == 'scope') {
|
||||
return this.formatScope(data);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
this.dataSource.data = this.sortEntities(controllerServiceEntities, {
|
||||
active: this.initialSortColumn,
|
||||
direction: this.initialSortDirection
|
||||
});
|
||||
}
|
||||
|
||||
@Input() selectedServiceId!: string;
|
||||
@Input() formatScope!: (entity: ControllerServiceEntity) => string;
|
||||
@Input() definedByCurrentGroup!: (entity: ControllerServiceEntity) => boolean;
|
||||
|
@ -96,14 +88,8 @@ export class ControllerServiceTable implements AfterViewInit {
|
|||
displayedColumns: string[] = ['moreDetails', 'name', 'type', 'bundle', 'state', 'scope', 'actions'];
|
||||
dataSource: MatTableDataSource<ControllerServiceEntity> = new MatTableDataSource<ControllerServiceEntity>();
|
||||
|
||||
@ViewChild(MatSort) sort!: MatSort;
|
||||
|
||||
constructor(private nifiCommon: NiFiCommon) {}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.dataSource.sort = this.sort;
|
||||
}
|
||||
|
||||
canRead(entity: ControllerServiceEntity): boolean {
|
||||
return entity.permissions.canRead;
|
||||
}
|
||||
|
@ -188,12 +174,16 @@ export class ControllerServiceTable implements AfterViewInit {
|
|||
return '';
|
||||
}
|
||||
|
||||
formatName(entity: ControllerServiceEntity): string {
|
||||
return this.canRead(entity) ? entity.component.name : entity.id;
|
||||
}
|
||||
|
||||
formatType(entity: ControllerServiceEntity): string {
|
||||
return this.nifiCommon.formatType(entity.component);
|
||||
return this.canRead(entity) ? this.nifiCommon.formatType(entity.component) : '';
|
||||
}
|
||||
|
||||
formatBundle(entity: ControllerServiceEntity): string {
|
||||
return this.nifiCommon.formatBundle(entity.component.bundle);
|
||||
return this.canRead(entity) ? this.nifiCommon.formatBundle(entity.component.bundle) : '';
|
||||
}
|
||||
|
||||
getServiceLink(entity: ControllerServiceEntity): string[] {
|
||||
|
@ -279,4 +269,39 @@ export class ControllerServiceTable implements AfterViewInit {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
sortData(sort: Sort) {
|
||||
this.dataSource.data = this.sortEntities(this.dataSource.data, sort);
|
||||
}
|
||||
|
||||
private sortEntities(data: ControllerServiceEntity[], sort: Sort): ControllerServiceEntity[] {
|
||||
if (!data) {
|
||||
return [];
|
||||
}
|
||||
return data.slice().sort((a, b) => {
|
||||
const isAsc = sort.direction === 'asc';
|
||||
let retVal = 0;
|
||||
|
||||
switch (sort.active) {
|
||||
case 'name':
|
||||
retVal = this.nifiCommon.compareString(this.formatName(a), this.formatName(b));
|
||||
break;
|
||||
case 'type':
|
||||
retVal = this.nifiCommon.compareString(this.formatType(a), this.formatType(b));
|
||||
break;
|
||||
case 'bundle':
|
||||
retVal = this.nifiCommon.compareString(this.formatBundle(a), this.formatBundle(b));
|
||||
break;
|
||||
case 'state':
|
||||
retVal = this.nifiCommon.compareString(this.formatState(a), this.formatState(b));
|
||||
break;
|
||||
case 'scope':
|
||||
retVal = this.nifiCommon.compareString(this.formatScope(a), this.formatScope(b));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return retVal * (isAsc ? 1 : -1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,14 @@
|
|||
</div>
|
||||
<div class="type-table">
|
||||
<div class="h-96 overflow-y-auto overflow-x-hidden border">
|
||||
<table mat-table [dataSource]="dataSource" matSort matSortDisableClear>
|
||||
<table
|
||||
mat-table
|
||||
[dataSource]="dataSource"
|
||||
matSort
|
||||
matSortDisableClear
|
||||
(matSortChange)="sortData($event)"
|
||||
[matSortActive]="initialSortColumn"
|
||||
[matSortDirection]="initialSortDirection">
|
||||
<!-- Type Column -->
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Type</th>
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AfterViewInit, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
||||
import { NiFiCommon } from '../../../service/nifi-common.service';
|
||||
import { MatSort, MatSortModule } from '@angular/material/sort';
|
||||
import { MatSortModule, Sort } from '@angular/material/sort';
|
||||
import { NgIf } from '@angular/common';
|
||||
import { ControllerServiceApiTipInput, DocumentedType, RestrictionsTipInput } from '../../../state/shared';
|
||||
import { NifiTooltipDirective } from '../tooltips/nifi-tooltip.directive';
|
||||
|
@ -43,27 +43,23 @@ import { NifiSpinnerDirective } from '../spinner/nifi-spinner.directive';
|
|||
],
|
||||
styleUrls: ['./extension-creation.component.scss']
|
||||
})
|
||||
export class ExtensionCreation implements AfterViewInit {
|
||||
export class ExtensionCreation {
|
||||
@Input() set documentedTypes(documentedTypes: DocumentedType[]) {
|
||||
if (this.selectedType == null && documentedTypes.length > 0) {
|
||||
this.selectedType = documentedTypes[0];
|
||||
}
|
||||
|
||||
this.dataSource = new MatTableDataSource<DocumentedType>(documentedTypes);
|
||||
this.dataSource.sort = this.sort;
|
||||
this.dataSource.sortingDataAccessor = (data: DocumentedType, displayColumn: string) => {
|
||||
if (displayColumn == 'type') {
|
||||
return this.formatType(data);
|
||||
} else if (displayColumn == 'version') {
|
||||
return this.formatVersion(data);
|
||||
} else if (displayColumn == 'tags') {
|
||||
return this.formatTags(data);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
this.dataSource.data = this.sortEntities(documentedTypes, {
|
||||
active: this.initialSortColumn,
|
||||
direction: this.initialSortDirection
|
||||
});
|
||||
}
|
||||
|
||||
@Input() componentType!: string;
|
||||
@Input() saving!: boolean;
|
||||
@Input() initialSortColumn: 'type' | 'version' | 'tags' = 'type';
|
||||
@Input() initialSortDirection: 'asc' | 'desc' = 'asc';
|
||||
|
||||
@Output() extensionTypeSelected: EventEmitter<DocumentedType> = new EventEmitter<DocumentedType>();
|
||||
|
||||
protected readonly RestrictionsTip = RestrictionsTip;
|
||||
|
@ -73,14 +69,8 @@ export class ExtensionCreation implements AfterViewInit {
|
|||
dataSource: MatTableDataSource<DocumentedType> = new MatTableDataSource<DocumentedType>();
|
||||
selectedType: DocumentedType | null = null;
|
||||
|
||||
@ViewChild(MatSort) sort!: MatSort;
|
||||
|
||||
constructor(private nifiCommon: NiFiCommon) {}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.dataSource.sort = this.sort;
|
||||
}
|
||||
|
||||
formatType(documentedType: DocumentedType): string {
|
||||
if (documentedType) {
|
||||
return this.nifiCommon.substringAfterLast(documentedType.type, '.');
|
||||
|
@ -115,7 +105,10 @@ export class ExtensionCreation implements AfterViewInit {
|
|||
|
||||
formatTags(documentedType: DocumentedType): string {
|
||||
if (documentedType?.tags) {
|
||||
return documentedType.tags.join(', ');
|
||||
return documentedType.tags
|
||||
.slice()
|
||||
.sort((a, b) => this.nifiCommon.compareString(a, b))
|
||||
.join(', ');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
@ -156,4 +149,30 @@ export class ExtensionCreation implements AfterViewInit {
|
|||
this.extensionTypeSelected.next(documentedType);
|
||||
}
|
||||
}
|
||||
|
||||
sortData(sort: Sort) {
|
||||
this.dataSource.data = this.sortEntities(this.dataSource.data, sort);
|
||||
}
|
||||
|
||||
sortEntities(data: DocumentedType[], sort: Sort): DocumentedType[] {
|
||||
if (!data) {
|
||||
return [];
|
||||
}
|
||||
return data.slice().sort((a, b) => {
|
||||
const isAsc = sort.direction === 'asc';
|
||||
let retVal = 0;
|
||||
switch (sort.active) {
|
||||
case 'type':
|
||||
retVal = this.nifiCommon.compareString(this.formatType(a), this.formatType(b));
|
||||
break;
|
||||
case 'version':
|
||||
retVal = this.nifiCommon.compareString(this.formatVersion(a), this.formatVersion(b));
|
||||
break;
|
||||
case 'tags':
|
||||
retVal = this.nifiCommon.compareString(this.formatTags(a), this.formatTags(b));
|
||||
break;
|
||||
}
|
||||
return retVal * (isAsc ? 1 : -1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue