From 822db5120ad2d1d663c2c6ff39232e9efad715fe Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Mon, 22 May 2023 16:56:13 +0200 Subject: [PATCH 01/24] 101731: Make ConfirmationModalComponent not dependent on DSpaceObject --- .../epeople-registry/epeople-registry.component.ts | 2 +- .../eperson-form/eperson-form.component.ts | 2 +- .../group-registry/group-form/group-form.component.ts | 2 +- .../confirmation-modal/confirmation-modal.component.html | 8 ++++---- .../confirmation-modal/confirmation-modal.component.ts | 5 +---- .../export-batch-selector.component.ts | 4 +++- .../export-metadata-selector.component.ts | 4 +++- 7 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/app/access-control/epeople-registry/epeople-registry.component.ts b/src/app/access-control/epeople-registry/epeople-registry.component.ts index c7b9907b82..c51070183a 100644 --- a/src/app/access-control/epeople-registry/epeople-registry.component.ts +++ b/src/app/access-control/epeople-registry/epeople-registry.component.ts @@ -228,7 +228,7 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy { deleteEPerson(ePerson: EPerson) { if (hasValue(ePerson.id)) { const modalRef = this.modalService.open(ConfirmationModalComponent); - modalRef.componentInstance.dso = ePerson; + modalRef.componentInstance.name = this.dsoNameService.getName(ePerson); modalRef.componentInstance.headerLabel = 'confirmation-modal.delete-eperson.header'; modalRef.componentInstance.infoLabel = 'confirmation-modal.delete-eperson.info'; modalRef.componentInstance.cancelLabel = 'confirmation-modal.delete-eperson.cancel'; diff --git a/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.ts b/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.ts index ce30062a69..41408c9e8f 100644 --- a/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.ts +++ b/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.ts @@ -454,7 +454,7 @@ export class EPersonFormComponent implements OnInit, OnDestroy { delete() { this.epersonService.getActiveEPerson().pipe(take(1)).subscribe((eperson: EPerson) => { const modalRef = this.modalService.open(ConfirmationModalComponent); - modalRef.componentInstance.dso = eperson; + modalRef.componentInstance.name = this.dsoNameService.getName(eperson); modalRef.componentInstance.headerLabel = 'confirmation-modal.delete-eperson.header'; modalRef.componentInstance.infoLabel = 'confirmation-modal.delete-eperson.info'; modalRef.componentInstance.cancelLabel = 'confirmation-modal.delete-eperson.cancel'; diff --git a/src/app/access-control/group-registry/group-form/group-form.component.ts b/src/app/access-control/group-registry/group-form/group-form.component.ts index b837d80479..37d30c218c 100644 --- a/src/app/access-control/group-registry/group-form/group-form.component.ts +++ b/src/app/access-control/group-registry/group-form/group-form.component.ts @@ -416,7 +416,7 @@ export class GroupFormComponent implements OnInit, OnDestroy { delete() { this.groupDataService.getActiveGroup().pipe(take(1)).subscribe((group: Group) => { const modalRef = this.modalService.open(ConfirmationModalComponent); - modalRef.componentInstance.dso = group; + modalRef.componentInstance.name = this.dsoNameService.getName(group); modalRef.componentInstance.headerLabel = this.messagePrefix + '.delete-group.modal.header'; modalRef.componentInstance.infoLabel = this.messagePrefix + '.delete-group.modal.info'; modalRef.componentInstance.cancelLabel = this.messagePrefix + '.delete-group.modal.cancel'; diff --git a/src/app/shared/confirmation-modal/confirmation-modal.component.html b/src/app/shared/confirmation-modal/confirmation-modal.component.html index 02434b1fa1..ff82f5bc83 100644 --- a/src/app/shared/confirmation-modal/confirmation-modal.component.html +++ b/src/app/shared/confirmation-modal/confirmation-modal.component.html @@ -1,18 +1,18 @@
- diff --git a/src/app/shared/confirmation-modal/confirmation-modal.component.ts b/src/app/shared/confirmation-modal/confirmation-modal.component.ts index 46eb4cedc5..e48986d880 100644 --- a/src/app/shared/confirmation-modal/confirmation-modal.component.ts +++ b/src/app/shared/confirmation-modal/confirmation-modal.component.ts @@ -1,7 +1,5 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; -import { DSpaceObject } from '../../core/shared/dspace-object.model'; -import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; @Component({ selector: 'ds-confirmation-modal', @@ -18,7 +16,7 @@ export class ConfirmationModalComponent { */ @Input() brandColor = 'primary'; - @Input() dso: DSpaceObject; + @Input() name: string; /** * An event fired when the cancel or confirm button is clicked, with respectively false or true @@ -28,7 +26,6 @@ export class ConfirmationModalComponent { constructor( protected activeModal: NgbActiveModal, - public dsoNameService: DSONameService, ) { } diff --git a/src/app/shared/dso-selector/modal-wrappers/export-batch-selector/export-batch-selector.component.ts b/src/app/shared/dso-selector/modal-wrappers/export-batch-selector/export-batch-selector.component.ts index 0645e09029..e5f5eca350 100644 --- a/src/app/shared/dso-selector/modal-wrappers/export-batch-selector/export-batch-selector.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/export-batch-selector/export-batch-selector.component.ts @@ -20,6 +20,7 @@ import { RemoteData } from '../../../../core/data/remote-data'; import { getProcessDetailRoute } from '../../../../process-page/process-page-routing.paths'; import { AuthorizationDataService } from '../../../../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../../../../core/data/feature-authorization/feature-id'; +import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; /** * Component to wrap a list of existing dso's inside a modal @@ -38,6 +39,7 @@ export class ExportBatchSelectorComponent extends DSOSelectorModalWrapperCompone protected notificationsService: NotificationsService, protected translationService: TranslateService, protected scriptDataService: ScriptDataService, protected authorizationDataService: AuthorizationDataService, + protected dsoNameService: DSONameService, private modalService: NgbModal) { super(activeModal, route); } @@ -49,7 +51,7 @@ export class ExportBatchSelectorComponent extends DSOSelectorModalWrapperCompone navigate(dso: DSpaceObject): Observable { if (dso instanceof Collection) { const modalRef = this.modalService.open(ConfirmationModalComponent); - modalRef.componentInstance.dso = dso; + modalRef.componentInstance.name = this.dsoNameService.getName(dso); modalRef.componentInstance.headerLabel = 'confirmation-modal.export-batch.header'; modalRef.componentInstance.infoLabel = 'confirmation-modal.export-batch.info'; modalRef.componentInstance.cancelLabel = 'confirmation-modal.export-batch.cancel'; diff --git a/src/app/shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component.ts b/src/app/shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component.ts index d4b4314a99..d1252bf485 100644 --- a/src/app/shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component.ts @@ -21,6 +21,7 @@ import { RemoteData } from '../../../../core/data/remote-data'; import { getProcessDetailRoute } from '../../../../process-page/process-page-routing.paths'; import { AuthorizationDataService } from '../../../../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../../../../core/data/feature-authorization/feature-id'; +import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; /** * Component to wrap a list of existing dso's inside a modal @@ -39,6 +40,7 @@ export class ExportMetadataSelectorComponent extends DSOSelectorModalWrapperComp protected notificationsService: NotificationsService, protected translationService: TranslateService, protected scriptDataService: ScriptDataService, protected authorizationDataService: AuthorizationDataService, + protected dsoNameService: DSONameService, private modalService: NgbModal) { super(activeModal, route); } @@ -50,7 +52,7 @@ export class ExportMetadataSelectorComponent extends DSOSelectorModalWrapperComp navigate(dso: DSpaceObject): Observable { if (dso instanceof Collection || dso instanceof Community) { const modalRef = this.modalService.open(ConfirmationModalComponent); - modalRef.componentInstance.dso = dso; + modalRef.componentInstance.name = this.dsoNameService.getName(dso); modalRef.componentInstance.headerLabel = 'confirmation-modal.export-metadata.header'; modalRef.componentInstance.infoLabel = 'confirmation-modal.export-metadata.info'; modalRef.componentInstance.cancelLabel = 'confirmation-modal.export-metadata.cancel'; From 7998ef489cc4e30dc0f058d481329e2f39096caa Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 23 Jun 2023 23:38:06 +0200 Subject: [PATCH 02/24] 101731: Make ConfirmationModalComponent not dependent on DSpaceObject --- .../workspace-item-admin-workflow-actions.component.ts | 2 +- .../subscription-view/subscription-view.component.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/admin/admin-workflow-page/admin-workflow-search-results/actions/workspace-item/workspace-item-admin-workflow-actions.component.ts b/src/app/admin/admin-workflow-page/admin-workflow-search-results/actions/workspace-item/workspace-item-admin-workflow-actions.component.ts index 36678460da..8db862dd5a 100644 --- a/src/app/admin/admin-workflow-page/admin-workflow-search-results/actions/workspace-item/workspace-item-admin-workflow-actions.component.ts +++ b/src/app/admin/admin-workflow-page/admin-workflow-search-results/actions/workspace-item/workspace-item-admin-workflow-actions.component.ts @@ -124,7 +124,7 @@ export class WorkspaceItemAdminWorkflowActionsComponent implements OnInit { */ deleteSupervisionOrder(supervisionOrderEntry: SupervisionOrderListEntry) { const modalRef = this.modalService.open(ConfirmationModalComponent); - modalRef.componentInstance.dso = supervisionOrderEntry.group; + modalRef.componentInstance.name = this.dsoNameService.getName(supervisionOrderEntry.group); modalRef.componentInstance.headerLabel = this.messagePrefix + '.delete-supervision.modal.header'; modalRef.componentInstance.infoLabel = this.messagePrefix + '.delete-supervision.modal.info'; modalRef.componentInstance.cancelLabel = this.messagePrefix + '.delete-supervision.modal.cancel'; diff --git a/src/app/shared/subscriptions/subscription-view/subscription-view.component.ts b/src/app/shared/subscriptions/subscription-view/subscription-view.component.ts index 072b8d7828..0362ae6695 100644 --- a/src/app/shared/subscriptions/subscription-view/subscription-view.component.ts +++ b/src/app/shared/subscriptions/subscription-view/subscription-view.component.ts @@ -82,7 +82,7 @@ export class SubscriptionViewComponent { deleteSubscriptionPopup(subscription: Subscription) { if (hasValue(subscription.id)) { const modalRef = this.modalService.open(ConfirmationModalComponent); - modalRef.componentInstance.dso = this.dso; + modalRef.componentInstance.name = this.dsoNameService.getName(this.dso); modalRef.componentInstance.headerLabel = 'confirmation-modal.delete-subscription.header'; modalRef.componentInstance.infoLabel = 'confirmation-modal.delete-subscription.info'; modalRef.componentInstance.cancelLabel = 'confirmation-modal.delete-subscription.cancel'; From 2f5370a08569045239fc73076552d70dfcffe6d8 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 16 Dec 2023 00:55:46 +0100 Subject: [PATCH 03/24] Fixed accessibility issues related to dso selectors - Fixed header ordering - Fixed input field not having a description what it does (because the header isn't always shown I decided to use aria-labels instead of regular labels) --- .../dso-selector/dso-selector/dso-selector.component.html | 1 + .../dso-selector/dso-selector/dso-selector.component.ts | 5 +++++ .../create-community-parent-selector.component.html | 6 +++--- .../create-item-parent-selector.component.html | 2 +- .../dso-selector-modal-wrapper.component.html | 2 +- .../edit-item-selector/edit-item-selector.component.html | 2 +- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/app/shared/dso-selector/dso-selector/dso-selector.component.html b/src/app/shared/dso-selector/dso-selector/dso-selector.component.html index c4f5dbc4cd..295165d171 100644 --- a/src/app/shared/dso-selector/dso-selector/dso-selector.component.html +++ b/src/app/shared/dso-selector/dso-selector/dso-selector.component.html @@ -2,6 +2,7 @@
diff --git a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts index 503e4c4412..4590e05363 100644 --- a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts +++ b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts @@ -75,6 +75,11 @@ export class DSOSelectorComponent implements OnInit, OnDestroy { */ @Input() sort: SortOptions; + /** + * The id that should be given to the input box, this is required for accessibility reasons + */ + @Input() searchBoxId: string | null = null; + // list of allowed selectable dsoTypes typesString: string; diff --git a/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.html b/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.html index a13be63880..8ae146b42c 100644 --- a/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.html +++ b/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.html @@ -6,14 +6,14 @@ -
{{'dso-selector.create.community.sub-level' | translate}}
+ {{'dso-selector.create.community.sub-level' | translate}} diff --git a/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.html b/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.html index 5fccd58f48..5288f08e02 100644 --- a/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.html +++ b/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.html @@ -5,7 +5,7 @@ diff --git a/src/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.html b/src/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.html index 85d8797e66..999a96e730 100644 --- a/src/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.html +++ b/src/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.html @@ -5,7 +5,7 @@ From 086c5463a8c1e84145139dd2ad084749d275a62a Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 16 Dec 2023 00:56:30 +0100 Subject: [PATCH 04/24] Removed invisible buttons on the CommunityListComponent & fixed content displacement when expanding com/col --- .../community-list.component.html | 46 +++++++++---------- .../community-list.component.scss | 4 ++ .../community-list.component.spec.ts | 35 +++++++------- .../community-list.component.ts | 1 + src/assets/i18n/en.json5 | 4 ++ 5 files changed, 51 insertions(+), 39 deletions(-) create mode 100644 src/app/community-list-page/community-list/community-list.component.scss diff --git a/src/app/community-list-page/community-list/community-list.component.html b/src/app/community-list-page/community-list/community-list.component.html index de67607bb4..5e3d6c5fa5 100644 --- a/src/app/community-list-page/community-list/community-list.component.html +++ b/src/app/community-list-page/community-list/community-list.component.html @@ -4,9 +4,9 @@
- +
+ +
@@ -46,10 +49,9 @@
- + {{node.payload.shortDescription}} @@ -58,10 +60,9 @@
- +
@@ -69,9 +70,9 @@
- +
{{ dsoNameService.getName(node.payload) }} @@ -81,10 +82,9 @@
- + {{node.payload.shortDescription}} diff --git a/src/app/community-list-page/community-list/community-list.component.scss b/src/app/community-list-page/community-list/community-list.component.scss new file mode 100644 index 0000000000..2e33380a29 --- /dev/null +++ b/src/app/community-list-page/community-list/community-list.component.scss @@ -0,0 +1,4 @@ +::ng-deep .fa-chevron-right::before { + display: block; + width: 16px; +} diff --git a/src/app/community-list-page/community-list/community-list.component.spec.ts b/src/app/community-list-page/community-list/community-list.component.spec.ts index fb47f4994d..cec1b555ab 100644 --- a/src/app/community-list-page/community-list/community-list.component.spec.ts +++ b/src/app/community-list-page/community-list/community-list.component.spec.ts @@ -5,7 +5,7 @@ import { CommunityListService, showMoreFlatNode, toFlatNode } from '../community import { CdkTreeModule } from '@angular/cdk/tree'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; -import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA, DebugElement } from '@angular/core'; import { RouterTestingModule } from '@angular/router/testing'; import { Community } from '../../core/shared/community.model'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; @@ -300,12 +300,14 @@ describe('CommunityListComponent', () => { describe('second top community node is expanded and has more children (collections) than page size of collection', () => { describe('children of second top com are added (page-limited pageSize 2)', () => { - let allNodes; + let allNodes: DebugElement[]; beforeEach(fakeAsync(() => { - const chevronExpand = fixture.debugElement.queryAll(By.css('.expandable-node button')); - const chevronExpandSpan = fixture.debugElement.queryAll(By.css('.expandable-node button span')); - if (chevronExpandSpan[1].nativeElement.classList.contains('fa-chevron-right')) { - chevronExpand[1].nativeElement.click(); + const toggleButtons: DebugElement[] = fixture.debugElement.queryAll(By.css('.expandable-node button')); + const toggleButtonText: DebugElement = toggleButtons[1].query(By.css('span')); + expect(toggleButtonText).not.toBeNull(); + + if (toggleButtonText.nativeElement.classList.contains('fa-chevron-right')) { + toggleButtons[1].nativeElement.click(); tick(); fixture.detectChanges(); } @@ -315,17 +317,18 @@ describe('CommunityListComponent', () => { allNodes = [...expandableNodesFound, ...childlessNodesFound]; })); it('tree contains 2 (page-limited) top com, 2 (page-limited) coll of 2nd top com, a show more for those page-limited coll and show more for page-limited top com', () => { - mockTopFlatnodesUnexpanded.slice(0, 2).map((topFlatnode: FlatNode) => { - expect(allNodes.find((foundEl) => { - return (foundEl.nativeElement.textContent.trim() === topFlatnode.name); - })).toBeTruthy(); - }); - mockCollectionsPage1.map((coll) => { - expect(allNodes.find((foundEl) => { - return (foundEl.nativeElement.textContent.trim() === coll.name); - })).toBeTruthy(); - }); + const allNodeNames: string[] = allNodes.map((node: DebugElement) => node.nativeElement.innerText.trim()); expect(allNodes.length).toEqual(4); + const flatNodes: string[] = mockTopFlatnodesUnexpanded.slice(0, 2).map((flatNode: FlatNode) => flatNode.name); + for (const flatNode of flatNodes) { + expect(allNodeNames).toContain(flatNode); + } + expect(flatNodes.length).toBe(2); + const page1CollectionNames: string[] = mockCollectionsPage1.map((collection: Collection) => collection.name); + for (const collectionName of page1CollectionNames) { + expect(allNodeNames).toContain(collectionName); + } + expect(page1CollectionNames.length).toBe(2); const showMoreEl = fixture.debugElement.queryAll(By.css('.show-more-node')); expect(showMoreEl.length).toEqual(2); }); diff --git a/src/app/community-list-page/community-list/community-list.component.ts b/src/app/community-list-page/community-list/community-list.component.ts index 6b5c6578e1..031a422469 100644 --- a/src/app/community-list-page/community-list/community-list.component.ts +++ b/src/app/community-list-page/community-list/community-list.component.ts @@ -19,6 +19,7 @@ import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; @Component({ selector: 'ds-community-list', templateUrl: './community-list.component.html', + styleUrls: ['./community-list.component.scss'], }) export class CommunityListComponent implements OnInit, OnDestroy { diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index d7c50b1a60..4f25ae0d0f 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1168,6 +1168,10 @@ "communityList.showMore": "Show More", + "communityList.expand": "Expand {{ name }}", + + "communityList.collapse": "Collapse {{ name }}", + "community.create.head": "Create a Community", "community.create.notifications.success": "Successfully created the Community", From 3c1243f6f183d12fa39a15984077086f41c264fc Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sat, 16 Dec 2023 01:31:34 +0100 Subject: [PATCH 05/24] Fixed search filters having empty input buttons --- .../org-unit-input-suggestions.component.html | 4 +++- .../org-unit-input-suggestions.component.spec.ts | 2 ++ .../person-input-suggestions.component.html | 4 +++- .../dso-input-suggestions.component.html | 4 +++- .../filter-input-suggestions.component.html | 7 +++---- .../input-suggestions/input-suggestions.component.html | 4 +++- .../validation-suggestions.component.html | 4 +++- .../search-range-filter/search-range-filter.component.html | 7 +++---- 8 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/app/entity-groups/research-entities/submission/item-list-elements/org-unit/org-unit-suggestions/org-unit-input-suggestions.component.html b/src/app/entity-groups/research-entities/submission/item-list-elements/org-unit/org-unit-suggestions/org-unit-input-suggestions.component.html index c4e31d3d81..58f39b8d0b 100644 --- a/src/app/entity-groups/research-entities/submission/item-list-elements/org-unit/org-unit-suggestions/org-unit-input-suggestions.component.html +++ b/src/app/entity-groups/research-entities/submission/item-list-elements/org-unit/org-unit-suggestions/org-unit-input-suggestions.component.html @@ -11,7 +11,9 @@ [dsDebounce]="debounceTime" (onDebounce)="find($event)" [placeholder]="placeholder" [ngModelOptions]="{standalone: true}" autocomplete="off"/> - +