Skip to content
This repository has been archived by the owner on Jan 24, 2023. It is now read-only.

Commit

Permalink
Merge pull request #2918 from cloudfoundry-incubator/warning-delete-si
Browse files Browse the repository at this point in the history
Show 'other apps bound to service instance' warning on delete app service instance step
  • Loading branch information
nwmac committed Sep 12, 2018
2 parents 463fa40 + 03a8157 commit 2abcab6
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,23 +1,50 @@
import { DatePipe } from '@angular/common';
import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable, of as observableOf } from 'rxjs';
import { first, map } from 'rxjs/operators';

import { IServiceBinding } from '../../../../core/cf-api-svc.types';
import { CurrentUserPermissionsService } from '../../../../core/current-user-permissions.service';
import { RowState } from '../../../../shared/components/list/data-sources-controllers/list-data-source-types';
import {
AppServiceBindingListConfigService,
} from '../../../../shared/components/list/list-types/app-sevice-bindings/app-service-binding-list-config.service';
import { ListViewTypes } from '../../../../shared/components/list/list.component.types';
import { PaginationMonitorFactory } from '../../../../shared/monitors/pagination-monitor.factory';
import { FetchAllServiceBindings } from '../../../../store/actions/service-bindings.actions';
import { AppState } from '../../../../store/app-state';
import { entityFactory, serviceSchemaKey } from '../../../../store/helpers/entity-factory';
import { createEntityRelationPaginationKey } from '../../../../store/helpers/entity-relations/entity-relations.types';
import { getPaginationObservables } from '../../../../store/reducers/pagination-reducer/pagination-reducer.helper';
import { APIResource } from '../../../../store/types/api.types';
import { QParam } from '../../../../store/types/pagination.types';
import { ApplicationService } from '../../application.service';
import { CurrentUserPermissionsService } from '../../../../core/current-user-permissions.service';

@Injectable()
export class AppDeleteServiceInstancesListConfigService extends AppServiceBindingListConfigService {
hideRefresh: boolean;
allowSelection: boolean;
obsCache: { [serviceGuid: string]: Observable<RowState> } = {};

static createFetchServiceBinding = (cfGuid: string, serviceInstanceGuid: string): FetchAllServiceBindings => {
const action = new FetchAllServiceBindings(
cfGuid,
createEntityRelationPaginationKey(serviceSchemaKey, serviceInstanceGuid),
);
action.initialParams['results-per-page'] = 1;
action.initialParams.q = [
new QParam('service_instance_guid', serviceInstanceGuid),
];
return action;
}

constructor(store: Store<AppState>,
appService: ApplicationService,
private _datePipe: DatePipe,
private currentUserPermissionService: CurrentUserPermissionsService) {
private currentUserPermissionService: CurrentUserPermissionsService,
private paginationMonitorFactory: PaginationMonitorFactory
) {
super(store, appService, _datePipe, currentUserPermissionService);

this.getGlobalActions = () => null;
Expand All @@ -28,5 +55,37 @@ export class AppDeleteServiceInstancesListConfigService extends AppServiceBindin
this.defaultView = 'table';
this.viewType = ListViewTypes.TABLE_ONLY;
this.allowSelection = true;

// Show a warning 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({});
}
if (!this.obsCache[serviceBinding.entity.service_instance_guid]) {
const action = AppDeleteServiceInstancesListConfigService.createFetchServiceBinding(
appService.cfGuid,
serviceBinding.entity.service_instance_guid
);
const pagObs = getPaginationObservables({
store,
action,
paginationMonitor: this.paginationMonitorFactory.create(
action.paginationKey,
entityFactory(action.entityKey)
)
});
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,
}))
);
// Ensure the request is made by sub'ing to the entities observable
pagObs.entities$.pipe(
first(),
).subscribe();
}
return this.obsCache[serviceBinding.entity.service_instance_guid];
};
}
}
2 changes: 0 additions & 2 deletions src/frontend/app/features/service-catalog/services.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,6 @@ export class ServicesService {
);
}



getServiceName = () => {
return observableCombineLatest(this.serviceExtraInfo$, this.service$)
.pipe(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export interface RowState {
blocked?: boolean;
highlighted?: boolean;
deleting?: boolean;
warning?: boolean;
[customState: string]: any;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Component, Input, OnInit } from '@angular/core';
import { Component, OnInit } from '@angular/core';

import { ApplicationService } from '../../../../../features/applications/application.service';
import { TableCellCustom } from '../../list.types';

@Component({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
mat-checkbox {
padding: 10px;
}

Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
mat-checkbox {
padding: 10px;
}

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
display: block;
}
}
&__errored {
&__errored,
&__warning {
.table-row__error {
display: flex;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,30 @@
$foreground: map-get($theme, foreground);
.table-row {
border-bottom-color: mat-color($foreground, divider);
&__error {
background-color: $error-color;
color: $text-color;
}
&__error-message {
a {
color: $text-color;
}
}
}
.table-row-wrapper {
&__errored {
.table-row {
background-color: transparentize($error-color, .9);
}
.table-row__error {
background-color: $error-color;
color: $text-color;
}
.table-row__error-message {
a {
color: $text-color;
}
}
}
&__warning {
.table-row {
background-color: transparentize($warn-color, .9);
}
.table-row__error {
background-color: $warn-color;
color: $text-color;
}
}
&__highlighted {
background-color: transparentize($primary-color, .95);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const tableColumnSelect = {
headerCellComponent: TableHeaderSelectComponent,
cellComponent: TableCellSelectComponent,
class: 'table-column-select',
cellFlex: '0 0 75px'
cellFlex: '0 0 60px'
};

const tableColumnAction = {
Expand Down
28 changes: 25 additions & 3 deletions src/frontend/app/store/actions/service-bindings.actions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { RequestOptions, URLSearchParams } from '@angular/http';

import { entityFactory, serviceBindingSchemaKey } from '../helpers/entity-factory';
import { PaginatedAction, PaginationParam } from '../types/pagination.types';
import { CFStartAction, ICFAction } from '../types/request.types';
import { RequestOptions, URLSearchParams } from '@angular/http';
import { getActions } from './action.helper';
import { entityFactory, serviceBindingSchemaKey } from '../helpers/entity-factory';


export const DELETE_SERVICE_BINDING_ACTION = '[ Service Instances ] Delete Service Binding';
export const DELETE_SERVICE_BINDING_ACTION_SUCCESS = '[ Service Instances ] Delete Service Binding success';
Expand All @@ -11,6 +13,7 @@ export const DELETE_SERVICE_BINDING_ACTION_FAILURE = '[ Service Instances ] Dele
export const CREATE_SERVICE_BINDING_ACTION = '[ Service Instances ] Create Service Binding';
export const CREATE_SERVICE_BINDING_ACTION_SUCCESS = '[ Service Instances ] Create Service Binding success';
export const CREATE_SERVICE_BINDING_ACTION_FAILURE = '[ Service Instances ] Create Service Binding failure';

export class CreateServiceBinding extends CFStartAction implements ICFAction {
constructor(
public endpointGuid: string,
Expand All @@ -33,7 +36,8 @@ export class CreateServiceBinding extends CFStartAction implements ICFAction {
CREATE_SERVICE_BINDING_ACTION,
CREATE_SERVICE_BINDING_ACTION_SUCCESS,
CREATE_SERVICE_BINDING_ACTION_FAILURE
]; entity = [entityFactory(serviceBindingSchemaKey)];
];
entity = [entityFactory(serviceBindingSchemaKey)];
entityKey = serviceBindingSchemaKey;
options: RequestOptions;
}
Expand All @@ -59,3 +63,21 @@ export class DeleteServiceBinding extends CFStartAction implements ICFAction {
options: RequestOptions;
removeEntityOnDelete = true;
}

export class FetchAllServiceBindings extends CFStartAction implements PaginatedAction {
constructor(public endpointGuid: string, public paginationKey: string, public includeRelations = [], public populateMissing = false) {
super();
this.options = new RequestOptions();
this.options.url = 'service_bindings';
this.options.method = 'get';
}
actions = getActions('Service Bindings', 'Get All');
entity = [entityFactory(serviceBindingSchemaKey)];
entityKey = serviceBindingSchemaKey;
options: RequestOptions;
initialParams: PaginationParam = {
'order-direction': 'asc',
page: 1,
'results-per-page': 100,
};
}

0 comments on commit 2abcab6

Please sign in to comment.