Skip to content

Commit 2204b90

Browse files
MillenniumFalconMechanicNoopDog
authored andcommitted
Updated logo link in prepared matrix modal. Resolves #987. (#1022)
1 parent f7a48a8 commit 2204b90

24 files changed

+354
-108
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ import { FileState } from "../files/_ngrx/file.state";
1212
import { HttpState } from "../http/_ngrx/http.state";
1313
import { SystemState } from "../system/_ngrx/system.state";
1414
import { TerraState } from "../files/_ngrx/terra/terra.state";
15+
import { ModalState } from "../modal/_ngrx/modal.state";
1516

16-
export interface AppState extends AuthState, ConfigState, FileState, HttpState, SystemState, TerraState {}
17+
export interface AppState extends AuthState, ConfigState, FileState, HttpState, ModalState, SystemState, TerraState {}

spa/src/app/files/files.module.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import { NgModule } from "@angular/core";
1010
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
1111
import { HttpClientModule } from "@angular/common/http";
12-
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
1312
import { RouterModule } from "@angular/router";
1413

1514
import { MatAutocompleteModule } from "@angular/material/autocomplete";
@@ -73,6 +72,7 @@ import { HCATableProjectsComponent } from "./hca-table-projects/hca-table-projec
7372
import { HCATableSamplesComponent } from "./hca-table-samples/hca-table-samples.component";
7473
import { HCATableSortComponent } from "./hca-table-sort/hca-table-sort.component";
7574
import { HCATooltipComponent } from "./hca-tooltip/hca-tooltip.component";
75+
import { ModalModule } from "../modal/modal.module";
7676
import { ProjectService } from "./project/project.service";
7777
import { ProjectDeprecatedComponent } from "./project-deprecated/project-deprecated.component";
7878
import { ProjectDownloadMatrixModalContainerComponent } from "./project-download-matrix-modal-container/project-download-matrix-modal-container.component";
@@ -99,8 +99,8 @@ import { TableScroll } from "./table-scroll/table-scroll.component";
9999

100100
@NgModule({
101101
imports: [
102-
BrowserAnimationsModule,
103102
FormsModule,
103+
HttpClientModule,
104104
MatAutocompleteModule,
105105
MatButtonModule,
106106
MatCardModule,
@@ -121,9 +121,7 @@ import { TableScroll } from "./table-scroll/table-scroll.component";
121121
RouterModule.forChild(routes),
122122

123123
CcPipeModule,
124-
125-
HttpClientModule,
126-
124+
ModalModule,
127125
SharedModule
128126
],
129127
declarations: [

spa/src/app/files/hca-project/hca-project.component.html

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -120,21 +120,23 @@ <h4 class="fontsize-m semi-bold">Project Downloads</h4>
120120
</p>
121121
<p class="fontsize-xs rhs" *ngIf="state.projectMatrixUrls && !state.projectMatrixUrls.isAnyProjectMatrixUrlAvailable()">No expression matrix available</p>
122122
</div>
123-
<div *ngFor="let species of state.projectMatrixUrls.listSpeciesWithMatrixUrls()"
124-
class="species-matrix-url">
125-
<p class="fontsize-xs semi-bold subhead lhs">
126-
<hca-tooltip [tooltipClass]="'hca-tooltip narrow'"
127-
[tooltipContent]="'Download expression matrix'"
128-
[tooltipDisabled]="false"
129-
[tooltipPosition]="'above'">{{species}}
130-
</hca-tooltip>
131-
</p>
132-
<p class="fontsize-xs rhs downloads">
133-
<span *ngFor="let matrixUrl of state.projectMatrixUrls.listMatrixUrlsBySpecies(species)"><a
134-
[href]="matrixUrl.url"><img
135-
src="assets/images/icon/hca-download-primary.png"/><span>{{matrixUrl.name}}</span></a></span>
136-
</p>
137-
</div>
123+
<ng-container *ngIf="state.projectMatrixUrls">
124+
<div *ngFor="let species of state.projectMatrixUrls.listSpeciesWithMatrixUrls()"
125+
class="species-matrix-url">
126+
<p class="fontsize-xs semi-bold subhead lhs">
127+
<hca-tooltip [tooltipClass]="'hca-tooltip narrow'"
128+
[tooltipContent]="'Download expression matrix'"
129+
[tooltipDisabled]="false"
130+
[tooltipPosition]="'above'">{{species}}
131+
</hca-tooltip>
132+
</p>
133+
<p class="fontsize-xs rhs downloads">
134+
<span *ngFor="let matrixUrl of state.projectMatrixUrls.listMatrixUrlsBySpecies(species)"><a
135+
[href]="matrixUrl.url"><img
136+
src="assets/images/icon/hca-download-primary.png"/><span>{{matrixUrl.name}}</span></a></span>
137+
</p>
138+
</div>
139+
</ng-container>
138140
</div>
139141
<div class="project-integrations">
140142
<h4 class="fontsize-m semi-bold">External Resources</h4>

spa/src/app/files/project-download-matrix-modal-container/project-download-matrix-modal-container.component.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@ import { MatDialog } from "@angular/material";
1111
import { ActivatedRoute } from "@angular/router";
1212
import { Subject } from "rxjs";
1313
import { takeUntil } from "rxjs/operators";
14-
import { Store } from "@ngrx/store";
1514

1615
// App dependencies
1716
import { ProjectDownloadMatrixModalComponent } from "../project-download-matrix-modal/project-download-matrix-modal.component";
18-
import { AppState } from "../../_ngrx/app.state";
1917

2018

2119
@Component({
@@ -34,11 +32,12 @@ export class ProjectDownloadMatrixModalContainerComponent implements OnDestroy {
3432
/**
3533
* @param {MatDialog} dialog
3634
* @param {ActivatedRoute} route
37-
* @param {Store<AppState>} store
3835
*/
39-
constructor(dialog: MatDialog, route: ActivatedRoute, private store: Store<AppState>) {
36+
constructor(dialog: MatDialog, route: ActivatedRoute) {
4037

41-
route.params.pipe(takeUntil(this.ngDestroy$)).subscribe(params => {
38+
route.params.pipe(
39+
takeUntil(this.ngDestroy$)
40+
).subscribe(params => {
4241

4342
dialog.open(ProjectDownloadMatrixModalComponent, {
4443
autoFocus: false,

spa/src/app/files/project-download-matrix-modal/project-download-matrix-modal.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<modal-layout *ngIf="state$ | async as state"
22
[loaded]="state.loaded"
3-
(closed)="onClosedClicked()">
3+
(closed)="redirectToProjects()">
44
<ng-container title *ngIf="state.loaded">
55
Download Project Expression Matrices
66
</ng-container>

spa/src/app/files/project-download-matrix-modal/project-download-matrix-modal.component.ts

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@
22
* Human Cell Atlas
33
* https://www.humancellatlas.org/
44
*
5-
* Component for displaying project prepared expression matrices downloads inside modal. Displayed
5+
* Component for displaying project prepared expression matrices downloads inside modal. The modal closes automatically
6+
* on NavigationStart event. The follow actions causes a redirect to the projects page (and therefore closes the modal):
7+
*
8+
* 1. Hitting escape
9+
* 2. Clicking the close icon
10+
* 3. Clicking the HCA logo
611
*/
712

813
// Core dependencies
914
import { Component, HostListener, Inject, OnDestroy, OnInit } from "@angular/core";
1015
import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material";
11-
import { Router } from "@angular/router";
16+
import { NavigationStart, Router, RouterEvent } from "@angular/router";
1217
import { select, Store } from "@ngrx/store";
1318
import { combineLatest, BehaviorSubject, Observable, Subject } from "rxjs";
1419
import { filter, map, takeUntil } from "rxjs/operators";
@@ -23,6 +28,8 @@ import { ProjectDownloadMatrixModalState } from "./project-download-matrix-modal
2328
import { FetchProjectRequestAction } from "../_ngrx/table/table.actions";
2429
import { selectSelectedProject } from "../_ngrx/file.selectors";
2530
import { Project } from "../shared/project.model";
31+
import { ModalOpenedAction } from "../../modal/_ngrx/modal-opened.action";
32+
import { ModalClosedAction } from "../../modal/_ngrx/modal-closed.action";
2633

2734
@Component({
2835
selector: "project-download-matrix-modal",
@@ -47,32 +54,33 @@ export class ProjectDownloadMatrixModalComponent implements OnDestroy, OnInit {
4754
private dialogRef: MatDialogRef<ProjectDownloadMatrixModalComponent>,
4855
@Inject(MAT_DIALOG_DATA) private data: any,
4956
private router: Router) {
50-
}
51-
52-
/**
53-
* Close dialog on key up of escape key.
54-
*/
55-
@HostListener("window:keyup.esc") onKeyUp() {
5657

57-
this.dialogRef.close();
58-
this.redirectToProjects()
58+
this.store.dispatch(new ModalOpenedAction());
5959
}
6060

6161
/**
62-
* Close modal and redirect to projects list.
62+
* Redirect to projects list - called from template on click of close icon, or on keyup of escape key. The resulting
63+
* navigation event causes the modal to close. See initCloseOnNavigation.
6364
*/
64-
public onClosedClicked(): void {
65+
@HostListener("window:keyup.esc")
66+
public redirectToProjects(): void {
6567

66-
this.dialogRef.close();
67-
this.redirectToProjects();
68+
this.router.navigateByUrl(`/${EntityName.PROJECTS}`, {replaceUrl: true});
6869
}
6970

7071
/**
71-
* Redirect to projects list.
72+
* Close the modal on any navigation event.
7273
*/
73-
public redirectToProjects(): void {
74+
private initCloseOnNavigation() {
7475

75-
this.router.navigateByUrl(`/${EntityName.PROJECTS}`, {replaceUrl: true});
76+
this.router.events.pipe(
77+
filter((event: RouterEvent) => event instanceof NavigationStart),
78+
filter(() => !!this.dialogRef),
79+
takeUntil(this.ngDestroy$)
80+
).subscribe(() => {
81+
this.store.dispatch(new ModalClosedAction());
82+
this.dialogRef.close();
83+
});
7684
}
7785

7886
/**
@@ -115,11 +123,13 @@ export class ProjectDownloadMatrixModalComponent implements OnDestroy, OnInit {
115123
}
116124

117125
/**
118-
* Grab the prepared matrix URLs for the selected project. Also listen for close events (click on backdrop or escape
119-
* key) and redirect to projects list.
126+
* Grab the prepared matrix URLs for the selected project. Also listen for navigation events, in which case we must
127+
* close the modal.
120128
*/
121129
public ngOnInit(): void {
122-
130+
131+
this.initCloseOnNavigation();
132+
123133
const projectId = this.data.projectId;
124134

125135
// Request project details so we can display the project title
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Human Cell Atlas
3+
* https://www.humancellatlas.org/
4+
*
5+
* Action triggered when modal is closed.
6+
*/
7+
8+
// Core dependencies
9+
import { Action } from "@ngrx/store";
10+
11+
export class ModalClosedAction implements Action {
12+
public static ACTION_TYPE = "MODAL.CLOSED";
13+
public readonly type = ModalClosedAction.ACTION_TYPE;
14+
constructor() {}
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Human Cell Atlas
3+
* https://www.humancellatlas.org/
4+
*
5+
* Action triggered when modal is opened.
6+
*/
7+
8+
// Core dependencies
9+
import { Action } from "@ngrx/store";
10+
11+
export class ModalOpenedAction implements Action {
12+
public static ACTION_TYPE = "MODAL.OPENED";
13+
public readonly type = ModalOpenedAction.ACTION_TYPE;
14+
constructor() {}
15+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* Human Cell Atlas
3+
* https://www.humancellatlas.org/
4+
*
5+
* Modal reducer, handles actions related to updating modal state.
6+
*/
7+
8+
// Core dependencies
9+
import { Action } from "@ngrx/store";
10+
11+
// App dependencies
12+
import { ModalClosedAction } from "./modal-closed.action";
13+
import { ModalOpenedAction } from "./modal-opened.action";
14+
import { ModalState } from "./modal.state";
15+
16+
/**
17+
* @param state {ModalState}
18+
* @param action {Action}
19+
* @returns {ModalState}
20+
*/
21+
export function reducer(state: ModalState = ModalState.getDefaultState(), action: Action): ModalState {
22+
23+
switch (action.type) {
24+
25+
// Handle case where modal was closed
26+
case ModalClosedAction.ACTION_TYPE:
27+
return state.closeModal();
28+
29+
// Handle case where modal was opened
30+
case ModalOpenedAction.ACTION_TYPE:
31+
return state.openModal();
32+
33+
default:
34+
return state;
35+
}
36+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Human Cell Atlas
3+
* https://www.humancellatlas.org/
4+
*
5+
* Selectors for querying modal-related state from the store.
6+
*/
7+
8+
// Core dependencies
9+
import { createSelector, createFeatureSelector } from "@ngrx/store";
10+
11+
// App dependencies
12+
import { ModalState } from "./modal.state";
13+
14+
/**
15+
* Get the modal state.
16+
*/
17+
export const selectModal = createFeatureSelector<ModalState>("modal");
18+
19+
/**
20+
* Returns true if modal is currently open, otherwise false.
21+
*/
22+
export const selectModalOpen = createSelector(selectModal, (state: ModalState) => state.open);

0 commit comments

Comments
 (0)