Skip to content

Commit

Permalink
Merge branch 'feature/questionnaire' into task/WG-96-add-assets-to-or…
Browse files Browse the repository at this point in the history
…iginal-questionnaire-code
  • Loading branch information
nathanfranklin authored Oct 6, 2023
2 parents a135d40 + 719b4d3 commit 2ec6f22
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 38 deletions.
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

## [Unreleased]

## [2.14] - 2023-10-03

### Changed

- WG-155: Add dev server as option for backend (#149)

### Fixed

- WG-145: fix spinner error on project listing page (#148)

## [2.13] - 2022-06-05

### Added
Expand Down Expand Up @@ -134,7 +144,8 @@ _No release_



[unreleased]: https://github.com/TACC-Cloud/hazmapper/compare/v2.13...HEAD
[unreleased]: https://github.com/TACC-Cloud/hazmapper/compare/v2.14...HEAD
[2.14]: https://github.com/TACC-Cloud/hazmapper/releases/tag/v2.14
[2.13]: https://github.com/TACC-Cloud/hazmapper/releases/tag/v2.13
[2.11]: https://github.com/TACC-Cloud/hazmapper/releases/tag/v2.11
[2.9]: https://github.com/TACC-Cloud/hazmapper/releases/tag/v2.9
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
TAG := $(shell git log --format=%h -1)
IMAGE ?= taccaci/hazmapper:$(TAG)

.PHONY: image
image:
.PHONY: build
build:
docker build -t $(IMAGE) -f angular/Dockerfile .
docker tag taccaci/hazmapper:${TAG} taccaci/hazmapper:latest

.PHONY: deploy
deploy:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,8 @@ export class FileBrowserComponent implements OnInit {

// TODO: change those hard coded systemIds to environment vars or some sort of config
// wait on the currentUser, systems and projects to resolve
combineLatest([this.authService.currentUser, this.agaveSystemsService.systems, this.agaveSystemsService.projects])
.pipe(take(1))
.subscribe(([user, systems, projects]) => {
combineLatest([this.authService.currentUser, this.agaveSystemsService.systems, this.agaveSystemsService.projects]).subscribe(
([user, systems, projects]) => {
this.myDataSystem = systems.find((sys) => sys.id === 'designsafe.storage.default');
this.communityDataSystem = systems.find((sys) => sys.id === 'designsafe.storage.community');
this.publishedDataSystem = systems.find((sys) => sys.id === 'designsafe.storage.published');
Expand All @@ -73,7 +72,8 @@ export class FileBrowserComponent implements OnInit {
path: this.currentUser.username,
};
this.browse(init);
});
}
);
}

selectSystem(system: SystemSummary): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
</div>
</div>

<div *ngIf="spinner; else projectLoaded">
<div *ngIf="loading; else projectLoaded">
<div id="welcome-no-information">
<div>
Loading Projects
Expand All @@ -34,15 +34,21 @@
</div>

<ng-template #projectLoaded>
<div *ngIf="notConnected; else projectConnected">
<div *ngIf="projectsData.failedMessage || dsProjectsData.failedMessage; else projectConnected">
<div id="welcome-no-information">
<div>Failed to Connect to Server!</div>
<div *ngIf="projectsData.failedMessage">
<small>Unable to get maps: {{ projectsData.failedMessage }}</small>
</div>
<div *ngIf="dsProjectsData.failedMessage">
<small>Unable to get projects: {{ dsProjectsData.failedMessage }}</small>
</div>
</div>
</div>

<ng-template #projectConnected>
<div *ngIf="projects.length > 0; else noProject" class="project-list-container">
<div *ngFor="let p of projects; let indexOfElement = index">
<div *ngIf="projectsData.projects.length > 0; else noProject" class="project-list-container">
<div *ngFor="let p of projectsData.projects; let indexOfElement = index">
<div
(click)="routeToProject(p.uuid)"
class="project-list-item"
Expand Down
33 changes: 18 additions & 15 deletions angular/src/app/components/main-welcome/main-welcome.component.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Component, OnInit } from '@angular/core';
import { Project } from '../../models/models';
import { Streetview } from '../../models/streetview';
import { ProjectsService } from '../../services/projects.service';
import { ProjectsService, ProjectsData } from '../../services/projects.service';
import { BsModalRef, BsModalService } from 'ngx-foundation';
import { AgaveSystemsService } from '../../services/agave-systems.service';
import { AgaveSystemsService, AgaveProjectsData } from '../../services/agave-systems.service';
import { ModalCreateProjectComponent } from '../modal-create-project/modal-create-project.component';
import { Router, ActivatedRoute } from '@angular/router';
import { ModalService } from 'src/app/services/modal.service';
Expand All @@ -21,11 +21,9 @@ export class MainWelcomeComponent implements OnInit {
release_url = 'https://github.com/TACC-cloud/hazmapper';
guide_url = 'https://www.designsafe-ci.org/rw/user-guides/tools-applications/visualization/hazmapper/';

spinner = true;
notConnected: boolean;

public projects = [];
public activeProject: Project;
private projectsData: ProjectsData;
private dsProjectsData: AgaveProjectsData;
private loading = true;

constructor(
private route: ActivatedRoute,
Expand All @@ -48,14 +46,19 @@ export class MainWelcomeComponent implements OnInit {
}
});

this.projectsService.loadingProjectsFailed.subscribe((notConnected) => {
this.notConnected = notConnected;
});

combineLatest([this.projectsService.projects, this.agaveSystemsService.projects]).subscribe(([projects, dsProjects]) => {
this.projects = this.agaveSystemsService.getProjectMetadata(projects, dsProjects);
this.spinner = false;
});
combineLatest([this.projectsService.projectsData, this.agaveSystemsService.projectsData]).subscribe(
([projectsData, dsProjectsData]) => {
this.projectsData = projectsData;
this.dsProjectsData = dsProjectsData;
if (!this.projectsData.loading && !this.dsProjectsData.loading) {
if (!this.projectsData.failedMessage && !this.dsProjectsData.failedMessage) {
// add extra info (i.e. DS project id/description) from related DS projects
this.projectsData.projects = this.agaveSystemsService.getProjectMetadata(projectsData.projects, dsProjectsData.projects);
}
this.loading = false;
}
}
);
}

routeToProject(projectUUID: string) {
Expand Down
36 changes: 33 additions & 3 deletions angular/src/app/services/agave-systems.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,47 @@ import { Injectable } from '@angular/core';
import { System, SystemSummary } from 'ng-tapis';
import { ApiService } from 'ng-tapis';
import { NotificationsService } from './notifications.service';
import { BehaviorSubject, Observable, ReplaySubject } from 'rxjs';
import { BehaviorSubject, Observable, ReplaySubject, combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { EnvService } from '../services/env.service';
import { DesignSafeProjectCollection, Project, AgaveFileOperations } from '../models/models';

export interface AgaveProjectsData {
projects: SystemSummary[];
failedMessage: string | null;
loading: boolean;
}

@Injectable({
providedIn: 'root',
})
export class AgaveSystemsService {
private _systems: ReplaySubject<SystemSummary[]> = new ReplaySubject<SystemSummary[]>(1);
public readonly systems: Observable<SystemSummary[]> = this._systems.asObservable();

private _projects: ReplaySubject<SystemSummary[]> = new ReplaySubject<SystemSummary[]>(1);
public readonly projects: Observable<SystemSummary[]> = this._projects.asObservable();
private _loadingProjects: BehaviorSubject<boolean> = new BehaviorSubject(true);
public loadingProjects: Observable<boolean> = this._loadingProjects.asObservable();
private _loadingProjectsFailedMessage: BehaviorSubject<string> = new BehaviorSubject('');
public loadingProjectsFailedMessage: Observable<string> = this._loadingProjectsFailedMessage.asObservable();
public readonly projectsData: Observable<AgaveProjectsData>;

constructor(
private tapis: ApiService,
private notificationsService: NotificationsService,
private envService: EnvService,
private http: HttpClient
) {}
) {
this.projectsData = combineLatest([this.projects, this.loadingProjectsFailedMessage, this.loadingProjects]).pipe(
map(([projects, failedMessage, loading]) => ({
projects,
failedMessage,
loading,
}))
);
}

list() {
this.tapis.systemsList({ type: 'STORAGE' }).subscribe(
Expand All @@ -31,6 +53,11 @@ export class AgaveSystemsService {
this._systems.next(null);
}
);

this._projects.next(null);
this._loadingProjects.next(true);
this._loadingProjectsFailedMessage.next(null);

this.http.get<DesignSafeProjectCollection>(this.envService.designSafeUrl + `/projects/v2/`).subscribe(
(resp) => {
const projectSystems = resp.projects.map((project) => {
Expand All @@ -41,15 +68,18 @@ export class AgaveSystemsService {
};
});
this._projects.next(projectSystems);
this._loadingProjects.next(false);
},
(error) => {
this._projects.next(null);
this._loadingProjectsFailedMessage.next(error.message || 'An error occured.');
this._loadingProjects.next(false);
}
);
}

getProjectMetadata(projects: Project[], dsProjects: SystemSummary[]): Project[] {
if (dsProjects.length > 0) {
if (dsProjects && dsProjects.length > 0) {
return projects.map((p) => {
const dsProject = dsProjects.find((dp) => dp.id === p.system_id);
p.title = dsProject ? dsProject.description : null;
Expand Down
22 changes: 21 additions & 1 deletion angular/src/app/services/env.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export class EnvService {
return 'https://agave.designsafe-ci.org/geo-staging/v2';
} else if (backend === EnvironmentType.Production) {
return 'https://agave.designsafe-ci.org/geo/v2';
} else if (backend === EnvironmentType.Dev) {
return 'https://agave.designsafe-ci.org/geo-dev/v2';
} else {
throw new Error('Unsupported Type');
}
Expand Down Expand Up @@ -131,7 +133,7 @@ export class EnvService {
// local devevelopers can use localhost or hazmapper.local but
// hazmapper.local is preferred as TAPIS supports it as a frame ancestor
// (i.e. it allows for point cloud iframe preview)
this._clientId = /^localhost/.test(hostname) ? 'RMCJHgW9CwJ6mKjhLTDnUYBo9Hka' : 'Eb9NCCtWkZ83c01UbIAITFvhD9ka';
this._clientId = /^localhost/.test(hostname) ? 'XgCBlhfAaqfv7jTu3NRc4IJDGdwa' : 'Eb9NCCtWkZ83c01UbIAITFvhD9ka';
} else if (/^hazmapper.tacc.utexas.edu/.test(hostname) && pathname.startsWith('/staging')) {
this._env = EnvironmentType.Staging;
this._apiUrl = this.getApiUrl(this.env);
Expand All @@ -150,6 +152,24 @@ export class EnvService {
clientToken: 'MLY|4936281379826603|f8c4732d3c9d96582b86158feb1c1a7a',
},
};
} else if (/^hazmapper.tacc.utexas.edu/.test(hostname) && pathname.startsWith('/dev')) {
this._env = EnvironmentType.Dev;
this._apiUrl = this.getApiUrl(this.env);
this._taggitUrl = origin + '/taggit-dev'; /* doesn't yet exist */
this._portalUrl = this.getPortalUrl(this.env);
this._clientId = 'oEuGsl7xi015wnrEpxIeUmvzc6Qa';
this._baseHref = '/dev/';
this._streetviewEnv.secrets = {
google: {
clientSecret: '',
clientId: '573001329633-1p0k8rko13s6n2p2cugp3timji3ip9f0.apps.googleusercontent.com',
},
mapillary: {
clientSecret: 'MLY|4936281379826603|cafd014ccd8cfc983e47c69c16082c7b',
clientId: '4936281379826603',
clientToken: 'MLY|4936281379826603|f8c4732d3c9d96582b86158feb1c1a7a',
},
};
} else if (/^hazmapper.tacc.utexas.edu/.test(hostname)) {
this._env = EnvironmentType.Production;
this._apiUrl = this.getApiUrl(this.env);
Expand Down
37 changes: 29 additions & 8 deletions angular/src/app/services/projects.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { BehaviorSubject, Observable, ReplaySubject } from 'rxjs';
import { BehaviorSubject, Observable, ReplaySubject, combineLatest } from 'rxjs';
import { DesignSafeProjectCollection, Project, ProjectRequest, AgaveFileOperations } from '../models/models';
import { RapidProjectRequest } from '../models/rapid-project-request';
import { IpanelsDisplay, defaultPanelsDisplay } from '../models/ui';
Expand All @@ -14,6 +14,12 @@ import { MAIN, LOGIN } from '../constants/routes';
import { AgaveSystemsService } from '../services/agave-systems.service';
import { Router } from '@angular/router';

export interface ProjectsData {
projects: Project[];
failedMessage: string | null;
loading: boolean;
}

@Injectable({
providedIn: 'root',
})
Expand All @@ -29,8 +35,13 @@ export class ProjectsService {
private _currentProjectUser: BehaviorSubject<IProjectUser> = new BehaviorSubject<IProjectUser>(null);
public readonly currentProjectUser: Observable<IProjectUser> = this._currentProjectUser.asObservable();

private _loadingProjectsFailed: BehaviorSubject<boolean> = new BehaviorSubject(false);
public loadingProjectsFailed: Observable<boolean> = this._loadingProjectsFailed.asObservable();
private _loadingProjects: BehaviorSubject<boolean> = new BehaviorSubject(true);
public loadingProjects: Observable<boolean> = this._loadingProjects.asObservable();

private _loadingProjectsFailedMessage: BehaviorSubject<string> = new BehaviorSubject('');
public loadingProjectsFailedMessage: Observable<string> = this._loadingProjectsFailedMessage.asObservable();

public readonly projectsData: Observable<ProjectsData>;

private _loadingActiveProject: BehaviorSubject<boolean> = new BehaviorSubject(true);
public loadingActiveProject: Observable<boolean> = this._loadingActiveProject.asObservable();
Expand All @@ -52,7 +63,15 @@ export class ProjectsService {
private router: Router,
private authService: AuthService,
private envService: EnvService
) {}
) {
this.projectsData = combineLatest([this.projects, this.loadingProjectsFailedMessage, this.loadingProjects]).pipe(
map(([projects, failedMessage, loading]) => ({
projects,
failedMessage,
loading,
}))
);
}

public getLastProjectKeyword() {
return `${this.envService.env}LastProject`;
Expand All @@ -72,15 +91,17 @@ export class ProjectsService {
}

getProjects(): void {
this._loadingProjectsFailed.next(false);
this._loadingProjects.next(true);
this._loadingProjectsFailedMessage.next(null);
this.http.get<Project[]>(this.envService.apiUrl + `/projects/`).subscribe(
(resp) => {
this.updateProjectsList(resp);
this._loadingProjectsFailed.next(false);
this._loadingProjects.next(false);
this._loadingProjectsFailedMessage.next(null);
},
(error) => {
this._loadingProjectsFailed.next(true);
this.notificationsService.showErrorToast('Failed to retrieve project data! Geoapi might be down.');
this._loadingProjects.next(false);
this._loadingProjectsFailedMessage.next(error.message || 'An error occured.');
}
);
}
Expand Down
1 change: 1 addition & 0 deletions angular/src/environments/environmentType.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export enum EnvironmentType {
Production = 'production',
Staging = 'staging',
Dev = 'dev' /* i.e. dev.geoapi-services.tacc.utexas.edu*/,
Local = 'local',
}
2 changes: 2 additions & 0 deletions angular/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

if (/^hazmapper.tacc.utexas.edu/.test(hostname) && pathname.startsWith('/staging')) {
document.getElementById('base').href = '/staging/';
} else if (/^hazmapper.tacc.utexas.edu/.test(hostname) && pathname.startsWith('/dev')) {
document.getElementById('base').href = '/dev/';
} else if (/^hazmapper.tacc.utexas.edu/.test(hostname)) {
document.getElementById('base').href = '/hazmapper/';
} else {
Expand Down

0 comments on commit 2ec6f22

Please sign in to comment.