Skip to content

Commit d9e2d76

Browse files
committed
fix(contributors): added bulk add and update for contributors
1 parent 54065e6 commit d9e2d76

File tree

12 files changed

+65
-92
lines changed

12 files changed

+65
-92
lines changed

src/app/features/collections/components/add-to-collection/project-contributors-step/project-contributors-step.component.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import { CustomConfirmationService } from '@osf/shared/services/custom-confirmat
3737
import { CustomDialogService } from '@osf/shared/services/custom-dialog.service';
3838
import { ToastService } from '@osf/shared/services/toast.service';
3939
import {
40-
AddContributor,
4140
BulkAddContributors,
4241
BulkUpdateContributors,
4342
ContributorsSelectors,
@@ -92,7 +91,6 @@ export class ProjectContributorsStepComponent {
9291
contributorsSaved = output<void>();
9392

9493
actions = createDispatchMap({
95-
addContributor: AddContributor,
9694
bulkAddContributors: BulkAddContributors,
9795
bulkUpdateContributors: BulkUpdateContributors,
9896
deleteContributor: DeleteContributor,
@@ -207,7 +205,7 @@ export class ProjectContributorsStepComponent {
207205
} else {
208206
const params = { name: res.data[0].fullName };
209207

210-
this.actions.addContributor(this.selectedProject()?.id, ResourceType.Project, res.data[0]).subscribe({
208+
this.actions.bulkAddContributors(this.selectedProject()?.id, ResourceType.Project, res.data).subscribe({
211209
next: () => this.toastService.showSuccess('project.contributors.toastMessages.addSuccessMessage', params),
212210
});
213211
}

src/app/features/contributors/contributors.component.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ import { LoaderService } from '@osf/shared/services/loader.service';
4545
import { ToastService } from '@osf/shared/services/toast.service';
4646
import {
4747
AcceptRequestAccess,
48-
AddContributor,
4948
BulkAddContributors,
5049
BulkAddContributorsFromParentProject,
5150
BulkUpdateContributors,
@@ -176,7 +175,6 @@ export class ContributorsComponent implements OnInit, OnDestroy {
176175
bulkUpdateContributors: BulkUpdateContributors,
177176
bulkAddContributors: BulkAddContributors,
178177
bulkAddContributorsFromParentProject: BulkAddContributorsFromParentProject,
179-
addContributor: AddContributor,
180178
createViewOnlyLink: CreateViewOnlyLink,
181179
deleteViewOnlyLink: DeleteViewOnlyLink,
182180
getRequestAccessContributors: GetRequestAccessContributors,
@@ -327,7 +325,7 @@ export class ContributorsComponent implements OnInit, OnDestroy {
327325

328326
private addContributorsToComponents(result: ContributorDialogAddModel): void {
329327
this.actions
330-
.bulkAddContributors(this.resourceId(), this.resourceType(), result.data, result.childNodeIds)
328+
.bulkAddContributors(this.resourceId(), this.resourceType(), result.data)
331329
.pipe(takeUntilDestroyed(this.destroyRef))
332330
.subscribe(() => this.toastService.showSuccess('project.contributors.toastMessages.multipleAddSuccessMessage'));
333331
}
@@ -355,7 +353,7 @@ export class ContributorsComponent implements OnInit, OnDestroy {
355353
} else {
356354
const params = { name: res.data[0].fullName };
357355

358-
this.actions.addContributor(this.resourceId(), this.resourceType(), res.data[0]).subscribe({
356+
this.actions.bulkAddContributors(this.resourceId(), this.resourceType(), res.data).subscribe({
359357
next: () => this.toastService.showSuccess('project.contributors.toastMessages.addSuccessMessage', params),
360358
});
361359
}

src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import { CustomConfirmationService } from '@osf/shared/services/custom-confirmat
3636
import { CustomDialogService } from '@osf/shared/services/custom-dialog.service';
3737
import { ToastService } from '@osf/shared/services/toast.service';
3838
import {
39-
AddContributor,
4039
BulkAddContributors,
4140
BulkUpdateContributors,
4241
ContributorsSelectors,
@@ -96,7 +95,6 @@ export class ContributorsDialogComponent implements OnInit {
9695
updatePermissionFilter: UpdatePermissionFilter,
9796
updateBibliographyFilter: UpdateBibliographyFilter,
9897
deleteContributor: DeleteContributor,
99-
addContributor: AddContributor,
10098
bulkAddContributors: BulkAddContributors,
10199
bulkUpdateContributors: BulkUpdateContributors,
102100
loadMoreContributors: LoadMoreContributors,
@@ -178,7 +176,7 @@ export class ContributorsDialogComponent implements OnInit {
178176
} else {
179177
const params = { name: res.data[0].fullName };
180178

181-
this.actions.addContributor(this.resourceId, this.resourceType, res.data[0]).subscribe({
179+
this.actions.bulkAddContributors(this.resourceId, this.resourceType, res.data).subscribe({
182180
next: () => {
183181
this.changesMade.set(true);
184182
this.toastService.showSuccess('project.contributors.toastMessages.addSuccessMessage', params);

src/app/features/preprints/components/stepper/preprints-metadata-step/preprints-contributors/preprints-contributors.component.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import { CustomConfirmationService } from '@osf/shared/services/custom-confirmat
3636
import { CustomDialogService } from '@osf/shared/services/custom-dialog.service';
3737
import { ToastService } from '@osf/shared/services/toast.service';
3838
import {
39-
AddContributor,
4039
BulkAddContributors,
4140
BulkUpdateContributors,
4241
ContributorsSelectors,
@@ -84,7 +83,6 @@ export class PreprintsContributorsComponent implements OnInit {
8483
deleteContributor: DeleteContributor,
8584
bulkUpdateContributors: BulkUpdateContributors,
8685
bulkAddContributors: BulkAddContributors,
87-
addContributor: AddContributor,
8886
loadMoreContributors: LoadMoreContributors,
8987
});
9088

@@ -157,7 +155,7 @@ export class PreprintsContributorsComponent implements OnInit {
157155
} else {
158156
const params = { name: res.data[0].fullName };
159157

160-
this.actions.addContributor(this.preprintId(), ResourceType.Preprint, res.data[0]).subscribe({
158+
this.actions.bulkAddContributors(this.preprintId(), ResourceType.Preprint, res.data).subscribe({
161159
next: () => this.toastService.showSuccess('project.contributors.toastMessages.addSuccessMessage', params),
162160
});
163161
}

src/app/features/registries/components/registries-metadata-step/registries-contributors/registries-contributors.component.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import { CustomConfirmationService } from '@osf/shared/services/custom-confirmat
3737
import { CustomDialogService } from '@osf/shared/services/custom-dialog.service';
3838
import { ToastService } from '@osf/shared/services/toast.service';
3939
import {
40-
AddContributor,
4140
BulkAddContributors,
4241
BulkUpdateContributors,
4342
ContributorsSelectors,
@@ -90,7 +89,6 @@ export class RegistriesContributorsComponent implements OnInit, OnDestroy {
9089
deleteContributor: DeleteContributor,
9190
bulkUpdateContributors: BulkUpdateContributors,
9291
bulkAddContributors: BulkAddContributors,
93-
addContributor: AddContributor,
9492
loadMoreContributors: LoadMoreContributors,
9593
resetContributorsState: ResetContributorsState,
9694
});
@@ -176,7 +174,7 @@ export class RegistriesContributorsComponent implements OnInit, OnDestroy {
176174
} else {
177175
const params = { name: res.data[0].fullName };
178176

179-
this.actions.addContributor(this.draftId(), ResourceType.DraftRegistration, res.data[0]).subscribe({
177+
this.actions.bulkAddContributors(this.draftId(), ResourceType.DraftRegistration, res.data).subscribe({
180178
next: () => this.toastService.showSuccess('project.contributors.toastMessages.addSuccessMessage', params),
181179
});
182180
}

src/app/shared/components/contributors/add-contributor-dialog/add-contributor-dialog.component.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,12 @@ export class AddContributorDialogComponent implements OnInit, OnDestroy {
8585
readonly isSearchState = computed(() => this.currentState() === AddDialogState.Search);
8686
readonly isDetailsState = computed(() => this.currentState() === AddDialogState.Details);
8787
readonly isComponentsState = computed(() => this.currentState() === AddDialogState.Components);
88-
readonly hasComponents = computed(() => this.components().length > 0);
89-
readonly buttonLabel = computed(() => (this.isComponentsState() ? 'common.buttons.done' : 'common.buttons.next'));
88+
readonly hasComponents = computed(() => this.components().length > 1);
89+
readonly buttonLabel = computed(() =>
90+
(this.isDetailsState() && !this.hasComponents()) || this.isComponentsState()
91+
? 'common.buttons.done'
92+
: 'common.buttons.next'
93+
);
9094

9195
constructor() {
9296
this.setupEffects();

src/app/shared/mappers/contributors/contributors.mapper.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,25 @@ export class ContributorsMapper {
110110
};
111111
}
112112
}
113+
114+
static toContributorUpdateRequest(model: ContributorModel): ContributorAddRequestModel {
115+
return {
116+
id: model.id,
117+
type: 'contributors',
118+
attributes: {
119+
bibliographic: model.isBibliographic,
120+
permission: model.permission,
121+
index: model.index,
122+
id: model.userId,
123+
},
124+
relationships: {
125+
users: {
126+
data: {
127+
id: model.id,
128+
type: 'users',
129+
},
130+
},
131+
},
132+
};
133+
}
113134
}

src/app/shared/models/contributors/contributor-response-json-api.model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export interface ContributorEmbedsJsonApi {
3333

3434
export interface ContributorAddRequestModel {
3535
type: 'contributors';
36+
id?: string;
3637
attributes: {
3738
bibliographic: boolean;
3839
permission: string;

src/app/shared/services/contributors.service.ts

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { forkJoin, map, Observable, of } from 'rxjs';
1+
import { map, Observable, of } from 'rxjs';
22

33
import { inject, Injectable } from '@angular/core';
44

@@ -10,11 +10,7 @@ import { ContributorsMapper } from '../mappers/contributors';
1010
import { ResponseJsonApi } from '../models/common/json-api.model';
1111
import { ContributorModel } from '../models/contributors/contributor.model';
1212
import { ContributorAddModel } from '../models/contributors/contributor-add.model';
13-
import {
14-
ContributorDataJsonApi,
15-
ContributorResponseJsonApi,
16-
ContributorsResponseJsonApi,
17-
} from '../models/contributors/contributor-response-json-api.model';
13+
import { ContributorsResponseJsonApi } from '../models/contributors/contributor-response-json-api.model';
1814
import { PaginatedData } from '../models/paginated-data.model';
1915
import { UserDataJsonApi } from '../models/user/user-json-api.model';
2016

@@ -110,25 +106,19 @@ export class ContributorsService {
110106
return of([]);
111107
}
112108

113-
const updateRequests = contributors.map((contributor) =>
114-
this.updateContributor(resourceType, resourceId, contributor)
115-
);
116-
117-
return forkJoin(updateRequests);
118-
}
109+
const baseUrl = `${this.getBaseUrl(resourceType, resourceId)}/`;
119110

120-
updateContributor(
121-
resourceType: ResourceType,
122-
resourceId: string,
123-
data: ContributorModel
124-
): Observable<ContributorModel> {
125-
const baseUrl = `${this.getBaseUrl(resourceType, resourceId)}/${data.userId}/`;
111+
const contributorData = {
112+
data: contributors.map((contributor) => ContributorsMapper.toContributorUpdateRequest(contributor)),
113+
};
126114

127-
const contributorData = { data: ContributorsMapper.toContributorAddRequest(data) };
115+
const headers = {
116+
'Content-Type': 'application/vnd.api+json; ext=bulk',
117+
};
128118

129119
return this.jsonApiService
130-
.patch<ContributorDataJsonApi>(baseUrl, contributorData)
131-
.pipe(map((contributor) => ContributorsMapper.getContributor(contributor)));
120+
.patch<ContributorsResponseJsonApi>(baseUrl, contributorData, undefined, headers)
121+
.pipe(map((response) => ContributorsMapper.getContributors(response.data)));
132122
}
133123

134124
bulkAddContributors(
@@ -141,27 +131,22 @@ export class ContributorsService {
141131
return of([]);
142132
}
143133

144-
const addRequests = contributors.map((contributor) =>
145-
this.addContributor(resourceType, resourceId, contributor, childNodeIds)
146-
);
147-
148-
return forkJoin(addRequests);
149-
}
150-
151-
addContributor(
152-
resourceType: ResourceType,
153-
resourceId: string,
154-
data: ContributorAddModel,
155-
childNodeIds?: string[]
156-
): Observable<ContributorModel> {
157134
const baseUrl = `${this.getBaseUrl(resourceType, resourceId)}/`;
158-
const type = data.id ? AddContributorType.Registered : AddContributorType.Unregistered;
159135

160-
const contributorData = { data: ContributorsMapper.toContributorAddRequest(data, type, childNodeIds) };
136+
const contributorData = {
137+
data: contributors.map((contributor) => {
138+
const type = contributor.id ? AddContributorType.Registered : AddContributorType.Unregistered;
139+
return ContributorsMapper.toContributorAddRequest(contributor, type, childNodeIds);
140+
}),
141+
};
142+
143+
const headers = {
144+
'Content-Type': 'application/vnd.api+json; ext=bulk',
145+
};
161146

162147
return this.jsonApiService
163-
.post<ContributorResponseJsonApi>(baseUrl, contributorData)
164-
.pipe(map((contributor) => ContributorsMapper.getContributor(contributor.data)));
148+
.post<ContributorsResponseJsonApi>(baseUrl, contributorData, undefined, headers)
149+
.pipe(map((response) => ContributorsMapper.getContributors(response.data)));
165150
}
166151

167152
addContributorsFromProject(resourceType: ResourceType, resourceId: string): Observable<void> {

src/app/shared/services/json-api.service.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,13 @@ export class JsonApiService {
3535
return httpParams;
3636
}
3737

38-
post<T>(url: string, body?: unknown, params?: Record<string, unknown>): Observable<T> {
39-
return this.http.post<T>(url, body, { params: this.buildHttpParams(params) });
38+
post<T>(
39+
url: string,
40+
body?: unknown,
41+
params?: Record<string, unknown>,
42+
headers?: Record<string, string>
43+
): Observable<T> {
44+
return this.http.post<T>(url, body, { params: this.buildHttpParams(params), headers });
4045
}
4146

4247
patch<T>(

0 commit comments

Comments
 (0)