diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java index 5dfa1a15af..71b1e92322 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java @@ -102,6 +102,7 @@ import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEnti import org.apache.nifi.web.api.entity.CurrentUserEntity; import org.apache.nifi.web.api.entity.FlowAnalysisResultEntity; import org.apache.nifi.web.api.entity.FlowAnalysisRuleEntity; +import org.apache.nifi.web.api.entity.FlowBreadcrumbEntity; import org.apache.nifi.web.api.entity.FlowComparisonEntity; import org.apache.nifi.web.api.entity.FlowConfigurationEntity; import org.apache.nifi.web.api.entity.FlowEntity; @@ -1008,6 +1009,14 @@ public interface NiFiServiceFacade { */ ProcessGroupFlowEntity getProcessGroupFlow(String groupId, boolean uiOnly); + /** + * Returns the breadcrumbs for the specified group. + * + * @param groupId group id + * @return the breadcrumbs + */ + FlowBreadcrumbEntity getProcessGroupBreadcrumbs(String groupId); + // ---------------------------------------- // ProcessGroup methods // ---------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java index e0382badc2..48aa84825e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java @@ -297,6 +297,7 @@ import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEnti import org.apache.nifi.web.api.entity.CurrentUserEntity; import org.apache.nifi.web.api.entity.FlowAnalysisResultEntity; import org.apache.nifi.web.api.entity.FlowAnalysisRuleEntity; +import org.apache.nifi.web.api.entity.FlowBreadcrumbEntity; import org.apache.nifi.web.api.entity.FlowComparisonEntity; import org.apache.nifi.web.api.entity.FlowConfigurationEntity; import org.apache.nifi.web.api.entity.FlowEntity; @@ -4783,6 +4784,12 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { return entityFactory.createProcessGroupFlowEntity(dtoFactory.createProcessGroupFlowDto(processGroup, groupStatus, revisionManager, this::getProcessGroupBulletins, uiOnly), permissions); } + @Override + public FlowBreadcrumbEntity getProcessGroupBreadcrumbs(final String groupId) { + final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); + return dtoFactory.createBreadcrumbEntity(processGroup); + } + @Override public ProcessGroupEntity getProcessGroup(final String groupId) { final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java index ec89e06f93..9b71235622 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java @@ -88,6 +88,7 @@ import org.apache.nifi.web.api.entity.ControllerStatusEntity; import org.apache.nifi.web.api.entity.CurrentUserEntity; import org.apache.nifi.web.api.entity.FlowAnalysisResultEntity; import org.apache.nifi.web.api.entity.FlowAnalysisRuleTypesEntity; +import org.apache.nifi.web.api.entity.FlowBreadcrumbEntity; import org.apache.nifi.web.api.entity.FlowConfigurationEntity; import org.apache.nifi.web.api.entity.FlowRegistryBucketEntity; import org.apache.nifi.web.api.entity.FlowRegistryBucketsEntity; @@ -401,6 +402,43 @@ public class FlowResource extends ApplicationResource { return generateOkResponse(entity).build(); } + @GET + @Consumes(MediaType.WILDCARD) + @Produces(MediaType.APPLICATION_JSON) + @Path("process-groups/{id}/breadcrumbs") + @ApiOperation( + value = "Gets the breadcrumbs for a process group", + response = FlowBreadcrumbEntity.class, + authorizations = { + @Authorization(value = "Read - /flow") + } + ) + @ApiResponses( + value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 404, message = "The specified resource could not be found."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + } + ) + public Response getBreadcrumbs( + @ApiParam( + value = "The process group id." + ) + @PathParam("id") final String groupId) { + + authorizeFlow(); + + if (isReplicateRequest()) { + return replicate(HttpMethod.GET); + } + + // get the breadcrumbs for this process group + final FlowBreadcrumbEntity breadcrumbEntity = serviceFacade.getProcessGroupBreadcrumbs(groupId); + return generateOkResponse(breadcrumbEntity).build(); + } + /** * Retrieves the metrics of the entire flow. * diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java index 58c77ba401..f6e451f838 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java @@ -1842,7 +1842,6 @@ public final class DtoFactory { Collection validationErrors = null; if (component instanceof ProcessorNode) { final ProcessorNode node = ((ProcessorNode) component); - dto.setGroupId(node.getProcessGroup().getIdentifier()); dto.setState(node.getScheduledState().name()); dto.setActiveThreadCount(node.getActiveThreadCount()); dto.setType(node.getComponentType()); @@ -1919,6 +1918,7 @@ public final class DtoFactory { orderedProperties.putAll(sortedProperties); // build the descriptor and property dtos + dto.setGroupId(processGroupId); dto.setDescriptors(new LinkedHashMap()); dto.setProperties(new LinkedHashMap()); for (final Map.Entry entry : orderedProperties.entrySet()) { @@ -2091,7 +2091,7 @@ public final class DtoFactory { * @param group group * @return dto */ - private FlowBreadcrumbEntity createBreadcrumbEntity(final ProcessGroup group) { + public FlowBreadcrumbEntity createBreadcrumbEntity(final ProcessGroup group) { if (group == null) { return null; } 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 7e39ca6974..07361220c0 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 @@ -45,7 +45,8 @@ const routes: Routes = [ { path: '', canMatch: [authGuard], - loadChildren: () => import('./pages/canvas/feature/flow-designer.module').then((m) => m.FlowDesignerModule) + loadChildren: () => + import('./pages/flow-designer/feature/flow-designer.module').then((m) => m.FlowDesignerModule) } ]; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/app.module.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/app.module.ts index cb45fb4c1a..6afaea16c7 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/app.module.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/app.module.ts @@ -20,7 +20,7 @@ import { BrowserModule } from '@angular/platform-browser'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { FlowDesignerModule } from './pages/canvas/feature/flow-designer.module'; +import { FlowDesignerModule } from './pages/flow-designer/feature/flow-designer.module'; import { StoreModule } from '@ngrx/store'; import { EffectsModule } from '@ngrx/effects'; import { StoreDevtoolsModule } from '@ngrx/store-devtools'; 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.module.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/header/header.module.ts deleted file mode 100644 index f5f6af2d95..0000000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/header/header.module.ts +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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, NgOptimizedImage } from '@angular/common'; -import { HeaderComponent } from './header.component'; -import { FlowStatus } from './flow-status/flow-status.component'; -import { CdkDrag } from '@angular/cdk/drag-drop'; -import { NewCanvasItem } from './new-canvas-item/new-canvas-item.component'; -import { MatButtonModule } from '@angular/material/button'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatDividerModule } from '@angular/material/divider'; -import { Search } from './search/search.component'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatAutocompleteModule } from '@angular/material/autocomplete'; -import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; -import { RouterLink } from '@angular/router'; -import { NifiTooltipDirective } from '../../../../ui/common/tooltips/nifi-tooltip.directive'; - -@NgModule({ - declarations: [HeaderComponent, NewCanvasItem, FlowStatus, Search], - exports: [HeaderComponent], - imports: [ - CommonModule, - NgOptimizedImage, - CdkDrag, - MatButtonModule, - MatMenuModule, - MatDividerModule, - FormsModule, - ReactiveFormsModule, - MatFormFieldModule, - MatAutocompleteModule, - CdkConnectedOverlay, - CdkOverlayOrigin, - RouterLink, - NifiTooltipDirective - ] -}) -export class HeaderModule {} 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 index 33ea2bf6a2..b29f003a77 100644 --- 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 @@ -25,6 +25,7 @@ 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'; +import { MatDialogModule } from '@angular/material/dialog'; @NgModule({ declarations: [Counters], @@ -35,7 +36,8 @@ import { ParameterContextListingModule } from '../../parameter-contexts/ui/param StoreModule.forFeature(countersFeatureKey, reducers), EffectsModule.forFeature(CounterListingEffects), CounterListingModule, - ParameterContextListingModule + ParameterContextListingModule, + MatDialogModule ] }) 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/canvas/feature/flow-designer-routing.module.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/feature/flow-designer-routing.module.ts similarity index 73% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/feature/flow-designer-routing.module.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/feature/flow-designer-routing.module.ts index 8f1dd32fc6..e52c9b3e3b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/feature/flow-designer-routing.module.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/feature/flow-designer-routing.module.ts @@ -20,22 +20,28 @@ import { RouterModule, Routes } from '@angular/router'; import { FlowDesigner } from './flow-designer.component'; import { RootGroupRedirector } from '../ui/root/redirector/root-group-redirector.component'; import { rootGroupGuard } from '../ui/root/guard/root-group.guard'; +import { Canvas } from '../ui/canvas/canvas.component'; +import { ControllerServices } from '../ui/controller-service/controller-services.component'; const routes: Routes = [ { path: 'process-groups/:processGroupId', component: FlowDesigner, children: [ - { path: 'bulk/:ids', component: FlowDesigner }, { - path: ':type/:id', - component: FlowDesigner, - children: [{ path: 'edit', component: FlowDesigner }] + path: 'controller-services', + loadChildren: () => + import('../ui/controller-service/controller-services.module').then( + (m) => m.ControllerServicesModule + ) + }, + { + path: '', + loadChildren: () => import('../ui/canvas/canvas.module').then((m) => m.CanvasModule) } ] }, { path: '', component: RootGroupRedirector, canActivate: [rootGroupGuard] } - // { path: '**', component: FlowDesignerComponent } ]; @NgModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/feature/flow-designer.component.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/feature/flow-designer.component.html similarity index 83% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/feature/flow-designer.component.html rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/feature/flow-designer.component.html index 7454102b90..c3a79d415a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/feature/flow-designer.component.html +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/feature/flow-designer.component.html @@ -15,8 +15,4 @@ ~ 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/canvas/feature/flow-designer.component.scss b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/feature/flow-designer.component.scss similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/feature/flow-designer.component.scss rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/feature/flow-designer.component.scss diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/feature/flow-designer.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/feature/flow-designer.component.spec.ts similarity index 78% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/feature/flow-designer.component.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/feature/flow-designer.component.spec.ts index 82b372f269..e092516ee5 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/feature/flow-designer.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/feature/flow-designer.component.spec.ts @@ -20,33 +20,16 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FlowDesigner } from './flow-designer.component'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../state/flow/flow.reducer'; -import { Component } from '@angular/core'; +import { RouterTestingModule } from '@angular/router/testing'; describe('FlowDesigner', () => { let component: FlowDesigner; let fixture: ComponentFixture; - @Component({ - selector: 'fd-header', - template: '' - }) - class MockHeader {} - - @Component({ - selector: 'fd-canvas', - template: '' - }) - class MockCanvas {} - - @Component({ - selector: 'fd-footer', - template: '' - }) - class MockFooter {} - beforeEach(() => { TestBed.configureTestingModule({ - declarations: [FlowDesigner, MockHeader, MockCanvas, MockFooter], + declarations: [FlowDesigner], + imports: [RouterTestingModule], providers: [ provideMockStore({ initialState diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/feature/flow-designer.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/feature/flow-designer.component.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/feature/flow-designer.component.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/feature/flow-designer.component.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/feature/flow-designer.module.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/feature/flow-designer.module.ts similarity index 85% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/feature/flow-designer.module.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/feature/flow-designer.module.ts index 1db87f1e24..2343c09e6a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/feature/flow-designer.module.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/feature/flow-designer.module.ts @@ -19,9 +19,6 @@ import { NgModule } from '@angular/core'; import { CommonModule, NgOptimizedImage } from '@angular/common'; import { FlowDesigner } from './flow-designer.component'; import { FlowDesignerRoutingModule } from './flow-designer-routing.module'; -import { HeaderModule } from '../ui/header/header.module'; -import { FooterModule } from '../ui/footer/footer.module'; -import { CanvasModule } from '../ui/canvas/canvas.module'; import { StoreModule } from '@ngrx/store'; import { EffectsModule } from '@ngrx/effects'; import { FlowEffects } from '../state/flow/flow.effects'; @@ -29,18 +26,16 @@ import { TransformEffects } from '../state/transform/transform.effects'; import { VersionControlTip } from '../ui/common/tooltips/version-control-tip/version-control-tip.component'; import { canvasFeatureKey, reducers } from '../state'; import { MatDialogModule } from '@angular/material/dialog'; +import { ControllerServicesEffects } from '../state/controller-services/controller-services.effects'; @NgModule({ declarations: [FlowDesigner, VersionControlTip], exports: [FlowDesigner], imports: [ CommonModule, - HeaderModule, - CanvasModule, - FooterModule, FlowDesignerRoutingModule, StoreModule.forFeature(canvasFeatureKey, reducers), - EffectsModule.forFeature(FlowEffects, TransformEffects), + EffectsModule.forFeature(FlowEffects, TransformEffects, ControllerServicesEffects), NgOptimizedImage, MatDialogModule ] diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/connectable-behavior.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/connectable-behavior.service.spec.ts similarity index 86% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/connectable-behavior.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/connectable-behavior.service.spec.ts index 078553e614..7848b5a4ad 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/connectable-behavior.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/connectable-behavior.service.spec.ts @@ -25,6 +25,8 @@ import { flowFeatureKey } from '../../state/flow'; import { selectFlowState } from '../../state/flow/flow.selectors'; import { CanvasState } from '../../state'; import { transformFeatureKey } from '../../state/transform'; +import { controllerServicesFeatureKey } from '../../state/controller-services'; +import * as fromControllerServices from '../../state/controller-services/controller-services.reducer'; describe('ConnectableBehavior', () => { let service: ConnectableBehavior; @@ -32,7 +34,8 @@ describe('ConnectableBehavior', () => { beforeEach(() => { const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; TestBed.configureTestingModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/connectable-behavior.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/behavior/connectable-behavior.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/connectable-behavior.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/connectable-behavior.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/draggable-behavior.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.spec.ts similarity index 87% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/draggable-behavior.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.spec.ts index dc62844f19..0d35ab7053 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/draggable-behavior.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.spec.ts @@ -22,11 +22,12 @@ import * as fromFlow from '../../state/flow/flow.reducer'; import * as fromTransform from '../../state/transform/transform.reducer'; import { provideMockStore } from '@ngrx/store/testing'; import { selectTransform } from '../../state/transform/transform.selectors'; -import { initialState } from '../../state/transform/transform.reducer'; import { CanvasState } from '../../state'; import { flowFeatureKey } from '../../state/flow'; import { transformFeatureKey } from '../../state/transform'; import { selectFlowState } from '../../state/flow/flow.selectors'; +import { controllerServicesFeatureKey } from '../../state/controller-services'; +import * as fromControllerServices from '../../state/controller-services/controller-services.reducer'; describe('DraggableBehavior', () => { let service: DraggableBehavior; @@ -34,7 +35,8 @@ describe('DraggableBehavior', () => { beforeEach(() => { const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; TestBed.configureTestingModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/draggable-behavior.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/behavior/draggable-behavior.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/draggable-behavior.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/editable-behavior.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/editable-behavior.service.spec.ts similarity index 88% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/editable-behavior.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/editable-behavior.service.spec.ts index e9c39da72f..9b1e42959b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/editable-behavior.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/editable-behavior.service.spec.ts @@ -26,13 +26,16 @@ import * as fromFlow from '../../state/flow/flow.reducer'; import { transformFeatureKey } from '../../state/transform'; import * as fromTransform from '../../state/transform/transform.reducer'; import { selectTransform } from '../../state/transform/transform.selectors'; +import { controllerServicesFeatureKey } from '../../state/controller-services'; +import * as fromControllerServices from '../../state/controller-services/controller-services.reducer'; describe('EditableBehaviorService', () => { let service: EditableBehavior; const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; beforeEach(() => { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/editable-behavior.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/behavior/editable-behavior.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/editable-behavior.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/editable-behavior.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/position-behavior.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/position-behavior.service.spec.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/position-behavior.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/position-behavior.service.spec.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/position-behavior.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/behavior/position-behavior.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/position-behavior.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/position-behavior.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/quick-select-behavior.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/quick-select-behavior.service.spec.ts similarity index 86% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/quick-select-behavior.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/quick-select-behavior.service.spec.ts index d00e6575ac..b1257754ef 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/quick-select-behavior.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/quick-select-behavior.service.spec.ts @@ -19,13 +19,14 @@ import { TestBed } from '@angular/core/testing'; import { QuickSelectBehavior } from './quick-select-behavior.service'; import { provideMockStore } from '@ngrx/store/testing'; -import { initialState } from '../../state/flow/flow.reducer'; import { selectFlowState } from '../../state/flow/flow.selectors'; import { CanvasState } from '../../state'; import { flowFeatureKey } from '../../state/flow'; import * as fromFlow from '../../state/flow/flow.reducer'; import { transformFeatureKey } from '../../state/transform'; import * as fromTransform from '../../state/transform/transform.reducer'; +import { controllerServicesFeatureKey } from '../../state/controller-services'; +import * as fromControllerServices from '../../state/controller-services/controller-services.reducer'; describe('QuickSelectBehavior', () => { let service: QuickSelectBehavior; @@ -33,7 +34,8 @@ describe('QuickSelectBehavior', () => { beforeEach(() => { const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; TestBed.configureTestingModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/quick-select-behavior.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/behavior/quick-select-behavior.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/quick-select-behavior.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/quick-select-behavior.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/selectable-behavior.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/selectable-behavior.service.spec.ts similarity index 86% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/selectable-behavior.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/selectable-behavior.service.spec.ts index 8c54c8e8ff..19897c183d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/selectable-behavior.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/selectable-behavior.service.spec.ts @@ -24,6 +24,8 @@ import { transformFeatureKey } from '../../state/transform'; import * as fromTransform from '../../state/transform/transform.reducer'; import { provideMockStore } from '@ngrx/store/testing'; import { selectFlowState } from '../../state/flow/flow.selectors'; +import { controllerServicesFeatureKey } from '../../state/controller-services'; +import * as fromControllerServices from '../../state/controller-services/controller-services.reducer'; describe('SelectableBehavior', () => { let service: SelectableBehavior; @@ -31,7 +33,8 @@ describe('SelectableBehavior', () => { beforeEach(() => { const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; TestBed.configureTestingModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/selectable-behavior.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/behavior/selectable-behavior.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/selectable-behavior.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/selectable-behavior.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/transition-behavior.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/transition-behavior.service.spec.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/transition-behavior.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/transition-behavior.service.spec.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/transition-behavior.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/behavior/transition-behavior.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/behavior/transition-behavior.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/transition-behavior.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/birdseye-view.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/birdseye-view.service.spec.ts similarity index 87% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/birdseye-view.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/birdseye-view.service.spec.ts index 8157fdc1da..b1fb156735 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/birdseye-view.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/birdseye-view.service.spec.ts @@ -26,6 +26,8 @@ import * as fromTransform from '../state/transform/transform.reducer'; import { provideMockStore } from '@ngrx/store/testing'; import { selectFlowState } from '../state/flow/flow.selectors'; import { selectTransform } from '../state/transform/transform.selectors'; +import { controllerServicesFeatureKey } from '../state/controller-services'; +import * as fromControllerServices from '../state/controller-services/controller-services.reducer'; describe('BirdseyeView', () => { let service: BirdseyeView; @@ -33,7 +35,8 @@ describe('BirdseyeView', () => { beforeEach(() => { const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; TestBed.configureTestingModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/birdseye-view.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/birdseye-view.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/birdseye-view.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/birdseye-view.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/canvas-utils.service.spec.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-utils.service.spec.ts similarity index 86% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/canvas-utils.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-utils.service.spec.ts index 170272aba7..265935bec8 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/canvas-utils.service.spec.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-utils.service.spec.ts @@ -25,7 +25,8 @@ import { transformFeatureKey } from '../state/transform'; import * as fromTransform from '../state/transform/transform.reducer'; import { provideMockStore } from '@ngrx/store/testing'; import { selectFlowState } from '../state/flow/flow.selectors'; -import { selectTransform } from '../state/transform/transform.selectors'; +import { controllerServicesFeatureKey } from '../state/controller-services'; +import * as fromControllerServices from '../state/controller-services/controller-services.reducer'; describe('CanvasUtils', () => { let service: CanvasUtils; @@ -33,7 +34,8 @@ describe('CanvasUtils', () => { beforeEach(() => { const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; TestBed.configureTestingModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/canvas-utils.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-utils.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/canvas-utils.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-utils.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/canvas-view.service.spec.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-view.service.spec.ts similarity index 87% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/canvas-view.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-view.service.spec.ts index a9e3015b72..21e166cc3a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/canvas-view.service.spec.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-view.service.spec.ts @@ -26,6 +26,8 @@ import * as fromTransform from '../state/transform/transform.reducer'; import { provideMockStore } from '@ngrx/store/testing'; import { selectFlowState } from '../state/flow/flow.selectors'; import { selectTransform } from '../state/transform/transform.selectors'; +import { controllerServicesFeatureKey } from '../state/controller-services'; +import * as fromControllerServices from '../state/controller-services/controller-services.reducer'; describe('CanvasView', () => { let service: CanvasView; @@ -33,7 +35,8 @@ describe('CanvasView', () => { beforeEach(() => { const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; TestBed.configureTestingModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/canvas-view.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-view.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/canvas-view.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-view.service.ts 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/controller-service.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/controller-service.service.ts new file mode 100644 index 0000000000..c354935607 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/controller-service.service.ts @@ -0,0 +1,107 @@ +/* + * 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 { Observable, throwError } from 'rxjs'; +import { HttpClient } from '@angular/common/http'; +import { Client } from '../../../service/client.service'; +import { NiFiCommon } from '../../../service/nifi-common.service'; +import { ControllerServiceEntity } from '../../../state/shared'; +import { + ConfigureControllerServiceRequest, + CreateControllerServiceRequest, + DeleteControllerServiceRequest +} from '../state/controller-services'; + +@Injectable({ providedIn: 'root' }) +export class ControllerServiceService { + private static readonly API: string = '../nifi-api'; + + /** + * The NiFi model contain the url for each component. That URL is an absolute URL. Angular CSRF handling + * does not work on absolute URLs, so we need to strip off the proto for the request header to be added. + * + * https://stackoverflow.com/a/59586462 + * + * @param url + * @private + */ + private stripProtocol(url: string): string { + return this.nifiCommon.substringAfterFirst(url, ':'); + } + + constructor( + private httpClient: HttpClient, + private client: Client, + private nifiCommon: NiFiCommon + ) {} + + getControllerServices(processGroupId: string): Observable { + const uiOnly: any = { uiOnly: true }; + return this.httpClient.get( + `${ControllerServiceService.API}/flow/process-groups/${processGroupId}/controller-services`, + { + params: uiOnly + } + ); + } + + getBreadcrumbs(processGroupId: string): Observable { + return this.httpClient.get(`${ControllerServiceService.API}/flow/process-groups/${processGroupId}/breadcrumbs`); + } + + getControllerService(id: string): Observable { + return this.httpClient.get(`${ControllerServiceService.API}/controller-services/${id}`); + } + + createControllerService(createControllerService: CreateControllerServiceRequest): Observable { + const processGroupId: string = createControllerService.processGroupId; + return this.httpClient.post( + `${ControllerServiceService.API}/process-groups/${processGroupId}/controller-services`, + { + revision: createControllerService.revision, + component: { + bundle: createControllerService.controllerServiceBundle, + type: createControllerService.controllerServiceType + } + } + ); + } + + getPropertyDescriptor(id: string, propertyName: string, sensitive: boolean): Observable { + const params: any = { + propertyName, + sensitive + }; + return this.httpClient.get(`${ControllerServiceService.API}/controller-services/${id}/descriptors`, { + params + }); + } + + updateControllerService(configureControllerService: ConfigureControllerServiceRequest): Observable { + return this.httpClient.put( + this.stripProtocol(configureControllerService.uri), + configureControllerService.payload + ); + } + + deleteControllerService(deleteControllerService: DeleteControllerServiceRequest): Observable { + const entity: ControllerServiceEntity = deleteControllerService.controllerService; + const revision: any = this.client.getRevision(entity); + return this.httpClient.delete(this.stripProtocol(entity.uri), { params: revision }); + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/flow.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/flow.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/flow.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/flow.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/connection-manager.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.spec.ts similarity index 87% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/connection-manager.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.spec.ts index e182b86901..5ecd9dd8c0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/connection-manager.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.spec.ts @@ -26,6 +26,8 @@ import * as fromTransform from '../../state/transform/transform.reducer'; import { provideMockStore } from '@ngrx/store/testing'; import { selectFlowState } from '../../state/flow/flow.selectors'; import { selectTransform } from '../../state/transform/transform.selectors'; +import { controllerServicesFeatureKey } from '../../state/controller-services'; +import * as fromControllerServices from '../../state/controller-services/controller-services.reducer'; describe('ConnectionManager', () => { let service: ConnectionManager; @@ -33,7 +35,8 @@ describe('ConnectionManager', () => { beforeEach(() => { const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; TestBed.configureTestingModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/connection-manager.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/manager/connection-manager.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/connection-manager.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/funnel-manager.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/funnel-manager.service.spec.ts similarity index 87% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/funnel-manager.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/funnel-manager.service.spec.ts index 7a8a4ee6e8..155847e2d2 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/funnel-manager.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/funnel-manager.service.spec.ts @@ -26,6 +26,8 @@ import * as fromTransform from '../../state/transform/transform.reducer'; import { provideMockStore } from '@ngrx/store/testing'; import { selectFlowState } from '../../state/flow/flow.selectors'; import { selectTransform } from '../../state/transform/transform.selectors'; +import { controllerServicesFeatureKey } from '../../state/controller-services'; +import * as fromControllerServices from '../../state/controller-services/controller-services.reducer'; describe('FunnelManager', () => { let service: FunnelManager; @@ -33,7 +35,8 @@ describe('FunnelManager', () => { beforeEach(() => { const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; TestBed.configureTestingModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/funnel-manager.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/manager/funnel-manager.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/funnel-manager.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/funnel-manager.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/label-manager.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.spec.ts similarity index 87% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/label-manager.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.spec.ts index 3ccd5b0409..5312632e53 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/label-manager.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.spec.ts @@ -26,6 +26,8 @@ import * as fromTransform from '../../state/transform/transform.reducer'; import { provideMockStore } from '@ngrx/store/testing'; import { selectFlowState } from '../../state/flow/flow.selectors'; import { selectTransform } from '../../state/transform/transform.selectors'; +import { controllerServicesFeatureKey } from '../../state/controller-services'; +import * as fromControllerServices from '../../state/controller-services/controller-services.reducer'; describe('LabelManager', () => { let service: LabelManager; @@ -33,7 +35,8 @@ describe('LabelManager', () => { beforeEach(() => { const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; TestBed.configureTestingModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/label-manager.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/manager/label-manager.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/label-manager.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/port-manager.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/port-manager.service.spec.ts similarity index 87% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/port-manager.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/port-manager.service.spec.ts index b089312c5a..9aa2d25126 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/port-manager.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/port-manager.service.spec.ts @@ -26,6 +26,8 @@ import * as fromTransform from '../../state/transform/transform.reducer'; import { provideMockStore } from '@ngrx/store/testing'; import { selectFlowState } from '../../state/flow/flow.selectors'; import { selectTransform } from '../../state/transform/transform.selectors'; +import { controllerServicesFeatureKey } from '../../state/controller-services'; +import * as fromControllerServices from '../../state/controller-services/controller-services.reducer'; describe('PortManager', () => { let service: PortManager; @@ -33,7 +35,8 @@ describe('PortManager', () => { beforeEach(() => { const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; TestBed.configureTestingModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/port-manager.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/manager/port-manager.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/port-manager.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/port-manager.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/process-group-manager.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/process-group-manager.service.spec.ts similarity index 87% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/process-group-manager.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/process-group-manager.service.spec.ts index 3014e9d7b7..19e42adcd3 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/process-group-manager.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/process-group-manager.service.spec.ts @@ -26,6 +26,8 @@ import * as fromTransform from '../../state/transform/transform.reducer'; import { provideMockStore } from '@ngrx/store/testing'; import { selectFlowState } from '../../state/flow/flow.selectors'; import { selectTransform } from '../../state/transform/transform.selectors'; +import { controllerServicesFeatureKey } from '../../state/controller-services'; +import * as fromControllerServices from '../../state/controller-services/controller-services.reducer'; describe('ProcessGroupManager', () => { let service: ProcessGroupManager; @@ -33,7 +35,8 @@ describe('ProcessGroupManager', () => { beforeEach(() => { const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; TestBed.configureTestingModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/process-group-manager.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/manager/process-group-manager.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/process-group-manager.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/process-group-manager.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/processor-manager.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/processor-manager.service.spec.ts similarity index 87% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/processor-manager.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/processor-manager.service.spec.ts index ab8ba60dcb..3712d27b7a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/processor-manager.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/processor-manager.service.spec.ts @@ -26,6 +26,8 @@ import * as fromTransform from '../../state/transform/transform.reducer'; import { provideMockStore } from '@ngrx/store/testing'; import { selectFlowState } from '../../state/flow/flow.selectors'; import { selectTransform } from '../../state/transform/transform.selectors'; +import { controllerServicesFeatureKey } from '../../state/controller-services'; +import * as fromControllerServices from '../../state/controller-services/controller-services.reducer'; describe('ProcessorManager', () => { let service: ProcessorManager; @@ -33,7 +35,8 @@ describe('ProcessorManager', () => { beforeEach(() => { const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; TestBed.configureTestingModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/processor-manager.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/manager/processor-manager.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/processor-manager.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/processor-manager.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/remote-process-group-manager.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/remote-process-group-manager.service.spec.ts similarity index 87% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/remote-process-group-manager.service.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/remote-process-group-manager.service.spec.ts index fecad0b4b9..422f1a41f9 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/remote-process-group-manager.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/remote-process-group-manager.service.spec.ts @@ -26,6 +26,8 @@ import * as fromTransform from '../../state/transform/transform.reducer'; import { provideMockStore } from '@ngrx/store/testing'; import { selectFlowState } from '../../state/flow/flow.selectors'; import { selectTransform } from '../../state/transform/transform.selectors'; +import { controllerServicesFeatureKey } from '../../state/controller-services'; +import * as fromControllerServices from '../../state/controller-services/controller-services.reducer'; describe('RemoteProcessGroupManager', () => { let service: RemoteProcessGroupManager; @@ -33,7 +35,8 @@ describe('RemoteProcessGroupManager', () => { beforeEach(() => { const initialState: CanvasState = { [flowFeatureKey]: fromFlow.initialState, - [transformFeatureKey]: fromTransform.initialState + [transformFeatureKey]: fromTransform.initialState, + [controllerServicesFeatureKey]: fromControllerServices.initialState }; TestBed.configureTestingModule({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/remote-process-group-manager.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/manager/remote-process-group-manager.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/manager/remote-process-group-manager.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/remote-process-group-manager.service.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/search.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/search.service.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/service/search.service.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/search.service.ts 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/controller-services/controller-services.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/controller-services/controller-services.actions.ts new file mode 100644 index 0000000000..b6d13e4070 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.actions.ts @@ -0,0 +1,102 @@ +/* + * 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 { + ConfigureControllerServiceRequest, + ConfigureControllerServiceSuccess, + CreateControllerServiceRequest, + CreateControllerServiceSuccess, + DeleteControllerServiceRequest, + DeleteControllerServiceSuccess, + LoadControllerServicesRequest, + LoadControllerServicesResponse, + SelectControllerServiceRequest +} from './index'; +import { EditControllerServiceDialogRequest } from '../../../../state/shared'; + +export const loadControllerServices = createAction( + '[Controller Services] Load Controller Services', + props<{ request: LoadControllerServicesRequest }>() +); + +export const loadControllerServicesSuccess = createAction( + '[Controller Services] Load Controller Services Success', + props<{ response: LoadControllerServicesResponse }>() +); + +export const controllerServicesApiError = createAction( + '[Controller Services] Load Controller Service Error', + props<{ error: string }>() +); + +export const openNewControllerServiceDialog = createAction('[Controller Services] Open New Controller Service Dialog'); + +export const createControllerService = createAction( + '[Controller Services] Create Controller Service', + props<{ request: CreateControllerServiceRequest }>() +); + +export const createControllerServiceSuccess = createAction( + '[Controller Services] Create Controller Service Success', + props<{ response: CreateControllerServiceSuccess }>() +); + +export const inlineCreateControllerServiceSuccess = createAction( + '[Controller Services] Inline Create Controller Service Success', + props<{ response: CreateControllerServiceSuccess }>() +); + +export const navigateToEditService = createAction( + '[Controller Services] Navigate To Edit Service', + props<{ id: string }>() +); + +export const openConfigureControllerServiceDialog = createAction( + '[Controller Services] Open Configure Controller Service Dialog', + props<{ request: EditControllerServiceDialogRequest }>() +); + +export const configureControllerService = createAction( + '[Controller Services] Configure Controller Service', + props<{ request: ConfigureControllerServiceRequest }>() +); + +export const configureControllerServiceSuccess = createAction( + '[Controller Services] Configure Controller Service Success', + props<{ response: ConfigureControllerServiceSuccess }>() +); + +export const promptControllerServiceDeletion = createAction( + '[Controller Services] Prompt Controller Service Deletion', + props<{ request: DeleteControllerServiceRequest }>() +); + +export const deleteControllerService = createAction( + '[Controller Services] Delete Controller Service', + props<{ request: DeleteControllerServiceRequest }>() +); + +export const deleteControllerServiceSuccess = createAction( + '[Controller Services] Delete Controller Service Success', + props<{ response: DeleteControllerServiceSuccess }>() +); + +export const selectControllerService = createAction( + '[Controller Services] Select Controller Service', + props<{ request: SelectControllerServiceRequest }>() +); 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/controller-services/controller-services.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/controller-services/controller-services.effects.ts new file mode 100644 index 0000000000..e4f99be402 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.effects.ts @@ -0,0 +1,466 @@ +/* + * 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 * as ControllerServicesActions from './controller-services.actions'; +import { + catchError, + combineLatest, + from, + map, + NEVER, + Observable, + of, + switchMap, + take, + tap, + withLatestFrom +} from 'rxjs'; +import { MatDialog } from '@angular/material/dialog'; +import { Store } from '@ngrx/store'; +import { NiFiState } from '../../../../state'; +import { selectControllerServiceTypes } from '../../../../state/extension-types/extension-types.selectors'; +import { CreateControllerService } from '../../../../ui/common/controller-service/create-controller-service/create-controller-service.component'; +import { Client } from '../../../../service/client.service'; +import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; +import { EditControllerService } from '../../../../ui/common/controller-service/edit-controller-service/edit-controller-service.component'; +import { + InlineServiceCreationRequest, + InlineServiceCreationResponse, + NewPropertyDialogRequest, + NewPropertyDialogResponse, + Property, + PropertyDescriptor +} from '../../../../state/shared'; +import { NewPropertyDialog } from '../../../../ui/common/new-property-dialog/new-property-dialog.component'; +import { Router } from '@angular/router'; +import { ExtensionTypesService } from '../../../../service/extension-types.service'; +import { selectCurrentProcessGroupId, selectSaving } from './controller-services.selectors'; +import { ControllerServiceService } from '../../service/controller-service.service'; + +@Injectable() +export class ControllerServicesEffects { + constructor( + private actions$: Actions, + private store: Store, + private client: Client, + private controllerServiceService: ControllerServiceService, + private extensionTypesService: ExtensionTypesService, + private dialog: MatDialog, + private router: Router + ) {} + + loadControllerServices$ = createEffect(() => + this.actions$.pipe( + ofType(ControllerServicesActions.loadControllerServices), + map((action) => action.request), + switchMap((request) => + combineLatest([ + this.controllerServiceService.getControllerServices(request.processGroupId), + this.controllerServiceService.getBreadcrumbs(request.processGroupId) + ]).pipe( + map(([controllerServicesResponse, breadcrumbsResponse]) => + ControllerServicesActions.loadControllerServicesSuccess({ + response: { + processGroupId: breadcrumbsResponse.id, + controllerServices: controllerServicesResponse.controllerServices, + loadedTimestamp: controllerServicesResponse.currentTime, + breadcrumb: breadcrumbsResponse + } + }) + ), + catchError((error) => + of( + ControllerServicesActions.controllerServicesApiError({ + error: error.error + }) + ) + ) + ) + ) + ) + ); + + openNewControllerServiceDialog$ = createEffect( + () => + this.actions$.pipe( + ofType(ControllerServicesActions.openNewControllerServiceDialog), + withLatestFrom( + this.store.select(selectControllerServiceTypes), + this.store.select(selectCurrentProcessGroupId) + ), + tap(([action, controllerServiceTypes, processGroupId]) => { + const dialogReference = this.dialog.open(CreateControllerService, { + data: { + controllerServiceTypes + }, + panelClass: 'medium-dialog' + }); + + dialogReference.componentInstance.saving$ = this.store.select(selectSaving); + + dialogReference.componentInstance.createControllerService + .pipe(take(1)) + .subscribe((controllerServiceType) => { + this.store.dispatch( + ControllerServicesActions.createControllerService({ + request: { + revision: { + clientId: this.client.getClientId(), + version: 0 + }, + processGroupId, + controllerServiceType: controllerServiceType.type, + controllerServiceBundle: controllerServiceType.bundle + } + }) + ); + }); + }) + ), + { dispatch: false } + ); + + createControllerService$ = createEffect(() => + this.actions$.pipe( + ofType(ControllerServicesActions.createControllerService), + map((action) => action.request), + switchMap((request) => + from(this.controllerServiceService.createControllerService(request)).pipe( + map((response) => + ControllerServicesActions.createControllerServiceSuccess({ + response: { + controllerService: response + } + }) + ), + catchError((error) => + of( + ControllerServicesActions.controllerServicesApiError({ + error: error.error + }) + ) + ) + ) + ) + ) + ); + + createControllerServiceSuccess$ = createEffect( + () => + this.actions$.pipe( + ofType(ControllerServicesActions.createControllerServiceSuccess), + tap(() => { + this.dialog.closeAll(); + }) + ), + { dispatch: false } + ); + + navigateToEditService$ = createEffect( + () => + this.actions$.pipe( + ofType(ControllerServicesActions.navigateToEditService), + map((action) => action.id), + withLatestFrom(this.store.select(selectCurrentProcessGroupId)), + tap(([id, processGroupId]) => { + this.router.navigate(['/process-groups', processGroupId, 'controller-services', id, 'edit']); + }) + ), + { dispatch: false } + ); + + openConfigureControllerServiceDialog$ = createEffect( + () => + this.actions$.pipe( + ofType(ControllerServicesActions.openConfigureControllerServiceDialog), + map((action) => action.request), + withLatestFrom(this.store.select(selectCurrentProcessGroupId)), + tap(([request, processGroupId]) => { + const serviceId: string = request.id; + + const editDialogReference = this.dialog.open(EditControllerService, { + data: { + controllerService: request.controllerService + }, + panelClass: 'large-dialog' + }); + + editDialogReference.componentInstance.saving$ = this.store.select(selectSaving); + + editDialogReference.componentInstance.createNewProperty = ( + existingProperties: string[], + allowsSensitive: boolean + ): Observable => { + const dialogRequest: NewPropertyDialogRequest = { existingProperties, allowsSensitive }; + const newPropertyDialogReference = this.dialog.open(NewPropertyDialog, { + data: dialogRequest, + panelClass: 'small-dialog' + }); + + return newPropertyDialogReference.componentInstance.newProperty.pipe( + take(1), + switchMap((dialogResponse: NewPropertyDialogResponse) => { + return this.controllerServiceService + .getPropertyDescriptor(request.id, dialogResponse.name, dialogResponse.sensitive) + .pipe( + take(1), + map((response) => { + newPropertyDialogReference.close(); + + return { + property: dialogResponse.name, + value: null, + descriptor: response.propertyDescriptor + }; + }) + ); + }) + ); + }; + + editDialogReference.componentInstance.getServiceLink = (serviceId: string) => { + return this.controllerServiceService.getControllerService(serviceId).pipe( + take(1), + map((serviceEntity) => { + return [ + '/process-groups', + serviceEntity.component.parentGroupId, + 'controller-services', + serviceEntity.id + ]; + }) + ); + }; + + editDialogReference.componentInstance.createNewService = ( + serviceRequest: InlineServiceCreationRequest + ): Observable => { + const descriptor: PropertyDescriptor = serviceRequest.descriptor; + + // fetch all services that implement the requested service api + return this.extensionTypesService + .getImplementingControllerServiceTypes( + // @ts-ignore + descriptor.identifiesControllerService, + descriptor.identifiesControllerServiceBundle + ) + .pipe( + take(1), + switchMap((implementingTypesResponse) => { + // show the create controller service dialog with the types that implemented the interface + const createServiceDialogReference = this.dialog.open(CreateControllerService, { + data: { + controllerServiceTypes: implementingTypesResponse.controllerServiceTypes + }, + panelClass: 'medium-dialog' + }); + + return createServiceDialogReference.componentInstance.createControllerService.pipe( + take(1), + switchMap((controllerServiceType) => { + // typically this sequence would be implemented with ngrx actions, however we are + // currently in an edit session and we need to return both the value (new service id) + // and updated property descriptor so the table renders correctly + return this.controllerServiceService + .createControllerService({ + revision: { + clientId: this.client.getClientId(), + version: 0 + }, + processGroupId, + controllerServiceType: controllerServiceType.type, + controllerServiceBundle: controllerServiceType.bundle + }) + .pipe( + take(1), + switchMap((createReponse) => { + // dispatch an inline create service success action so the new service is in the state + this.store.dispatch( + ControllerServicesActions.inlineCreateControllerServiceSuccess( + { + response: { + controllerService: createReponse + } + } + ) + ); + + // fetch an updated property descriptor + return this.controllerServiceService + .getPropertyDescriptor(serviceId, descriptor.name, false) + .pipe( + take(1), + map((descriptorResponse) => { + createServiceDialogReference.close(); + + return { + value: createReponse.id, + descriptor: + descriptorResponse.propertyDescriptor + }; + }) + ); + }), + catchError((error) => { + // TODO - show error + return NEVER; + }) + ); + }) + ); + }) + ); + }; + + editDialogReference.componentInstance.editControllerService + .pipe(take(1)) + .subscribe((payload: any) => { + this.store.dispatch( + ControllerServicesActions.configureControllerService({ + request: { + id: request.controllerService.id, + uri: request.controllerService.uri, + payload + } + }) + ); + }); + + editDialogReference.afterClosed().subscribe((response) => { + if (response != 'ROUTED') { + this.store.dispatch( + ControllerServicesActions.selectControllerService({ + request: { + processGroupId, + id: serviceId + } + }) + ); + } + }); + }) + ), + { dispatch: false } + ); + + configureControllerService$ = createEffect(() => + this.actions$.pipe( + ofType(ControllerServicesActions.configureControllerService), + map((action) => action.request), + switchMap((request) => + from(this.controllerServiceService.updateControllerService(request)).pipe( + map((response) => + ControllerServicesActions.configureControllerServiceSuccess({ + response: { + id: request.id, + controllerService: response + } + }) + ), + catchError((error) => + of( + ControllerServicesActions.controllerServicesApiError({ + error: error.error + }) + ) + ) + ) + ) + ) + ); + + configureControllerServiceSuccess$ = createEffect( + () => + this.actions$.pipe( + ofType(ControllerServicesActions.configureControllerServiceSuccess), + tap(() => { + this.dialog.closeAll(); + }) + ), + { dispatch: false } + ); + + promptControllerServiceDeletion$ = createEffect( + () => + this.actions$.pipe( + ofType(ControllerServicesActions.promptControllerServiceDeletion), + map((action) => action.request), + tap((request) => { + const dialogReference = this.dialog.open(YesNoDialog, { + data: { + title: 'Delete Controller Service', + message: `Delete controller service ${request.controllerService.component.name}?` + }, + panelClass: 'small-dialog' + }); + + dialogReference.componentInstance.yes.pipe(take(1)).subscribe(() => { + this.store.dispatch( + ControllerServicesActions.deleteControllerService({ + request + }) + ); + }); + }) + ), + { dispatch: false } + ); + + deleteControllerService$ = createEffect(() => + this.actions$.pipe( + ofType(ControllerServicesActions.deleteControllerService), + map((action) => action.request), + switchMap((request) => + from(this.controllerServiceService.deleteControllerService(request)).pipe( + map((response) => + ControllerServicesActions.deleteControllerServiceSuccess({ + response: { + controllerService: response + } + }) + ), + catchError((error) => + of( + ControllerServicesActions.controllerServicesApiError({ + error: error.error + }) + ) + ) + ) + ) + ) + ); + + selectControllerService$ = createEffect( + () => + this.actions$.pipe( + ofType(ControllerServicesActions.selectControllerService), + map((action) => action.request), + tap((request) => { + this.router.navigate([ + '/process-groups', + request.processGroupId, + 'controller-services', + request.id + ]); + }) + ), + { dispatch: false } + ); +} 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/controller-services/controller-services.reducer.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.reducer.ts new file mode 100644 index 0000000000..30aaf2628e --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.reducer.ts @@ -0,0 +1,113 @@ +/* + * 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 { createReducer, on } from '@ngrx/store'; +import { + configureControllerService, + configureControllerServiceSuccess, + controllerServicesApiError, + createControllerService, + createControllerServiceSuccess, + deleteControllerServiceSuccess, + inlineCreateControllerServiceSuccess, + loadControllerServices, + loadControllerServicesSuccess +} from './controller-services.actions'; +import { produce } from 'immer'; +import { ControllerServicesState } from './index'; + +export const initialState: ControllerServicesState = { + processGroupId: 'root', + controllerServices: [], + breadcrumb: { + id: '', + permissions: { + canRead: false, + canWrite: false + }, + versionedFlowState: '', + breadcrumb: { + id: '', + name: '' + } + }, + saving: false, + loadedTimestamp: '', + error: null, + status: 'pending' +}; + +export const controllerServicesReducer = createReducer( + initialState, + on(loadControllerServices, (state) => ({ + ...state, + status: 'loading' as const + })), + on(loadControllerServicesSuccess, (state, { response }) => ({ + ...state, + processGroupId: response.processGroupId, + controllerServices: response.controllerServices, + breadcrumb: response.breadcrumb, + loadedTimestamp: response.loadedTimestamp, + error: null, + status: 'success' as const + })), + on(controllerServicesApiError, (state, { error }) => ({ + ...state, + saving: false, + error, + status: 'error' as const + })), + on(createControllerService, (state, { request }) => ({ + ...state, + saving: true + })), + on(createControllerServiceSuccess, (state, { response }) => { + return produce(state, (draftState) => { + draftState.controllerServices.push(response.controllerService); + draftState.saving = false; + }); + }), + on(inlineCreateControllerServiceSuccess, (state, { response }) => { + return produce(state, (draftState) => { + draftState.controllerServices.push(response.controllerService); + }); + }), + on(configureControllerService, (state, { request }) => ({ + ...state, + saving: true + })), + on(configureControllerServiceSuccess, (state, { response }) => { + return produce(state, (draftState) => { + const componentIndex: number = draftState.controllerServices.findIndex((f: any) => response.id === f.id); + if (componentIndex > -1) { + draftState.controllerServices[componentIndex] = response.controllerService; + } + draftState.saving = false; + }); + }), + on(deleteControllerServiceSuccess, (state, { response }) => { + return produce(state, (draftState) => { + const componentIndex: number = draftState.controllerServices.findIndex( + (f: any) => response.controllerService.id === f.id + ); + if (componentIndex > -1) { + draftState.controllerServices.splice(componentIndex, 1); + } + }); + }) +); 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/controller-services/controller-services.selectors.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.selectors.ts new file mode 100644 index 0000000000..c9da553c3c --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.selectors.ts @@ -0,0 +1,70 @@ +/* + * 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 { selectCurrentRoute } from '../../../../state/router/router.selectors'; +import { ControllerServiceEntity } from '../../../../state/shared'; +import { CanvasState, selectCanvasState } from '../index'; +import { controllerServicesFeatureKey, ControllerServicesState } from './index'; + +export const selectControllerServicesState = createSelector( + selectCanvasState, + (state: CanvasState) => state[controllerServicesFeatureKey] +); + +export const selectSaving = createSelector( + selectControllerServicesState, + (state: ControllerServicesState) => state.saving +); + +export const selectCurrentProcessGroupId = createSelector( + selectControllerServicesState, + (state: ControllerServicesState) => state.processGroupId +); + +export const selectProcessGroupIdFromRoute = createSelector(selectCurrentRoute, (route) => { + if (route) { + // always select the process group from the route + return route.params.processGroupId; + } + return null; +}); + +export const selectControllerServiceIdFromRoute = createSelector(selectCurrentRoute, (route) => { + if (route) { + // always select the controller service from the route + return route.params.id; + } + return null; +}); + +export const selectSingleEditedService = createSelector(selectCurrentRoute, (route) => { + if (route?.routeConfig?.path == 'edit') { + return route.params.id; + } + return null; +}); + +export const selectServices = createSelector( + selectControllerServicesState, + (state: ControllerServicesState) => state.controllerServices +); + +export const selectService = (id: string) => + createSelector(selectServices, (services: ControllerServiceEntity[]) => + services.find((service) => id == service.id) + ); 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/controller-services/index.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/index.ts new file mode 100644 index 0000000000..0fc6f55c5c --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/index.ts @@ -0,0 +1,77 @@ +/* + * 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 { Bundle, ControllerServiceEntity, Revision } from '../../../../state/shared'; +import { BreadcrumbEntity } from '../shared'; + +export const controllerServicesFeatureKey = 'controllerServiceListing'; + +export interface LoadControllerServicesRequest { + processGroupId: string; +} + +export interface LoadControllerServicesResponse { + processGroupId: string; + breadcrumb: BreadcrumbEntity; + controllerServices: ControllerServiceEntity[]; + loadedTimestamp: string; +} + +export interface CreateControllerServiceRequest { + processGroupId: string; + controllerServiceType: string; + controllerServiceBundle: Bundle; + revision: Revision; +} + +export interface CreateControllerServiceSuccess { + controllerService: ControllerServiceEntity; +} + +export interface ConfigureControllerServiceRequest { + id: string; + uri: string; + payload: any; +} + +export interface ConfigureControllerServiceSuccess { + id: string; + controllerService: ControllerServiceEntity; +} + +export interface DeleteControllerServiceRequest { + controllerService: ControllerServiceEntity; +} + +export interface DeleteControllerServiceSuccess { + controllerService: ControllerServiceEntity; +} + +export interface SelectControllerServiceRequest { + processGroupId: string; + id: string; +} + +export interface ControllerServicesState { + processGroupId: string; + breadcrumb: BreadcrumbEntity; + controllerServices: ControllerServiceEntity[]; + saving: boolean; + loadedTimestamp: string; + error: string | null; + status: 'pending' | 'loading' | 'error' | 'success'; +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/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 similarity index 95% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/flow/flow.actions.ts rename to 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 c6320ae0cd..49fbb1e428 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/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 @@ -51,7 +51,9 @@ import { UpdateConnectionRequest, UpdateConnectionSuccess, UpdatePositionsRequest, - UploadProcessGroupRequest + UploadProcessGroupRequest, + EditCurrentProcessGroupRequest, + NavigateToControllerServicesRequest } from './index'; /* @@ -243,6 +245,20 @@ export const navigateToEditComponent = createAction( export const editComponent = createAction('[Canvas] Edit Component', props<{ request: EditComponentDialogRequest }>()); +export const navigateToEditCurrentProcessGroup = createAction('[Canvas] Navigate To Edit Current Process Group'); + +export const navigateToControllerServicesForProcessGroup = createAction( + '[Canvas] Navigate To Controller Services For Process Group', + props<{ request: NavigateToControllerServicesRequest }>() +); + +export const editCurrentProcessGroup = createAction( + '[Canvas] Edit Current Process Group', + props<{ + request: EditCurrentProcessGroupRequest; + }>() +); + export const openEditPortDialog = createAction( '[Canvas] Open Edit Port Dialog', props<{ request: EditComponentDialogRequest }>() diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/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 similarity index 86% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/flow/flow.effects.ts rename to 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 711ee0a3c0..623bf47a54 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/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 @@ -28,6 +28,7 @@ import { interval, map, mergeMap, + NEVER, Observable, of, switchMap, @@ -60,15 +61,18 @@ import { } from './flow.selectors'; import { ConnectionManager } from '../../service/manager/connection-manager.service'; import { MatDialog } from '@angular/material/dialog'; -import { CreatePort } from '../../ui/port/create-port/create-port.component'; -import { EditPort } from '../../ui/port/edit-port/edit-port.component'; +import { CreatePort } from '../../ui/canvas/items/port/create-port/create-port.component'; +import { EditPort } from '../../ui/canvas/items/port/edit-port/edit-port.component'; import { ComponentType, + InlineServiceCreationRequest, + InlineServiceCreationResponse, NewPropertyDialogRequest, NewPropertyDialogResponse, Parameter, ParameterEntity, - Property + Property, + PropertyDescriptor } from '../../../../state/shared'; import { Router } from '@angular/router'; import { Client } from '../../../../service/client.service'; @@ -76,16 +80,20 @@ import { CanvasUtils } from '../../service/canvas-utils.service'; import { CanvasView } from '../../service/canvas-view.service'; import { selectProcessorTypes } from '../../../../state/extension-types/extension-types.selectors'; import { NiFiState } from '../../../../state'; -import { CreateProcessor } from '../../ui/processor/create-processor/create-processor.component'; -import { EditProcessor } from '../../ui/processor/edit-processor/edit-processor.component'; +import { CreateProcessor } from '../../ui/canvas/items/processor/create-processor/create-processor.component'; +import { EditProcessor } from '../../ui/canvas/items/processor/edit-processor/edit-processor.component'; import { NewPropertyDialog } from '../../../../ui/common/new-property-dialog/new-property-dialog.component'; import { BirdseyeView } from '../../service/birdseye-view.service'; -import { CreateProcessGroup } from '../../ui/process-group/create-process-group/create-process-group.component'; -import { CreateConnection } from '../../ui/connection/create-connection/create-connection.component'; -import { EditConnectionComponent } from '../../ui/connection/edit-connection/edit-connection.component'; +import { CreateProcessGroup } from '../../ui/canvas/items/process-group/create-process-group/create-process-group.component'; +import { CreateConnection } from '../../ui/canvas/items/connection/create-connection/create-connection.component'; +import { EditConnectionComponent } from '../../ui/canvas/items/connection/edit-connection/edit-connection.component'; import { OkDialog } from '../../../../ui/common/ok-dialog/ok-dialog.component'; -import { GroupComponents } from '../../ui/process-group/group-components/group-components.component'; -import { EditProcessGroup } from '../../ui/process-group/edit-process-group/edit-process-group.component'; +import { GroupComponents } from '../../ui/canvas/items/process-group/group-components/group-components.component'; +import { EditProcessGroup } from '../../ui/canvas/items/process-group/edit-process-group/edit-process-group.component'; +import { CreateControllerService } from '../../../../ui/common/controller-service/create-controller-service/create-controller-service.component'; +import * as ControllerServicesActions from '../controller-services/controller-services.actions'; +import { ExtensionTypesService } from '../../../../service/extension-types.service'; +import { ControllerServiceService } from '../../service/controller-service.service'; @Injectable() export class FlowEffects { @@ -93,6 +101,8 @@ export class FlowEffects { private actions$: Actions, private store: Store, private flowService: FlowService, + private extensionTypesService: ExtensionTypesService, + private controllerServiceService: ControllerServiceService, private client: Client, private canvasUtils: CanvasUtils, private canvasView: CanvasView, @@ -642,7 +652,31 @@ export class FlowEffects { { dispatch: false } ); - editComponentRequest$ = createEffect(() => + navigateToEditCurrentProcessGroup$ = createEffect( + () => + this.actions$.pipe( + ofType(FlowActions.navigateToEditCurrentProcessGroup), + withLatestFrom(this.store.select(selectCurrentProcessGroupId)), + tap(([action, processGroupId]) => { + this.router.navigate(['/process-groups', processGroupId, 'edit']); + }) + ), + { dispatch: false } + ); + + navigateToControllerServicesForProcessGroup$ = createEffect( + () => + this.actions$.pipe( + ofType(FlowActions.navigateToControllerServicesForProcessGroup), + map((action) => action.request), + tap((request) => { + this.router.navigate(['/process-groups', request.id, 'controller-services']); + }) + ), + { dispatch: false } + ); + + editComponent$ = createEffect(() => this.actions$.pipe( ofType(FlowActions.editComponent), map((action) => action.request), @@ -664,6 +698,33 @@ export class FlowEffects { ) ); + editCurrentProcessGroup$ = createEffect(() => + this.actions$.pipe( + ofType(FlowActions.editCurrentProcessGroup), + map((action) => action.request), + switchMap((request) => + from(this.flowService.getProcessGroup(request.id)).pipe( + map((response) => + FlowActions.openEditProcessGroupDialog({ + request: { + type: ComponentType.ProcessGroup, + uri: response.uri, + entity: response + } + }) + ), + catchError((error) => + of( + FlowActions.flowApiError({ + error: error.error + }) + ) + ) + ) + ) + ) + ); + openEditPortDialog$ = createEffect( () => this.actions$.pipe( @@ -701,8 +762,13 @@ export class FlowEffects { this.actions$.pipe( ofType(FlowActions.openEditProcessorDialog), map((action) => action.request), - withLatestFrom(this.store.select(selectCurrentParameterContext)), - tap(([request, parameterContext]) => { + withLatestFrom( + this.store.select(selectCurrentParameterContext), + this.store.select(selectCurrentProcessGroupId) + ), + tap(([request, parameterContext, processGroupId]) => { + const processorId: string = request.entity.id; + const editDialogReference = this.dialog.open(EditProcessor, { data: request, panelClass: 'large-dialog' @@ -724,11 +790,7 @@ export class FlowEffects { take(1), switchMap((dialogResponse: NewPropertyDialogResponse) => { return this.flowService - .getPropertyDescriptor( - request.entity.id, - dialogResponse.name, - dialogResponse.sensitive - ) + .getPropertyDescriptor(processorId, dialogResponse.name, dialogResponse.sensitive) .pipe( take(1), map((response) => { @@ -763,7 +825,6 @@ export class FlowEffects { return this.flowService.getControllerService(serviceId).pipe( take(1), map((serviceEntity) => { - // TODO - finalize once route is defined return [ '/process-groups', serviceEntity.component.parentGroupId, @@ -774,7 +835,85 @@ export class FlowEffects { ); }; - // TODO - inline service creation... + editDialogReference.componentInstance.createNewService = ( + serviceRequest: InlineServiceCreationRequest + ): Observable => { + const descriptor: PropertyDescriptor = serviceRequest.descriptor; + + // fetch all services that implement the requested service api + return this.extensionTypesService + .getImplementingControllerServiceTypes( + // @ts-ignore + descriptor.identifiesControllerService, + descriptor.identifiesControllerServiceBundle + ) + .pipe( + take(1), + switchMap((implementingTypesResponse) => { + // show the create controller service dialog with the types that implemented the interface + const createServiceDialogReference = this.dialog.open(CreateControllerService, { + data: { + controllerServiceTypes: implementingTypesResponse.controllerServiceTypes + }, + panelClass: 'medium-dialog' + }); + + return createServiceDialogReference.componentInstance.createControllerService.pipe( + take(1), + switchMap((controllerServiceType) => { + // typically this sequence would be implemented with ngrx actions, however we are + // currently in an edit session and we need to return both the value (new service id) + // and updated property descriptor so the table renders correctly + return this.controllerServiceService + .createControllerService({ + revision: { + clientId: this.client.getClientId(), + version: 0 + }, + processGroupId, + controllerServiceType: controllerServiceType.type, + controllerServiceBundle: controllerServiceType.bundle + }) + .pipe( + take(1), + switchMap((createReponse) => { + // dispatch an inline create service success action so the new service is in the state + this.store.dispatch( + ControllerServicesActions.inlineCreateControllerServiceSuccess( + { + response: { + controllerService: createReponse + } + } + ) + ); + + // fetch an updated property descriptor + return this.flowService + .getPropertyDescriptor(processorId, descriptor.name, false) + .pipe( + take(1), + map((descriptorResponse) => { + createServiceDialogReference.close(); + + return { + value: createReponse.id, + descriptor: + descriptorResponse.propertyDescriptor + }; + }) + ); + }), + catchError((error) => { + // TODO - show error + return NEVER; + }) + ); + }) + ); + }) + ); + }; editDialogReference.componentInstance.editProcessor .pipe(takeUntil(editDialogReference.afterClosed())) @@ -782,7 +921,7 @@ export class FlowEffects { this.store.dispatch( FlowActions.updateProcessor({ request: { - id: request.entity.id, + id: processorId, uri: request.uri, type: request.type, payload @@ -791,20 +930,23 @@ export class FlowEffects { ); }); - editDialogReference.afterClosed().subscribe(() => { + editDialogReference.afterClosed().subscribe((response) => { this.store.dispatch(FlowActions.clearFlowApiError()); - this.store.dispatch( - FlowActions.selectComponents({ - request: { - components: [ - { - id: request.entity.id, - componentType: request.type - } - ] - } - }) - ); + + if (response != 'ROUTED') { + this.store.dispatch( + FlowActions.selectComponents({ + request: { + components: [ + { + id: processorId, + componentType: request.type + } + ] + } + }) + ); + } }); }) ), diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/flow/flow.reducer.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.reducer.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/flow/flow.reducer.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.reducer.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/flow/flow.selectors.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.selectors.ts similarity index 96% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/flow/flow.selectors.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.selectors.ts index 7ee08f6285..2f5749fd74 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/flow/flow.selectors.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.selectors.ts @@ -111,6 +111,16 @@ export const selectSingleEditedComponent = createSelector(selectCurrentRoute, (r return selectedComponent; }); +export const selectEditedCurrentProcessGroup = createSelector(selectCurrentRoute, (route) => { + if (route?.routeConfig?.path == 'edit') { + if (route.params.ids == null && route.params.type == null) { + return route.params.processGroupId; + } + } + + return null; +}); + export const selectTransitionRequired = createSelector(selectFlowState, (state: FlowState) => state.transitionRequired); export const selectDragging = createSelector(selectFlowState, (state: FlowState) => state.dragging); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/flow/index.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/index.ts similarity index 97% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/flow/index.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/index.ts index bd64e6f501..08c25e4dad 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/flow/index.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/index.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { Position } from '../shared'; +import { BreadcrumbEntity, Position } from '../shared'; import { BulletinEntity, Bundle, @@ -220,6 +220,14 @@ export interface EditComponentDialogRequest { entity: any; } +export interface NavigateToControllerServicesRequest { + id: string; +} + +export interface EditCurrentProcessGroupRequest { + id: string; +} + export interface EditConnectionDialogRequest extends EditComponentDialogRequest { newDestination?: { type: ComponentType | null; @@ -362,20 +370,6 @@ export interface ComponentEntity { component: any; } -export interface Breadcrumb { - id: string; - name: string; - versionControlInformation?: VersionControlInformation; -} - -export interface BreadcrumbEntity { - id: string; - permissions: Permissions; - versionedFlowState: string; - breadcrumb: Breadcrumb; - parentBreadcrumb?: BreadcrumbEntity; -} - export interface Relationship { autoTerminate: boolean; description: string; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/index.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/index.ts similarity index 81% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/index.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/index.ts index 0d471355a8..037c25a007 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/index.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/index.ts @@ -24,18 +24,22 @@ import { flowFeatureKey, FlowState } from './flow'; import { Action, combineReducers, createFeatureSelector } from '@ngrx/store'; import { transformReducer } from './transform/transform.reducer'; import { flowReducer } from './flow/flow.reducer'; +import { controllerServicesFeatureKey, ControllerServicesState } from './controller-services'; +import { controllerServicesReducer } from './controller-services/controller-services.reducer'; export const canvasFeatureKey = 'canvas'; export interface CanvasState { [flowFeatureKey]: FlowState; [transformFeatureKey]: CanvasTransform; + [controllerServicesFeatureKey]: ControllerServicesState; } export function reducers(state: CanvasState | undefined, action: Action) { return combineReducers({ [flowFeatureKey]: flowReducer, - [transformFeatureKey]: transformReducer + [transformFeatureKey]: transformReducer, + [controllerServicesFeatureKey]: controllerServicesReducer })(state, action); } 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/shared/index.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/shared/index.ts new file mode 100644 index 0000000000..aa64ccef55 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/shared/index.ts @@ -0,0 +1,43 @@ +/* + * 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 { Permissions } from '../../../../state/shared'; +import { VersionControlInformation } from '../flow'; + +export interface Dimension { + width: number; + height: number; +} + +export interface Position { + x: number; + y: number; +} + +export interface Breadcrumb { + id: string; + name: string; + versionControlInformation?: VersionControlInformation; +} + +export interface BreadcrumbEntity { + id: string; + permissions: Permissions; + versionedFlowState: string; + breadcrumb: Breadcrumb; + parentBreadcrumb?: BreadcrumbEntity; +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/transform/index.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/transform/index.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/transform/index.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/transform/index.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/transform/transform.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/transform/transform.actions.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/transform/transform.actions.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/transform/transform.actions.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/transform/transform.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/transform/transform.effects.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/transform/transform.effects.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/transform/transform.effects.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/transform/transform.reducer.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/transform/transform.reducer.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/transform/transform.reducer.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/transform/transform.reducer.ts diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/transform/transform.selectors.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/transform/transform.selectors.ts similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/state/transform/transform.selectors.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/transform/transform.selectors.ts 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/canvas-routing.module.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/canvas-routing.module.ts new file mode 100644 index 0000000000..0df4294bce --- /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/canvas-routing.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 { RouterModule, Routes } from '@angular/router'; +import { Canvas } from './canvas.component'; + +const routes: Routes = [ + { + path: '', + component: Canvas, + children: [ + { path: 'bulk/:ids', component: Canvas }, + { path: 'edit', component: Canvas }, + { + path: ':type/:id', + component: Canvas, + children: [{ path: 'edit', component: Canvas }] + } + ] + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class CanvasRoutingModule {} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/canvas.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/canvas.component.html similarity index 68% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/canvas.component.html rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/canvas.component.html index e3429ebf4d..7e5a0fcdaa 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/canvas.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/canvas.component.html @@ -15,6 +15,12 @@ ~ 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/canvas/ui/canvas/canvas.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/canvas.component.scss similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/canvas.component.scss rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/canvas.component.scss diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/canvas.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/canvas.component.spec.ts similarity index 81% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/canvas.component.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/canvas.component.spec.ts index 6131a83ebd..cc13e3defe 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/canvas.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/canvas.component.spec.ts @@ -21,23 +21,35 @@ import { Canvas } from './canvas.component'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../state/flow/flow.reducer'; import { ContextMenu } from './context-menu/context-menu.component'; -import { GraphControls } from './graph-controls/graph-controls.component'; -import { OperationControl } from './operation-control/operation-control.component'; -import { NavigationControl } from './navigation-control/navigation-control.component'; import { Component } from '@angular/core'; import { CdkContextMenuTrigger } from '@angular/cdk/menu'; import { selectBreadcrumbs } from '../../state/flow/flow.selectors'; -import { BreadcrumbEntity } from '../../state/flow'; +import { BreadcrumbEntity } from '../../state/shared'; describe('Canvas', () => { let component: Canvas; let fixture: ComponentFixture; @Component({ - selector: 'birdseye', + selector: 'fd-header', + standalone: true, template: '' }) - class MockBirdseye {} + class MockHeader {} + + @Component({ + selector: 'fd-footer', + standalone: true, + template: '' + }) + class MockFooter {} + + @Component({ + selector: 'graph-controls', + standalone: true, + template: '' + }) + class MockGraphControls {} beforeEach(() => { const breadcrumbEntity: BreadcrumbEntity = { @@ -54,8 +66,8 @@ describe('Canvas', () => { }; TestBed.configureTestingModule({ - declarations: [Canvas, ContextMenu, GraphControls, OperationControl, NavigationControl, MockBirdseye], - imports: [CdkContextMenuTrigger], + declarations: [Canvas], + imports: [CdkContextMenuTrigger, ContextMenu, MockGraphControls, MockHeader, MockFooter], providers: [ provideMockStore({ initialState, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/canvas.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/canvas.component.ts similarity index 97% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/canvas.component.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/canvas.component.ts index 308196945f..9e9bc10102 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/canvas.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/canvas.component.ts @@ -23,6 +23,7 @@ import { centerSelectedComponent, deselectAllComponents, editComponent, + editCurrentProcessGroup, loadProcessGroup, selectComponents, setSkipTransform, @@ -39,6 +40,7 @@ import { selectBulkSelectedComponentIds, selectConnection, selectCurrentProcessGroupId, + selectEditedCurrentProcessGroup, selectFunnel, selectInputPort, selectLabel, @@ -216,6 +218,23 @@ export class Canvas implements OnInit, OnDestroy { }) ); }); + + // edit the current process group from the route + this.store + .select(selectEditedCurrentProcessGroup) + .pipe( + filter((processGroupId) => processGroupId != null), + takeUntilDestroyed() + ) + .subscribe((processGroupId) => { + this.store.dispatch( + editCurrentProcessGroup({ + request: { + id: processGroupId + } + }) + ); + }); } ngOnInit(): void { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/canvas.module.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/canvas.module.ts similarity index 72% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/canvas.module.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/canvas.module.ts index e2700f3842..ede89130d1 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/canvas.module.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/canvas.module.ts @@ -21,13 +21,24 @@ import { Canvas } from './canvas.component'; import { ContextMenu } from './context-menu/context-menu.component'; import { CdkContextMenuTrigger, CdkMenu, CdkMenuItem, CdkMenuTrigger } from '@angular/cdk/menu'; import { GraphControls } from './graph-controls/graph-controls.component'; -import { NavigationControl } from './navigation-control/navigation-control.component'; -import { OperationControl } from './operation-control/operation-control.component'; -import { Birdseye } from './birdseye/birdseye.component'; +import { CanvasRoutingModule } from './canvas-routing.module'; +import { HeaderComponent } from './header/header.component'; +import { FooterComponent } from './footer/footer.component'; @NgModule({ - declarations: [Canvas, ContextMenu, GraphControls, NavigationControl, Birdseye, OperationControl], + declarations: [Canvas], exports: [Canvas], - imports: [CommonModule, CdkMenu, CdkMenuItem, CdkMenuTrigger, CdkContextMenuTrigger] + imports: [ + CommonModule, + CdkMenu, + CdkMenuItem, + CdkMenuTrigger, + CdkContextMenuTrigger, + CanvasRoutingModule, + GraphControls, + ContextMenu, + HeaderComponent, + FooterComponent + ] }) export class CanvasModule {} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/context-menu/context-menu.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/context-menu/context-menu.component.html similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/context-menu/context-menu.component.html rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/context-menu/context-menu.component.html diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/context-menu/context-menu.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/context-menu/context-menu.component.scss similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/context-menu/context-menu.component.scss rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/context-menu/context-menu.component.scss diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/context-menu/context-menu.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/context-menu/context-menu.component.spec.ts similarity index 97% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/context-menu/context-menu.component.spec.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/context-menu/context-menu.component.spec.ts index abdbb78da7..31dd8e7d8c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/context-menu/context-menu.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/context-menu/context-menu.component.spec.ts @@ -27,7 +27,7 @@ describe('ContextMenu', () => { beforeEach(() => { TestBed.configureTestingModule({ - declarations: [ContextMenu], + imports: [ContextMenu], providers: [provideMockStore({ initialState })] }); fixture = TestBed.createComponent(ContextMenu); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/context-menu/context-menu.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/context-menu/context-menu.component.ts similarity index 95% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/context-menu/context-menu.component.ts rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/context-menu/context-menu.component.ts index a21ab2194c..5ac2010bd9 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/canvas/context-menu/context-menu.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/context-menu/context-menu.component.ts @@ -27,12 +27,16 @@ import { leaveProcessGroup, moveComponents, navigateToComponent, + navigateToControllerServicesForProcessGroup, navigateToEditComponent, + navigateToEditCurrentProcessGroup, reloadFlow } from '../../../state/flow/flow.actions'; import { CanvasUtils } from '../../../service/canvas-utils.service'; import { DeleteComponentRequest, MoveComponentRequest } from '../../../state/flow'; import { ComponentType } from '../../../../../state/shared'; +import { AsyncPipe, NgForOf, NgIf } from '@angular/common'; +import { CdkMenu, CdkMenuItem, CdkMenuTrigger } from '@angular/cdk/menu'; export interface ContextMenuItemDefinition { isSeparator?: boolean; @@ -50,7 +54,9 @@ export interface ContextMenuDefinition { @Component({ selector: 'fd-context-menu', + standalone: true, templateUrl: './context-menu.component.html', + imports: [NgForOf, AsyncPipe, CdkMenu, CdkMenuItem, NgIf, CdkMenuTrigger], styleUrls: ['./context-menu.component.scss'] }) export class ContextMenu implements OnInit { @@ -286,8 +292,9 @@ export class ContextMenu implements OnInit { clazz: 'fa fa-gear', text: 'Configure', action: function (store: Store, selection: any) { - // TODO - when selection is empty support configuring the current Process Group - if (!selection.empty()) { + if (selection.empty()) { + store.dispatch(navigateToEditCurrentProcessGroup()); + } else { const selectionData = selection.datum(); store.dispatch( navigateToEditComponent({ @@ -300,6 +307,33 @@ export class ContextMenu implements OnInit { } } }, + { + condition: function (canvasUtils: CanvasUtils, selection: any) { + return canvasUtils.isProcessGroup(selection) || selection.empty(); + }, + clazz: 'fa fa-list', + text: 'Controller Services', + action: function (store: Store, selection: any, canvasUtils: CanvasUtils) { + if (selection.empty()) { + store.dispatch( + navigateToControllerServicesForProcessGroup({ + request: { + id: canvasUtils.getProcessGroupId() + } + }) + ); + } else { + const selectionData = selection.datum(); + store.dispatch( + navigateToControllerServicesForProcessGroup({ + request: { + id: selectionData.id + } + }) + ); + } + } + }, { condition: function (canvasUtils: CanvasUtils, selection: any) { // TODO - hasDetails diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/footer/footer.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/footer/footer.component.html similarity index 94% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/footer/footer.component.html rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/footer/footer.component.html index 796f9ba309..7705dfc3de 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/canvas/ui/footer/footer.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/footer/footer.component.html @@ -16,7 +16,7 @@ -->