Skip to content

Commit 2828fff

Browse files
author
Salim Terres
committed
Bug #13947 [Pastis] Display issue after refreshing in creation mode on the Documentary Profiles app.
1 parent cf5778e commit 2828fff

File tree

5 files changed

+89
-47
lines changed

5 files changed

+89
-47
lines changed

ui/ui-frontend/projects/pastis/src/app/core/services/file.service.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ export class FileService implements OnDestroy {
133133
* Get profile from backend with id
134134
*/
135135
getProfileAndUpdateTree(element: ProfileDescription) {
136+
// Cancel previous request if still pending to avoid data race conditions
137+
if (this._profileServiceGetProfileSubscription != null) {
138+
this._profileServiceGetProfileSubscription.unsubscribe();
139+
}
140+
136141
this.loaderService.start();
137142
this._profileServiceGetProfileSubscription = this.profileService
138143
.getProfile(element)

ui/ui-frontend/projects/pastis/src/app/main/main.component.ts

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ knowledge of the CeCILL-C license and that you accept its terms.
7474
import { CdkTextareaAutosize } from '@angular/cdk/text-field';
7575
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
7676
import { ActivatedRoute, Router } from '@angular/router';
77-
import { finalize, Subscription } from 'rxjs';
77+
import { finalize, map, Subscription, switchMap } from 'rxjs';
7878
import { FileService } from '../core/services/file.service';
7979
import { ToggleSidenavService } from '../core/services/toggle-sidenav.service';
8080
import { FileNode, FileNodeInsertAttributeParams, FileNodeInsertParams } from '../models/file-node';
@@ -108,6 +108,7 @@ export class MainComponent implements OnInit, OnDestroy {
108108
uploadedProfileSelected: ProfileDescription;
109109

110110
private _routeParamsSubscription: Subscription;
111+
private _profileLoadingSubscription: Subscription;
111112

112113
constructor(
113114
public fileService: FileService,
@@ -118,9 +119,6 @@ export class MainComponent implements OnInit, OnDestroy {
118119
private loaderService: NgxUiLoaderService,
119120
private router: Router,
120121
) {
121-
this.uploadedProfileResponse = this.router.getCurrentNavigation().extras.state as ProfileResponse;
122-
this.uploadedProfileSelected = this.router.getCurrentNavigation().extras.state as ProfileDescription;
123-
124122
this.sideNavService.isOpened.subscribe((status) => {
125123
this.opened = status;
126124
});
@@ -133,29 +131,20 @@ export class MainComponent implements OnInit, OnDestroy {
133131
this.fileService.currentTreeLoaded = false;
134132
this._routeParamsSubscription = this.route.params.subscribe((params) => {
135133
const profileId = params.id;
134+
136135
// If a profileId has been defined, it is retrieved from backend
137136
if (profileId !== undefined) {
138-
if (this.uploadedProfileSelected === undefined) {
139-
this.router.navigate(['/pastis/tenant/1'], { skipLocationChange: false });
140-
} else {
141-
this.fileService.getProfileAndUpdateTree(this.uploadedProfileSelected);
142-
}
137+
this.loadProfileById(profileId);
143138
} else {
144-
// Otherwise we must have an user uploaded profile
145-
this.uploadedProfileResponse.id = null;
146-
147-
this.loaderService.start();
148-
this.profileService
149-
.getMetaModel(this.uploadedProfileResponse.sedaVersion)
150-
.pipe(
151-
tap((metaModel) => {
152-
this.sedaService.setMetaModel(metaModel);
153-
this.fileService.linkFileNodeToSedaData(null, [this.uploadedProfileResponse.profile]);
154-
this.fileService.updateTreeWithProfile(this.uploadedProfileResponse);
155-
}),
156-
finalize(() => this.loaderService.stop()),
157-
)
158-
.subscribe();
139+
// Check for query params to create a new profile
140+
this.route.queryParams.subscribe((queryParams) => {
141+
if (queryParams['type'] && queryParams['version']) {
142+
this.createNewProfile(queryParams['type'], queryParams['version']);
143+
} else {
144+
// No valid params, redirect to list
145+
this.router.navigate(['/'], { skipLocationChange: false });
146+
}
147+
});
159148
}
160149
});
161150
this.opened = true;
@@ -193,6 +182,55 @@ export class MainComponent implements OnInit, OnDestroy {
193182
if (this._routeParamsSubscription != null) {
194183
this._routeParamsSubscription.unsubscribe();
195184
}
185+
if (this._profileLoadingSubscription != null) {
186+
this._profileLoadingSubscription.unsubscribe();
187+
}
196188
if (this.pendingSub) this.pendingSub.unsubscribe();
197189
}
190+
191+
private loadProfileById(profileId: string) {
192+
// Unsubscribe from previous profile loading to avoid multiple concurrent requests
193+
if (this._profileLoadingSubscription != null) {
194+
this._profileLoadingSubscription.unsubscribe();
195+
}
196+
197+
// Subscribe to profiles list
198+
this._profileLoadingSubscription = this.profileService.retrievedProfiles.subscribe((profiles) => {
199+
if (!profiles || profiles.length === 0) {
200+
// Profiles not loaded yet, refresh the list
201+
this.profileService.refreshListProfiles();
202+
return;
203+
}
204+
205+
// Find the profile in the list
206+
const profileDescription = profiles.find((p) => p.id === profileId);
207+
if (profileDescription) {
208+
this.fileService.getProfileAndUpdateTree(profileDescription);
209+
} else {
210+
this.router.navigate(['/'], { skipLocationChange: false });
211+
}
212+
});
213+
}
214+
215+
private createNewProfile(profileType: string, profileVersion: string) {
216+
this.loaderService.start();
217+
this.profileService
218+
.createProfile('/pastis/profile', profileType as any, profileVersion as any)
219+
.pipe(
220+
tap((profileResponse) => {
221+
this.uploadedProfileResponse = profileResponse;
222+
this.uploadedProfileResponse.id = null;
223+
}),
224+
switchMap((profileResponse) =>
225+
this.profileService.getMetaModel(profileResponse.sedaVersion).pipe(map((metaModel) => ({ profileResponse, metaModel }))),
226+
),
227+
tap(({ profileResponse, metaModel }) => {
228+
this.sedaService.setMetaModel(metaModel);
229+
this.fileService.linkFileNodeToSedaData(null, [profileResponse.profile]);
230+
this.fileService.updateTreeWithProfile(profileResponse);
231+
}),
232+
finalize(() => this.loaderService.stop()),
233+
)
234+
.subscribe();
235+
}
198236
}

ui/ui-frontend/projects/pastis/src/app/profile/list-profile/list-profile.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ <h5>{{ 'APPLICATION.PASTIS_APP.TITLE' | translate }}</h5>
3737
type="file"
3838
/>
3939
</button>
40-
<pastis-popup-option *ngIf="!isStandalone" [sedaUrl]="sedaUrl" [newProfileUrl]="newProfileUrl"></pastis-popup-option>
40+
<pastis-popup-option *ngIf="!isStandalone" [sedaUrl]="sedaUrl"></pastis-popup-option>
4141
</vitamui-banner>
4242
</div>
4343

ui/ui-frontend/projects/pastis/src/app/profile/list-profile/list-profile.component.ts

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ import { ProfileService } from '../../core/services/profile.service';
8484
import { ToggleSidenavService } from '../../core/services/toggle-sidenav.service';
8585
import { BreadcrumbDataTop } from '../../models/breadcrumb';
8686
import { ProfileDescription } from '../../models/profile-description.model';
87-
import { ProfileResponse } from '../../models/profile-response';
8887
import { DataGeneriquePopupService } from '../../shared/data-generique-popup.service';
8988
import { PastisDialogData } from '../../shared/pastis-dialog/classes/pastis-dialog-data';
9089
import { CreateProfileComponent, CreateProfileFormResult } from '../create-profile/create-profile.component';
@@ -134,9 +133,6 @@ export class ListProfileComponent extends SidenavPage<ProfileDescription> implem
134133

135134
sedaUrl: string =
136135
this.pastisConfig.pastisPathPrefix + (this.isStandalone ? '' : this.startupService.getTenantIdentifier()) + this.pastisConfig.sedaUrl;
137-
138-
newProfileUrl: string = this.pastisConfig.pastisNewProfile;
139-
140136
subscription1$: Subscription;
141137
_uploadProfileSub: Subscription;
142138
subscriptions: Subscription[] = [];
@@ -251,8 +247,7 @@ export class ListProfileComponent extends SidenavPage<ProfileDescription> implem
251247

252248
editProfile(element: ProfileDescription) {
253249
this.profileService.controlSchema.next(element?.controlSchema);
254-
this.router.navigate([this.pastisConfig.pastisEditPage, element.id], {
255-
state: element,
250+
this.router.navigate(['edit', element.id], {
256251
relativeTo: this.route,
257252
skipLocationChange: false,
258253
});
@@ -265,8 +260,11 @@ export class ListProfileComponent extends SidenavPage<ProfileDescription> implem
265260
const formData = new FormData();
266261
formData.append('file', fileToUpload, fileToUpload.name);
267262
this._uploadProfileSub = this.profileService.uploadProfile(formData).subscribe((response: any) => {
268-
if (response) {
269-
this.router.navigate([this.pastisConfig.pastisNewProfile], { state: response, relativeTo: this.route });
263+
if (response && response.id) {
264+
// Navigate to edit page with the profile ID
265+
this.router.navigate(['edit', response.id], {
266+
relativeTo: this.route,
267+
});
270268
}
271269
});
272270
this.subscriptions.push(this._uploadProfileSub);
@@ -289,16 +287,16 @@ export class ListProfileComponent extends SidenavPage<ProfileDescription> implem
289287
const dialogRef = this.dialog.open(CreateProfileComponent, createProfileDialogConfig);
290288
const subscription = dialogRef
291289
.afterClosed()
292-
.pipe(
293-
filter<CreateProfileFormResult>((result) => Boolean(result)),
294-
switchMap((result) =>
295-
this.profileService.createProfile(this.pastisConfig.createProfileByTypeUrl, result.profileType, result.profileVersion),
296-
),
297-
filter<ProfileResponse>((profileResponse) => Boolean(profileResponse)),
298-
)
299-
.subscribe((profileResponse) =>
300-
this.router.navigate([this.pastisConfig.pastisNewProfile], { state: profileResponse, relativeTo: this.route }),
301-
);
290+
.pipe(filter<CreateProfileFormResult>((result) => Boolean(result)))
291+
.subscribe((result) => {
292+
this.router.navigate(['new'], {
293+
queryParams: {
294+
type: result.profileType,
295+
version: result.profileVersion,
296+
},
297+
relativeTo: this.route,
298+
});
299+
});
302300
this.subscriptions.push(subscription);
303301
}
304302

ui/ui-frontend/projects/pastis/src/app/shared/pastis-popup-option/pastis-popup-option.component.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,6 @@ export class PastisPopupOptionComponent implements OnInit, OnDestroy {
102102
@Input()
103103
sedaUrl: string;
104104
@Input()
105-
newProfileUrl: string;
106-
@Input()
107105
uploader: FileUploader = new FileUploader({ url: '' });
108106

109107
expanded = false;
@@ -145,8 +143,11 @@ export class PastisPopupOptionComponent implements OnInit, OnDestroy {
145143
const formData = new FormData();
146144
formData.append('file', fileToUpload, fileToUpload.name);
147145
this.profileService.uploadProfile(formData).subscribe((response: any) => {
148-
if (response) {
149-
this.router.navigate([this.newProfileUrl], { state: response, relativeTo: this.route });
146+
if (response && response.id) {
147+
// Navigate to edit page with the profile ID
148+
this.router.navigate(['edit', response.id], {
149+
relativeTo: this.route,
150+
});
150151
}
151152
});
152153
}

0 commit comments

Comments
 (0)