Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ export class FileService implements OnDestroy {
* Get profile from backend with id
*/
getProfileAndUpdateTree(element: ProfileDescription) {
// Cancel previous request if still pending to avoid data race conditions
if (this._profileServiceGetProfileSubscription != null) {
this._profileServiceGetProfileSubscription.unsubscribe();
}

this.loaderService.start();
this._profileServiceGetProfileSubscription = this.profileService
.getProfile(element)
Expand Down
86 changes: 62 additions & 24 deletions ui/ui-frontend/projects/pastis/src/app/main/main.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ knowledge of the CeCILL-C license and that you accept its terms.
import { CdkTextareaAutosize } from '@angular/cdk/text-field';
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { finalize, Subscription } from 'rxjs';
import { finalize, map, Subscription, switchMap } from 'rxjs';
import { FileService } from '../core/services/file.service';
import { ToggleSidenavService } from '../core/services/toggle-sidenav.service';
import { FileNode, FileNodeInsertAttributeParams, FileNodeInsertParams } from '../models/file-node';
Expand Down Expand Up @@ -108,6 +108,7 @@ export class MainComponent implements OnInit, OnDestroy {
uploadedProfileSelected: ProfileDescription;

private _routeParamsSubscription: Subscription;
private _profileLoadingSubscription: Subscription;

constructor(
public fileService: FileService,
Expand All @@ -118,9 +119,6 @@ export class MainComponent implements OnInit, OnDestroy {
private loaderService: NgxUiLoaderService,
private router: Router,
) {
this.uploadedProfileResponse = this.router.getCurrentNavigation().extras.state as ProfileResponse;
this.uploadedProfileSelected = this.router.getCurrentNavigation().extras.state as ProfileDescription;

this.sideNavService.isOpened.subscribe((status) => {
this.opened = status;
});
Expand All @@ -133,29 +131,20 @@ export class MainComponent implements OnInit, OnDestroy {
this.fileService.currentTreeLoaded = false;
this._routeParamsSubscription = this.route.params.subscribe((params) => {
const profileId = params.id;

// If a profileId has been defined, it is retrieved from backend
if (profileId !== undefined) {
if (this.uploadedProfileSelected === undefined) {
this.router.navigate(['/pastis/tenant/1'], { skipLocationChange: false });
} else {
this.fileService.getProfileAndUpdateTree(this.uploadedProfileSelected);
}
this.loadProfileById(profileId);
} else {
// Otherwise we must have an user uploaded profile
this.uploadedProfileResponse.id = null;

this.loaderService.start();
this.profileService
.getMetaModel(this.uploadedProfileResponse.sedaVersion)
.pipe(
tap((metaModel) => {
this.sedaService.setMetaModel(metaModel);
this.fileService.linkFileNodeToSedaData(null, [this.uploadedProfileResponse.profile]);
this.fileService.updateTreeWithProfile(this.uploadedProfileResponse);
}),
finalize(() => this.loaderService.stop()),
)
.subscribe();
// Check for query params to create a new profile
this.route.queryParams.subscribe((queryParams) => {
if (queryParams['type'] && queryParams['version']) {
this.createNewProfile(queryParams['type'], queryParams['version']);
} else {
// No valid params, redirect to list
this.router.navigate(['/'], { skipLocationChange: false });
}
});
}
});
this.opened = true;
Expand Down Expand Up @@ -193,6 +182,55 @@ export class MainComponent implements OnInit, OnDestroy {
if (this._routeParamsSubscription != null) {
this._routeParamsSubscription.unsubscribe();
}
if (this._profileLoadingSubscription != null) {
this._profileLoadingSubscription.unsubscribe();
}
if (this.pendingSub) this.pendingSub.unsubscribe();
}

private loadProfileById(profileId: string) {
// Unsubscribe from previous profile loading to avoid multiple concurrent requests
if (this._profileLoadingSubscription != null) {
this._profileLoadingSubscription.unsubscribe();
}

// Subscribe to profiles list
this._profileLoadingSubscription = this.profileService.retrievedProfiles.subscribe((profiles) => {
if (!profiles || profiles.length === 0) {
// Profiles not loaded yet, refresh the list
this.profileService.refreshListProfiles();
return;
}

// Find the profile in the list
const profileDescription = profiles.find((p) => p.id === profileId);
if (profileDescription) {
this.fileService.getProfileAndUpdateTree(profileDescription);
} else {
this.router.navigate(['/'], { skipLocationChange: false });
}
});
}

private createNewProfile(profileType: string, profileVersion: string) {
this.loaderService.start();
this.profileService
.createProfile('/pastis/profile', profileType as any, profileVersion as any)
.pipe(
tap((profileResponse) => {
this.uploadedProfileResponse = profileResponse;
this.uploadedProfileResponse.id = null;
}),
switchMap((profileResponse) =>
this.profileService.getMetaModel(profileResponse.sedaVersion).pipe(map((metaModel) => ({ profileResponse, metaModel }))),
),
tap(({ profileResponse, metaModel }) => {
this.sedaService.setMetaModel(metaModel);
this.fileService.linkFileNodeToSedaData(null, [profileResponse.profile]);
this.fileService.updateTreeWithProfile(profileResponse);
}),
finalize(() => this.loaderService.stop()),
)
.subscribe();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ <h5>{{ 'APPLICATION.PASTIS_APP.TITLE' | translate }}</h5>
type="file"
/>
</button>
<pastis-popup-option *ngIf="!isStandalone" [sedaUrl]="sedaUrl" [newProfileUrl]="newProfileUrl"></pastis-popup-option>
<pastis-popup-option *ngIf="!isStandalone" [sedaUrl]="sedaUrl"></pastis-popup-option>
</vitamui-banner>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ import { ProfileService } from '../../core/services/profile.service';
import { ToggleSidenavService } from '../../core/services/toggle-sidenav.service';
import { BreadcrumbDataTop } from '../../models/breadcrumb';
import { ProfileDescription } from '../../models/profile-description.model';
import { ProfileResponse } from '../../models/profile-response';
import { DataGeneriquePopupService } from '../../shared/data-generique-popup.service';
import { PastisDialogData } from '../../shared/pastis-dialog/classes/pastis-dialog-data';
import { CreateProfileComponent, CreateProfileFormResult } from '../create-profile/create-profile.component';
Expand Down Expand Up @@ -134,9 +133,6 @@ export class ListProfileComponent extends SidenavPage<ProfileDescription> implem

sedaUrl: string =
this.pastisConfig.pastisPathPrefix + (this.isStandalone ? '' : this.startupService.getTenantIdentifier()) + this.pastisConfig.sedaUrl;

newProfileUrl: string = this.pastisConfig.pastisNewProfile;

subscription1$: Subscription;
_uploadProfileSub: Subscription;
subscriptions: Subscription[] = [];
Expand Down Expand Up @@ -251,8 +247,7 @@ export class ListProfileComponent extends SidenavPage<ProfileDescription> implem

editProfile(element: ProfileDescription) {
this.profileService.controlSchema.next(element?.controlSchema);
this.router.navigate([this.pastisConfig.pastisEditPage, element.id], {
state: element,
this.router.navigate(['edit', element.id], {
relativeTo: this.route,
skipLocationChange: false,
});
Expand All @@ -265,8 +260,11 @@ export class ListProfileComponent extends SidenavPage<ProfileDescription> implem
const formData = new FormData();
formData.append('file', fileToUpload, fileToUpload.name);
this._uploadProfileSub = this.profileService.uploadProfile(formData).subscribe((response: any) => {
if (response) {
this.router.navigate([this.pastisConfig.pastisNewProfile], { state: response, relativeTo: this.route });
if (response && response.id) {
// Navigate to edit page with the profile ID
this.router.navigate(['edit', response.id], {
relativeTo: this.route,
});
}
});
this.subscriptions.push(this._uploadProfileSub);
Expand All @@ -289,16 +287,16 @@ export class ListProfileComponent extends SidenavPage<ProfileDescription> implem
const dialogRef = this.dialog.open(CreateProfileComponent, createProfileDialogConfig);
const subscription = dialogRef
.afterClosed()
.pipe(
filter<CreateProfileFormResult>((result) => Boolean(result)),
switchMap((result) =>
this.profileService.createProfile(this.pastisConfig.createProfileByTypeUrl, result.profileType, result.profileVersion),
),
filter<ProfileResponse>((profileResponse) => Boolean(profileResponse)),
)
.subscribe((profileResponse) =>
this.router.navigate([this.pastisConfig.pastisNewProfile], { state: profileResponse, relativeTo: this.route }),
);
.pipe(filter<CreateProfileFormResult>((result) => Boolean(result)))
.subscribe((result) => {
this.router.navigate(['new'], {
queryParams: {
type: result.profileType,
version: result.profileVersion,
},
relativeTo: this.route,
});
});
this.subscriptions.push(subscription);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,11 @@ export class PastisPopupOptionComponent implements OnInit, OnDestroy {
const formData = new FormData();
formData.append('file', fileToUpload, fileToUpload.name);
this.profileService.uploadProfile(formData).subscribe((response: any) => {
if (response) {
this.router.navigate([this.newProfileUrl], { state: response, relativeTo: this.route });
if (response && response.id) {
// Navigate to edit page with the profile ID
this.router.navigate(['edit', response.id], {
relativeTo: this.route,
});
}
});
}
Expand Down
Loading