Skip to content

Commit

Permalink
fix(dsp-app): reloads resource list when resource is changed, separat…
Browse files Browse the repository at this point in the history
…es projects and membership loading.. (#1343)
  • Loading branch information
irmastnt committed Jan 12, 2024
1 parent d6211f9 commit b4bd34b
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 33 deletions.
Expand Up @@ -42,6 +42,7 @@ export enum Events {
gravSearchExecuted,
projectCreated,
resourceDeleted,
resourceChanged,
resourceCreated,
unselectedListItem,
}
@@ -1,4 +1,4 @@
<dasch-swiss-app-progress-indicator *ngIf="loading"></dasch-swiss-app-progress-indicator>
<dasch-swiss-app-progress-indicator *ngIf="isLoading$ | async"></dasch-swiss-app-progress-indicator>
<div *ngIf="(readProject$ | async) as project" class="content large middle">
<div>
<p>Project Description</p>
Expand Down
47 changes: 29 additions & 18 deletions 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<void> = new Subject<void>();

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$,
Expand All @@ -46,11 +49,19 @@ export class DescriptionComponent {

RouteConstants = RouteConstants;

@Select(ProjectsSelectors.isProjectsLoading) isLoading$: Observable<boolean>;

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);

Expand Down
Expand Up @@ -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();
}
Expand Down
Expand Up @@ -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,
Expand Down Expand Up @@ -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())
);
}

Expand Down
Expand Up @@ -3,6 +3,7 @@ import { IKeyValuePairs } from '../model-interfaces';

export class ProjectsStateModel {
isLoading = false;
isMembershipLoading = false;
hasLoadingErrors = false;
allProjects: ReadProject[] = [];
projectMembers: IKeyValuePairs<ReadUser> = {};
Expand Down
21 changes: 11 additions & 10 deletions libs/vre/shared/app-state/src/lib/projects/projects.state.ts
Expand Up @@ -38,6 +38,7 @@ import { ProjectsStateModel } from './projects.state-model';

const defaults: ProjectsStateModel = {
isLoading: false,
isMembershipLoading: false,
hasLoadingErrors: false,
allProjects: [],
projectMembers: {},
Expand Down Expand Up @@ -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 });
});
}
}
Expand All @@ -166,14 +167,14 @@ export class ProjectsState {

@Action(RemoveUserFromProjectAction)
removeUserFromProject(ctx: StateContext<ProjectsStateModel>, { 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<UserResponse> | ApiResponseError) => response as ApiResponseData<UserResponse>),
tap({
next: (response: ApiResponseData<UserResponse>) => {
ctx.dispatch([new SetUserAction(response.body.user), new LoadProjectMembersAction(projectIri)]);
ctx.patchState({ isLoading: false });
ctx.patchState({ isMembershipLoading: false });
},
error: error => {
this.errorHandler.showMessage(error);
Expand All @@ -187,14 +188,14 @@ export class ProjectsState {
ctx: StateContext<ProjectsStateModel>,
{ 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<UserResponse> | ApiResponseError) => response as ApiResponseData<UserResponse>),
tap({
next: (response: ApiResponseData<UserResponse>) => {
ctx.dispatch([new SetUserAction(response.body.user), new LoadProjectMembersAction(projectIri)]);
ctx.patchState({ isLoading: false });
ctx.patchState({ isMembershipLoading: false });
},
error: error => {
ctx.patchState({ hasLoadingErrors: true });
Expand All @@ -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),
Expand All @@ -222,7 +223,7 @@ export class ProjectsState {
next: (response: ApiResponseData<MembersResponse>) => {
ctx.setState({
...ctx.getState(),
isLoading: false,
isMembershipLoading: false,
projectMembers: {
[projectIri]: { value: response.body.members },
},
Expand All @@ -238,7 +239,7 @@ export class ProjectsState {

@Action(LoadProjectGroupsAction)
loadProjectGroupsAction(ctx: StateContext<ProjectsStateModel>) {
ctx.patchState({ isLoading: true });
ctx.patchState({ isMembershipLoading: true });
return this._dspApiConnection.admin.groupsEndpoint.getGroups().pipe(
take(1),
map(
Expand All @@ -259,7 +260,7 @@ export class ProjectsState {

ctx.setState({
...ctx.getState(),
isLoading: false,
isMembershipLoading: false,
projectGroups: groups,
});
},
Expand Down

0 comments on commit b4bd34b

Please sign in to comment.