This is an automated email from the ASF dual-hosted git repository.
mcgilman pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new d14686cb3a [NIFI-12415] Counters (#8077)
d14686cb3a is described below
commit d14686cb3ae16a501187e527bc32c91449674bb6
Author: Rob Fellows <[email protected]>
AuthorDate: Wed Nov 29 18:00:28 2023 -0500
[NIFI-12415] Counters (#8077)
* [NIFI-12415] Counters page
* populate counter the table.
* support counter reset.
* filtering by name and by context
* sorting, including initial sort
* added basic tests
* Formatted with Prettier
* review feedback - removing unused things.
* align mat-table usage to a common style
* disable the Counter menu item if the user doesn't have
counterPermissions.canRead
This closes #8077
---
.../nifi-web-frontend/src/main/nifi/package.json | 1 +
.../src/main/nifi/src/app/app-routing.module.ts | 5 +
.../pages/canvas/ui/header/header.component.html | 116 +++++++++--------
.../counters/feature/counters-routing.module.ts | 33 +++++
.../pages/counters/feature/counters.component.html | 28 ++++
.../pages/counters/feature/counters.component.scss | 20 +++
.../counters/feature/counters.component.spec.ts | 44 +++++++
.../pages/counters/feature/counters.component.ts | 38 ++++++
.../app/pages/counters/feature/counters.module.ts | 41 ++++++
.../app/pages/counters/service/counters.service.ts | 40 ++++++
.../counter-listing/counter-listing.actions.ts | 45 +++++++
.../counter-listing/counter-listing.effects.ts | 106 +++++++++++++++
.../counter-listing/counter-listing.reducer.ts | 61 +++++++++
.../counter-listing/counter-listing.selectors.ts | 27 ++++
.../pages/counters/state/counter-listing/index.ts | 45 +++++++
.../nifi/src/app/pages/counters/state/index.ts | 34 +++++
.../counter-listing/counter-listing.component.html | 42 ++++++
.../counter-listing/counter-listing.component.scss | 16 +++
.../counter-listing.component.spec.ts | 40 ++++++
.../counter-listing/counter-listing.component.ts | 58 +++++++++
.../ui/counter-listing/counter-listing.module.ts | 42 ++++++
.../counter-table/counter-table.component.html | 93 ++++++++++++++
.../counter-table/counter-table.component.scss | 16 +++
.../counter-table/counter-table.component.spec.ts | 52 ++++++++
.../counter-table/counter-table.component.ts | 142 +++++++++++++++++++++
.../parameter-context-table.component.html | 2 +-
.../parameter-context-table.component.scss | 60 ---------
.../parameter-context-table.component.ts | 2 +-
.../parameter-table/parameter-table.component.html | 2 +-
.../parameter-table/parameter-table.component.scss | 35 +----
.../parameter-table/parameter-table.component.ts | 2 +-
.../reporting-task-table.component.html | 2 +-
.../reporting-task-table.component.scss | 54 +-------
.../reporting-task-table.component.ts | 2 +-
.../controller-service-table.component.html | 2 +-
.../controller-service-table.component.scss | 46 +------
.../controller-service-table.component.ts | 2 +-
.../property-table/property-table.component.html | 2 +-
.../property-table/property-table.component.scss | 37 +-----
.../property-table/property-table.component.ts | 2 +-
.../styles/listing-table.scss} | 26 ++--
41 files changed, 1156 insertions(+), 307 deletions(-)
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/package.json
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/package.json
index 1f33078257..88400f65cc 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/package.json
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/package.json
@@ -7,6 +7,7 @@
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test --karma-config=karma.conf.js --watch=false",
+ "prettier": "prettier --config .prettierrc . --check",
"prettier-format": "prettier --config .prettierrc . --write",
"ci": "npm ci --ignore-scripts"
},
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/app-routing.module.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/app-routing.module.ts
index 4ba1aad916..7e39ca6974 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/app-routing.module.ts
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/app-routing.module.ts
@@ -37,6 +37,11 @@ const routes: Routes = [
(m) => m.ParameterContextsModule
)
},
+ {
+ path: 'counters',
+ canMatch: [authGuard],
+ loadChildren: () =>
import('./pages/counters/feature/counters.module').then((m) => m.CountersModule)
+ },
{
path: '',
canMatch: [authGuard],
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/header/header.component.html
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/header/header.component.html
index 6421d46024..af4af65ca4 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/header/header.component.html
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/header/header.component.html
@@ -64,62 +64,66 @@
<i class="fa fa-navicon"></i>
</button>
<mat-menu #globalMenu="matMenu" xPosition="before">
- <button mat-menu-item class="global-menu-item">
- <i class="fa fa-fw fa-table mr-2"></i>
- Summary
- </button>
- <button mat-menu-item class="global-menu-item">
- <i class="icon fa-fw icon-counter mr-2"></i>
- Counter
- </button>
- <button mat-menu-item class="global-menu-item">
- <i class="fa fa-fw fa-sticky-note-o mr-2"></i>
- Bulletin Board
- </button>
- <mat-divider></mat-divider>
- <button mat-menu-item class="global-menu-item">
- <i class="icon fa-fw icon-provenance mr-2"></i>
- Data Provenance
- </button>
- <mat-divider></mat-divider>
- <button mat-menu-item class="global-menu-item"
[routerLink]="['/settings']">
- <i class="fa fa-fw fa-wrench mr-2"></i>
- Controller Settings
- </button>
- <button mat-menu-item class="global-menu-item"
[routerLink]="['/parameter-contexts']">
- <i class="fa fa-fw mr-2"></i>
- Parameter Contexts
- </button>
- <button mat-menu-item class="global-menu-item">
- <i class="fa fa-fw fa-cubes mr-2"></i>
- Cluster
- </button>
- <button mat-menu-item class="global-menu-item">
- <i class="fa fa-fw fa-history mr-2"></i>
- Flow Configuration History
- </button>
- <button mat-menu-item class="global-menu-item">
- <i class="fa fa-fw fa-area-chart mr-2"></i>
- Node Status History
- </button>
- <mat-divider></mat-divider>
- <button mat-menu-item class="global-menu-item">
- <i class="fa fa-fw fa-users mr-2"></i>
- Users
- </button>
- <button mat-menu-item class="global-menu-item">
- <i class="fa fa-fw fa-key mr-2"></i>
- Policies
- </button>
- <mat-divider></mat-divider>
- <button mat-menu-item class="global-menu-item">
- <i class="fa fa-fw fa-question-circle mr-2"></i>
- Help
- </button>
- <button mat-menu-item class="global-menu-item">
- <i class="fa fa-fw fa-info-circle mr-2"></i>
- About
- </button>
+ <ng-container *ngIf="currentUser$ | async as user">
+ <button mat-menu-item class="global-menu-item">
+ <i class="fa fa-fw fa-table mr-2"></i>
+ Summary
+ </button>
+ <button mat-menu-item class="global-menu-item"
+ [routerLink]="['/counters']"
+ [disabled]="!user.countersPermissions.canRead">
+ <i class="icon fa-fw icon-counter mr-2"></i>
+ Counter
+ </button>
+ <button mat-menu-item class="global-menu-item">
+ <i class="fa fa-fw fa-sticky-note-o mr-2"></i>
+ Bulletin Board
+ </button>
+ <mat-divider></mat-divider>
+ <button mat-menu-item class="global-menu-item">
+ <i class="icon fa-fw icon-provenance mr-2"></i>
+ Data Provenance
+ </button>
+ <mat-divider></mat-divider>
+ <button mat-menu-item class="global-menu-item"
[routerLink]="['/settings']">
+ <i class="fa fa-fw fa-wrench mr-2"></i>
+ Controller Settings
+ </button>
+ <button mat-menu-item class="global-menu-item"
[routerLink]="['/parameter-contexts']">
+ <i class="fa fa-fw mr-2"></i>
+ Parameter Contexts
+ </button>
+ <button mat-menu-item class="global-menu-item">
+ <i class="fa fa-fw fa-cubes mr-2"></i>
+ Cluster
+ </button>
+ <button mat-menu-item class="global-menu-item">
+ <i class="fa fa-fw fa-history mr-2"></i>
+ Flow Configuration History
+ </button>
+ <button mat-menu-item class="global-menu-item">
+ <i class="fa fa-fw fa-area-chart mr-2"></i>
+ Node Status History
+ </button>
+ <mat-divider></mat-divider>
+ <button mat-menu-item class="global-menu-item">
+ <i class="fa fa-fw fa-users mr-2"></i>
+ Users
+ </button>
+ <button mat-menu-item class="global-menu-item">
+ <i class="fa fa-fw fa-key mr-2"></i>
+ Policies
+ </button>
+ <mat-divider></mat-divider>
+ <button mat-menu-item class="global-menu-item">
+ <i class="fa fa-fw fa-question-circle mr-2"></i>
+ Help
+ </button>
+ <button mat-menu-item class="global-menu-item">
+ <i class="fa fa-fw fa-info-circle mr-2"></i>
+ About
+ </button>
+ </ng-container>
</mat-menu>
</div>
</div>
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters-routing.module.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters-routing.module.ts
new file mode 100644
index 0000000000..bce25cce01
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters-routing.module.ts
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { RouterModule, Routes } from '@angular/router';
+import { NgModule } from '@angular/core';
+import { Counters } from './counters.component';
+
+const routes: Routes = [
+ {
+ path: '',
+ component: Counters
+ }
+];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class CountersRoutingModule {}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.component.html
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.component.html
new file mode 100644
index 0000000000..73fcf5e390
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.component.html
@@ -0,0 +1,28 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<div class="p-4 flex flex-col h-screen justify-between gap-y-5">
+ <div class="flex justify-between">
+ <h3 class="text-xl bold counter-header">NiFi Counters</h3>
+ <button class="nifi-button" [routerLink]="['/']">
+ <i class="fa fa-times"></i>
+ </button>
+ </div>
+ <div class="flex-1">
+ <counter-listing></counter-listing>
+ </div>
+</div>
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.component.scss
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.component.scss
new file mode 100644
index 0000000000..7efe128f47
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.component.scss
@@ -0,0 +1,20 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.counter-header {
+ color: #728e9b;
+}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.component.spec.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.component.spec.ts
new file mode 100644
index 0000000000..e30779c978
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.component.spec.ts
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Counters } from './counters.component';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { provideMockStore } from '@ngrx/store/testing';
+import { initialState } from
'../state/counter-listing/counter-listing.reducer';
+import { CounterListing } from
'../ui/counter-listing/counter-listing.component';
+import { RouterModule } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+
+describe('Counters', () => {
+ let component: Counters;
+ let fixture: ComponentFixture<Counters>;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [Counters, CounterListing],
+ imports: [RouterModule, RouterTestingModule],
+ providers: [provideMockStore({ initialState })]
+ });
+ fixture = TestBed.createComponent(Counters);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.component.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.component.ts
new file mode 100644
index 0000000000..6d3998b6d2
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.component.ts
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Component, OnDestroy, OnInit } from '@angular/core';
+import { Store } from '@ngrx/store';
+import { NiFiState } from '../../../state';
+import { startUserPolling, stopUserPolling } from
'../../../state/user/user.actions';
+
+@Component({
+ selector: 'counters',
+ templateUrl: './counters.component.html',
+ styleUrls: ['./counters.component.scss']
+})
+export class Counters implements OnInit, OnDestroy {
+ constructor(private store: Store<NiFiState>) {}
+
+ ngOnInit(): void {
+ this.store.dispatch(startUserPolling());
+ }
+
+ ngOnDestroy(): void {
+ this.store.dispatch(stopUserPolling());
+ }
+}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.module.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.module.ts
new file mode 100644
index 0000000000..33ea2bf6a2
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/feature/counters.module.ts
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { Counters } from './counters.component';
+import { CountersRoutingModule } from './counters-routing.module';
+import { StoreModule } from '@ngrx/store';
+import { countersFeatureKey, reducers } from '../state';
+import { EffectsModule } from '@ngrx/effects';
+import { CounterListingEffects } from
'../state/counter-listing/counter-listing.effects';
+import { CounterListingModule } from
'../ui/counter-listing/counter-listing.module';
+import { ParameterContextListingModule } from
'../../parameter-contexts/ui/parameter-context-listing/parameter-context-listing.module';
+
+@NgModule({
+ declarations: [Counters],
+ exports: [Counters],
+ imports: [
+ CommonModule,
+ CountersRoutingModule,
+ StoreModule.forFeature(countersFeatureKey, reducers),
+ EffectsModule.forFeature(CounterListingEffects),
+ CounterListingModule,
+ ParameterContextListingModule
+ ]
+})
+export class CountersModule {}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/service/counters.service.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/service/counters.service.ts
new file mode 100644
index 0000000000..987d23e757
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/service/counters.service.ts
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { Client } from '../../../service/client.service';
+import { Observable } from 'rxjs';
+import { CounterEntity, ResetCounterRequest } from '../state/counter-listing';
+
+@Injectable({ providedIn: 'root' })
+export class CountersService {
+ private static readonly API: string = '../nifi-api';
+
+ constructor(
+ private httpClient: HttpClient,
+ private client: Client
+ ) {}
+
+ getCounters(): Observable<any> {
+ return this.httpClient.get(`${CountersService.API}/counters`);
+ }
+
+ resetCounter(counterResetRequest: ResetCounterRequest): Observable<any> {
+ return
this.httpClient.put(`${CountersService.API}/counters/${counterResetRequest.counter.id}`,
null);
+ }
+}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/counter-listing.actions.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/counter-listing.actions.ts
new file mode 100644
index 0000000000..cb2eb9dd70
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/counter-listing.actions.ts
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { createAction, props } from '@ngrx/store';
+import { LoadCounterListingResponse, ResetCounterRequest, ResetCounterSuccess
} from './index';
+
+const COUNTER_PREFIX: string = '[Counter Listing]';
+
+export const loadCounters = createAction(`${COUNTER_PREFIX} Load Counter
Listing`);
+
+export const loadCountersSuccess = createAction(
+ `${COUNTER_PREFIX} Load Counter Listing Success`,
+ props<{ response: LoadCounterListingResponse }>()
+);
+
+export const counterListingApiError = createAction(
+ `${COUNTER_PREFIX} Load Counter Listing Errors`,
+ props<{ error: string }>()
+);
+
+export const promptCounterReset = createAction(
+ `${COUNTER_PREFIX} Prompt Counter Reset`,
+ props<{ request: ResetCounterRequest }>()
+);
+
+export const resetCounter = createAction(`${COUNTER_PREFIX} Reset Counter`,
props<{ request: ResetCounterRequest }>());
+
+export const resetCounterSuccess = createAction(
+ `${COUNTER_PREFIX} Reset Counter Success`,
+ props<{ response: ResetCounterSuccess }>()
+);
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/counter-listing.effects.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/counter-listing.effects.ts
new file mode 100644
index 0000000000..0f35e30e66
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/counter-listing.effects.ts
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Injectable } from '@angular/core';
+import { Actions, createEffect, ofType } from '@ngrx/effects';
+import { NiFiState } from '../../../../state';
+import { Store } from '@ngrx/store';
+import { Router } from '@angular/router';
+import * as CounterListingActions from './counter-listing.actions';
+import { catchError, from, map, of, switchMap, take, tap } from 'rxjs';
+import { CountersService } from '../../service/counters.service';
+import { MatDialog } from '@angular/material/dialog';
+import { YesNoDialog } from
'../../../../ui/common/yes-no-dialog/yes-no-dialog.component';
+
+@Injectable()
+export class CounterListingEffects {
+ constructor(
+ private actions$: Actions,
+ private store: Store<NiFiState>,
+ private router: Router,
+ private countersService: CountersService,
+ private dialog: MatDialog
+ ) {}
+
+ loadCounters$ = createEffect(() =>
+ this.actions$.pipe(
+ ofType(CounterListingActions.loadCounters),
+ switchMap(() =>
+ from(this.countersService.getCounters()).pipe(
+ map((response) =>
+ CounterListingActions.loadCountersSuccess({
+ response: {
+ counters:
response.counters.aggregateSnapshot.counters,
+ loadedTimestamp:
response.counters.aggregateSnapshot.generated
+ }
+ })
+ ),
+ catchError((error) =>
+ of(
+ CounterListingActions.counterListingApiError({
+ error: error.error
+ })
+ )
+ )
+ )
+ )
+ )
+ );
+
+ promptCounterReset$ = createEffect(
+ () =>
+ this.actions$.pipe(
+ ofType(CounterListingActions.promptCounterReset),
+ map((action) => action.request),
+ tap((request) => {
+ const dialogReference = this.dialog.open(YesNoDialog, {
+ data: {
+ title: 'Reset Counter',
+ message: `Reset counter '${request.counter.name}'
to default value?`
+ },
+ panelClass: 'small-dialog'
+ });
+
+
dialogReference.componentInstance.yes.pipe(take(1)).subscribe(() => {
+ this.store.dispatch(
+ CounterListingActions.resetCounter({
+ request
+ })
+ );
+ });
+ })
+ ),
+ { dispatch: false }
+ );
+
+ resetCounter$ = createEffect(() =>
+ this.actions$.pipe(
+ ofType(CounterListingActions.resetCounter),
+ map((action) => action.request),
+ switchMap((request) =>
+ from(this.countersService.resetCounter(request)).pipe(
+ map((response) =>
+ CounterListingActions.resetCounterSuccess({
+ response
+ })
+ ),
+ catchError((error) =>
of(CounterListingActions.counterListingApiError({ error: error.error })))
+ )
+ )
+ )
+ );
+}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/counter-listing.reducer.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/counter-listing.reducer.ts
new file mode 100644
index 0000000000..bc1904ff7d
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/counter-listing.reducer.ts
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { CounterListingState } from './index';
+import { createReducer, on } from '@ngrx/store';
+import { loadCounters, loadCountersSuccess, resetCounterSuccess } from
'./counter-listing.actions';
+import { parameterContextListingApiError } from
'../../../parameter-contexts/state/parameter-context-listing/parameter-context-listing.actions';
+import { produce } from 'immer';
+
+export const initialState: CounterListingState = {
+ counters: [],
+ saving: false,
+ loadedTimestamp: '',
+ error: null,
+ status: 'pending'
+};
+
+export const counterListingReducer = createReducer(
+ initialState,
+ on(loadCounters, (state) => ({
+ ...state,
+ status: 'loading' as const
+ })),
+ on(loadCountersSuccess, (state, { response }) => ({
+ ...state,
+ counters: response.counters,
+ loadedTimestamp: response.loadedTimestamp,
+ error: null,
+ status: 'success' as const
+ })),
+ on(parameterContextListingApiError, (state, { error }) => ({
+ ...state,
+ saving: false,
+ error,
+ status: 'error' as const
+ })),
+ on(resetCounterSuccess, (state, { response }) => {
+ return produce(state, (draftState) => {
+ const index: number = draftState.counters.findIndex((c: any) =>
c.id === response.counter.id);
+ if (index > -1) {
+ draftState.counters[index] = {
+ ...response.counter
+ };
+ }
+ });
+ })
+);
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/counter-listing.selectors.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/counter-listing.selectors.ts
new file mode 100644
index 0000000000..5855fef5ca
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/counter-listing.selectors.ts
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { createSelector } from '@ngrx/store';
+import { countersFeatureKey, CountersState, selectCounterState } from
'../index';
+import { CounterListingState } from './index';
+
+export const selectCounterListingState = createSelector(
+ selectCounterState,
+ (state: CountersState) => state[countersFeatureKey]
+);
+
+export const selectCounters = createSelector(selectCounterListingState,
(state: CounterListingState) => state.counters);
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/index.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/index.ts
new file mode 100644
index 0000000000..7459519b37
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/counter-listing/index.ts
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export interface CounterEntity {
+ id: string;
+ context: string;
+ name: string;
+ valueCount: number;
+ value: string;
+}
+
+export interface CounterListingState {
+ counters: CounterEntity[];
+ saving: boolean;
+ loadedTimestamp: string;
+ error: string | null;
+ status: 'pending' | 'loading' | 'error' | 'success';
+}
+
+export interface LoadCounterListingResponse {
+ counters: CounterEntity[];
+ loadedTimestamp: string;
+}
+
+export interface ResetCounterRequest {
+ counter: CounterEntity;
+}
+
+export interface ResetCounterSuccess {
+ counter: CounterEntity;
+}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/index.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/index.ts
new file mode 100644
index 0000000000..cb8f2597ca
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/state/index.ts
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { CounterListingState } from './counter-listing';
+import { Action, combineReducers, createFeatureSelector } from '@ngrx/store';
+import { counterListingReducer } from
'./counter-listing/counter-listing.reducer';
+
+export const countersFeatureKey = 'counters';
+
+export interface CountersState {
+ [countersFeatureKey]: CounterListingState;
+}
+
+export function reducers(state: CountersState | undefined, action: Action) {
+ return combineReducers({
+ [countersFeatureKey]: counterListingReducer
+ })(state, action);
+}
+
+export const selectCounterState =
createFeatureSelector<CountersState>(countersFeatureKey);
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.component.html
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.component.html
new file mode 100644
index 0000000000..2e9cf2ec02
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.component.html
@@ -0,0 +1,42 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<ng-container *ngIf="counterListingState$ | async; let counterListingState">
+ <div *ngIf="isInitialLoading(counterListingState); else loaded">
+ <ngx-skeleton-loader count="3"></ngx-skeleton-loader>
+ </div>
+
+ <ng-template #loaded>
+ <div class="flex flex-col h-full gap-y-2">
+ <div class="flex-1" *ngIf="currentUser$ | async as user">
+ <counter-table
+ [counters]="counterListingState.counters"
+ [canModifyCounters]="user.countersPermissions.canWrite"
+ (resetCounter)="resetCounter($event)"></counter-table>
+ </div>
+ <div class="flex justify-between">
+ <div class="refresh-container flex items-center gap-x-2">
+ <button class="nifi-button"
(click)="refreshCounterListing()">
+ <i class="fa fa-refresh"
[class.fa-spin]="counterListingState.status === 'loading'"></i>
+ </button>
+ <div>Last updated:</div>
+ <div class="refresh-timestamp">{{
counterListingState.loadedTimestamp }}</div>
+ </div>
+ </div>
+ </div>
+ </ng-template>
+</ng-container>
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.component.scss
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.component.scss
new file mode 100644
index 0000000000..3651a8ab70
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.component.scss
@@ -0,0 +1,16 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.component.spec.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.component.spec.ts
new file mode 100644
index 0000000000..a868ca1e5f
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.component.spec.ts
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { CounterListing } from './counter-listing.component';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { provideMockStore } from '@ngrx/store/testing';
+import { initialState } from
'../../state/counter-listing/counter-listing.reducer';
+
+describe('CounterListing', () => {
+ let component: CounterListing;
+ let fixture: ComponentFixture<CounterListing>;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [CounterListing],
+ providers: [provideMockStore({ initialState })]
+ });
+ fixture = TestBed.createComponent(CounterListing);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.component.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.component.ts
new file mode 100644
index 0000000000..3cf0994b49
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.component.ts
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Component, OnInit } from '@angular/core';
+import { CounterEntity, CounterListingState } from
'../../state/counter-listing';
+import { Store } from '@ngrx/store';
+import { loadCounters, promptCounterReset } from
'../../state/counter-listing/counter-listing.actions';
+import { selectCounterListingState } from
'../../state/counter-listing/counter-listing.selectors';
+import { initialState } from
'../../state/counter-listing/counter-listing.reducer';
+import { selectUser } from '../../../../state/user/user.selectors';
+
+@Component({
+ selector: 'counter-listing',
+ templateUrl: './counter-listing.component.html',
+ styleUrls: ['./counter-listing.component.scss']
+})
+export class CounterListing implements OnInit {
+ counterListingState$ = this.store.select(selectCounterListingState);
+ currentUser$ = this.store.select(selectUser);
+
+ constructor(private store: Store<CounterListingState>) {}
+
+ ngOnInit(): void {
+ this.store.dispatch(loadCounters());
+ }
+
+ isInitialLoading(state: CounterListingState): boolean {
+ return state.loadedTimestamp == initialState.loadedTimestamp;
+ }
+
+ refreshCounterListing() {
+ this.store.dispatch(loadCounters());
+ }
+
+ resetCounter(entity: CounterEntity): void {
+ this.store.dispatch(
+ promptCounterReset({
+ request: {
+ counter: entity
+ }
+ })
+ );
+ }
+}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.module.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.module.ts
new file mode 100644
index 0000000000..7ac4eb7aaf
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-listing.module.ts
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { NgModule } from '@angular/core';
+import { CounterListing } from './counter-listing.component';
+import { CommonModule } from '@angular/common';
+import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
+import { CounterTable } from './counter-table/counter-table.component';
+import { MatTableModule } from '@angular/material/table';
+import { MatSortModule } from '@angular/material/sort';
+import { MatInputModule } from '@angular/material/input';
+import { ReactiveFormsModule } from '@angular/forms';
+import { MatSelectModule } from '@angular/material/select';
+
+@NgModule({
+ declarations: [CounterListing, CounterTable],
+ exports: [CounterListing],
+ imports: [
+ CommonModule,
+ NgxSkeletonLoaderModule,
+ MatTableModule,
+ MatSortModule,
+ MatInputModule,
+ ReactiveFormsModule,
+ MatSelectModule
+ ]
+})
+export class CounterListingModule {}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-table/counter-table.component.html
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-table/counter-table.component.html
new file mode 100644
index 0000000000..ee1eb3580f
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-table/counter-table.component.html
@@ -0,0 +1,93 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<div class="counter-table h-full flex flex-col">
+ <div class="counter-table-filter-container">
+ <div class="value">Displaying {{ filteredCount }} of {{ totalCount
}}</div>
+ <form [formGroup]="filterForm">
+ <div class="flex pt-2">
+ <div class="mr-2">
+ <mat-form-field>
+ <mat-label>Filter</mat-label>
+ <input matInput type="text" class="small"
formControlName="filterTerm" />
+ </mat-form-field>
+ </div>
+ <div>
+ <mat-form-field>
+ <mat-label>Filter By</mat-label>
+ <mat-select formControlName="filterColumn">
+ <mat-option value="name"> name </mat-option>
+ <mat-option value="context"> context </mat-option>
+ </mat-select>
+ </mat-form-field>
+ </div>
+ </div>
+ </form>
+ </div>
+ <div class="flex-1 relative">
+ <div class="listing-table overflow-y-auto border absolute inset-0">
+ <table
+ mat-table
+ [dataSource]="dataSource"
+ matSort
+ matSortDisableClear
+ [matSortActive]="initialSortColumn"
+ [matSortDirection]="initialSortDirection">
+ <!-- Context column -->
+ <ng-container matColumnDef="context">
+ <th mat-header-cell *matHeaderCellDef
mat-sort-header>Context</th>
+ <td mat-cell *matCellDef="let item">
+ {{ formatContext(item) }}
+ </td>
+ </ng-container>
+
+ <!-- Name Column -->
+ <ng-container matColumnDef="name">
+ <th mat-header-cell *matHeaderCellDef
mat-sort-header>Name</th>
+ <td mat-cell *matCellDef="let item">
+ {{ formatName(item) }}
+ </td>
+ </ng-container>
+
+ <!-- Value column -->
+ <ng-container matColumnDef="value">
+ <th mat-header-cell *matHeaderCellDef
mat-sort-header>Value</th>
+ <td mat-cell *matCellDef="let item">
+ {{ formatValue(item) }}
+ </td>
+ </ng-container>
+
+ <ng-container matColumnDef="reset">
+ <th mat-header-cell *matHeaderCellDef></th>
+ <td mat-cell *matCellDef="let item">
+ <ng-container *ngIf="canModifyCounters">
+ <div class="flex items-center gap-x-3">
+ <div
+ class="pointer fa fa-undo"
+ title="Reset Counter"
+ *ngIf="canModifyCounters"
+ (click)="resetClicked(item, $event)"></div>
+ </div>
+ </ng-container>
+ </td>
+ </ng-container>
+
+ <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky:
true"></tr>
+ <tr mat-row *matRowDef="let row; let even = even; columns:
displayedColumns" [class.even]="even"></tr>
+ </table>
+ </div>
+ </div>
+</div>
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-table/counter-table.component.scss
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-table/counter-table.component.scss
new file mode 100644
index 0000000000..3651a8ab70
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-table/counter-table.component.scss
@@ -0,0 +1,16 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-table/counter-table.component.spec.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-table/counter-table.component.spec.ts
new file mode 100644
index 0000000000..b41dc7647a
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-table/counter-table.component.spec.ts
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CounterTable } from './counter-table.component';
+import { MatTableModule } from '@angular/material/table';
+import { MatSortModule } from '@angular/material/sort';
+import { MatInputModule } from '@angular/material/input';
+import { ReactiveFormsModule } from '@angular/forms';
+import { MatSelectModule } from '@angular/material/select';
+import { NoopAnimationsModule } from '@angular/platform-browser/animations';
+
+describe('CounterTableComponent', () => {
+ let component: CounterTable;
+ let fixture: ComponentFixture<CounterTable>;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [CounterTable],
+ imports: [
+ MatTableModule,
+ MatSortModule,
+ MatInputModule,
+ ReactiveFormsModule,
+ MatSelectModule,
+ NoopAnimationsModule
+ ]
+ });
+ fixture = TestBed.createComponent(CounterTable);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-table/counter-table.component.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-table/counter-table.component.ts
new file mode 100644
index 0000000000..0052424805
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/counters/ui/counter-listing/counter-table/counter-table.component.ts
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { AfterViewInit, Component, EventEmitter, Input, Output, ViewChild }
from '@angular/core';
+import { CounterEntity } from '../../../state/counter-listing';
+import { MatTableDataSource } from '@angular/material/table';
+import { MatSort } from '@angular/material/sort';
+import { FormBuilder, FormGroup } from '@angular/forms';
+import { debounceTime } from 'rxjs';
+
+@Component({
+ selector: 'counter-table',
+ templateUrl: './counter-table.component.html',
+ styleUrls: ['./counter-table.component.scss',
'../../../../../../assets/styles/listing-table.scss']
+})
+export class CounterTable implements AfterViewInit {
+ private _canModifyCounters: boolean = false;
+ filterTerm: string = '';
+ filterColumn: 'context' | 'name' = 'name';
+ totalCount: number = 0;
+ filteredCount: number = 0;
+
+ displayedColumns: string[] = ['context', 'name', 'value'];
+ dataSource: MatTableDataSource<CounterEntity> = new
MatTableDataSource<CounterEntity>();
+ filterForm: FormGroup;
+
+ @Input() initialSortColumn: 'context' | 'name' = '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.filterPredicate = (data: CounterEntity, filter:
string) => {
+ const filterArray = filter.split('|');
+ const filterTerm = filterArray[0];
+ const filterColumn = filterArray[1];
+
+ if (filterColumn === 'name') {
+ return
data.name.toLowerCase().indexOf(filterTerm.toLowerCase()) >= 0;
+ } else {
+ return
data.context.toLowerCase().indexOf(filterTerm.toLowerCase()) >= 0;
+ }
+ };
+ this.totalCount = counterEntities.length;
+ this.filteredCount = counterEntities.length;
+
+ // apply any filtering to the new data
+ const filterTerm = this.filterForm.get('filterTerm')?.value;
+ if (filterTerm?.length > 0) {
+ const filterColumn = this.filterForm.get('filterColumn')?.value;
+ this.applyFilter(filterTerm, filterColumn);
+ }
+ }
+
+ @Input()
+ set canModifyCounters(canWrite: boolean) {
+ if (canWrite) {
+ this.displayedColumns = ['context', 'name', 'value', 'reset'];
+ } else {
+ this.displayedColumns = ['context', 'name', 'value'];
+ }
+ this._canModifyCounters = canWrite;
+ }
+
+ get canModifyCounters(): boolean {
+ return this._canModifyCounters;
+ }
+
+ @Output() resetCounter: EventEmitter<CounterEntity> = new
EventEmitter<CounterEntity>();
+
+ @ViewChild(MatSort) sort!: MatSort;
+
+ constructor(private formBuilder: FormBuilder) {
+ this.filterForm = this.formBuilder.group({ filterTerm: '',
filterColumn: 'name' });
+ }
+
+ ngAfterViewInit(): void {
+ this.dataSource.sort = this.sort;
+
+ this.filterForm
+ .get('filterTerm')
+ ?.valueChanges.pipe(debounceTime(500))
+ .subscribe((filterTerm: string) => {
+ const filterColumn =
this.filterForm.get('filterColumn')?.value;
+ this.applyFilter(filterTerm, filterColumn);
+ });
+
+
this.filterForm.get('filterColumn')?.valueChanges.subscribe((filterColumn:
string) => {
+ const filterTerm = this.filterForm.get('filterTerm')?.value;
+ this.applyFilter(filterTerm, filterColumn);
+ });
+ }
+
+ applyFilter(filterTerm: string, filterColumn: string) {
+ this.dataSource.filter = `${filterTerm}|${filterColumn}`;
+ this.filteredCount = this.dataSource.filteredData.length;
+ }
+
+ formatContext(counter: CounterEntity): string {
+ return counter.context;
+ }
+
+ formatName(counter: CounterEntity): string {
+ return counter.name;
+ }
+
+ formatValue(counter: CounterEntity): string {
+ return counter.value;
+ }
+
+ resetClicked(counter: CounterEntity, event: MouseEvent) {
+ event.stopPropagation();
+ this.resetCounter.next(counter);
+ }
+}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.html
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.html
index a75ad02c0d..0af15cd41d 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.html
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.html
@@ -16,7 +16,7 @@
-->
<div class="relative h-full border">
- <div class="parameter-context-table absolute inset-0 overflow-y-auto">
+ <div class="listing-table absolute inset-0 overflow-y-auto">
<table mat-table [dataSource]="dataSource" matSort matSortDisableClear>
<!-- More Details Column -->
<ng-container matColumnDef="moreDetails">
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.scss
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.scss
index 10d9962109..2944f98194 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.scss
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.scss
@@ -14,63 +14,3 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-.parameter-context-table {
- table {
- width: 100%;
-
- td,
- th {
- max-width: 300px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- padding: 0 8px;
- }
-
- th {
- background-color: #728e9b;
- color: #fff;
- }
-
- tr:hover {
- background-color: #dce3e6 !important;
- }
-
- .selected {
- background-color: #ffef85 !important;
- }
-
- .even {
- background-color: #f4f6f7;
- }
-
- .fa,
- .icon {
- color: #004849;
- width: 10px;
- height: 14px;
- text-align: center;
- }
-
- .mat-column-moreDetails {
- min-width: 30px;
- }
-
- .mat-column-actions {
- min-width: 115px;
- }
- }
-
- .mat-mdc-table .mdc-data-table__header-row {
- height: 35px;
- }
-
- .mat-mdc-table .mdc-data-table__row {
- height: 35px;
- }
-}
-
-::ng-deep .mat-sort-header-arrow {
- color: #fff;
-}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.ts
index 45b20048c2..ea0f8deac4 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.ts
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.ts
@@ -24,7 +24,7 @@ import { ParameterContextEntity } from
'../../../state/parameter-context-listing
@Component({
selector: 'parameter-context-table',
templateUrl: './parameter-context-table.component.html',
- styleUrls: ['./parameter-context-table.component.scss']
+ styleUrls: ['./parameter-context-table.component.scss',
'../../../../../../assets/styles/listing-table.scss']
})
export class ParameterContextTable implements AfterViewInit {
@Input() set parameterContexts(parameterContextEntities:
ParameterContextEntity[]) {
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.html
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.html
index d899927fd6..dab0d4ae1a 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.html
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.html
@@ -15,7 +15,7 @@
~ limitations under the License.
-->
-<div class="parameter-table flex gap-x-3">
+<div class="parameter-table listing-table flex gap-x-3">
<div class="flex flex-col gap-y-3" style="flex-grow: 3">
<div class="flex justify-end items-center">
<button class="nifi-button" type="button"
(click)="newParameterClicked()">
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.scss
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.scss
index f0b830c6c1..c6fc0792cf 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.scss
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.scss
@@ -17,51 +17,18 @@
@use '@angular/material' as mat;
-.parameter-table {
+.parameter-table.listing-table {
@include mat.table-density(-4);
min-width: 740px;
table {
- width: 100%;
-
td,
th {
- max-width: 300px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- padding: 0 8px;
cursor: default;
}
- th {
- background-color: #728e9b;
- color: #fff;
- }
-
- tr:hover {
- background-color: #dce3e6 !important;
- }
-
- .selected {
- background-color: #ffef85 !important;
- }
-
- .even {
- background-color: #f4f6f7;
- }
-
- .fa {
- width: 10px;
- height: 14px;
- }
-
.mat-column-actions {
width: 75px;
}
}
}
-
-::ng-deep .mat-sort-header-arrow {
- color: #fff;
-}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.ts
index bc677cf4ef..e0260c6887 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.ts
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.ts
@@ -57,7 +57,7 @@ export interface ParameterItem {
NifiTooltipDirective,
ParameterReferences
],
- styleUrls: ['./parameter-table.component.scss'],
+ styleUrls: ['./parameter-table.component.scss',
'../../../../../../assets/styles/listing-table.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.html
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.html
index be00de4d6a..8f791bac2d 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.html
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.html
@@ -16,7 +16,7 @@
-->
<div class="relative h-full border">
- <div class="reporting-task-table absolute inset-0 overflow-y-auto">
+ <div class="reporting-task-table listing-table absolute inset-0
overflow-y-auto">
<table mat-table [dataSource]="dataSource" matSort matSortDisableClear>
<!-- More Details Column -->
<ng-container matColumnDef="moreDetails">
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.scss
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.scss
index 11b26e5415..6411871761 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.scss
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.scss
@@ -15,62 +15,10 @@
* limitations under the License.
*/
-.reporting-task-table {
+.reporting-task-table.listing-table {
table {
- width: 100%;
-
- td,
- th {
- max-width: 300px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- padding: 0 8px;
- }
-
- th {
- background-color: #728e9b;
- color: #fff;
- }
-
- tr:hover {
- background-color: #dce3e6 !important;
- }
-
- .selected {
- background-color: #ffef85 !important;
- }
-
- .even {
- background-color: #f4f6f7;
- }
-
- .fa,
- .icon {
- color: #004849;
- width: 10px;
- height: 14px;
- text-align: center;
- }
-
.mat-column-moreDetails {
min-width: 100px;
}
-
- .mat-column-actions {
- min-width: 115px;
- }
- }
-
- .mat-mdc-table .mdc-data-table__header-row {
- height: 35px;
- }
-
- .mat-mdc-table .mdc-data-table__row {
- height: 35px;
}
}
-
-::ng-deep .mat-sort-header-arrow {
- color: #fff;
-}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.ts
index e5c7e9a3ba..8134d344c2 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.ts
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.ts
@@ -28,7 +28,7 @@ import { BulletinsTipInput, TextTipInput,
ValidationErrorsTipInput } from '../..
@Component({
selector: 'reporting-task-table',
templateUrl: './reporting-task-table.component.html',
- styleUrls: ['./reporting-task-table.component.scss']
+ styleUrls: ['./reporting-task-table.component.scss',
'../../../../../../assets/styles/listing-table.scss']
})
export class ReportingTaskTable implements AfterViewInit {
@Input() set reportingTasks(reportingTaskEntities: ReportingTaskEntity[]) {
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.html
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.html
index 9411785c7a..1ea07471c8 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.html
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.html
@@ -16,7 +16,7 @@
-->
<div class="relative h-full border">
- <div class="controller-service-table absolute inset-0 overflow-y-auto">
+ <div class="controller-service-table listing-table absolute inset-0
overflow-y-auto">
<table mat-table [dataSource]="dataSource" matSort matSortDisableClear>
<!-- More Details Column -->
<ng-container matColumnDef="moreDetails">
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.scss
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.scss
index 3de9d43ec1..3a513b3e55 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.scss
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.scss
@@ -17,56 +17,12 @@
@use '@angular/material' as mat;
-.controller-service-table {
+.controller-service-table.listing-table {
@include mat.table-density(-4);
table {
- width: 100%;
-
- td,
- th {
- max-width: 300px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- padding: 0 8px;
- }
-
- th {
- background-color: #728e9b;
- color: #fff;
- }
-
- tr:hover {
- background-color: #dce3e6 !important;
- }
-
- .selected {
- background-color: #ffef85 !important;
- }
-
- .even {
- background-color: #f4f6f7;
- }
-
- .fa,
- .icon {
- color: #004849;
- width: 10px;
- height: 14px;
- text-align: center;
- }
-
.mat-column-moreDetails {
min-width: 90px;
}
-
- .mat-column-actions {
- min-width: 115px;
- }
}
}
-
-::ng-deep .mat-sort-header-arrow {
- color: #fff;
-}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.ts
index e3f517706c..6e27c87c04 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.ts
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.ts
@@ -38,7 +38,7 @@ import { ValidationErrorsTip } from
'../../tooltips/validation-errors-tip/valida
standalone: true,
templateUrl: './controller-service-table.component.html',
imports: [MatButtonModule, MatDialogModule, MatTableModule, MatSortModule,
NgIf, NgClass, NifiTooltipDirective],
- styleUrls: ['./controller-service-table.component.scss']
+ styleUrls: ['./controller-service-table.component.scss',
'../../../../../assets/styles/listing-table.scss']
})
export class ControllerServiceTable implements AfterViewInit {
@Input() set controllerServices(controllerServiceEntities:
ControllerServiceEntity[]) {
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.html
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.html
index 563f9cc304..5f52eeed03 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.html
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.html
@@ -15,7 +15,7 @@
~ limitations under the License.
-->
-<div class="property-table flex flex-col gap-y-3">
+<div class="property-table listing-table flex flex-col gap-y-3">
<div class="flex justify-between items-center">
<div class="font-bold">Required field</div>
<div>
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.scss
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.scss
index bd5acec8f9..9517ea1a8b 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.scss
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.scss
@@ -17,7 +17,7 @@
@use '@angular/material' as mat;
-.property-table {
+.property-table.listing-table {
@include mat.table-density(-4);
min-width: 740px;
@@ -26,46 +26,11 @@
td,
th {
- max-width: 300px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- padding: 0 8px;
cursor: default;
}
- th {
- background-color: #728e9b;
- color: #fff;
- }
-
- tr:hover {
- background-color: #dce3e6 !important;
- }
-
- .selected {
- background-color: #ffef85 !important;
- }
-
- .even {
- background-color: #f4f6f7;
- }
-
- .fa {
- width: 10px;
- height: 14px;
- }
-
- .mat-column-actions {
- min-width: 115px;
- }
-
.mat-column-property {
min-width: 230px;
}
}
}
-
-::ng-deep .mat-sort-header-arrow {
- color: #fff;
-}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.ts
index 0900ead04d..75b2ca8b1f 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.ts
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.ts
@@ -87,7 +87,7 @@ export interface PropertyItem extends Property {
RouterLink,
AsyncPipe
],
- styleUrls: ['./property-table.component.scss'],
+ styleUrls: ['./property-table.component.scss',
'../../../../assets/styles/listing-table.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.scss
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/assets/styles/listing-table.scss
similarity index 59%
copy from
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.scss
copy to
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/assets/styles/listing-table.scss
index 10d9962109..33ca896721 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.scss
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/assets/styles/listing-table.scss
@@ -1,21 +1,21 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-.parameter-context-table {
+.listing-table {
table {
width: 100%;