Skip to content

Commit a2d922e

Browse files
committed
Merge remote-tracking branch 'upstream/feature/pbs-25.02' into fix/ANG-9238-v2
2 parents bf82359 + 6e30deb commit a2d922e

File tree

13 files changed

+115
-12
lines changed

13 files changed

+115
-12
lines changed

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

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import {
5050
AcceptRequestAccess,
5151
AddContributor,
5252
BulkAddContributors,
53+
BulkAddContributorsFromParentProject,
5354
BulkUpdateContributors,
5455
ContributorsSelectors,
5556
CreateViewOnlyLink,
@@ -164,6 +165,7 @@ export class ContributorsComponent implements OnInit, OnDestroy {
164165
deleteContributor: DeleteContributor,
165166
bulkUpdateContributors: BulkUpdateContributors,
166167
bulkAddContributors: BulkAddContributors,
168+
bulkAddContributorsFromParentProject: BulkAddContributorsFromParentProject,
167169
addContributor: AddContributor,
168170
createViewOnlyLink: CreateViewOnlyLink,
169171
deleteViewOnlyLink: DeleteViewOnlyLink,
@@ -255,33 +257,42 @@ export class ContributorsComponent implements OnInit, OnDestroy {
255257
}
256258

257259
openAddContributorDialog() {
258-
const rootParentId = this.resourceDetails().rootParentId ?? this.resourceId();
260+
const resourceDetails = this.resourceDetails();
261+
const resourceId = this.resourceId();
262+
const rootParentId = resourceDetails.rootParentId ?? resourceId;
259263

260264
this.loaderService.show();
261265

262266
this.actions
263-
.getResourceWithChildren(rootParentId, this.resourceId(), this.resourceType())
267+
.getResourceWithChildren(rootParentId, resourceId, this.resourceType())
264268
.pipe(takeUntilDestroyed(this.destroyRef))
265269
.subscribe(() => {
266270
this.loaderService.hide();
267271

268-
const components = this.mapNodesToComponentCheckboxItems(this.resourceChildren(), this.resourceId());
272+
const components = this.mapNodesToComponentCheckboxItems(this.resourceChildren(), resourceId);
269273

270274
this.customDialogService
271275
.open(AddContributorDialogComponent, {
272276
header: 'project.contributors.addDialog.addRegisteredContributor',
273277
width: '448px',
274278
data: {
275279
components,
276-
resourceName: this.resourceDetails().title,
280+
resourceName: resourceDetails.title,
281+
parentResourceName: resourceDetails.parent?.title,
282+
allowAddingContributorsFromParentProject:
283+
this.resourceType() === ResourceType.Project &&
284+
resourceDetails.rootParentId &&
285+
resourceDetails.rootParentId !== resourceId,
277286
},
278287
})
279288
.onClose.pipe(
280289
filter((res: ContributorDialogAddModel) => !!res),
281290
takeUntilDestroyed(this.destroyRef)
282291
)
283292
.subscribe((res: ContributorDialogAddModel) => {
284-
if (res.type === AddContributorType.Unregistered) {
293+
if (res.type === AddContributorType.ParentProject) {
294+
this.addContributorsFromParentProjectToComponents();
295+
} else if (res.type === AddContributorType.Unregistered) {
285296
this.openAddUnregisteredContributorDialog();
286297
} else {
287298
this.addContributorsToComponents(res);
@@ -311,6 +322,13 @@ export class ContributorsComponent implements OnInit, OnDestroy {
311322
.subscribe(() => this.toastService.showSuccess('project.contributors.toastMessages.multipleAddSuccessMessage'));
312323
}
313324

325+
private addContributorsFromParentProjectToComponents(): void {
326+
this.actions
327+
.bulkAddContributorsFromParentProject(this.resourceId(), this.resourceType())
328+
.pipe(takeUntilDestroyed(this.destroyRef))
329+
.subscribe(() => this.toastService.showSuccess('project.contributors.toastMessages.multipleAddSuccessMessage'));
330+
}
331+
314332
openAddUnregisteredContributorDialog() {
315333
this.customDialogService
316334
.open(AddUnregisteredContributorDialogComponent, {

src/app/features/files/components/move-file-dialog/move-file-dialog.component.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ export class MoveFileDialogComponent {
182182
}
183183

184184
this.isFilesUpdating.set(true);
185+
const headerKey = this.isMoveAction ? 'files.dialogs.moveFile.movingHeader' : 'files.dialogs.moveFile.copingHeader';
186+
this.config.header = this.translateService.instant(headerKey);
185187
const action = this.config.data.action;
186188
const files: FileModel[] = this.config.data.files;
187189
const totalFiles = files.length;
@@ -209,6 +211,7 @@ export class MoveFileDialogComponent {
209211
this.openReplaceMoveDialog(conflictFiles, path, action);
210212
} else {
211213
this.showToast(action);
214+
this.config.header = this.translateService.instant('files.dialogs.moveFile.title');
212215
this.completeMove();
213216
}
214217
}

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,22 @@
7070
</div>
7171
}
7272

73+
@if (allowAddingContributorsFromParentProject() && this.isSearchState()) {
74+
<div class="flex justify-content-center mt-2">
75+
<p-button
76+
class="w-full"
77+
styleClass="w-full"
78+
severity="secondary"
79+
(onClick)="addSourceProjectContributors()"
80+
[label]="
81+
'project.contributors.addDialog.addingContributorsFromParentProject'
82+
| translate: { projectName: parentResourceName() }
83+
"
84+
>
85+
</p-button>
86+
</div>
87+
}
88+
7389
<div class="flex gap-2 mt-6">
7490
<p-button
7591
class="w-full"

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

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ export class AddContributorDialogComponent implements OnInit, OnDestroy {
7070
readonly selectedUsers = signal<ContributorAddModel[]>([]);
7171
readonly components = signal<ComponentCheckboxItemModel[]>([]);
7272
readonly resourceName = signal<string>('');
73+
readonly parentResourceName = signal<string>('');
74+
readonly allowAddingContributorsFromParentProject = signal<boolean>(false);
7375

7476
readonly contributorNames = computed(() =>
7577
this.selectedUsers()
@@ -118,6 +120,10 @@ export class AddContributorDialogComponent implements OnInit, OnDestroy {
118120
}
119121
}
120122

123+
addSourceProjectContributors(): void {
124+
this.closeDialogWithData(AddContributorType.ParentProject);
125+
}
126+
121127
addUnregistered(): void {
122128
this.dialogRef.close({
123129
data: [],
@@ -134,7 +140,8 @@ export class AddContributorDialogComponent implements OnInit, OnDestroy {
134140
private initializeDialogData(): void {
135141
this.selectedUsers.set([]);
136142

137-
const { components, resourceName } = this.config.data || {};
143+
const { components, resourceName, parentResourceName, allowAddingContributorsFromParentProject } =
144+
this.config.data || {};
138145

139146
if (components) {
140147
this.components.set(components);
@@ -143,9 +150,17 @@ export class AddContributorDialogComponent implements OnInit, OnDestroy {
143150
if (resourceName) {
144151
this.resourceName.set(resourceName);
145152
}
153+
154+
if (allowAddingContributorsFromParentProject) {
155+
this.allowAddingContributorsFromParentProject.set(allowAddingContributorsFromParentProject);
156+
}
157+
158+
if (parentResourceName) {
159+
this.parentResourceName.set(parentResourceName);
160+
}
146161
}
147162

148-
private closeDialogWithData(): void {
163+
private closeDialogWithData(AddContributorTypeValue = AddContributorType.Registered): void {
149164
const childNodeIds = this.components()
150165
.filter((c) => c.checked && !c.isCurrent)
151166
.map((c) => c.id);
@@ -154,7 +169,7 @@ export class AddContributorDialogComponent implements OnInit, OnDestroy {
154169

155170
this.dialogRef.close({
156171
data: filteredUsers,
157-
type: AddContributorType.Registered,
172+
type: AddContributorTypeValue,
158173
childNodeIds: childNodeIds.length > 0 ? childNodeIds : undefined,
159174
} as ContributorDialogAddModel);
160175
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export enum AddContributorType {
22
Registered = 1,
33
Unregistered,
4+
ParentProject,
45
}

src/app/shared/mappers/nodes/base-node.mapper.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export class BaseNodeMapper {
6060
wikiEnabled: data.attributes.wiki_enabled,
6161
customCitation: data.attributes.custom_citation || undefined,
6262
rootParentId: data.relationships.root?.data?.id,
63+
parent: data.embeds?.parent?.data ? this.getNodeData(data.embeds?.parent.data) : undefined,
6364
};
6465
}
6566

src/app/shared/models/nodes/base-node-embeds-json-api.model.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
BaseNodeDataJsonApi,
23
ContributorDataJsonApi,
34
IdentifierAttributes,
45
IdentifiersJsonApiData,
@@ -23,6 +24,9 @@ export interface BaseNodeEmbedsJsonApi {
2324
region?: {
2425
data: RegionDataJsonApi;
2526
};
27+
parent?: {
28+
data: BaseNodeDataJsonApi;
29+
};
2630
}
2731

2832
export interface JsonApiResource<T extends string, A> {

src/app/shared/models/nodes/base-node.model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export interface BaseNodeModel {
2323
wikiEnabled: boolean;
2424
rootParentId?: string;
2525
type: string;
26+
parent?: BaseNodeModel;
2627
}
2728

2829
export interface NodeModel extends BaseNodeModel {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@ export class ContributorsService {
164164
.pipe(map((contributor) => ContributorsMapper.getContributor(contributor.data)));
165165
}
166166

167+
addContributorsFromProject(resourceType: ResourceType, resourceId: string): Observable<void> {
168+
const baseUrl = `${this.getBaseUrl(resourceType, resourceId)}/?copy_contributors_from_parent_project=true`;
169+
const contributorData = { data: { type: AddContributorType.ParentProject } };
170+
return this.jsonApiService.patch(baseUrl, contributorData);
171+
}
172+
167173
deleteContributor(resourceType: ResourceType, resourceId: string, userId: string): Observable<void> {
168174
const baseUrl = `${this.getBaseUrl(resourceType, resourceId)}/${userId}/`;
169175

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,11 @@ export class ResourceGuidService {
6666

6767
getResourceDetails(resourceId: string, resourceType: ResourceType): Observable<BaseNodeModel> {
6868
const resourcePath = this.urlMap.get(resourceType);
69-
69+
const params: Record<string, unknown> = {
70+
embed: 'parent',
71+
};
7072
return this.jsonApiService
71-
.get<ResponseDataJsonApi<BaseNodeDataJsonApi>>(`${this.apiUrl}/${resourcePath}/${resourceId}/`)
73+
.get<ResponseDataJsonApi<BaseNodeDataJsonApi>>(`${this.apiUrl}/${resourcePath}/${resourceId}/`, params)
7274
.pipe(map((response) => BaseNodeMapper.getNodeData(response.data)));
7375
}
7476

0 commit comments

Comments
 (0)