diff --git a/src/app/features/collections/components/add-to-collection/project-contributors-step/project-contributors-step.component.html b/src/app/features/collections/components/add-to-collection/project-contributors-step/project-contributors-step.component.html index 3bb5e8140..f0715c95f 100644 --- a/src/app/features/collections/components/add-to-collection/project-contributors-step/project-contributors-step.component.html +++ b/src/app/features/collections/components/add-to-collection/project-contributors-step/project-contributors-step.component.html @@ -41,7 +41,6 @@

{{ 'collections.addToCollection.projectContributors' | translate }}

class="w-full" [contributors]="projectContributors()" [isLoading]="isContributorsLoading()" - [showCuratorColumn]="false" (remove)="handleRemoveContributor($event)" > diff --git a/src/app/features/home/pages/dashboard/dashboard.component.ts b/src/app/features/home/pages/dashboard/dashboard.component.ts index e2b1288a0..efde941ef 100644 --- a/src/app/features/home/pages/dashboard/dashboard.component.ts +++ b/src/app/features/home/pages/dashboard/dashboard.component.ts @@ -70,7 +70,7 @@ export class DashboardComponent implements OnInit { return this.projects().filter((project) => project.title.toLowerCase().includes(search)); }); - protected readonly existsProjects = computed(() => { + readonly existsProjects = computed(() => { return this.projects().length || !!this.searchControl.value?.length; }); diff --git a/src/app/features/metadata/components/metadata-affiliated-institutions/metadata-affiliated-institutions.component.html b/src/app/features/metadata/components/metadata-affiliated-institutions/metadata-affiliated-institutions.component.html index 21b111021..90fb07ee2 100644 --- a/src/app/features/metadata/components/metadata-affiliated-institutions/metadata-affiliated-institutions.component.html +++ b/src/app/features/metadata/components/metadata-affiliated-institutions/metadata-affiliated-institutions.component.html @@ -7,6 +7,7 @@

{{ 'project.overview.metadata.affiliatedInstitutions' | translate }}

severity="secondary" [label]="'common.buttons.edit' | translate" (onClick)="openEditAffiliatedInstitutionsDialog.emit()" + data-test-edit-institutions-button > } diff --git a/src/app/features/metadata/components/metadata-contributors/metadata-contributors.component.html b/src/app/features/metadata/components/metadata-contributors/metadata-contributors.component.html index a65f57fb3..1d8eb0a3a 100644 --- a/src/app/features/metadata/components/metadata-contributors/metadata-contributors.component.html +++ b/src/app/features/metadata/components/metadata-contributors/metadata-contributors.component.html @@ -7,6 +7,7 @@

{{ 'project.overview.metadata.contributors' | translate }}

(onClick)="openEditContributorDialog.emit()" severity="secondary" [label]="'common.buttons.edit' | translate" + data-test-edit-contributors-button > } @@ -15,7 +16,9 @@

{{ 'project.overview.metadata.contributors' | translate }}

@for (contributor of contributors(); track contributor.id) {
- {{ contributor.fullName }} + + {{ contributor.fullName }} + {{ $last ? '' : ',' }}
} diff --git a/src/app/features/metadata/components/metadata-description/metadata-description.component.html b/src/app/features/metadata/components/metadata-description/metadata-description.component.html index 4a943d8e0..b1dd3143b 100644 --- a/src/app/features/metadata/components/metadata-description/metadata-description.component.html +++ b/src/app/features/metadata/components/metadata-description/metadata-description.component.html @@ -7,6 +7,7 @@

{{ 'project.overview.metadata.description' | translate }}

severity="secondary" [label]="'common.buttons.edit' | translate" (onClick)="openEditDescriptionDialog.emit()" + data-test-edit-description-button > }
diff --git a/src/app/features/metadata/components/metadata-funding/metadata-funding.component.html b/src/app/features/metadata/components/metadata-funding/metadata-funding.component.html index cf6f14c49..d02ec5408 100644 --- a/src/app/features/metadata/components/metadata-funding/metadata-funding.component.html +++ b/src/app/features/metadata/components/metadata-funding/metadata-funding.component.html @@ -7,6 +7,7 @@

{{ 'project.overview.metadata.fundingSupport' | translate }}

severity="secondary" [label]="'common.buttons.edit' | translate" (onClick)="openEditFundingDialog.emit()" + data-test-edit-funding-button > } @@ -15,22 +16,29 @@

{{ 'project.overview.metadata.fundingSupport' | translate }}

@for (funder of funders(); track funder.funderIdentifier) {
-

{{ 'files.detail.resourceMetadata.fields.funder' | translate }}: {{ funder.funderName }}

+

+ {{ 'files.detail.resourceMetadata.fields.funder' | translate }}: {{ funder.funderName }} +

+ @if (funder.awardTitle) { -

{{ 'files.detail.resourceMetadata.fields.awardTitle' | translate }}: {{ funder.awardTitle }}

+

+ {{ 'files.detail.resourceMetadata.fields.awardTitle' | translate }}: {{ funder.awardTitle }} +

} @if (funder.awardUri) {

{{ 'files.detail.resourceMetadata.fields.awardUri' | translate }}: - + {{ funder.awardUri }}

} @if (funder.awardNumber) { -

{{ 'files.detail.resourceMetadata.fields.awardNumber' | translate }}: {{ funder.awardNumber }}

+

+ {{ 'files.detail.resourceMetadata.fields.awardNumber' | translate }}: {{ funder.awardNumber }} +

}
} diff --git a/src/app/features/metadata/components/metadata-license/metadata-license.component.html b/src/app/features/metadata/components/metadata-license/metadata-license.component.html index d4a993b05..ec313d5de 100644 --- a/src/app/features/metadata/components/metadata-license/metadata-license.component.html +++ b/src/app/features/metadata/components/metadata-license/metadata-license.component.html @@ -7,11 +7,12 @@

{{ 'project.overview.metadata.license' | translate }}

severity="secondary" [label]="'common.buttons.edit' | translate" (onClick)="openEditLicenseDialog.emit()" + data-test-edit-license-button /> }
-

{{ license()?.name || ('project.overview.metadata.noLicense' | translate) }}

+

{{ license()?.name || ('project.overview.metadata.noLicense' | translate) }}

diff --git a/src/app/features/metadata/components/metadata-publication-doi/metadata-publication-doi.component.html b/src/app/features/metadata/components/metadata-publication-doi/metadata-publication-doi.component.html index 477b6f458..b01ba6977 100644 --- a/src/app/features/metadata/components/metadata-publication-doi/metadata-publication-doi.component.html +++ b/src/app/features/metadata/components/metadata-publication-doi/metadata-publication-doi.component.html @@ -7,6 +7,7 @@

{{ 'project.overview.metadata.publication' | translate }}

severity="secondary" [label]="'common.buttons.edit' | translate" (onClick)="openEditPublicationDoiDialog.emit()" + data-test-edit-doi-button > } diff --git a/src/app/features/metadata/components/metadata-resource-information/metadata-resource-information.component.html b/src/app/features/metadata/components/metadata-resource-information/metadata-resource-information.component.html index 5f2621417..12971a7be 100644 --- a/src/app/features/metadata/components/metadata-resource-information/metadata-resource-information.component.html +++ b/src/app/features/metadata/components/metadata-resource-information/metadata-resource-information.component.html @@ -7,6 +7,7 @@

severity="secondary" text (onClick)="showResourceInfo.emit()" + [ariaLabel]="'project.metadata.resourceInformation.tooltipDialog.header' | translate" >

@@ -15,6 +16,7 @@

severity="secondary" [label]="'common.buttons.edit' | translate" (onClick)="openEditResourceInformationDialog.emit()" + data-test-edit-resource-information-button > } @@ -22,12 +24,12 @@

@if (customItemMetadata()?.resourceTypeGeneral) {
-

+

{{ 'project.overview.metadata.resourceType' | translate }}: {{ getResourceTypeName(customItemMetadata()?.resourceTypeGeneral!) }}

-

+

{{ 'project.overview.metadata.resourceLanguage' | translate }}: {{ getLanguageName(customItemMetadata()?.language || '') }}

diff --git a/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.html b/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.html index 2c4a1e26d..016f57413 100644 --- a/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.html +++ b/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.html @@ -7,10 +7,16 @@
- +
diff --git a/src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.html b/src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.html index 6b9690a0e..11ef9c4cf 100644 --- a/src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.html +++ b/src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.html @@ -4,9 +4,9 @@

{{ 'project.contributors.addContributor' | translate }}

@@ -14,52 +14,43 @@

{{ 'project.contributors.addContributor' | translate }}

-
- @if (isContributorsLoading()) { -
- @for (item of [1, 2, 3]; track item) { -
-
- - -
- -
- } -
- } @else { - @if (contributors().length === 0) { -
- {{ 'project.contributors.table.emptyMessage' | translate }} -
- } @else { -
- @for (contributor of contributors(); track contributor.id) { -
-
-
- {{ contributor.fullName }} - {{ contributor.permission | translate | titlecase }} -
-
+ - -
- } -
- } - } -
+ @if (hasChanges) { +
+ + + + +
+ }
- - +
diff --git a/src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.spec.ts b/src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.spec.ts index 5da51138a..162cfdc9f 100644 --- a/src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.spec.ts +++ b/src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.spec.ts @@ -8,7 +8,7 @@ import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MOCK_STORE, TranslateServiceMock } from '@osf/shared/mocks'; +import { MOCK_STORE, MockCustomConfirmationServiceProvider, TranslateServiceMock } from '@osf/shared/mocks'; import { ContributorsSelectors } from '@osf/shared/stores'; import { ContributorsDialogComponent } from './contributors-dialog.component'; @@ -26,6 +26,7 @@ describe('ContributorsDialogComponent', () => { imports: [ContributorsDialogComponent, MockPipe(TranslatePipe)], providers: [ TranslateServiceMock, + MockCustomConfirmationServiceProvider, MockProviders(MessageService, DynamicDialogRef, DynamicDialogConfig), MockProvider(Store, MOCK_STORE), ], diff --git a/src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.ts b/src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.ts index e81e91e79..007daa5e7 100644 --- a/src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.ts +++ b/src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.ts @@ -4,13 +4,10 @@ import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { Button } from 'primeng/button'; import { DialogService, DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog'; -import { Skeleton } from 'primeng/skeleton'; -import { Tooltip } from 'primeng/tooltip'; import { filter, forkJoin } from 'rxjs'; -import { TitleCasePipe } from '@angular/common'; -import { ChangeDetectionStrategy, Component, DestroyRef, inject, OnInit, signal } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, effect, inject, OnInit, signal } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormControl, FormsModule } from '@angular/forms'; @@ -18,22 +15,25 @@ import { SearchInputComponent } from '@osf/shared/components'; import { AddContributorDialogComponent, AddUnregisteredContributorDialogComponent, + ContributorsListComponent, } from '@osf/shared/components/contributors'; import { AddContributorType, ResourceType } from '@osf/shared/enums'; +import { findChangedItems } from '@osf/shared/helpers'; import { ContributorDialogAddModel, ContributorModel } from '@osf/shared/models'; -import { ToastService } from '@osf/shared/services'; +import { CustomConfirmationService, ToastService } from '@osf/shared/services'; import { AddContributor, ContributorsSelectors, DeleteContributor, UpdateBibliographyFilter, + UpdateContributor, UpdatePermissionFilter, UpdateSearchValue, } from '@osf/shared/stores'; @Component({ selector: 'osf-contributors-dialog', - imports: [Button, SearchInputComponent, Skeleton, Tooltip, TranslatePipe, TitleCasePipe, FormsModule], + imports: [Button, SearchInputComponent, TranslatePipe, FormsModule, ContributorsListComponent], templateUrl: './contributors-dialog.component.html', changeDetection: ChangeDetectionStrategy.OnPush, providers: [DialogService], @@ -47,14 +47,18 @@ export class ContributorsDialogComponent implements OnInit { readonly dialogRef = inject(DynamicDialogRef); readonly config = inject(DynamicDialogConfig); readonly dialogService = inject(DialogService); - isContributorsLoading = signal(false); - contributors = select(ContributorsSelectors.getContributors); + readonly customConfirmationService = inject(CustomConfirmationService); + + isLoading = select(ContributorsSelectors.isContributorsLoading); + initialContributors = select(ContributorsSelectors.getContributors); + contributors = signal([]); actions = createDispatchMap({ updateSearchValue: UpdateSearchValue, updatePermissionFilter: UpdatePermissionFilter, updateBibliographyFilter: UpdateBibliographyFilter, deleteContributor: DeleteContributor, addContributor: AddContributor, + updateContributor: UpdateContributor, }); private readonly resourceType: ResourceType; @@ -62,10 +66,15 @@ export class ContributorsDialogComponent implements OnInit { constructor() { this.resourceId = this.config.data?.resourceId; - this.resourceType = this.config.data?.resourceType; - this.isContributorsLoading.set(this.config.data?.isLoading || false); + effect(() => { + this.contributors.set(JSON.parse(JSON.stringify(this.initialContributors()))); + }); + } + + get hasChanges(): boolean { + return JSON.stringify(this.initialContributors()) !== JSON.stringify(this.contributors()); } ngOnInit(): void { @@ -79,7 +88,7 @@ export class ContributorsDialogComponent implements OnInit { } openAddContributorDialog(): void { - const addedContributorIds = this.contributors().map((x) => x.userId); + const addedContributorIds = this.initialContributors().map((x) => x.userId); this.dialogService .open(AddContributorDialogComponent, { @@ -104,10 +113,9 @@ export class ContributorsDialogComponent implements OnInit { this.actions.addContributor(this.resourceId, this.resourceType, payload) ); - forkJoin(addRequests).subscribe(() => { - this.toastService.showSuccess('project.contributors.toastMessages.multipleAddSuccessMessage'); - this.dialogRef.close({ refresh: true }); - }); + forkJoin(addRequests).subscribe(() => + this.toastService.showSuccess('project.contributors.toastMessages.multipleAddSuccessMessage') + ); } } }); @@ -141,17 +149,27 @@ export class ContributorsDialogComponent implements OnInit { } removeContributor(contributor: ContributorModel): void { - this.actions - .deleteContributor(this.resourceId, this.resourceType, contributor.userId) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe({ - next: () => { - this.toastService.showSuccess('project.contributors.removeDialog.successMessage', { - name: contributor.fullName, + this.customConfirmationService.confirmDelete({ + headerKey: 'project.contributors.removeDialog.title', + messageKey: 'project.contributors.removeDialog.message', + messageParams: { name: contributor.fullName }, + acceptLabelKey: 'common.buttons.remove', + onConfirm: () => { + this.actions + .deleteContributor(this.resourceId, this.resourceType, contributor.userId) + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe({ + next: () => + this.toastService.showSuccess('project.contributors.removeDialog.successMessage', { + name: contributor.fullName, + }), }); - this.dialogRef.close({ refresh: true }); - }, - }); + }, + }); + } + + cancel() { + this.contributors.set(JSON.parse(JSON.stringify(this.initialContributors()))); } onClose(): void { @@ -159,6 +177,14 @@ export class ContributorsDialogComponent implements OnInit { } onSave(): void { - this.dialogRef.close({ saved: true }); + const updatedContributors = findChangedItems(this.initialContributors(), this.contributors(), 'id'); + + const updateRequests = updatedContributors.map((payload) => + this.actions.updateContributor(this.resourceId, this.resourceType, payload) + ); + + forkJoin(updateRequests).subscribe(() => { + this.toastService.showSuccess('project.contributors.toastMessages.multipleUpdateSuccessMessage'); + }); } } diff --git a/src/app/features/metadata/dialogs/funding-dialog/funding-dialog.component.html b/src/app/features/metadata/dialogs/funding-dialog/funding-dialog.component.html index 734741348..4256b8dbc 100644 --- a/src/app/features/metadata/dialogs/funding-dialog/funding-dialog.component.html +++ b/src/app/features/metadata/dialogs/funding-dialog/funding-dialog.component.html @@ -71,12 +71,18 @@
- + +
diff --git a/src/app/features/metadata/dialogs/resource-information-dialog/resource-information-dialog.component.html b/src/app/features/metadata/dialogs/resource-information-dialog/resource-information-dialog.component.html index 9882a7e53..22b3da58d 100644 --- a/src/app/features/metadata/dialogs/resource-information-dialog/resource-information-dialog.component.html +++ b/src/app/features/metadata/dialogs/resource-information-dialog/resource-information-dialog.component.html @@ -13,6 +13,7 @@ [placeholder]="'common.buttons.select' | translate" appendTo="body" class="w-full" + data-test-select-resource-type /> @@ -34,6 +35,7 @@ [virtualScroll]="true" [virtualScrollItemSize]="35" class="w-full" + data-test-select-resource-language > {{ option.label }} @@ -42,7 +44,17 @@
- - + +
diff --git a/src/app/features/metadata/metadata.component.ts b/src/app/features/metadata/metadata.component.ts index 5054fd063..08f5ad69c 100644 --- a/src/app/features/metadata/metadata.component.ts +++ b/src/app/features/metadata/metadata.component.ts @@ -289,10 +289,9 @@ export class MetadataComponent implements OnInit { data: { resourceId: this.resourceId, resourceType: this.resourceType(), - isLoading: this.isContributorsLoading(), }, }); - dialogRef.onClose.pipe(filter((result) => !!result && (result.refresh || result.saved))).subscribe({ + dialogRef.onClose.pipe(filter((result) => !!result)).subscribe({ next: () => { this.actions.getResourceMetadata(this.resourceId, this.resourceType()); this.toastService.showSuccess('project.metadata.contributors.updateSucceed'); diff --git a/src/app/features/metadata/pages/add-metadata/add-metadata.component.html b/src/app/features/metadata/pages/add-metadata/add-metadata.component.html index 7fc6f84f4..a370c83f1 100644 --- a/src/app/features/metadata/pages/add-metadata/add-metadata.component.html +++ b/src/app/features/metadata/pages/add-metadata/add-metadata.component.html @@ -38,7 +38,8 @@

{{ meta.attributes.template.title }}

} diff --git a/src/app/features/project/contributors/contributors.component.html b/src/app/features/project/contributors/contributors.component.html index 5bed0121b..264057038 100644 --- a/src/app/features/project/contributors/contributors.component.html +++ b/src/app/features/project/contributors/contributors.component.html @@ -64,7 +64,7 @@

{{ 'navigation.contributors' | translate } class="w-full" [contributors]="contributors()" [isLoading]="isContributorsLoading()" - [showCuratorColumn]="true" + [showCurator]="true" (remove)="removeContributor($event)" > diff --git a/src/app/shared/components/confirm-email/confirm-email.component.ts b/src/app/shared/components/confirm-email/confirm-email.component.ts index 6e1020e42..c7ce1f632 100644 --- a/src/app/shared/components/confirm-email/confirm-email.component.ts +++ b/src/app/shared/components/confirm-email/confirm-email.component.ts @@ -10,10 +10,11 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormsModule } from '@angular/forms'; import { DeleteEmail, UserEmailsSelectors, VerifyEmail } from '@core/store/user-emails'; -import { LoadingSpinnerComponent } from '@osf/shared/components'; import { AccountEmailModel } from '@osf/shared/models'; import { ToastService } from '@osf/shared/services'; +import { LoadingSpinnerComponent } from '../loading-spinner/loading-spinner.component'; + @Component({ selector: 'osf-confirm-email', imports: [Button, FormsModule, TranslatePipe, LoadingSpinnerComponent], diff --git a/src/app/shared/components/contributors/add-contributor-dialog/add-contributor-dialog.component.html b/src/app/shared/components/contributors/add-contributor-dialog/add-contributor-dialog.component.html index 9f9bc7d7d..f471d1f6f 100644 --- a/src/app/shared/components/contributors/add-contributor-dialog/add-contributor-dialog.component.html +++ b/src/app/shared/components/contributors/add-contributor-dialog/add-contributor-dialog.component.html @@ -37,6 +37,7 @@ severity="secondary" [label]="'project.contributors.addDialog.addUnregisteredContributor' | translate" (click)="addUnregistered()" + data-test-add-unregistered-contributor-button /> } @@ -59,6 +60,7 @@ (click)="dialogRef.close()" severity="info" [label]="'common.buttons.cancel' | translate" + data-test-cancel-add-contributor-button > @@ -68,6 +70,7 @@ (click)="addContributor()" [label]="'common.buttons.next' | translate" [disabled]="!selectedUsers().length" + data-test-add-contributor-button > diff --git a/src/app/shared/components/contributors/add-unregistered-contributor-dialog/add-unregistered-contributor-dialog.component.html b/src/app/shared/components/contributors/add-unregistered-contributor-dialog/add-unregistered-contributor-dialog.component.html index a9b38a2ce..5251fecdb 100644 --- a/src/app/shared/components/contributors/add-unregistered-contributor-dialog/add-unregistered-contributor-dialog.component.html +++ b/src/app/shared/components/contributors/add-unregistered-contributor-dialog/add-unregistered-contributor-dialog.component.html @@ -28,7 +28,8 @@ class="btn-full-width md:w-auto" severity="secondary" [label]="'project.contributors.addDialog.addRegisteredContributor' | translate" - (click)="addRegistered()" + (onClick)="addRegistered()" + data-test-add-registered-contributor-button > @@ -37,18 +38,20 @@ diff --git a/src/app/shared/components/contributors/contributors-list/contributors-list.component.html b/src/app/shared/components/contributors/contributors-list/contributors-list.component.html index 4d53364a0..62e4ea59f 100644 --- a/src/app/shared/components/contributors/contributors-list/contributors-list.component.html +++ b/src/app/shared/components/contributors/contributors-list/contributors-list.component.html @@ -70,7 +70,7 @@

{{ 'project.contributors.bibliographicContributorInfo.heading' | translate } - @if (showCuratorColumn()) { + @if (showCurator()) {
{{ 'project.contributors.table.headers.curator' | translate }} @@ -85,8 +85,12 @@

{{ 'project.contributors.curatorInfo.heading' | translate }}

} - {{ 'project.contributors.table.headers.employment' | translate }} - {{ 'project.contributors.table.headers.education' | translate }} + @if (showEmployment()) { + {{ 'project.contributors.table.headers.employment' | translate }} + } + @if (showEducation()) { + {{ 'project.contributors.table.headers.education' | translate }} + } @@ -112,10 +116,15 @@

{{ 'project.contributors.curatorInfo.heading' | translate }}

- +
- @if (showCuratorColumn()) { + @if (showCurator()) {
{{ 'project.contributors.curatorInfo.heading' | translate }} binary="true" [ngModel]="contributor.isCurator" [disabled]="true" + [ariaLabel]="'project.contributors.curatorInfo.heading' | translate" >
} - - @if (contributor.employment?.length) { - - {{ 'project.contributors.employment.show' | translate }} - - } @else { - {{ 'project.contributors.employment.none' | translate }} - } - - -
- @if (contributor.education?.length) { + @if (showEmployment()) { + + @if (contributor.employment?.length) { - {{ 'project.contributors.education.show' | translate }} + {{ 'project.contributors.employment.show' | translate }} } @else { - {{ 'project.contributors.education.none' | translate }} + {{ 'project.contributors.employment.none' | translate }} } -
- + + } + @if (showEducation()) { + +
+ @if (contributor.education?.length) { + + {{ 'project.contributors.education.show' | translate }} + + } @else { + {{ 'project.contributors.education.none' | translate }} + } +
+ + } {{ 'project.contributors.curatorInfo.heading' | translate }} text [ariaLabel]="'common.buttons.delete' | translate" (onClick)="removeContributor(contributor)" + data-test-remove-contributor-button /> diff --git a/src/app/shared/components/contributors/contributors-list/contributors-list.component.spec.ts b/src/app/shared/components/contributors/contributors-list/contributors-list.component.spec.ts index d267bdbdf..2fc1eef8b 100644 --- a/src/app/shared/components/contributors/contributors-list/contributors-list.component.spec.ts +++ b/src/app/shared/components/contributors/contributors-list/contributors-list.component.spec.ts @@ -32,7 +32,7 @@ describe('ContributorsListComponent', () => { it('should have default values', () => { expect(component.contributors()).toEqual([]); expect(component.isLoading()).toBe(false); - expect(component.showCuratorColumn()).toBe(false); + expect(component.showCurator()).toBe(false); }); it('should accept contributors input', () => { @@ -50,11 +50,11 @@ describe('ContributorsListComponent', () => { expect(component.isLoading()).toBe(true); }); - it('should accept showCuratorColumn input', () => { - fixture.componentRef.setInput('showCuratorColumn', true); + it('should accept showCurator input', () => { + fixture.componentRef.setInput('showCurator', true); fixture.detectChanges(); - expect(component.showCuratorColumn()).toBe(true); + expect(component.showCurator()).toBe(true); }); it('should have permissionsOptions defined', () => { @@ -94,10 +94,10 @@ describe('ContributorsListComponent', () => { }); it('should handle curator column visibility', () => { - fixture.componentRef.setInput('showCuratorColumn', true); + fixture.componentRef.setInput('showCurator', true); fixture.detectChanges(); - expect(component.showCuratorColumn()).toBe(true); + expect(component.showCurator()).toBe(true); }); it('should handle all inputs together', () => { @@ -105,12 +105,12 @@ describe('ContributorsListComponent', () => { fixture.componentRef.setInput('contributors', contributors); fixture.componentRef.setInput('isLoading', false); - fixture.componentRef.setInput('showCuratorColumn', true); + fixture.componentRef.setInput('showCurator', true); fixture.detectChanges(); expect(component.contributors()).toEqual(contributors); expect(component.isLoading()).toBe(false); - expect(component.showCuratorColumn()).toBe(true); + expect(component.showCurator()).toBe(true); }); it('should handle empty contributors list', () => { diff --git a/src/app/shared/components/contributors/contributors-list/contributors-list.component.ts b/src/app/shared/components/contributors/contributors-list/contributors-list.component.ts index e0864a4fb..5202d25e1 100644 --- a/src/app/shared/components/contributors/contributors-list/contributors-list.component.ts +++ b/src/app/shared/components/contributors/contributors-list/contributors-list.component.ts @@ -28,7 +28,9 @@ import { SelectComponent } from '../../select/select.component'; export class ContributorsListComponent { contributors = input([]); isLoading = input(false); - showCuratorColumn = input(false); + showCurator = input(false); + showEducation = input(true); + showEmployment = input(true); remove = output(); diff --git a/src/app/shared/components/copy-button/copy-button.component.html b/src/app/shared/components/copy-button/copy-button.component.html index f426260cb..40d0f5c49 100644 --- a/src/app/shared/components/copy-button/copy-button.component.html +++ b/src/app/shared/components/copy-button/copy-button.component.html @@ -6,6 +6,7 @@ text [pTooltip]="(copyItem() ? tooltip() : 'common.labels.noData') | translate" [disabled]="!copyItem()" - (click)="copy()" + (onClick)="copy()" + [ariaLabel]="ariaLabel() | translate" > diff --git a/src/app/shared/components/copy-button/copy-button.component.ts b/src/app/shared/components/copy-button/copy-button.component.ts index 58f7b491e..da15a6240 100644 --- a/src/app/shared/components/copy-button/copy-button.component.ts +++ b/src/app/shared/components/copy-button/copy-button.component.ts @@ -21,6 +21,7 @@ export class CopyButtonComponent { tooltip = input('common.buttons.copy'); label = input(''); severity = input('contrast'); + ariaLabel = input('common.accessibility.copyButtonInfo'); private readonly clipboard = inject(Clipboard); private readonly toastService = inject(ToastService); diff --git a/src/app/shared/components/sub-header/sub-header.component.html b/src/app/shared/components/sub-header/sub-header.component.html index c11b83ec6..32b73bcf6 100644 --- a/src/app/shared/components/sub-header/sub-header.component.html +++ b/src/app/shared/components/sub-header/sub-header.component.html @@ -31,6 +31,7 @@

(onClick)="buttonClick.emit()" [loading]="isSubmitting()" [disabled]="isButtonDisabled()" + data-test-sub-header-button > } diff --git a/src/app/shared/components/subjects/subjects.component.html b/src/app/shared/components/subjects/subjects.component.html index e02642187..862ae009e 100644 --- a/src/app/shared/components/subjects/subjects.component.html +++ b/src/app/shared/components/subjects/subjects.component.html @@ -1,5 +1,7 @@

{{ 'shared.subjects.title' | translate }}

+

{{ 'shared.subjects.description' | translate }}

+ @if (!selected().length) {

{{ 'shared.subjects.noSelected' | translate }}

diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index d64c6ed28..31123445a 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -64,7 +64,8 @@ "tooltipBtn": "Tooltip button", "customizeOptions": "Customize options", "toggleProjectVisibility": "Toggle project visibility", - "tagInput": "Tag input" + "tagInput": "Tag input", + "copyButtonInfo": "Copy to clipboard button" }, "dialogs": { "confirmation": "Confirmation"