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

Show 'other apps bound to service instance' warning on delete app service instance step #2918

Merged
merged 1 commit into from
Sep 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,
};
}