Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove recents and favorites when entities are deleted #4431

Merged
merged 13 commits into from
Jul 24, 2020
31 changes: 31 additions & 0 deletions src/frontend/packages/store/src/actions/entity.delete.actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Action } from '@ngrx/store';

import { EntityRequestAction } from '../types/request.types';
import { IFavoriteMetadata, UserFavorite } from '../types/user-favorites.types';

export class EntityDeleteCompleteAction implements Action {

public static ACTION_TYPE = '[Entity] Entity delete complete';
public type = EntityDeleteCompleteAction.ACTION_TYPE;

constructor(
public entityGuid: string,
public entityType: string,
public endpointType: string,
public endpointGuid: string,
public action: EntityRequestAction,
) {}

// Create an entity delete action if we have all of the properties we need
public static parse(action: EntityRequestAction): EntityDeleteCompleteAction {
if (action.guid && action.entityType && action.endpointType && action.endpointGuid) {
return new EntityDeleteCompleteAction(action.guid, action.entityType, action.endpointGuid, action.endpointType, action);
}
return null;
}

public asFavorite(): UserFavorite<IFavoriteMetadata> {
return new UserFavorite<IFavoriteMetadata>(this.endpointGuid, this.endpointType, this.entityType, this.entityGuid);
}

}
27 changes: 22 additions & 5 deletions src/frontend/packages/store/src/effects/api.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import { Actions, Effect, ofType } from '@ngrx/effects';
import { Store } from '@ngrx/store';
import { mergeMap, withLatestFrom } from 'rxjs/operators';

import { EntityDeleteCompleteAction } from '../actions/entity.delete.actions';
import { baseRequestPipelineFactory } from '../entity-request-pipeline/base-single-entity-request.pipeline';
import { basePaginatedRequestPipeline } from '../entity-request-pipeline/entity-pagination-request-pipeline';
import { apiRequestPipelineFactory } from '../entity-request-pipeline/entity-request-pipeline';
import { PipelineHttpClient } from '../entity-request-pipeline/pipline-http-client.service';
import { PaginatedAction } from '../types/pagination.types';
import { ICFAction } from '../types/request.types';
import { ApiActionTypes } from './../actions/request.actions';
import { ICFAction, WrapperRequestActionSuccess } from '../types/request.types';
import { ApiActionTypes, RequestTypes } from './../actions/request.actions';
import { InternalAppState } from './../app-state';

@Injectable()
Expand All @@ -18,9 +19,7 @@ export class APIEffect {
private actions$: Actions,
private store: Store<InternalAppState>,
private httpClient: PipelineHttpClient
) {

}
) { }

@Effect()
apiRequest$ = this.actions$.pipe(
Expand All @@ -44,4 +43,22 @@ export class APIEffect {
}),
);

// Whenever we spot a delete success operation, look to see if the action
// fulfils the entity delete requirements and dispatch an entity delete action if it does
@Effect()
apiDeleteRequest$ = this.actions$.pipe(
ofType<WrapperRequestActionSuccess>(RequestTypes.SUCCESS),
withLatestFrom(this.store),
mergeMap(([action, appState]) => {
if (action.requestType === 'delete') {
const deleteAction = EntityDeleteCompleteAction.parse(action.apiAction);
if (deleteAction) {
// Dispatch a delete action for the entity
this.store.dispatch(deleteAction);
}
}
return [];
})
);

}
13 changes: 12 additions & 1 deletion src/frontend/packages/store/src/effects/user-favorites-effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Actions, Effect, ofType } from '@ngrx/effects';
import { Store } from '@ngrx/store';
import { catchError, first, mergeMap, switchMap } from 'rxjs/operators';

import { EntityDeleteCompleteAction } from '../actions/entity.delete.actions';
import { ClearPaginationOfEntity } from '../actions/pagination.actions';
import {
GetUserFavoritesAction,
Expand All @@ -27,7 +28,6 @@ import { UserFavoriteManager } from '../user-favorite-manager';

const favoriteUrlPath = `/pp/${proxyAPIVersion}/favorites`;


@Injectable()
export class UserFavoritesEffect {

Expand Down Expand Up @@ -144,4 +144,15 @@ export class UserFavoritesEffect {
);
})
);

@Effect()
entityDeleteRequest$ = this.actions$.pipe(
ofType<EntityDeleteCompleteAction>(EntityDeleteCompleteAction.ACTION_TYPE),
mergeMap((action: EntityDeleteCompleteAction) => {
// Delete the favorite if there is one
this.store.dispatch(new RemoveUserFavoriteAction(action.asFavorite()));
richard-cox marked this conversation as resolved.
Show resolved Hide resolved
return [];
})
);

}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EntityDeleteCompleteAction } from '../../actions/entity.delete.actions';
import { AddRecentlyVisitedEntityAction } from '../../actions/recently-visited.actions';
import { IRecentlyVisitedEntity, IRecentlyVisitedState } from '../../types/recently-visited.types';

Expand Down Expand Up @@ -62,3 +63,11 @@ export function cleanRecentsList(state: IRecentlyVisitedState, endpointGuids: st
// Convert the array back into a map
return filtered.reduce(recentArrayToMap, {});
}

export function clearEntityFromRecentsList(state: IRecentlyVisitedState, action: EntityDeleteCompleteAction): IRecentlyVisitedState {
// Remove entity from the map if it exists
const fav = action.asFavorite();
richard-cox marked this conversation as resolved.
Show resolved Hide resolved
const newState = { ...state };
delete newState[fav.guid];
return newState;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,25 @@ import {
GetAllEndpointsSuccess,
UNREGISTER_ENDPOINTS_SUCCESS,
} from '../../actions/endpoint.actions';
import { EntityDeleteCompleteAction } from '../../actions/entity.delete.actions';
import { AddRecentlyVisitedEntityAction, SetRecentlyVisitedEntityAction } from '../../actions/recently-visited.actions';
import { entityCatalog } from '../../entity-catalog/entity-catalog';
import { endpointEntityType, STRATOS_ENDPOINT_TYPE } from '../../helpers/stratos-entity-factory';
import { IRecentlyVisitedState } from '../../types/recently-visited.types';
import { addRecentlyVisitedEntity, cleanRecentsList, getDefaultRecentState } from './recently-visited.reducer.helpers';
import {
addRecentlyVisitedEntity,
cleanRecentsList,
clearEntityFromRecentsList,
getDefaultRecentState,
} from './recently-visited.reducer.helpers';

export function recentlyVisitedReducer(
state: IRecentlyVisitedState = getDefaultRecentState(),
action: Action
): IRecentlyVisitedState {
switch (action.type) {
case EntityDeleteCompleteAction.ACTION_TYPE:
return clearEntityFromRecentsList(state, action as EntityDeleteCompleteAction);
case AddRecentlyVisitedEntityAction.ACTION_TYPE:
return addRecentlyVisitedEntity(state, action as AddRecentlyVisitedEntityAction);
case SetRecentlyVisitedEntityAction.ACTION_TYPE:
Expand Down