This is an automated email from the ASF dual-hosted git repository.
scottyaslan 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 830b7443d5 NIFI-13081: Adding support to edit a label (#8681)
830b7443d5 is described below
commit 830b7443d5f311413658b0453a80db4bff92d918
Author: Matt Gilman <[email protected]>
AuthorDate: Mon Apr 22 16:05:28 2024 -0400
NIFI-13081: Adding support to edit a label (#8681)
* NIFI-13081:
- Adding support to edit a label.
* NIFI-13081:
- Fixing lint issues.
This closes #8681
---
.../service/canvas-context-menu.service.ts | 2 +-
.../pages/flow-designer/state/flow/flow.actions.ts | 5 +
.../pages/flow-designer/state/flow/flow.effects.ts | 35 +++++++
.../label/edit-label/edit-label.component.html | 58 +++++++++++
.../label/edit-label/edit-label.component.scss | 26 +++++
.../label/edit-label/edit-label.component.spec.ts | 93 +++++++++++++++++
.../items/label/edit-label/edit-label.component.ts | 116 +++++++++++++++++++++
7 files changed, 334 insertions(+), 1 deletion(-)
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts
index 418f9ae54f..8e6ec08eee 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts
@@ -1213,7 +1213,7 @@ export class CanvasContextMenu implements
ContextMenuDefinitionProvider {
},
{
condition: (selection: d3.Selection<any, any, any, any>) => {
- return this.canvasUtils.isDisconnected(selection);
+ return this.canvasUtils.isDisconnected(selection) &&
this.canvasUtils.canModify(selection);
},
clazz: 'fa icon-group',
text: 'Group',
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts
index 5f2c30ae9f..c00c48bc3f 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts
@@ -426,6 +426,11 @@ export const openEditRemoteProcessGroupDialog =
createAction(
props<{ request: EditComponentDialogRequest }>()
);
+export const openEditLabelDialog = createAction(
+ `${CANVAS_PREFIX} Open Edit Label Dialog`,
+ props<{ request: EditComponentDialogRequest }>()
+);
+
export const navigateToManageRemotePorts = createAction(
`${CANVAS_PREFIX} Open Remote Process Group Manage Remote Ports`,
props<{ request: RpgManageRemotePortsRequest }>()
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts
index eb92454cd2..d5f9d96b55 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts
@@ -129,6 +129,7 @@ import { ExtensionTypesService } from
'../../../../service/extension-types.servi
import { ChangeComponentVersionDialog } from
'../../../../ui/common/change-component-version-dialog/change-component-version-dialog';
import { SnippetService } from '../../service/snippet.service';
import { selectTransform } from '../transform/transform.selectors';
+import { EditLabel } from
'../../ui/canvas/items/label/edit-label/edit-label.component';
@Injectable()
export class FlowEffects {
@@ -1053,6 +1054,8 @@ export class FlowEffects {
case ComponentType.InputPort:
case ComponentType.OutputPort:
return of(FlowActions.openEditPortDialog({ request }));
+ case ComponentType.Label:
+ return of(FlowActions.openEditLabelDialog({ request
}));
default:
return of(FlowActions.flowApiError({ error:
'Unsupported type of Component.' }));
}
@@ -1119,6 +1122,38 @@ export class FlowEffects {
{ dispatch: false }
);
+ openEditLabelDialog$ = createEffect(
+ () =>
+ this.actions$.pipe(
+ ofType(FlowActions.openEditLabelDialog),
+ map((action) => action.request),
+ tap((request) => {
+ this.dialog
+ .open(EditLabel, {
+ ...MEDIUM_DIALOG,
+ data: request
+ })
+ .afterClosed()
+ .subscribe(() => {
+
this.store.dispatch(FlowActions.clearFlowApiError());
+ this.store.dispatch(
+ FlowActions.selectComponents({
+ request: {
+ components: [
+ {
+ id: request.entity.id,
+ componentType: request.type
+ }
+ ]
+ }
+ })
+ );
+ });
+ })
+ ),
+ { dispatch: false }
+ );
+
openEditProcessorDialog$ = createEffect(
() =>
this.actions$.pipe(
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.html
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.html
new file mode 100644
index 0000000000..8e66d176cc
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.html
@@ -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.
+ -->
+
+<h2 mat-dialog-title>{{ readonly ? 'Label Details' : 'Edit Label' }}</h2>
+<form class="edit-label-form" [formGroup]="editLabelForm">
+ <error-banner></error-banner>
+ <mat-dialog-content>
+ <div>
+ <mat-form-field>
+ <mat-label>Label Value</mat-label>
+ <textarea matInput formControlName="value" type="text"
rows="5" [readonly]="readonly"></textarea>
+ </mat-form-field>
+ </div>
+ <div>
+ <mat-form-field subscriptSizing="dynamic">
+ <mat-label>Font Size</mat-label>
+ <mat-select formControlName="fontSize">
+ @for (option of fontSizeOptions; track option) {
+ <mat-option [value]="option.value"
[disabled]="readonly">
+ {{ option.text }}
+ </mat-option>
+ }
+ </mat-select>
+ </mat-form-field>
+ </div>
+ </mat-dialog-content>
+ @if ({ value: (saving$ | async)! }; as saving) {
+ <mat-dialog-actions align="end">
+ @if (readonly) {
+ <button mat-button mat-dialog-close
color="primary">Close</button>
+ } @else {
+ <button mat-button mat-dialog-close>Cancel</button>
+ <button
+ [disabled]="!editLabelForm.dirty || editLabelForm.invalid
|| saving.value"
+ type="button"
+ color="primary"
+ (click)="editLabel()"
+ mat-button>
+ <span *nifiSpinner="saving.value">Apply</span>
+ </button>
+ }
+ </mat-dialog-actions>
+ }
+</form>
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.scss
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.scss
new file mode 100644
index 0000000000..425fde60b0
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.scss
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+@use '@angular/material' as mat;
+
+.edit-label-form {
+ @include mat.button-density(-1);
+
+ .mat-mdc-form-field {
+ width: 100%;
+ }
+}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.spec.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.spec.ts
new file mode 100644
index 0000000000..67007081c6
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.spec.ts
@@ -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.
+ */
+
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EditLabel } from './edit-label.component';
+import { EditComponentDialogRequest } from '../../../../../state/flow';
+import { MAT_DIALOG_DATA } from '@angular/material/dialog';
+import { ComponentType } from '../../../../../../../state/shared';
+import { provideMockStore } from '@ngrx/store/testing';
+import { initialState } from '../../../../../state/flow/flow.reducer';
+import { NoopAnimationsModule } from '@angular/platform-browser/animations';
+import { ClusterConnectionService } from
'../../../../../../../service/cluster-connection.service';
+
+describe('EditLabel', () => {
+ let component: EditLabel;
+ let fixture: ComponentFixture<EditLabel>;
+
+ const data: EditComponentDialogRequest = {
+ type: ComponentType.Label,
+ uri:
'https://localhost:4200/nifi-api/labels/d7c98831-018e-1000-6a26-6d74b57897e5',
+ entity: {
+ revision: {
+ version: 0
+ },
+ id: 'd7c98831-018e-1000-6a26-6d74b57897e5',
+ uri:
'https://localhost:4200/nifi-api/labels/d7c98831-018e-1000-6a26-6d74b57897e5',
+ position: {
+ x: 424,
+ y: -432
+ },
+ permissions: {
+ canRead: true,
+ canWrite: true
+ },
+ dimensions: {
+ width: 150,
+ height: 150
+ },
+ zIndex: 4,
+ component: {
+ id: 'd7c98831-018e-1000-6a26-6d74b57897e5',
+ versionedComponentId: 'c99e7867-73c6-3687-8f27-9b1ee5d761c4',
+ parentGroupId: 'f588fccd-018d-1000-e6dd-56d56dead186',
+ position: {
+ x: 424,
+ y: -432
+ },
+ width: 150,
+ height: 150,
+ zIndex: 4,
+ style: {}
+ }
+ }
+ };
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [EditLabel, NoopAnimationsModule],
+ providers: [
+ { provide: MAT_DIALOG_DATA, useValue: data },
+ provideMockStore({ initialState }),
+ {
+ provide: ClusterConnectionService,
+ useValue: {
+ isDisconnectionAcknowledged: jest.fn()
+ }
+ }
+ ]
+ });
+ fixture = TestBed.createComponent(EditLabel);
+ 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/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.ts
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.ts
new file mode 100644
index 0000000000..abf2ed0ce9
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.ts
@@ -0,0 +1,116 @@
+/*
+ * 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, Inject } from '@angular/core';
+import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
+import { CanvasState } from '../../../../../state';
+import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators
} from '@angular/forms';
+import { Store } from '@ngrx/store';
+import { updateComponent } from '../../../../../state/flow/flow.actions';
+import { Client } from '../../../../../../../service/client.service';
+import { EditComponentDialogRequest } from '../../../../../state/flow';
+import { SelectOption } from '../../../../../../../state/shared';
+import { ErrorBanner } from
'../../../../../../../ui/common/error-banner/error-banner.component';
+import { MatInputModule } from '@angular/material/input';
+import { MatCheckboxModule } from '@angular/material/checkbox';
+import { MatButtonModule } from '@angular/material/button';
+import { AsyncPipe } from '@angular/common';
+import { selectSaving } from '../../../../../state/flow/flow.selectors';
+import { NifiSpinnerDirective } from
'../../../../../../../ui/common/spinner/nifi-spinner.directive';
+import { ClusterConnectionService } from
'../../../../../../../service/cluster-connection.service';
+import { MatOption } from '@angular/material/autocomplete';
+import { MatSelect } from '@angular/material/select';
+import { NifiTooltipDirective } from
'../../../../../../../ui/common/tooltips/nifi-tooltip.directive';
+
+@Component({
+ selector: 'edit-label',
+ standalone: true,
+ templateUrl: './edit-label.component.html',
+ imports: [
+ ReactiveFormsModule,
+ ErrorBanner,
+ MatDialogModule,
+ MatInputModule,
+ MatCheckboxModule,
+ MatButtonModule,
+ AsyncPipe,
+ NifiSpinnerDirective,
+ MatOption,
+ MatSelect,
+ NifiTooltipDirective
+ ],
+ styleUrls: ['./edit-label.component.scss']
+})
+export class EditLabel {
+ saving$ = this.store.select(selectSaving);
+
+ editLabelForm: FormGroup;
+ readonly: boolean;
+
+ fontSizeOptions: SelectOption[] = [12, 14, 16, 18, 20, 22,
24].map((fontSize) => {
+ return {
+ text: `${fontSize}px`,
+ value: `${fontSize}px`
+ };
+ });
+
+ constructor(
+ @Inject(MAT_DIALOG_DATA) public request: EditComponentDialogRequest,
+ private formBuilder: FormBuilder,
+ private store: Store<CanvasState>,
+ private client: Client,
+ private clusterConnectionService: ClusterConnectionService
+ ) {
+ this.readonly = !request.entity.permissions.canWrite;
+
+ let fontSize = this.fontSizeOptions[0].value;
+ if (request.entity.component.style['font-size']) {
+ fontSize = request.entity.component.style['font-size'];
+ }
+
+ // build the form
+ this.editLabelForm = this.formBuilder.group({
+ value: new FormControl(request.entity.component.label,
Validators.required),
+ fontSize: new FormControl(fontSize, Validators.required)
+ });
+ }
+
+ editLabel() {
+ const payload: any = {
+ revision: this.client.getRevision(this.request.entity),
+ disconnectedNodeAcknowledged:
this.clusterConnectionService.isDisconnectionAcknowledged(),
+ component: {
+ id: this.request.entity.id,
+ label: this.editLabelForm.get('value')?.value,
+ style: {
+ 'font-size': this.editLabelForm.get('fontSize')?.value
+ }
+ }
+ };
+
+ this.store.dispatch(
+ updateComponent({
+ request: {
+ id: this.request.entity.id,
+ type: this.request.type,
+ uri: this.request.uri,
+ payload
+ }
+ })
+ );
+ }
+}