Removed invisible buttons on the CommunityListComponent & fixed content displacement when expanding com/col

This commit is contained in:
Alexandre Vryghem
2023-12-16 00:56:30 +01:00
parent 2f5370a085
commit 086c5463a8
5 changed files with 51 additions and 39 deletions

View File

@@ -4,9 +4,9 @@
<cdk-tree-node *cdkTreeNodeDef="let node; when: isShowMore" cdkTreeNodePadding <cdk-tree-node *cdkTreeNodeDef="let node; when: isShowMore" cdkTreeNodePadding
class="example-tree-node show-more-node"> class="example-tree-node show-more-node">
<div class="btn-group"> <div class="btn-group">
<button type="button" class="btn btn-default" cdkTreeNodeToggle> <span aria-hidden="true" class="btn btn-default invisible" cdkTreeNodeToggle>
<span class="fa fa-chevron-right invisible" aria-hidden="true"></span> <span class="fa fa-chevron-right"></span>
</button> </span>
<div class="align-middle pt-2"> <div class="align-middle pt-2">
<button *ngIf="!(dataSource.loading$ | async)" (click)="getNextPage(node)" <button *ngIf="!(dataSource.loading$ | async)" (click)="getNextPage(node)"
class="btn btn-outline-primary btn-sm" role="button"> class="btn btn-outline-primary btn-sm" role="button">
@@ -24,15 +24,18 @@
<cdk-tree-node *cdkTreeNodeDef="let node; when: hasChild" cdkTreeNodePadding <cdk-tree-node *cdkTreeNodeDef="let node; when: hasChild" cdkTreeNodePadding
class="example-tree-node expandable-node"> class="example-tree-node expandable-node">
<div class="btn-group"> <div class="btn-group">
<button type="button" class="btn btn-default" cdkTreeNodeToggle <button *ngIf="hasChild(null, node) | async" type="button" class="btn btn-default" cdkTreeNodeToggle
[title]="'toggle ' + dsoNameService.getName(node.payload)" [attr.aria-label]="(node.isExpanded ? 'communityList.collapse' : 'communityList.expand') | translate:{ name: dsoNameService.getName(node.payload) }"
[attr.aria-label]="'toggle ' + dsoNameService.getName(node.payload)"
(click)="toggleExpanded(node)" (click)="toggleExpanded(node)"
[ngClass]="(hasChild(null, node)| async) ? 'visible' : 'invisible'" data-test="expand-button">
[attr.data-test]="(hasChild(null, node)| async) ? 'expand-button' : ''">
<span class="{{node.isExpanded ? 'fa fa-chevron-down' : 'fa fa-chevron-right'}}" <span class="{{node.isExpanded ? 'fa fa-chevron-down' : 'fa fa-chevron-right'}}"
aria-hidden="true"></span> aria-hidden="true"></span>
<span class="sr-only">{{ (node.isExpanded ? 'communityList.collapse' : 'communityList.expand') | translate:{ name: dsoNameService.getName(node.payload) } }}</span>
</button> </button>
<!--Don't render the button when non-expandable otherwise it's still accessible, instead render this placeholder-->
<span *ngIf="!(hasChild(null, node) | async)" aria-hidden="true" class="btn btn-default invisible">
<span class="fa fa-chevron-right"></span>
</span>
<div class="d-flex flex-row"> <div class="d-flex flex-row">
<span class="align-middle pt-2 lead"> <span class="align-middle pt-2 lead">
<a [routerLink]="node.route" class="lead"> <a [routerLink]="node.route" class="lead">
@@ -46,10 +49,9 @@
<ds-truncatable [id]="node.id"> <ds-truncatable [id]="node.id">
<div class="text-muted" cdkTreeNodePadding> <div class="text-muted" cdkTreeNodePadding>
<div class="d-flex" *ngIf="node.payload.shortDescription"> <div class="d-flex" *ngIf="node.payload.shortDescription">
<button type="button" class="btn btn-default invisible"> <span aria-hidden="true" class="btn btn-default invisible">
<span class="{{node.isExpanded ? 'fa fa-chevron-down' : 'fa fa-chevron-right'}}" <span class="fa fa-chevron-right"></span>
aria-hidden="true"></span> </span>
</button>
<ds-truncatable-part [id]="node.id" [minLines]="3"> <ds-truncatable-part [id]="node.id" [minLines]="3">
<span>{{node.payload.shortDescription}}</span> <span>{{node.payload.shortDescription}}</span>
</ds-truncatable-part> </ds-truncatable-part>
@@ -58,10 +60,9 @@
</ds-truncatable> </ds-truncatable>
<div class="d-flex" *ngIf="node===loadingNode && dataSource.loading$ | async" <div class="d-flex" *ngIf="node===loadingNode && dataSource.loading$ | async"
cdkTreeNodePadding> cdkTreeNodePadding>
<button type="button" class="btn btn-default invisible"> <span aria-hidden="true" class="btn btn-default invisible">
<span class="{{node.isExpanded ? 'fa fa-chevron-down' : 'fa fa-chevron-right'}}" <span class="fa fa-chevron-right"></span>
aria-hidden="true"></span> </span>
</button>
<ds-themed-loading class="ds-themed-loading"></ds-themed-loading> <ds-themed-loading class="ds-themed-loading"></ds-themed-loading>
</div> </div>
</cdk-tree-node> </cdk-tree-node>
@@ -69,9 +70,9 @@
<cdk-tree-node *cdkTreeNodeDef="let node; when: !(hasChild && isShowMore)" cdkTreeNodePadding <cdk-tree-node *cdkTreeNodeDef="let node; when: !(hasChild && isShowMore)" cdkTreeNodePadding
class="example-tree-node childless-node"> class="example-tree-node childless-node">
<div class="btn-group"> <div class="btn-group">
<button type="button" class="btn btn-default" cdkTreeNodeToggle> <span aria-hidden="true" class="btn btn-default invisible" cdkTreeNodeToggle>
<span class="fa fa-chevron-right invisible" aria-hidden="true"></span> <span class="fa fa-chevron-right"></span>
</button> </span>
<h6 class="align-middle pt-2"> <h6 class="align-middle pt-2">
<a [routerLink]="node.route" class="lead"> <a [routerLink]="node.route" class="lead">
{{ dsoNameService.getName(node.payload) }} {{ dsoNameService.getName(node.payload) }}
@@ -81,10 +82,9 @@
<ds-truncatable [id]="node.id"> <ds-truncatable [id]="node.id">
<div class="text-muted" cdkTreeNodePadding> <div class="text-muted" cdkTreeNodePadding>
<div class="d-flex" *ngIf="node.payload.shortDescription"> <div class="d-flex" *ngIf="node.payload.shortDescription">
<button type="button" class="btn btn-default invisible"> <span aria-hidden="true" class="btn btn-default invisible">
<span class="{{node.isExpanded ? 'fa fa-chevron-down' : 'fa fa-chevron-right'}}" <span class="fa fa-chevron-right"></span>
aria-hidden="true"></span> </span>
</button>
<ds-truncatable-part [id]="node.id" [minLines]="3"> <ds-truncatable-part [id]="node.id" [minLines]="3">
<span>{{node.payload.shortDescription}}</span> <span>{{node.payload.shortDescription}}</span>
</ds-truncatable-part> </ds-truncatable-part>

View File

@@ -0,0 +1,4 @@
::ng-deep .fa-chevron-right::before {
display: block;
width: 16px;
}

View File

@@ -5,7 +5,7 @@ import { CommunityListService, showMoreFlatNode, toFlatNode } from '../community
import { CdkTreeModule } from '@angular/cdk/tree'; import { CdkTreeModule } from '@angular/cdk/tree';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; 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 { RouterTestingModule } from '@angular/router/testing';
import { Community } from '../../core/shared/community.model'; import { Community } from '../../core/shared/community.model';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; 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('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)', () => { describe('children of second top com are added (page-limited pageSize 2)', () => {
let allNodes; let allNodes: DebugElement[];
beforeEach(fakeAsync(() => { beforeEach(fakeAsync(() => {
const chevronExpand = fixture.debugElement.queryAll(By.css('.expandable-node button')); const toggleButtons: DebugElement[] = fixture.debugElement.queryAll(By.css('.expandable-node button'));
const chevronExpandSpan = fixture.debugElement.queryAll(By.css('.expandable-node button span')); const toggleButtonText: DebugElement = toggleButtons[1].query(By.css('span'));
if (chevronExpandSpan[1].nativeElement.classList.contains('fa-chevron-right')) { expect(toggleButtonText).not.toBeNull();
chevronExpand[1].nativeElement.click();
if (toggleButtonText.nativeElement.classList.contains('fa-chevron-right')) {
toggleButtons[1].nativeElement.click();
tick(); tick();
fixture.detectChanges(); fixture.detectChanges();
} }
@@ -315,17 +317,18 @@ describe('CommunityListComponent', () => {
allNodes = [...expandableNodesFound, ...childlessNodesFound]; 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', () => { 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) => { const allNodeNames: string[] = allNodes.map((node: DebugElement) => node.nativeElement.innerText.trim());
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();
});
expect(allNodes.length).toEqual(4); 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')); const showMoreEl = fixture.debugElement.queryAll(By.css('.show-more-node'));
expect(showMoreEl.length).toEqual(2); expect(showMoreEl.length).toEqual(2);
}); });

View File

@@ -19,6 +19,7 @@ import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
@Component({ @Component({
selector: 'ds-community-list', selector: 'ds-community-list',
templateUrl: './community-list.component.html', templateUrl: './community-list.component.html',
styleUrls: ['./community-list.component.scss'],
}) })
export class CommunityListComponent implements OnInit, OnDestroy { export class CommunityListComponent implements OnInit, OnDestroy {

View File

@@ -1168,6 +1168,10 @@
"communityList.showMore": "Show More", "communityList.showMore": "Show More",
"communityList.expand": "Expand {{ name }}",
"communityList.collapse": "Collapse {{ name }}",
"community.create.head": "Create a Community", "community.create.head": "Create a Community",
"community.create.notifications.success": "Successfully created the Community", "community.create.notifications.success": "Successfully created the Community",