Skip to content

Commit 27d6b93

Browse files
Added project edits functionality. Resolves #1135. (#1144)
1 parent de6c47f commit 27d6b93

20 files changed

+385
-43
lines changed

spa/src/app/_ngrx/app.effects.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { FileManifestEffects } from "../files/_ngrx/file-manifest/file-manifest.
1313
import { IntegrationEffects } from "../files/_ngrx/integration/integration.effects";
1414
import { MatrixEffects } from "../files/_ngrx/matrix/matrix.effects";
1515
import { ProjectEffects } from "../files/_ngrx/project/project.effects";
16+
import { ProjectEditsEffects } from "../files/_ngrx/project-edits/project-edits.effects";
1617
import { ReleaseEffects } from "../files/_ngrx/release/release.effects";
1718
import { SystemEffects } from "../system/_ngrx/system.effects";
1819
import { TableEffects } from "../files/_ngrx/table/table.effects";
@@ -26,6 +27,7 @@ export const AppEffects = [
2627
IntegrationEffects,
2728
MatrixEffects,
2829
ProjectEffects,
30+
ProjectEditsEffects,
2931
ReleaseEffects,
3032
SystemEffects,
3133
TableEffects,

spa/src/app/app.component.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import { filter, map, takeUntil } from "rxjs/operators";
1717
import { Config } from "./config/config.model";
1818
import { selectConfigConfig } from "./config/_ngrx/config.selectors";
1919
import { SetViewStateAction } from "./files/_ngrx/file-facet-list/set-view-state.action";
20+
import { ClearReleaseReferrerAction } from "./files/_ngrx/release/clear-release-referrer.action";
21+
import { FetchProjectEditsRequestAction } from "./files/_ngrx/project-edits/fetch-project-edits-request.action";
2022
import { EntityName } from "./files/shared/entity-name.model";
2123
import { FileFacetName } from "./files/shared/file-facet-name.model";
2224
import { QueryStringFacet } from "./files/shared/query-string-facet.model";
@@ -28,7 +30,6 @@ import { HealthRequestAction } from "./system/_ngrx/health/health-request.action
2830
import { selectHealth, selectIndex } from "./system/_ngrx/system.selectors";
2931
import { IndexRequestAction } from "./system/_ngrx/index/index-request.action";
3032
import { SystemState } from "./system.state";
31-
import { ClearReleaseReferrerAction } from "./files/_ngrx/release/clear-release-referrer.action";
3233

3334
@Component({
3435
selector: "app-root",
@@ -125,6 +126,14 @@ export class AppComponent implements OnInit, OnDestroy {
125126
return !!params["filter"];
126127
}
127128

129+
/**
130+
* Load project edits data from local JSON files.
131+
*/
132+
private loadProjectEditsData(): void {
133+
134+
this.store.dispatch(new FetchProjectEditsRequestAction());
135+
}
136+
128137
/**
129138
* Load release data from local JSON files.
130139
*/
@@ -285,6 +294,7 @@ export class AppComponent implements OnInit, OnDestroy {
285294
this.setAppStateFromURL();
286295
this.systemCheck();
287296
this.loadReleaseData();
297+
this.loadProjectEditsData();
288298
this.initReleaseReferrerListener();
289299

290300
this.config$ = this.store.pipe(

spa/src/app/files/_ngrx/file.reducer.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import * as fileManifestReducer from "./file-manifest/file-manifest.reducer";
1212
import * as integrationReducer from "./integration/integration.reducer";
1313
import * as matrixReducer from "./matrix/matrix.reducer";
1414
import * as projectReducer from "./project/project.reducer";
15+
import * as projectEditsReducer from "./project-edits/project-edits.reducer";
1516
import * as releaseReducer from "./release/release.reducer";
1617
import * as tableReducer from "./table/table.reducer";
1718
import * as searchReducer from "./search/search.reducer";
@@ -23,6 +24,7 @@ export const reducer = {
2324
integration: integrationReducer.reducer,
2425
matrix: matrixReducer.reducer,
2526
project: projectReducer.reducer,
27+
projectEdits: projectEditsReducer.reducer,
2628
release: releaseReducer.reducer,
2729
search: searchReducer.reducer,
2830
tableState: tableReducer.reducer

spa/src/app/files/_ngrx/file.state.mock.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { EntityName } from "../shared/entity-name.model";
1919
import * as searchStateMock from "./search/search.state.mock";
2020
import { IntegrationState } from "./integration/integration.state";
2121
import { ReleaseState } from "./release/release.state";
22+
import { ProjectEditsState } from "./project-edits/project-edits.state";
2223

2324
/**
2425
* Default project state - current tab is projects, no selected search terms
@@ -30,6 +31,7 @@ export const DEFAULT_PROJECTS_STATE = {
3031
integration: IntegrationState.getDefaultState(),
3132
matrix: MatrixState.getDefaultState(),
3233
project: ProjectState.getDefaultState(),
34+
projectEdits: ProjectEditsState.getDefaultState(),
3335
release: ReleaseState.getDefaultState(),
3436
search: SearchState.getDefaultState(),
3537
tableState: getDefaultTableState(),

spa/src/app/files/_ngrx/file.state.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { FileSummaryState } from "./file-summary/file-summary.state";
1313
import { IntegrationState } from "./integration/integration.state";
1414
import { MatrixState } from "./matrix/matrix.state";
1515
import { ProjectState } from "./project/project.state";
16+
import { ProjectEditsState } from "./project-edits/project-edits.state";
1617
import { ReleaseState } from "./release/release.state";
1718
import { SearchState } from "./search/search.state";
1819
import { TableState } from "./table/table.state";
@@ -25,6 +26,7 @@ export interface FileState {
2526
integration: IntegrationState,
2627
matrix: MatrixState;
2728
project: ProjectState;
29+
projectEdits: ProjectEditsState,
2830
release: ReleaseState,
2931
search: SearchState;
3032
tableState: TableState;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* Human Cell Atlas
3+
* https://www.humancellatlas.org/
4+
*
5+
* Action that is triggered on load of app, to read local JSON project edits data into store.
6+
*/
7+
8+
// Core dependencies
9+
import { Action } from "@ngrx/store";
10+
11+
export class FetchProjectEditsRequestAction implements Action {
12+
public static ACTION_TYPE = "PROJECT.FETCH_EDITS_REQUEST";
13+
public readonly type = FetchProjectEditsRequestAction.ACTION_TYPE;
14+
constructor() {}
15+
}
16+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Human Cell Atlas
3+
* https://www.humancellatlas.org/
4+
*
5+
* Action that is triggered when project edits data has been successfully read from local JSON.
6+
*/
7+
8+
// Core dependencies
9+
import { Action } from "@ngrx/store";
10+
11+
// App dependencies
12+
import { Project } from "../../shared/project.model";
13+
14+
export class FetchProjectEditsSuccessAction implements Action {
15+
public static ACTION_TYPE = "PROJECT.FETCH_EDITS_SUCCESS";
16+
public readonly type = FetchProjectEditsSuccessAction.ACTION_TYPE;
17+
constructor(public readonly projects: Project[]) {}
18+
}
19+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* Human Cell Atlas
3+
* https://www.humancellatlas.org/
4+
*
5+
* Coordination of side effects from project edits-related functionality.
6+
*/
7+
8+
// Core dependencies
9+
import { Injectable } from "@angular/core";
10+
import { Actions, Effect, ofType } from "@ngrx/effects";
11+
import { Action, select, Store } from "@ngrx/store";
12+
import { Observable, of } from "rxjs";
13+
import { map, switchMap, take } from "rxjs/operators";
14+
15+
// App dependencies
16+
import { FetchProjectEditsRequestAction } from "./fetch-project-edits-request.action";
17+
import { FetchProjectEditsSuccessAction } from "./fetch-project-edits-success.action";
18+
import { AppState } from "../../../_ngrx/app.state";
19+
import { ProjectEditsService } from "../../shared/project-edits.service";
20+
21+
@Injectable()
22+
export class ProjectEditsEffects {
23+
24+
/**
25+
* @param {Store<AppState>} store
26+
* @param {Actions} actions$
27+
* @param {ProjectEditsService} projectEditsService
28+
*/
29+
constructor(private store: Store<AppState>,
30+
private actions$: Actions,
31+
private projectEditsService: ProjectEditsService) {
32+
}
33+
34+
/**
35+
* Trigger fetch of project edits.
36+
*/
37+
@Effect()
38+
fetchProjectEdits: Observable<Action> = this.actions$
39+
.pipe(
40+
ofType(FetchProjectEditsRequestAction.ACTION_TYPE),
41+
switchMap(() => {
42+
43+
return this.projectEditsService.fetchProjectEdits();
44+
}),
45+
map((projects) => {
46+
47+
return new FetchProjectEditsSuccessAction(projects);
48+
})
49+
);
50+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Human Cell Atlas
3+
* https://www.humancellatlas.org/
4+
*
5+
* Model of project edits-related state, persisted in local store.
6+
*/
7+
8+
// App dependencies
9+
import { Project } from "../../shared/project.model";
10+
11+
export interface ProjectEdits {
12+
projects: Project[];
13+
projectsById: Map<string, Project>;
14+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Human Cell Atlas
3+
* https://www.humancellatlas.org/
4+
*
5+
* Reducer responsible for updating project edits-related state.
6+
*/
7+
8+
// Core dependencies
9+
import { Action } from "@ngrx/store";
10+
11+
// App dependencies
12+
import { FetchProjectEditsRequestAction } from "./fetch-project-edits-request.action";
13+
import { FetchProjectEditsSuccessAction } from "./fetch-project-edits-success.action";
14+
import { ProjectEditsState } from "./project-edits.state";
15+
16+
export function reducer(state: ProjectEditsState = ProjectEditsState.getDefaultState(), action: Action): ProjectEditsState {
17+
18+
switch (action.type) {
19+
20+
case FetchProjectEditsRequestAction.ACTION_TYPE:
21+
return state.fetchProjectEditsRequest();
22+
23+
case FetchProjectEditsSuccessAction.ACTION_TYPE:
24+
return state.fetchProjectEditsSuccess(action as FetchProjectEditsSuccessAction);
25+
26+
default:
27+
return state;
28+
}
29+
}

0 commit comments

Comments
 (0)