1
- import { select , Store } from '@ngxs/store' ;
1
+ import { createDispatchMap , select } from '@ngxs/store' ;
2
2
3
3
import { TranslatePipe } from '@ngx-translate/core' ;
4
4
5
- import { ButtonModule } from 'primeng/button' ;
6
- import { CheckboxModule } from 'primeng/checkbox' ;
7
- import { DropdownModule } from 'primeng/dropdown' ;
5
+ import { Button } from 'primeng/button' ;
6
+ import { Checkbox } from 'primeng/checkbox' ;
8
7
import { DynamicDialogRef } from 'primeng/dynamicdialog' ;
9
- import { InputTextModule } from 'primeng/inputtext' ;
8
+ import { InputText } from 'primeng/inputtext' ;
10
9
import { Select } from 'primeng/select' ;
11
10
import { Textarea } from 'primeng/textarea' ;
12
11
13
- import { CommonModule , NgOptimizedImage } from '@angular/common' ;
14
- import { ChangeDetectionStrategy , Component , DestroyRef , inject , OnInit } from '@angular/core' ;
15
- import { takeUntilDestroyed , toSignal } from '@angular/core/rxjs-interop' ;
12
+ import { ChangeDetectionStrategy , Component , DestroyRef , effect , inject , OnInit } from '@angular/core' ;
13
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop' ;
16
14
import { FormControl , FormGroup , ReactiveFormsModule , Validators } from '@angular/forms' ;
17
15
18
- import { STORAGE_LOCATIONS } from '@core/constants' ;
16
+ import { UserSelectors } from '@core/store/user' ;
17
+ import { AffiliatedInstitutionSelectComponent } from '@osf/shared/components' ;
19
18
import { ComponentFormControls } from '@osf/shared/enums' ;
20
- import { IS_XSMALL } from '@osf/shared/helpers' ;
21
- import { ComponentForm } from '@osf/shared/models' ;
19
+ import { CustomValidators } from '@osf/shared/helpers' ;
20
+ import { ComponentForm , Institution } from '@osf/shared/models' ;
22
21
import { ToastService } from '@osf/shared/services' ;
22
+ import { FetchRegions , RegionsSelectors } from '@osf/shared/stores' ;
23
23
24
24
import { CreateComponent , GetComponents , ProjectOverviewSelectors } from '../../store' ;
25
25
26
26
@Component ( {
27
27
selector : 'osf-add-component-dialog' ,
28
28
imports : [
29
- CommonModule ,
30
29
ReactiveFormsModule ,
31
- ButtonModule ,
32
- InputTextModule ,
33
- DropdownModule ,
34
- CheckboxModule ,
30
+ Button ,
31
+ InputText ,
32
+ Checkbox ,
35
33
Select ,
36
34
Textarea ,
37
- NgOptimizedImage ,
38
35
TranslatePipe ,
36
+ AffiliatedInstitutionSelectComponent ,
39
37
] ,
40
38
templateUrl : './add-component-dialog.component.html' ,
41
39
styleUrl : './add-component-dialog.component.scss' ,
42
40
changeDetection : ChangeDetectionStrategy . OnPush ,
43
41
} )
44
42
export class AddComponentDialogComponent implements OnInit {
45
- private store = inject ( Store ) ;
46
43
private readonly toastService = inject ( ToastService ) ;
47
44
48
- isMobile = toSignal ( inject ( IS_XSMALL ) ) ;
49
45
dialogRef = inject ( DynamicDialogRef ) ;
50
46
destroyRef = inject ( DestroyRef ) ;
51
47
ComponentFormControls = ComponentFormControls ;
52
- storageLocations = STORAGE_LOCATIONS ;
53
- isSubmitting = select ( ProjectOverviewSelectors . getComponentsSubmitting ) ;
54
- currentProject = this . store . selectSignal ( ProjectOverviewSelectors . getProject ) ;
55
48
56
- toggleAddContributors ( ) : void {
57
- const control = this . componentForm . get ( ComponentFormControls . AddContributors ) ;
58
- if ( control ) {
59
- control . setValue ( ! control . value ) ;
60
- }
61
- }
49
+ storageLocations = select ( RegionsSelectors . getRegions ) ;
50
+ currentUser = select ( UserSelectors . getCurrentUser ) ;
51
+ currentProject = select ( ProjectOverviewSelectors . getProject ) ;
52
+ areRegionsLoading = select ( RegionsSelectors . areRegionsLoading ) ;
53
+ isSubmitting = select ( ProjectOverviewSelectors . getComponentsSubmitting ) ;
62
54
63
- toggleAddTags ( ) : void {
64
- const control = this . componentForm . get ( ComponentFormControls . AddTags ) ;
65
- if ( control ) {
66
- control . setValue ( ! control . value ) ;
67
- }
68
- }
55
+ actions = createDispatchMap ( {
56
+ createComponent : CreateComponent ,
57
+ getComponents : GetComponents ,
58
+ getRegions : FetchRegions ,
59
+ } ) ;
69
60
70
61
componentForm = new FormGroup < ComponentForm > ( {
71
62
[ ComponentFormControls . Title ] : new FormControl ( '' , {
72
63
nonNullable : true ,
73
- validators : [ Validators . required ] ,
64
+ validators : [ CustomValidators . requiredTrimmed ( ) ] ,
74
65
} ) ,
75
- [ ComponentFormControls . StorageLocation ] : new FormControl ( 'us ' , {
66
+ [ ComponentFormControls . StorageLocation ] : new FormControl ( '' , {
76
67
nonNullable : true ,
77
68
validators : [ Validators . required ] ,
78
69
} ) ,
@@ -90,21 +81,27 @@ export class AddComponentDialogComponent implements OnInit {
90
81
} ) ,
91
82
} ) ;
92
83
93
- ngOnInit ( ) : void {
94
- this . selectAllAffiliations ( ) ;
84
+ constructor ( ) {
85
+ effect ( ( ) => {
86
+ const storageLocations = this . storageLocations ( ) ;
87
+ if ( ! storageLocations ) return ;
88
+
89
+ const defaultRegion = this . currentUser ( ) ?. defaultRegionId || storageLocations [ 0 ] . id ;
90
+ this . componentForm . controls [ ComponentFormControls . StorageLocation ] . setValue ( defaultRegion ) ;
91
+ } ) ;
95
92
}
96
93
97
- selectAllAffiliations ( ) : void {
98
- const allAffiliationValues = this . currentProject ( ) ?. affiliatedInstitutions ?. map ( ( aff ) => aff . id ) || [ ] ;
99
- this . componentForm . get ( ComponentFormControls . Affiliations ) ?. setValue ( allAffiliationValues ) ;
94
+ ngOnInit ( ) : void {
95
+ this . actions . getRegions ( ) ;
100
96
}
101
97
102
- removeAllAffiliations ( ) : void {
103
- this . componentForm . get ( ComponentFormControls . Affiliations ) ?. setValue ( [ ] ) ;
98
+ setSelectedInstitutions ( institutions : Institution [ ] ) {
99
+ const selectedValues = institutions . map ( ( inst ) => inst . id ) ;
100
+ this . componentForm . get ( ComponentFormControls . Affiliations ) ?. setValue ( selectedValues ) ;
104
101
}
105
102
106
103
submitForm ( ) : void {
107
- if ( ! this . componentForm . valid ) {
104
+ if ( this . componentForm . invalid ) {
108
105
this . componentForm . markAllAsTouched ( ) ;
109
106
return ;
110
107
}
@@ -118,23 +115,21 @@ export class AddComponentDialogComponent implements OnInit {
118
115
119
116
const tags = formValue . addTags ? project . tags : [ ] ;
120
117
121
- this . store
122
- . dispatch (
123
- new CreateComponent (
124
- project . id ,
125
- formValue . title ,
126
- formValue . description ,
127
- tags ,
128
- formValue . storageLocation ,
129
- formValue . affiliations ,
130
- formValue . addContributors
131
- )
118
+ this . actions
119
+ . createComponent (
120
+ project . id ,
121
+ formValue . title ,
122
+ formValue . description ,
123
+ tags ,
124
+ formValue . storageLocation ,
125
+ formValue . affiliations ,
126
+ formValue . addContributors
132
127
)
133
128
. pipe ( takeUntilDestroyed ( this . destroyRef ) )
134
129
. subscribe ( {
135
130
next : ( ) => {
136
131
this . dialogRef . close ( ) ;
137
- this . store . dispatch ( new GetComponents ( project . id ) ) ;
132
+ this . actions . getComponents ( project . id ) ;
138
133
this . toastService . showSuccess ( 'project.overview.dialog.toast.addComponent.success' ) ;
139
134
} ,
140
135
} ) ;
0 commit comments