Skip to content

Commit ede02f8

Browse files
authored
Feat(project-redirect-modal): added project redirect modal (#350)
* fix(add-project-redirect-modal): added project redirect modal * refactor(add-project-redirect-modal): added pipe to the modal subscription
1 parent ac6e1ed commit ede02f8

File tree

8 files changed

+73
-21
lines changed

8 files changed

+73
-21
lines changed

src/app/features/home/pages/dashboard/dashboard.component.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Button } from 'primeng/button';
77
import { DialogService, DynamicDialogRef } from 'primeng/dynamicdialog';
88
import { TablePageEvent } from 'primeng/table';
99

10-
import { debounceTime, distinctUntilChanged } from 'rxjs';
10+
import { debounceTime, distinctUntilChanged, filter, tap } from 'rxjs';
1111

1212
import { Component, computed, DestroyRef, effect, inject, OnInit, signal } from '@angular/core';
1313
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
@@ -20,6 +20,7 @@ import { MY_PROJECTS_TABLE_PARAMS } from '@osf/shared/constants';
2020
import { SortOrder } from '@osf/shared/enums';
2121
import { IS_MEDIUM } from '@osf/shared/helpers';
2222
import { MyResourcesItem, MyResourcesSearchFilters, TableParameters } from '@osf/shared/models';
23+
import { ProjectRedirectDialogService } from '@osf/shared/services';
2324
import { ClearMyResources, GetMyProjects, MyResourcesSelectors } from '@osf/shared/stores';
2425

2526
@Component({
@@ -35,6 +36,7 @@ export class DashboardComponent implements OnInit {
3536
private readonly route = inject(ActivatedRoute);
3637
private readonly translateService = inject(TranslateService);
3738
private readonly dialogService = inject(DialogService);
39+
private readonly projectRedirectDialogService = inject(ProjectRedirectDialogService);
3840

3941
readonly isMedium = toSignal(inject(IS_MEDIUM));
4042

@@ -175,13 +177,20 @@ export class DashboardComponent implements OnInit {
175177
createProject(): void {
176178
const dialogWidth = this.isMedium() ? '850px' : '95vw';
177179

178-
this.dialogService.open(CreateProjectDialogComponent, {
179-
width: dialogWidth,
180-
focusOnShow: false,
181-
header: this.translateService.instant('myProjects.header.createProject'),
182-
closeOnEscape: true,
183-
modal: true,
184-
closable: true,
185-
});
180+
this.dialogService
181+
.open(CreateProjectDialogComponent, {
182+
width: dialogWidth,
183+
focusOnShow: false,
184+
header: this.translateService.instant('myProjects.header.createProject'),
185+
closeOnEscape: true,
186+
modal: true,
187+
closable: true,
188+
})
189+
.onClose.pipe(
190+
filter((result) => result.project.id),
191+
tap((result) => this.projectRedirectDialogService.showProjectRedirectDialog(result.project.id)),
192+
takeUntilDestroyed(this.destroyRef)
193+
)
194+
.subscribe();
186195
}
187196
}

src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createDispatchMap, select } from '@ngxs/store';
1+
import { createDispatchMap, select, Store } from '@ngxs/store';
22

33
import { TranslatePipe } from '@ngx-translate/core';
44

@@ -24,6 +24,7 @@ import { CreateProject, GetMyProjects, MyResourcesSelectors } from '@osf/shared/
2424
})
2525
export class CreateProjectDialogComponent {
2626
readonly dialogRef = inject(DynamicDialogRef);
27+
private readonly store = inject(Store);
2728

2829
private actions = createDispatchMap({
2930
getMyProjects: GetMyProjects,
@@ -70,8 +71,10 @@ export class CreateProjectDialogComponent {
7071
)
7172
.subscribe({
7273
next: () => {
74+
const projects = this.store.selectSnapshot(MyResourcesSelectors.getProjects);
75+
const newProject = projects[0];
7376
this.actions.getMyProjects(1, MY_PROJECTS_TABLE_PARAMS.rows, {});
74-
this.dialogRef.close();
77+
this.dialogRef.close({ project: newProject });
7578
},
7679
});
7780
}

src/app/features/my-projects/my-projects.component.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { DialogService } from 'primeng/dynamicdialog';
77
import { TablePageEvent } from 'primeng/table';
88
import { Tab, TabList, TabPanel, TabPanels, Tabs } from 'primeng/tabs';
99

10-
import { debounceTime, distinctUntilChanged } from 'rxjs';
10+
import { debounceTime, distinctUntilChanged, filter, tap } from 'rxjs';
1111

1212
import {
1313
ChangeDetectionStrategy,
@@ -38,6 +38,7 @@ import {
3838
GetMyRegistrations,
3939
MyResourcesSelectors,
4040
} from '@osf/shared/stores';
41+
import { ProjectRedirectDialogService } from '@shared/services';
4142

4243
import { CreateProjectDialogComponent } from './components';
4344
import { MY_PROJECTS_TABS } from './constants';
@@ -68,6 +69,7 @@ export class MyProjectsComponent implements OnInit {
6869
readonly router = inject(Router);
6970
readonly route = inject(ActivatedRoute);
7071
readonly translateService = inject(TranslateService);
72+
readonly projectRedirectDialogService = inject(ProjectRedirectDialogService);
7173

7274
readonly isLoading = signal(false);
7375
readonly isTablet = toSignal(inject(IS_MEDIUM));
@@ -326,14 +328,21 @@ export class MyProjectsComponent implements OnInit {
326328
createProject(): void {
327329
const dialogWidth = this.isTablet() ? '850px' : '95vw';
328330

329-
this.dialogService.open(CreateProjectDialogComponent, {
330-
width: dialogWidth,
331-
focusOnShow: false,
332-
header: this.translateService.instant('myProjects.header.createProject'),
333-
closeOnEscape: true,
334-
modal: true,
335-
closable: true,
336-
});
331+
this.dialogService
332+
.open(CreateProjectDialogComponent, {
333+
width: dialogWidth,
334+
focusOnShow: false,
335+
header: this.translateService.instant('myProjects.header.createProject'),
336+
closeOnEscape: true,
337+
modal: true,
338+
closable: true,
339+
})
340+
.onClose.pipe(
341+
filter((result) => result.project.id),
342+
tap((result) => this.projectRedirectDialogService.showProjectRedirectDialog(result.project.id)),
343+
takeUntilDestroyed(this.destroyRef)
344+
)
345+
.subscribe();
337346
}
338347

339348
navigateToProject(project: MyResourcesItem): void {

src/app/shared/models/confirmation-options.model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export interface AcceptConfirmationOptions {
1818
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1919
messageParams?: any;
2020
acceptLabelKey?: string;
21+
rejectLabelKey?: string;
2122
onConfirm: () => void;
2223
onReject?: () => void;
2324
}

src/app/shared/services/custom-confirmation.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export class CustomConfirmationService {
4343
label: this.translateService.instant(options.acceptLabelKey || 'common.buttons.move'),
4444
},
4545
rejectButtonProps: {
46-
label: this.translateService.instant('common.buttons.cancel'),
46+
label: this.translateService.instant(options.rejectLabelKey || 'common.buttons.cancel'),
4747
severity: 'info',
4848
},
4949
accept: () => {

src/app/shared/services/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export { LoaderService } from './loader.service';
1515
export { MetaTagsService } from './meta-tags.service';
1616
export { MyResourcesService } from './my-resources.service';
1717
export { NodeLinksService } from './node-links.service';
18+
export { ProjectRedirectDialogService } from './project-redirect-dialog.service';
1819
export { RegionsService } from './regions.service';
1920
export { ResourceGuidService } from './resource.service';
2021
export { ResourceCardService } from './resource-card.service';
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { inject, Injectable } from '@angular/core';
2+
import { Router } from '@angular/router';
3+
4+
import { CustomConfirmationService } from './custom-confirmation.service';
5+
6+
@Injectable({
7+
providedIn: 'root',
8+
})
9+
export class ProjectRedirectDialogService {
10+
private readonly confirmationService = inject(CustomConfirmationService);
11+
private readonly router = inject(Router);
12+
13+
showProjectRedirectDialog(projectId: string): void {
14+
this.confirmationService.confirmAccept({
15+
headerKey: 'myProjects.redirectDialog.header',
16+
messageKey: 'myProjects.redirectDialog.message',
17+
acceptLabelKey: 'myProjects.redirectDialog.confirmButton',
18+
rejectLabelKey: 'myProjects.redirectDialog.rejectButton',
19+
onConfirm: () => this.router.navigate(['/', projectId]),
20+
onReject: () => null,
21+
});
22+
}
23+
}

src/assets/i18n/en.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,12 @@
437437
},
438438
"updateProjectDetailsMessage": "Successfully updated project details.",
439439
"updateProjectSettingsMessage": "Successfully updated project settings."
440+
},
441+
"redirectDialog": {
442+
"header": "Success",
443+
"message": "New project created successfully!",
444+
"confirmButton": "Go to project",
445+
"rejectButton": "Keep working here"
440446
}
441447
},
442448
"myProfile": {

0 commit comments

Comments
 (0)