Skip to content

Commit

Permalink
Merge pull request #3129 from cloudfoundry-incubator/delete-app-safeg…
Browse files Browse the repository at this point in the history
…uards

Delete App Stepper: Disable delete of routes and services that are bound to other app/s
  • Loading branch information
nwmac authored Oct 30, 2018
2 parents 1149553 + a3053d4 commit c73f7bb
Show file tree
Hide file tree
Showing 17 changed files with 143 additions and 134 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class ApplicationDeleteComponent<T> {
cellDefinition: {
getValue: row => row.entity.service_instance.entity.name
},
cellFlex: '0 0 200px'
cellFlex: '1 0'
},
{
columnId: 'service',
Expand Down Expand Up @@ -102,12 +102,13 @@ export class ApplicationDeleteComponent<T> {
headerCell: () => 'Host',
columnId: 'host',
cellComponent: TableCellRouteComponent,
cellFlex: '0 0 200px'
cellFlex: '1 0'
},
{
columnId: 'tcproute',
headerCell: () => 'TCP Route',
cellComponent: TableCellTCPRouteComponent,
cellFlex: '1'
}
];
public appDeleteColumns: ITableColumn<APIResource<IApp>>[] = [
Expand All @@ -119,24 +120,27 @@ export class ApplicationDeleteComponent<T> {
getLink: row => `/applications/${row.metadata.guid}`,
newTab: true,
},
cellFlex: '0 0 200px'
cellFlex: '1 0'
},
{
columnId: 'status',
headerCell: () => 'Status',
cellComponent: TableCellAppStatusComponent,
cellFlex: '1'
},
{
columnId: 'instances',
headerCell: () => 'Instances',
cellComponent: TableCellAppInstancesComponent
cellComponent: TableCellAppInstancesComponent,
cellFlex: '1'
},
{
columnId: 'creation',
headerCell: () => 'Creation Date',
cellDefinition: {
getValue: (row: APIResource) => this.datePipe.transform(row.metadata.created_at, 'medium')
}
},
cellFlex: '1'
}
];

Expand All @@ -146,7 +150,6 @@ export class ApplicationDeleteComponent<T> {
public selectedApplication$: Observable<APIResource<IApp>[]>;
public selectedRoutes$ = new ReplaySubject<APIResource<IRoute>[]>(1);
public selectedServiceInstances$ = new ReplaySubject<APIResource<IServiceBinding>[]>(1);
private appWallFetchAction: GetAllApplications;
public fetchingApplicationData$: Observable<boolean>;

public serviceInstancesSchemaKey = serviceInstancesSchemaKey;
Expand All @@ -168,7 +171,7 @@ export class ApplicationDeleteComponent<T> {
private datePipe: DatePipe
) {
this.setupAppMonitor();
this.cancelUrl = `/application/${applicationService.cfGuid}/${applicationService.appGuid}`;
this.cancelUrl = `/applications/${applicationService.cfGuid}/${applicationService.appGuid}`;
const { fetch, monitors } = this.buildRelatedEntitiesActionMonitors();
const { instanceMonitor, routeMonitor } = monitors;
this.instanceMonitor = instanceMonitor;
Expand Down Expand Up @@ -221,7 +224,6 @@ export class ApplicationDeleteComponent<T> {
* Builds the related entities actions and monitors to monitor the state of the entities.
*/
public buildRelatedEntitiesActionMonitors() {
const serviceToInstanceRelationKey = createEntityRelationKey(serviceBindingSchemaKey, serviceInstancesSchemaKey);
const { appGuid, cfGuid } = this.applicationService;
const instanceAction = AppServiceBindingDataSource.createGetAllServiceBindings(appGuid, cfGuid);
const routesAction = new GetAppRoutes(appGuid, cfGuid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ export class AppDeleteServiceInstancesListConfigService extends AppServiceBindin

constructor(store: Store<AppState>,
appService: ApplicationService,
private _datePipe: DatePipe,
private currentUserPermissionService: CurrentUserPermissionsService,
_datePipe: DatePipe,
currentUserPermissionService: CurrentUserPermissionsService,
private paginationMonitorFactory: PaginationMonitorFactory
) {
super(store, appService, _datePipe, currentUserPermissionService);
Expand All @@ -56,7 +56,7 @@ export class AppDeleteServiceInstancesListConfigService extends AppServiceBindin
this.viewType = ListViewTypes.TABLE_ONLY;
this.allowSelection = true;

// Show a warning if there is more than one service binding associated with a service instance
// Disable select if there is more than one service binding associated with a service instance
this.dataSource.getRowState = (serviceBinding: APIResource<IServiceBinding>): Observable<RowState> => {
if (!serviceBinding) {
return observableOf({});
Expand All @@ -76,8 +76,8 @@ export class AppDeleteServiceInstancesListConfigService extends AppServiceBindin
});
this.obsCache[serviceBinding.entity.service_instance_guid] = pagObs.pagination$.pipe(
map(pag => ({
message: `There are other applications bound to this service instance (${pag.totalResults - 1}).`,
warning: pag.totalResults > 1,
disabledReason: 'Service is attached to other applications',
disabled: pag.totalResults > 1
}))
);
// Ensure the request is made by sub'ing to the entities observable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ export class DeleteAppServiceInstancesComponent implements OnDestroy {
private selectedSub: Subscription;

constructor(private config: ListConfig<APIResource>) {
const dataSource = this.config.getDataSource();

this.selectedSub = this.config.getDataSource().selectedRows$.subscribe(
(selected) => {
this.selected.emit(Array.from(selected.values()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,41 @@ import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store';

import { ConfirmationDialogService } from '../../../../shared/components/confirmation-dialog.service';
import { ITableColumn } from '../../../../shared/components/list/list-table/table.types';
import {
CfAppRoutesListConfigService,
} from '../../../../shared/components/list/list-types/app-route/cf-app-routes-list-config.service';
import { ListView } from '../../../../store/actions/list.actions';
import { AppState } from '../../../../store/app-state';
import { APIResource } from '../../../../store/types/api.types';
import { ApplicationService } from '../../application.service';
import { IServiceInstance } from '../../../../core/cf-api-svc.types';
import { IRoute } from '../../../../core/cf-api.types';
import { APIResource } from '../../../../store/types/api.types';
import { RowState } from '../../../../shared/components/list/data-sources-controllers/list-data-source-types';
import { Observable, of as observableOf } from 'rxjs';
import { GetAppRoutes } from '../../../../store/actions/application-service-routes.actions';
import { createEntityRelationKey } from '../../../../store/helpers/entity-relations/entity-relations.types';
import { routeSchemaKey, domainSchemaKey, applicationSchemaKey } from '../../../../store/helpers/entity-factory';


@Injectable()
export class AppDeleteRoutesListConfigService extends CfAppRoutesListConfigService {
serviceInstanceColumns: ITableColumn<APIResource<IServiceInstance>>[];
defaultView: ListView;
constructor(
store: Store<AppState>,
appService: ApplicationService,
confirmDialog: ConfirmationDialogService
) {
super(store, appService, confirmDialog);
super(store, appService, confirmDialog, new GetAppRoutes(appService.appGuid, appService.cfGuid, null, [
createEntityRelationKey(routeSchemaKey, domainSchemaKey),
createEntityRelationKey(routeSchemaKey, applicationSchemaKey),
]));
this.getGlobalActions = () => null;
this.getMultiActions = () => null;
this.getSingleActions = () => null;
this.allowSelection = true;
this.routesDataSource.getRowState = (route: APIResource<IRoute>): Observable<RowState> =>
observableOf({
disabledReason: 'Route is attached to other applications',
disabled: route && route.entity.apps ? route.entity.apps.length > 1 : false
});
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { Component, OnInit, Input, Output, EventEmitter, OnDestroy } from '@angular/core';
import { APIResource } from '../../../../store/types/api.types';
import { IRoute } from '../../../../core/cf-api.types';
import { ApplicationServiceMock } from '../../../../test-framework/application-service-helper';
import { ListConfig } from '../../../../shared/components/list/list.component.types';
import { CfAppRoutesListConfigService } from '../../../../shared/components/list/list-types/app-route/cf-app-routes-list-config.service';
import { AppDeleteRoutesListConfigService } from './app-delete-routes-list-config.service';
import { Component, EventEmitter, OnDestroy, Output } from '@angular/core';
import { Subscription } from 'rxjs';

import { IServiceBinding } from '../../../../core/cf-api-svc.types';
import { ListConfig } from '../../../../shared/components/list/list.component.types';
import { APIResource } from '../../../../store/types/api.types';
import { AppDeleteRoutesListConfigService } from './app-delete-routes-list-config.service';

@Component({
selector: 'app-delete-app-routes',
Expand All @@ -28,8 +25,6 @@ export class DeleteAppRoutesComponent implements OnDestroy {
private selectedSub: Subscription;

constructor(private config: ListConfig<APIResource>) {
const dataSource = this.config.getDataSource();

this.selectedSub = this.config.getDataSource().selectedRows$.subscribe(
(selected) => {
this.selected.emit(Array.from(selected.values()));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Subscription } from 'rxjs';
import { first } from 'rxjs/operators';

import { ConfirmationDialogService } from '../../../../../../../shared/components/confirmation-dialog.service';
import {
CfAppRoutesListConfigService,
} from '../../../../../../../shared/components/list/list-types/app-route/cf-app-routes-list-config.service';
import { ListConfig } from '../../../../../../../shared/components/list/list.component.types';
import { PaginationMonitorFactory } from '../../../../../../../shared/monitors/pagination-monitor.factory';
import { AppState } from '../../../../../../../store/app-state';
import { EntityInfo, APIResource } from '../../../../../../../store/types/api.types';
import { ApplicationService } from '../../../../../application.service';
import { FetchAllDomains } from '../../../../../../../store/actions/domains.actions';
import { AppState } from '../../../../../../../store/app-state';
import { domainSchemaKey, entityFactory } from '../../../../../../../store/helpers/entity-factory';
import { getPaginationObservables } from '../../../../../../../store/reducers/pagination-reducer/pagination-reducer.helper';
import { entityFactory, domainSchemaKey } from '../../../../../../../store/helpers/entity-factory';
import { first } from 'rxjs/operators';
import { APIResource, EntityInfo } from '../../../../../../../store/types/api.types';
import { ApplicationService } from '../../../../../application.service';

@Component({
selector: 'app-routes-tab',
Expand All @@ -22,7 +23,13 @@ import { first } from 'rxjs/operators';
providers: [
{
provide: ListConfig,
useClass: CfAppRoutesListConfigService
useFactory: (
store: Store<AppState>,
appService: ApplicationService,
confirmDialog: ConfirmationDialogService) => {
return new CfAppRoutesListConfigService(store, appService, confirmDialog);
},
deps: [Store, ApplicationService, ConfirmationDialogService]
}
]
})
Expand All @@ -32,7 +39,6 @@ export class RoutesTabComponent implements OnInit {
constructor(
private store: Store<AppState>,
private appService: ApplicationService,
private listConfig: ListConfig<EntityInfo>,
private paginationMonitorFactory: PaginationMonitorFactory
) {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';

import { ListDataSource } from '../../../../shared/components/list/data-sources-controllers/list-data-source';
import {
CfBuildpackCardComponent,
} from '../../../../shared/components/list/list-types/cf-buildpacks/cf-buildpack-card/cf-buildpack-card.component';
import {
CfBuildpacksListConfigService,
} from '../../../../shared/components/list/list-types/cf-buildpacks/cf-buildpacks-list-config.service';
import { ListConfig } from '../../../../shared/components/list/list.component.types';
import { APIResource } from '../../../../store/types/api.types';

@Component({
selector: 'app-cloud-foundry-build-packs',
Expand All @@ -21,8 +16,4 @@ import { APIResource } from '../../../../store/types/api.types';
}
]
})
export class CloudFoundryBuildPacksComponent {
constructor(private listConfig: ListConfig<APIResource>) {
const dataSource: ListDataSource<APIResource> = listConfig.getDataSource();
}
}
export class CloudFoundryBuildPacksComponent { }
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';

import { IFeatureFlag } from '../../../../core/cf-api.types';
import { ListDataSource } from '../../../../shared/components/list/data-sources-controllers/list-data-source';
import {
CfFeatureFlagsListConfigService,
} from '../../../../shared/components/list/list-types/cf-feature-flags/cf-feature-flags-list-config.service';
Expand All @@ -18,13 +16,4 @@ import { ListConfig } from '../../../../shared/components/list/list.component.ty
}
]
})
export class CloudFoundryFeatureFlagsComponent implements OnInit {

constructor(private listConfig: ListConfig<IFeatureFlag>) {
const dataSource: ListDataSource<IFeatureFlag> = listConfig.getDataSource();
}

ngOnInit() {
}

}
export class CloudFoundryFeatureFlagsComponent { }
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';

import { ListDataSource } from '../../../../../shared/components/list/data-sources-controllers/list-data-source';
import {
CfSpacesListConfigService,
} from '../../../../../shared/components/list/list-types/cf-spaces/cf-spaces-list-config.service';
import { ListConfig } from '../../../../../shared/components/list/list.component.types';
import { APIResource } from '../../../../../store/types/api.types';
import { ISpace } from '../../../../../core/cf-api.types';

@Component({
selector: 'app-cloud-foundry-organization-spaces',
Expand All @@ -19,13 +16,4 @@ import { ISpace } from '../../../../../core/cf-api.types';
}
]
})
export class CloudFoundryOrganizationSpacesComponent implements OnInit {

constructor(private listConfig: ListConfig<APIResource<ISpace>>) {
const dataSource: ListDataSource<APIResource<ISpace>> = listConfig.getDataSource();
}

ngOnInit() {
}

}
export class CloudFoundryOrganizationSpacesComponent { }
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Component, OnInit } from '@angular/core';
import { ListConfig } from '../../../../../shared/components/list/list.component.types';
import { Component } from '@angular/core';

import {
CfOrgUsersListConfigService
CfOrgUsersListConfigService,
} from '../../../../../shared/components/list/list-types/cf-org-users/cf-org-users-list-config.service';
import { ListConfig } from '../../../../../shared/components/list/list.component.types';

@Component({
selector: 'app-cloud-foundry-organization-users',
Expand All @@ -13,11 +14,4 @@ import {
useClass: CfOrgUsersListConfigService
}]
})
export class CloudFoundryOrganizationUsersComponent implements OnInit {

constructor() { }

ngOnInit() {
}

}
export class CloudFoundryOrganizationUsersComponent { }
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';

import { ListDataSource } from '../../../../shared/components/list/data-sources-controllers/list-data-source';
import { CfOrgCardComponent } from '../../../../shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component';
import { CfOrgsListConfigService } from '../../../../shared/components/list/list-types/cf-orgs/cf-orgs-list-config.service';
import { ListConfig } from '../../../../shared/components/list/list.component.types';
import { APIResource } from '../../../../store/types/api.types';

@Component({
selector: 'app-cloud-foundry-organizations',
Expand All @@ -17,12 +15,6 @@ import { APIResource } from '../../../../store/types/api.types';
}
]
})
export class CloudFoundryOrganizationsComponent implements OnInit {
export class CloudFoundryOrganizationsComponent {
cardComponent = CfOrgCardComponent;

constructor(private listConfig: ListConfig<APIResource>) {
const dataSource: ListDataSource<APIResource> = listConfig.getDataSource();
}

ngOnInit() { }
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export interface RowState {
highlighted?: boolean;
deleting?: boolean;
warning?: boolean;
disabled?: boolean;
[customState: string]: any;
}

Expand Down
Loading

0 comments on commit c73f7bb

Please sign in to comment.