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 #3351 from cloudfoundry-incubator/blank-org-details
Browse files Browse the repository at this point in the history
Fix null exception after creating a space in an new org
  • Loading branch information
KlapTrap committed Jan 17, 2019
2 parents c203b4a + 2483356 commit fde8637
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 45 deletions.
4 changes: 2 additions & 2 deletions src/frontend/app/core/cf-api.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export interface IDeveloper {
audited_spaces_url: string;
}

export interface IOrganization {
export interface IOrganization<spaceT = APIResource<ISpace>[]> {
name: string;
billing_enabled?: boolean;
quota_definition_guid?: string;
Expand All @@ -176,7 +176,7 @@ export interface IOrganization {
space_quota_definitions_url?: string;
guid?: string;
cfGuid?: string;
spaces?: APIResource<ISpace>[];
spaces?: spaceT;
private_domains?: APIResource<IPrivateDomain>[];
quota_definition?: APIResource<IQuotaDefinition>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Observable, Subscription } from 'rxjs';
import { filter, map, take, tap } from 'rxjs/operators';

import { IOrganization } from '../../../../core/cf-api.types';
import { safeUnsubscribe } from '../../../../core/utils.service';
import { StepOnNextFunction } from '../../../../shared/components/stepper/step/step.component';
import { PaginationMonitorFactory } from '../../../../shared/monitors/pagination-monitor.factory';
import { UpdateOrganization } from '../../../../store/actions/organization.actions';
Expand Down Expand Up @@ -126,6 +127,6 @@ export class EditOrganizationStepComponent implements OnInit, OnDestroy {
}

ngOnDestroy(): void {
this.fetchOrgsSub.unsubscribe();
safeUnsubscribe(this.fetchOrgsSub, this.orgSubscription);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,9 @@ export class CloudFoundryEndpointService {
this.allApps$ = pagObs.entities$.pipe(// Ensure we sub to entities to kick off fetch process
switchMap(() => pagObs.pagination$),
filter(pagination => !!pagination && !!pagination.pageRequests && !!pagination.pageRequests[1] && !pagination.pageRequests[1].busy),
switchMap(pagination => pagination.maxedResults ? observableOf(null) : pagObs.entities$)
switchMap(pagination => pagination.maxedResults ? observableOf(null) : pagObs.entities$),
publishReplay(1),
refCount()
);

this.loadingApps$ = pagObs.entities$.pipe(// Ensure we sub to entities to kick off fetch process
Expand Down
115 changes: 74 additions & 41 deletions src/frontend/app/store/reducers/organization-space.reducer.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,89 @@
import { IOrganization, ISpace } from '../../core/cf-api.types';
import { BaseSpaceAction, CREATE_SPACE_SUCCESS, DELETE_SPACE_SUCCESS } from '../actions/space.actions';
import { APIResource } from '../types/api.types';
import {
BaseSpaceAction,
CREATE_SPACE_SUCCESS,
CreateSpace,
DELETE_SPACE_SUCCESS,
DeleteSpace,
} from '../actions/space.actions';
import { spaceSchemaKey } from '../helpers/entity-factory';
import { APIResource, NormalizedResponse } from '../types/api.types';
import { APISuccessOrFailedAction } from '../types/request.types';

// Note - This reducer will be updated when we address general entity relation deletion
import { IRequestEntityTypeState } from '../app-state';
type entityOrgType = APIResource<IOrganization<string[]>>;
// Note - This reducer will be updated when we address general deletion of entities within inline lists (not paginated lists)
export function updateOrganizationSpaceReducer() {
return function (state: APIResource, action: APISuccessOrFailedAction) {
return function (state: IRequestEntityTypeState<entityOrgType>, action: APISuccessOrFailedAction<NormalizedResponse>) {
switch (action.type) {
case DELETE_SPACE_SUCCESS:
const deleteSpaceAction: DeleteSpace = action.apiAction as DeleteSpace;
return removeSpaceFromOrg(state, deleteSpaceAction.orgGuid, deleteSpaceAction.guid);
case CREATE_SPACE_SUCCESS:
const spaceAction: BaseSpaceAction = action.apiAction as BaseSpaceAction;
return deleteOrgSpaces(state, spaceAction.orgGuid, spaceAction);
const createSpaceAction = action.apiAction as CreateSpace;
const response = action.response;
const space = response.entities[spaceSchemaKey][response.result[0]];
return addSpaceToOrg(state, createSpaceAction.orgGuid, space);
}
return state;
};
}

function deleteOrgSpaces(state: APIResource, orgGuid: string, spaceAction: BaseSpaceAction) {
if (!orgGuid) {
return state;
}
function addSpaceToOrg(
state: IRequestEntityTypeState<entityOrgType>,
orgGuid: string,
newSpace: APIResource<ISpace>
) {
const orgToModify = getOrg(state, orgGuid);
const newSpaces = [
...orgToModify.entity.spaces,
newSpace.metadata.guid
];
const mergedOrg = applySpacesToOrg(orgToModify, newSpaces);
return {
...state,
[orgGuid]: mergedOrg
};
}

const orgGuids = Object.keys(state);
if (orgGuids.indexOf(orgGuid) === -1) {
return state;
}
function removeSpaceFromOrg(
state: IRequestEntityTypeState<entityOrgType>,
orgGuid: string,
spaceGuid: string
) {
const orgToModify = getOrg(state, orgGuid);
const newSpaces = orgToModify.entity.spaces.reduce((spaceIds, spaceId) => {
if (spaceId !== spaceGuid) {
spaceIds.push(spaceId);
}
return spaceIds;
}, []);
const mergedOrg = applySpacesToOrg(orgToModify, newSpaces);
return applyModifyOrgToState(state, mergedOrg);
}

const newState = {};
orgGuids.forEach(currentGuid => {
const org: APIResource<IOrganization> = state[currentGuid];
if (currentGuid === orgGuid) {
let newSpaces: APIResource<ISpace>[] = null;
if (spaceAction.removeEntityOnDelete) {
const spaceIndex = org.entity.spaces.findIndex(space => {
return typeof (space) === 'string' ? space === spaceAction.guid : space.metadata.guid === spaceAction.guid;
});
if (spaceIndex >= 0) {
newSpaces = [...org.entity.spaces];
newSpaces.splice(spaceIndex, 1);
}
}
const newOrg = {
...org,
entity: {
...org.entity,
spaces: newSpaces
}
};
newState[currentGuid] = newOrg;
} else {
newState[currentGuid] = org;
function applySpacesToOrg(org: entityOrgType, spaces: string[]): entityOrgType {
return {
...org,
entity: {
...org.entity,
spaces
}
});
return newState;
};
}

function applyModifyOrgToState(state: IRequestEntityTypeState<entityOrgType>, org: entityOrgType) {
return {
...state,
[org.metadata.guid]: org
};
}

function getOrg(
state: IRequestEntityTypeState<entityOrgType>,
orgGuid: string,
) {
const {
[orgGuid]: newOrg
} = state;
return newOrg;
}

0 comments on commit fde8637

Please sign in to comment.