diff --git a/apps/dsp-app/src/app/main/services/component-communication-event.service.ts b/apps/dsp-app/src/app/main/services/component-communication-event.service.ts
index 30e461bc08..b34274597c 100644
--- a/apps/dsp-app/src/app/main/services/component-communication-event.service.ts
+++ b/apps/dsp-app/src/app/main/services/component-communication-event.service.ts
@@ -42,6 +42,7 @@ export enum Events {
gravSearchExecuted,
projectCreated,
resourceDeleted,
+ resourceChanged,
resourceCreated,
unselectedListItem,
}
diff --git a/apps/dsp-app/src/app/project/description/description.component.html b/apps/dsp-app/src/app/project/description/description.component.html
index ae7120b534..b0d2cb3df4 100644
--- a/apps/dsp-app/src/app/project/description/description.component.html
+++ b/apps/dsp-app/src/app/project/description/description.component.html
@@ -1,4 +1,4 @@
-
+
Project Description
diff --git a/apps/dsp-app/src/app/project/description/description.component.ts b/apps/dsp-app/src/app/project/description/description.component.ts
index 2dc956b203..25f5efa39e 100644
--- a/apps/dsp-app/src/app/project/description/description.component.ts
+++ b/apps/dsp-app/src/app/project/description/description.component.ts
@@ -1,35 +1,38 @@
-import { ChangeDetectionStrategy, Component } from '@angular/core';
+import { Component, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ReadUser } from '@dasch-swiss/dsp-js';
import { StringLiteral } from '@dasch-swiss/dsp-js/src/models/admin/string-literal';
import { RouteConstants } from '@dasch-swiss/vre/shared/app-config';
import { ProjectService } from '@dasch-swiss/vre/shared/app-helper-services';
import { ProjectsSelectors, UserSelectors } from '@dasch-swiss/vre/shared/app-state';
-import { Store } from '@ngxs/store';
-import { combineLatest } from 'rxjs';
-import { map, switchMap, tap } from 'rxjs/operators';
+import { Select, Store } from '@ngxs/store';
+import { Observable, Subject, combineLatest } from 'rxjs';
+import { map, takeUntil, takeWhile } from 'rxjs/operators';
import { AppGlobal } from '../../app-global';
@Component({
- changeDetection: ChangeDetectionStrategy.OnPush,
+ // changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'app-description',
templateUrl: './description.component.html',
styleUrls: ['./description.component.scss'],
})
-export class DescriptionComponent {
- loading = false;
- readProject$ = this._route.paramMap.pipe(
- switchMap(params => {
- this.loading = true;
- return this._store
- .select(ProjectsSelectors.allProjects)
- .pipe(map(projects => projects.find(x => x.id.split('/').pop() === params.get(RouteConstants.uuidParameter))));
- }),
- tap(() => {
- this.loading = false;
+export class DescriptionComponent implements OnDestroy {
+ destroyed$: Subject
= new Subject();
+
+ readProject$ = combineLatest([this._route.paramMap, this._store.select(ProjectsSelectors.allProjects)]).pipe(
+ takeUntil(this.destroyed$),
+ map(([params, allProjects]) => {
+ const projects = allProjects.find(x => x.id.split('/').pop() === params.get(RouteConstants.uuidParameter));
+ return projects;
})
);
- sortedDescriptions$ = this.readProject$.pipe(map(({ description }) => this._sortDescriptionsByLanguage(description)));
+
+ sortedDescriptions$ = this.readProject$.pipe(
+ takeUntil(this.destroyed$),
+ takeWhile(readProject => readProject !== undefined),
+ map(({ description }) => this._sortDescriptionsByLanguage(description))
+ );
+
userHasPermission$ = combineLatest([
this._store.select(UserSelectors.user),
this.readProject$,
@@ -46,11 +49,19 @@ export class DescriptionComponent {
RouteConstants = RouteConstants;
+ @Select(ProjectsSelectors.isProjectsLoading) isLoading$: Observable;
+
constructor(
private _route: ActivatedRoute,
- private _store: Store
+ private _store: Store,
+ private _projectService: ProjectService
) {}
+ ngOnDestroy(): void {
+ this.destroyed$.next();
+ this.destroyed$.complete();
+ }
+
private _sortDescriptionsByLanguage(descriptions: StringLiteral[]): StringLiteral[] {
const languageOrder = AppGlobal.languagesList.map(l => l.language);
diff --git a/apps/dsp-app/src/app/workspace/resource/properties/properties.component.ts b/apps/dsp-app/src/app/workspace/resource/properties/properties.component.ts
index 0f83b58964..4c012b14c7 100644
--- a/apps/dsp-app/src/app/workspace/resource/properties/properties.component.ts
+++ b/apps/dsp-app/src/app/workspace/resource/properties/properties.component.ts
@@ -391,6 +391,7 @@ export class PropertiesComponent implements OnInit, OnChanges, OnDestroy {
this.resource.res.label = payload.label;
this.lastModificationDate = response.lastModificationDate;
// if annotations tab is active; a label of a region has been changed --> update regions
+ this._componentCommsService.emit(new EmitEvent(CommsEvents.resourceChanged));
if (this.isAnnotation) {
this.regionChanged.emit();
}
diff --git a/apps/dsp-app/src/app/workspace/results/list-view/list-view.component.ts b/apps/dsp-app/src/app/workspace/results/list-view/list-view.component.ts
index 412444e4ee..7432ce6c9d 100644
--- a/apps/dsp-app/src/app/workspace/results/list-view/list-view.component.ts
+++ b/apps/dsp-app/src/app/workspace/results/list-view/list-view.component.ts
@@ -21,7 +21,7 @@ import {
import { DspApiConnectionToken, RouteConstants } from '@dasch-swiss/vre/shared/app-config';
import { AppErrorHandler } from '@dasch-swiss/vre/shared/app-error-handler';
import { NotificationService } from '@dasch-swiss/vre/shared/app-notification';
-import { of, Subject, Subscription } from 'rxjs';
+import { Subject, Subscription, of } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
import {
ComponentCommunicationEventService,
@@ -141,9 +141,8 @@ export class ListViewComponent implements OnChanges, OnInit, OnDestroy {
ngOnInit(): void {
this.componentCommsSubscriptions.push(
- this._componentCommsService.on(Events.resourceDeleted, () => {
- this._doSearch();
- })
+ this._componentCommsService.on(Events.resourceChanged, () => this._doSearch()),
+ this._componentCommsService.on(Events.resourceDeleted, () => this._doSearch())
);
}
diff --git a/libs/vre/shared/app-state/src/lib/projects/projects.state-model.ts b/libs/vre/shared/app-state/src/lib/projects/projects.state-model.ts
index 670c78d7ef..95d74090d8 100644
--- a/libs/vre/shared/app-state/src/lib/projects/projects.state-model.ts
+++ b/libs/vre/shared/app-state/src/lib/projects/projects.state-model.ts
@@ -3,6 +3,7 @@ import { IKeyValuePairs } from '../model-interfaces';
export class ProjectsStateModel {
isLoading = false;
+ isMembershipLoading = false;
hasLoadingErrors = false;
allProjects: ReadProject[] = [];
projectMembers: IKeyValuePairs = {};
diff --git a/libs/vre/shared/app-state/src/lib/projects/projects.state.ts b/libs/vre/shared/app-state/src/lib/projects/projects.state.ts
index 84ed684c52..79b322c596 100644
--- a/libs/vre/shared/app-state/src/lib/projects/projects.state.ts
+++ b/libs/vre/shared/app-state/src/lib/projects/projects.state.ts
@@ -38,6 +38,7 @@ import { ProjectsStateModel } from './projects.state-model';
const defaults: ProjectsStateModel = {
isLoading: false,
+ isMembershipLoading: false,
hasLoadingErrors: false,
allProjects: [],
projectMembers: {},
@@ -139,10 +140,10 @@ export class ProjectsState {
const userProjectAdminGroups = this.store.selectSnapshot(UserSelectors.userProjectAdminGroups);
const isProjectAdmin = ProjectService.IsProjectAdminOrSysAdmin(user, userProjectAdminGroups, projectIri);
if (isProjectAdmin) {
- ctx.patchState({ isLoading: true });
+ ctx.patchState({ isMembershipLoading: true });
ctx.dispatch([new LoadProjectMembersAction(projectUuid), new LoadProjectGroupsAction(projectUuid)]);
this.actions.pipe(take(1), ofActionSuccessful(LoadProjectGroupsAction)).subscribe(() => {
- ctx.patchState({ isLoading: false });
+ ctx.patchState({ isMembershipLoading: false });
});
}
}
@@ -166,14 +167,14 @@ export class ProjectsState {
@Action(RemoveUserFromProjectAction)
removeUserFromProject(ctx: StateContext, { userId, projectIri }: RemoveUserFromProjectAction) {
- ctx.patchState({ isLoading: true });
+ ctx.patchState({ isMembershipLoading: true });
return this._dspApiConnection.admin.usersEndpoint.removeUserFromProjectMembership(userId, projectIri).pipe(
take(1),
map((response: ApiResponseData | ApiResponseError) => response as ApiResponseData),
tap({
next: (response: ApiResponseData) => {
ctx.dispatch([new SetUserAction(response.body.user), new LoadProjectMembersAction(projectIri)]);
- ctx.patchState({ isLoading: false });
+ ctx.patchState({ isMembershipLoading: false });
},
error: error => {
this.errorHandler.showMessage(error);
@@ -187,14 +188,14 @@ export class ProjectsState {
ctx: StateContext,
{ userId, projectIri }: AddUserToProjectMembershipAction
) {
- ctx.patchState({ isLoading: true, hasLoadingErrors: false });
+ ctx.patchState({ isMembershipLoading: true, hasLoadingErrors: false });
return this._dspApiConnection.admin.usersEndpoint.addUserToProjectMembership(userId, projectIri).pipe(
take(1),
map((response: ApiResponseData | ApiResponseError) => response as ApiResponseData),
tap({
next: (response: ApiResponseData) => {
ctx.dispatch([new SetUserAction(response.body.user), new LoadProjectMembersAction(projectIri)]);
- ctx.patchState({ isLoading: false });
+ ctx.patchState({ isMembershipLoading: false });
},
error: error => {
ctx.patchState({ hasLoadingErrors: true });
@@ -210,7 +211,7 @@ export class ProjectsState {
return;
}
- ctx.patchState({ isLoading: true });
+ ctx.patchState({ isMembershipLoading: true });
const projectIri = this.projectService.uuidToIri(projectUuid);
return this._dspApiConnection.admin.projectsEndpoint.getProjectMembersByIri(projectIri).pipe(
take(1),
@@ -222,7 +223,7 @@ export class ProjectsState {
next: (response: ApiResponseData) => {
ctx.setState({
...ctx.getState(),
- isLoading: false,
+ isMembershipLoading: false,
projectMembers: {
[projectIri]: { value: response.body.members },
},
@@ -238,7 +239,7 @@ export class ProjectsState {
@Action(LoadProjectGroupsAction)
loadProjectGroupsAction(ctx: StateContext) {
- ctx.patchState({ isLoading: true });
+ ctx.patchState({ isMembershipLoading: true });
return this._dspApiConnection.admin.groupsEndpoint.getGroups().pipe(
take(1),
map(
@@ -259,7 +260,7 @@ export class ProjectsState {
ctx.setState({
...ctx.getState(),
- isLoading: false,
+ isMembershipLoading: false,
projectGroups: groups,
});
},