@@ -23,9 +23,18 @@ import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
2323import { FormGroup } from '@angular/forms' ;
2424import { ActivatedRoute , Router , RouterLink } from '@angular/router' ;
2525
26+ import { ENVIRONMENT } from '@core/provider/environment.provider' ;
2627import { UserSelectors } from '@core/store/user' ;
28+ import { CedarMetadataRecordData , CedarRecordDataBinding } from '@osf/features/metadata/models' ;
29+ import {
30+ CreateCedarMetadataRecord ,
31+ GetCedarMetadataRecords ,
32+ MetadataSelectors ,
33+ UpdateCedarMetadataRecord ,
34+ } from '@osf/features/metadata/store' ;
2735import { LoadingSpinnerComponent } from '@osf/shared/components/loading-spinner/loading-spinner.component' ;
2836import { CollectionSubmissionReviewState } from '@osf/shared/enums/collection-submission-review-state.enum' ;
37+ import { ResourceType } from '@osf/shared/enums/resource-type.enum' ;
2938import { CanDeactivateComponent } from '@osf/shared/models/can-deactivate.interface' ;
3039import { BrandService } from '@osf/shared/services/brand.service' ;
3140import { CustomDialogService } from '@osf/shared/services/custom-dialog.service' ;
@@ -81,6 +90,7 @@ export class AddToCollectionComponent implements CanDeactivateComponent {
8190 private readonly headerStyleHelper = inject ( HeaderStyleService ) ;
8291 private readonly platformId = inject ( PLATFORM_ID ) ;
8392 private readonly isBrowser = isPlatformBrowser ( this . platformId ) ;
93+ private readonly environment = inject ( ENVIRONMENT ) ;
8494
8595 readonly selectedProjectId = toSignal < string | null > (
8696 this . route . params . pipe ( map ( ( params ) => params [ 'id' ] ) ) ?? of ( null )
@@ -92,15 +102,18 @@ export class AddToCollectionComponent implements CanDeactivateComponent {
92102
93103 isProviderLoading = select ( CollectionsSelectors . getCollectionProviderLoading ) ;
94104 collectionProvider = select ( CollectionsSelectors . getCollectionProvider ) ;
105+ requiredMetadataTemplate = select ( CollectionsSelectors . getRequiredMetadataTemplate ) ;
95106 selectedProject = select ( ProjectsSelectors . getSelectedProject ) ;
96107 currentUser = select ( UserSelectors . getCurrentUser ) ;
97108 currentCollectionSubmission = select ( AddToCollectionSelectors . getCurrentCollectionSubmission ) ;
109+ cedarRecords = select ( MetadataSelectors . getCedarRecords ) ;
98110
99111 providerId = signal < string > ( '' ) ;
100112 allowNavigation = signal < boolean > ( false ) ;
101113 projectMetadataSaved = signal < boolean > ( false ) ;
102114 projectContributorsSaved = signal < boolean > ( false ) ;
103115 collectionMetadataSaved = signal < boolean > ( false ) ;
116+ pendingCedarData = signal < CedarRecordDataBinding | null > ( null ) ;
104117 stepperActiveValue = signal < number > ( AddToCollectionSteps . SelectProject ) ;
105118
106119 primaryCollectionId = computed ( ( ) => this . collectionProvider ( ) ?. primaryCollection ?. id ) ;
@@ -110,6 +123,13 @@ export class AddToCollectionComponent implements CanDeactivateComponent {
110123 isCollectionMetadataDisabled = computed (
111124 ( ) => ! this . selectedProject ( ) || ! this . projectMetadataSaved ( ) || ! this . projectContributorsSaved ( )
112125 ) ;
126+ isCedarMode = computed ( ( ) => this . environment . collectionSubmissionWithCedar && ! ! this . requiredMetadataTemplate ( ) ) ;
127+ existingCedarRecord = computed < CedarMetadataRecordData | null > ( ( ) => {
128+ const records = this . cedarRecords ( ) ;
129+ const templateId = this . requiredMetadataTemplate ( ) ?. id ;
130+ if ( ! records ?. length || ! templateId ) return null ;
131+ return records . find ( ( r ) => r . relationships ?. template ?. data ?. id === templateId ) ?? null ;
132+ } ) ;
113133
114134 readonly actions = createDispatchMap ( {
115135 getCollectionProvider : GetCollectionProvider ,
@@ -118,6 +138,9 @@ export class AddToCollectionComponent implements CanDeactivateComponent {
118138 deleteCollectionSubmission : RemoveCollectionSubmission ,
119139 setSelectedProject : SetSelectedProject ,
120140 getCurrentCollectionSubmission : GetCurrentCollectionSubmission ,
141+ getCedarRecords : GetCedarMetadataRecords ,
142+ createCedarRecord : CreateCedarMetadataRecord ,
143+ updateCedarRecord : UpdateCedarMetadataRecord ,
121144 } ) ;
122145
123146 showRemoveButton = computed (
@@ -174,20 +197,29 @@ export class AddToCollectionComponent implements CanDeactivateComponent {
174197 this . stepperActiveValue . set ( AddToCollectionSteps . Complete ) ;
175198 }
176199
200+ handleCedarDataSaved ( data : CedarRecordDataBinding ) : void {
201+ this . pendingCedarData . set ( data ) ;
202+ this . collectionMetadataSaved . set ( true ) ;
203+ this . stepperActiveValue . set ( AddToCollectionSteps . Complete ) ;
204+ }
205+
177206 handleAddToCollection ( ) {
178207 const payload = {
179208 collectionId : this . primaryCollectionId ( ) || '' ,
180209 projectId : this . selectedProject ( ) ?. id || '' ,
181- collectionMetadata : this . collectionMetadataForm . value || { } ,
210+ collectionMetadata : this . isCedarMode ( ) ? { } : this . collectionMetadataForm . value || { } ,
182211 userId : this . currentUser ( ) ?. id || '' ,
183212 } ;
184213
185- if ( this . isEditMode ( ) ) {
214+ const isEditMode = this . isEditMode ( ) ;
215+
216+ if ( isEditMode ) {
186217 this . loaderService . show ( ) ;
187218
188219 this . actions
189220 . updateCollectionSubmission ( payload )
190221 . pipe (
222+ switchMap ( ( ) => this . saveCedarRecordIfNeeded ( ) ) ,
191223 finalize ( ( ) => this . loaderService . hide ( ) ) ,
192224 takeUntilDestroyed ( this . destroyRef )
193225 )
@@ -210,6 +242,7 @@ export class AddToCollectionComponent implements CanDeactivateComponent {
210242 } )
211243 . onClose . pipe (
212244 filter ( ( res ) => ! ! res ) ,
245+ switchMap ( ( ) => this . saveCedarRecordIfNeeded ( ) ) ,
213246 takeUntilDestroyed ( this . destroyRef )
214247 )
215248 . subscribe ( {
@@ -245,21 +278,35 @@ export class AddToCollectionComponent implements CanDeactivateComponent {
245278 collectionId,
246279 comment : res ?. comment || '' ,
247280 } ;
248- this . loaderService . show ( ) ;
281+
249282 return this . actions . deleteCollectionSubmission ( payload ) ;
250283 } ) ,
251- finalize ( ( ) => this . loaderService . hide ( ) ) ,
252284 takeUntilDestroyed ( this . destroyRef )
253285 )
254286 . subscribe ( {
255287 next : ( ) => {
256288 this . toastService . showSuccess ( 'collections.removeDialog.success' ) ;
289+ this . loaderService . show ( ) ;
257290 this . allowNavigation . set ( true ) ;
258291 this . router . navigate ( [ projectId , 'overview' ] ) ;
259292 } ,
260293 } ) ;
261294 }
262295
296+ private saveCedarRecordIfNeeded ( ) : Observable < unknown > {
297+ if ( ! this . isCedarMode ( ) ) return of ( null ) ;
298+
299+ const cedarData = this . pendingCedarData ( ) ;
300+ const projectId = this . selectedProject ( ) ?. id ;
301+ const templateId = this . requiredMetadataTemplate ( ) ?. id ;
302+ if ( ! cedarData || ! projectId || ! templateId ) return of ( null ) ;
303+
304+ const existingId = this . existingCedarRecord ( ) ?. id ;
305+ return existingId
306+ ? this . actions . updateCedarRecord ( cedarData , existingId , projectId , ResourceType . Project )
307+ : this . actions . createCedarRecord ( cedarData , projectId , ResourceType . Project ) ;
308+ }
309+
263310 private initializeProvider ( ) : void {
264311 const id = this . route . snapshot . paramMap . get ( 'providerId' ) ;
265312 if ( ! id ) {
@@ -298,6 +345,14 @@ export class AddToCollectionComponent implements CanDeactivateComponent {
298345 this . actions . setSelectedProject ( submission . project ) ;
299346 }
300347 } ) ;
348+
349+ effect ( ( ) => {
350+ const projectId = this . selectedProjectId ( ) ;
351+ const isCedar = this . isCedarMode ( ) ;
352+ if ( isCedar && projectId ) {
353+ this . actions . getCedarRecords ( projectId , ResourceType . Project ) ;
354+ }
355+ } ) ;
301356 }
302357
303358 private setupCleanup ( ) {
0 commit comments