Skip to content

Commit ea220e8

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

File tree

5 files changed

+89
-45
lines changed

5 files changed

+89
-45
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
@@ -75,7 +75,7 @@ import { CdkTextareaAutosize } from '@angular/cdk/text-field';
7575
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
7676
import { ActivatedRoute, Router } from '@angular/router';
7777
import { ToastContainerDirective, ToastrService } from 'ngx-toastr';
78-
import { finalize, Subscription } from 'rxjs';
78+
import { finalize, map, Subscription, switchMap } from 'rxjs';
7979
import { FileService } from '../core/services/file.service';
8080
import { ToggleSidenavService } from '../core/services/toggle-sidenav.service';
8181
import { FileNode, FileNodeInsertAttributeParams, FileNodeInsertParams } from '../models/file-node';
@@ -110,6 +110,7 @@ export class MainComponent implements OnInit, OnDestroy {
110110
uploadedProfileSelected: ProfileDescription;
111111

112112
private _routeParamsSubscription: Subscription;
113+
private _profileLoadingSubscription: Subscription;
113114

114115
constructor(
115116
public fileService: FileService,
@@ -121,9 +122,6 @@ export class MainComponent implements OnInit, OnDestroy {
121122
private loaderService: NgxUiLoaderService,
122123
private router: Router,
123124
) {
124-
this.uploadedProfileResponse = this.router.getCurrentNavigation().extras.state as ProfileResponse;
125-
this.uploadedProfileSelected = this.router.getCurrentNavigation().extras.state as ProfileDescription;
126-
127125
this.sideNavService.isOpened.subscribe((status) => {
128126
this.opened = status;
129127
});
@@ -137,29 +135,20 @@ export class MainComponent implements OnInit, OnDestroy {
137135
this.toastrService.overlayContainer = this.toastContainer;
138136
this._routeParamsSubscription = this.route.params.subscribe((params) => {
139137
const profileId = params.id;
138+
140139
// If a profileId has been defined, it is retrieved from backend
141140
if (profileId !== undefined) {
142-
if (this.uploadedProfileSelected === undefined) {
143-
this.router.navigate(['/pastis/tenant/1'], { skipLocationChange: false });
144-
} else {
145-
this.fileService.getProfileAndUpdateTree(this.uploadedProfileSelected);
146-
}
141+
this.loadProfileById(profileId);
147142
} else {
148-
// Otherwise we must have an user uploaded profile
149-
this.uploadedProfileResponse.id = null;
150-
151-
this.loaderService.start();
152-
this.profileService
153-
.getMetaModel(this.uploadedProfileResponse.sedaVersion)
154-
.pipe(
155-
tap((metaModel) => {
156-
this.sedaService.setMetaModel(metaModel);
157-
this.fileService.linkFileNodeToSedaData(null, [this.uploadedProfileResponse.profile]);
158-
this.fileService.updateTreeWithProfile(this.uploadedProfileResponse);
159-
}),
160-
finalize(() => this.loaderService.stop()),
161-
)
162-
.subscribe();
143+
// Check for query params to create a new profile
144+
this.route.queryParams.subscribe((queryParams) => {
145+
if (queryParams['type'] && queryParams['version']) {
146+
this.createNewProfile(queryParams['type'], queryParams['version']);
147+
} else {
148+
// No valid params, redirect to list
149+
this.router.navigate(['/'], { skipLocationChange: false });
150+
}
151+
});
163152
}
164153
});
165154
this.opened = true;
@@ -197,6 +186,55 @@ export class MainComponent implements OnInit, OnDestroy {
197186
if (this._routeParamsSubscription != null) {
198187
this._routeParamsSubscription.unsubscribe();
199188
}
189+
if (this._profileLoadingSubscription != null) {
190+
this._profileLoadingSubscription.unsubscribe();
191+
}
200192
if (this.pendingSub) this.pendingSub.unsubscribe();
201193
}
194+
195+
private loadProfileById(profileId: string) {
196+
// Unsubscribe from previous profile loading to avoid multiple concurrent requests
197+
if (this._profileLoadingSubscription != null) {
198+
this._profileLoadingSubscription.unsubscribe();
199+
}
200+
201+
// Subscribe to profiles list
202+
this._profileLoadingSubscription = this.profileService.retrievedProfiles.subscribe((profiles) => {
203+
if (!profiles || profiles.length === 0) {
204+
// Profiles not loaded yet, refresh the list
205+
this.profileService.refreshListProfiles();
206+
return;
207+
}
208+
209+
// Find the profile in the list
210+
const profileDescription = profiles.find((p) => p.id === profileId);
211+
if (profileDescription) {
212+
this.fileService.getProfileAndUpdateTree(profileDescription);
213+
} else {
214+
this.router.navigate(['/'], { skipLocationChange: false });
215+
}
216+
});
217+
}
218+
219+
private createNewProfile(profileType: string, profileVersion: string) {
220+
this.loaderService.start();
221+
this.profileService
222+
.createProfile('/pastis/profile', profileType as any, profileVersion as any)
223+
.pipe(
224+
tap((profileResponse) => {
225+
this.uploadedProfileResponse = profileResponse;
226+
this.uploadedProfileResponse.id = null;
227+
}),
228+
switchMap((profileResponse) =>
229+
this.profileService.getMetaModel(profileResponse.sedaVersion).pipe(map((metaModel) => ({ profileResponse, metaModel }))),
230+
),
231+
tap(({ profileResponse, metaModel }) => {
232+
this.sedaService.setMetaModel(metaModel);
233+
this.fileService.linkFileNodeToSedaData(null, [profileResponse.profile]);
234+
this.fileService.updateTreeWithProfile(profileResponse);
235+
}),
236+
finalize(() => this.loaderService.stop()),
237+
)
238+
.subscribe();
239+
}
202240
}

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
@@ -40,7 +40,7 @@
4040
type="file"
4141
/>
4242
</button>
43-
<pastis-popup-option *ngIf="!isStandalone" [sedaUrl]="sedaUrl" [newProfileUrl]="newProfileUrl"></pastis-popup-option>
43+
<pastis-popup-option *ngIf="!isStandalone" [sedaUrl]="sedaUrl"></pastis-popup-option>
4444
</vitamui-common-banner>
4545
</div>
4646

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';
@@ -135,9 +134,6 @@ export class ListProfileComponent extends SidenavPage<ProfileDescription> implem
135134

136135
sedaUrl: string =
137136
this.pastisConfig.pastisPathPrefix + (this.isStandalone ? '' : this.startupService.getTenantIdentifier()) + this.pastisConfig.sedaUrl;
138-
139-
newProfileUrl: string = this.pastisConfig.pastisNewProfile;
140-
141137
subscription1$: Subscription;
142138
_uploadProfileSub: Subscription;
143139
subscriptions: Subscription[] = [];
@@ -252,8 +248,7 @@ export class ListProfileComponent extends SidenavPage<ProfileDescription> implem
252248

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

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,11 @@ export class PastisPopupOptionComponent implements OnInit, OnDestroy {
150150
const formData = new FormData();
151151
formData.append('file', fileToUpload, fileToUpload.name);
152152
this.profileService.uploadProfile(formData).subscribe((response: any) => {
153-
if (response) {
154-
this.router.navigate([this.newProfileUrl], { state: response, relativeTo: this.route });
153+
if (response && response.id) {
154+
// Navigate to edit page with the profile ID
155+
this.router.navigate(['edit', response.id], {
156+
relativeTo: this.route,
157+
});
155158
}
156159
});
157160
}

0 commit comments

Comments
 (0)