ACA-3426 - Search Headers for Document List (#5800)

* [ACA-3426] Move filter-menu inside search and renamed as search-header

* [ACA-3426] adf-search-header removed from document-list and implemented in app-files

* [ACA-3426] Allow custom header filters inside document-list

* [ACA-3426] Decouple search from the document-list

* [ACA-3409] NodePaging ouputed to the DL

* [ACA-3426] - fixed injection for service

* Dev baptiste aca 3430 (#5773)

* [ACA-3430] Add style to filter and hide action buttons from facet widgets

* [ACA-3430] Update eventEmitter created in the DL and create  unit tests for the search-header

Co-authored-by: BaptisteMahe <mahe.baptiste.19@gmail.com>

* [ACA-3426] - added parent for service

* [ACA-3426] - added parent for service - fixed method

* [ACA-3426] Revert update EventEmitter inside DL

* [ACA-3436] Use of the node input instead of nodeUpdate mehtod

* [ACA-3426] Add clear behaviour to search-header

* [ACA-3426] Remove useless update exposition

* [ACA-3426] Update filter button styles and padding inside the filter menu

* [ACA-3443] Propagate filters states through DL and datatable to avoid hiding the header

* [ACA-3426] Refactor showHeader logic and use it for the filters

* [ACA-3426] - fixed pagination for filter result

* [ACA-3426] - fixed messed files after rebase

* [ACA-3426] - added simplified config version

* [ACA-3426] - enabling created by filter

* [ACA-3426] Fix search-date-range apply method

* [ACA-3426] Fix loading style and default showHeaderMode

* [ACA-3426] Changed showHedaer default to always

* [ACA-3426] - stabilised the feature and added injection token

* [ACA-3426] Add unit test for showHeader new behaviour

* [ACA-3426] Add documentation to search-header

* [ACA-3426] - added parent filtering for special folders

* [ACA-3426] - added unit test for search header

* [ACA-3426] - fixed search fitler behavour

* [ACA-3426] - fixed search result inject service

* [ACA-3426] - fixed search result inject service for search sorting

* [ACA-3426] - fixed title for matching selector

* [ACA-3426] - fixed app config with missing search widget

* Update search-header.component.md

Co-authored-by: BaptisteMahe <mahe.baptiste.19@gmail.com>
Co-authored-by: Eugenio Romano <eromano@users.noreply.github.com>
This commit is contained in:
Vito
2020-06-22 09:24:57 +01:00
committed by GitHub
parent 5a0ba6666d
commit 29d953e2d1
54 changed files with 1888 additions and 544 deletions

View File

@@ -4,11 +4,12 @@
[class.adf-datatable-card]="display === 'gallery'"
[class.adf-datatable-list]="display === 'list'"
[class.adf-sticky-header]="isStickyHeaderEnabled()"
[class.adf-datatable--empty]="!isHeaderVisible()">
<div *ngIf="isHeaderVisible()" class="adf-datatable-header" role="rowgroup" [ngClass]="{ 'adf-sr-only': !showHeader }">
[class.adf-datatable--empty]="(isEmpty() && !isHeaderVisible()) || loading"
[class.adf-datatable--empty--header-visible]="isEmpty() && isHeaderVisible()">
<div *ngIf="isHeaderVisible()" class="adf-datatable-header" role="rowgroup" [ngClass]="{ 'adf-sr-only': !isHeaderVisible() }">
<adf-datatable-row
data-automation-id="datatable-row-header"
[disabled]="!showHeader"
[disabled]="!isHeaderVisible()"
class="adf-datatable-row"
*ngIf="display === 'list'"
role="row">
@@ -29,19 +30,19 @@
(click)="onColumnHeaderClick(col)"
(keyup.enter)="onColumnHeaderClick(col)"
role="columnheader"
[attr.tabindex]="showHeader ? 0 : null"
[attr.tabindex]="isHeaderVisible() ? 0 : null"
[attr.aria-sort]="col.sortable ? (getAriaSort(col) | translate) : null"
adf-drop-zone dropTarget="header" [dropColumn]="col">
<span *ngIf="col.title" class="adf-datatable-cell-value">{{ col.title | translate}}</span>
<span *ngIf="col.title && col.sortable" class="adf-sr-only" aria-live="polite">{{ getSortLiveAnnouncement(col) | translate: { string: col.title | translate } }}</span>
<ng-template *ngIf="allowFiltering" [ngTemplateOutlet]="filterTemplateRef" [ngTemplateOutletContext]="{$implicit: col}"></ng-template>
<ng-template *ngIf="allowFiltering" [ngTemplateOutlet]="headerFilterTemplate" [ngTemplateOutletContext]="{$implicit: col}"></ng-template>
</div>
<!-- Actions (right) -->
<div *ngIf="actions && actionsPosition === 'right'" class="adf-actions-column adf-datatable-cell-header adf-datatable__actions-cell">
<span class="adf-sr-only">{{ 'ADF-DATATABLE.ACCESSIBILITY.ACTIONS' | translate }}</span>
</div>
</adf-datatable-row>
<mat-form-field *ngIf="display === 'gallery' && showHeader">
<mat-form-field *ngIf="display === 'gallery' && isHeaderVisible()">
<mat-select [value]="getSortingKey()" [attr.data-automation-id]="'grid-view-sorting'">
<mat-option *ngFor="let col of getSortableColumns()"
[value]="col.key"

View File

@@ -334,6 +334,7 @@
color: $data-table-header-color;
padding-bottom: 8px;
box-sizing: border-box;
padding-top: 12px !important;
&.adf-sortable {
@include adf-no-select;
@@ -653,4 +654,28 @@
}
}
}
.adf-datatable--empty--header-visible {
.adf-datatable-header {
border: $data-table-dividers-wrapper-border;
}
.adf-datatable-body {
@include flex-column;
justify-content: center;
align-items: center;
.adf-datatable-row {
height: 100%;
background-color: mat-color($background, card);
border: none !important;
&:hover, &:focus {
background-color: unset;
cursor: default;
}
}
}
}
}

View File

@@ -23,7 +23,7 @@ import { DataRow } from '../../data/data-row.model';
import { DataSorting } from '../../data/data-sorting.model';
import { ObjectDataColumn } from '../../data/object-datacolumn.model';
import { ObjectDataTableAdapter } from '../../data/object-datatable-adapter';
import { DataTableComponent } from './datatable.component';
import { DataTableComponent, ShowHeaderMode } from './datatable.component';
import { setupTestBed } from '../../../testing/setup-test-bed';
import { CoreTestingModule } from '../../../testing/core.testing.module';
import { DataColumnListComponent } from '../../../data-column/data-column-list.component';
@@ -160,7 +160,8 @@ describe('DataTable', () => {
expect(element.querySelector('.adf-datatable-list')).not.toBeNull();
});
it('should hide the header if showHeader is false', () => {
describe('Header modes', () => {
const newData = new ObjectDataTableAdapter(
[
{ name: '1' },
@@ -168,65 +169,113 @@ describe('DataTable', () => {
],
[new ObjectDataColumn({ key: 'name' })]
);
const emptyData = new ObjectDataTableAdapter();
dataTable.showHeader = false;
dataTable.loading = false;
dataTable.ngOnChanges({
data: new SimpleChange(null, newData, false)
it('should show the header if showHeader is `Data` and there is data', () => {
dataTable.showHeader = ShowHeaderMode.Data;
dataTable.loading = false;
dataTable.ngOnChanges({
data: new SimpleChange(null, newData, false)
});
fixture.detectChanges();
expect(element.querySelector('.adf-datatable-header')).toBeDefined();
});
fixture.detectChanges();
it('should hide the header if showHeader is `Data` and there is no data', () => {
expect(element.querySelector('.adf-datatable-header')).toBe(null);
});
dataTable.showHeader = ShowHeaderMode.Data;
dataTable.loading = false;
dataTable.ngOnChanges({
data: new SimpleChange(null, emptyData, false)
});
it('should hide the header if there are no elements inside', () => {
const newData = new ObjectDataTableAdapter(
);
fixture.detectChanges();
dataTable.ngOnChanges({
data: new SimpleChange(null, newData, false)
expect(element.querySelector('.adf-datatable-header')).toBeNull();
});
fixture.detectChanges();
it('should always show the header if showHeader is `Always`', () => {
expect(element.querySelector('.adf-datatable-header')).toBe(null);
});
dataTable.showHeader = ShowHeaderMode.Always;
dataTable.loading = false;
it('should hide the header if noPermission is true', () => {
const newData = new ObjectDataTableAdapter(
);
dataTable.ngOnChanges({
data: new SimpleChange(null, newData, false)
});
fixture.detectChanges();
expect(element.querySelector('.adf-datatable-header')).toBeDefined();
dataTable.noPermission = true;
dataTable.loading = false;
dataTable.ngOnChanges({
data: new SimpleChange(null, newData, false)
dataTable.ngOnChanges({
data: new SimpleChange(null, emptyData, false)
});
fixture.detectChanges();
expect(element.querySelector('.adf-datatable-header')).toBeDefined();
});
fixture.detectChanges();
it('should never show the header if showHeader is `Never`', () => {
expect(element.querySelector('.adf-datatable-header')).toBe(null);
});
dataTable.showHeader = ShowHeaderMode.Never;
dataTable.loading = false;
dataTable.ngOnChanges({
data: new SimpleChange(null, newData, false)
});
it('should show the header if showHeader is true', () => {
const newData = new ObjectDataTableAdapter(
[
{ name: '1' },
{ name: '2' }
],
[new ObjectDataColumn({ key: 'name' })]
);
dataTable.showHeader = true;
dataTable.loading = false;
fixture.detectChanges();
dataTable.ngOnChanges({
data: new SimpleChange(null, newData, false)
expect(element.querySelector('.adf-datatable-header')).toBeNull();
dataTable.ngOnChanges({
data: new SimpleChange(null, emptyData, false)
});
fixture.detectChanges();
expect(element.querySelector('.adf-datatable-header')).toBeNull();
});
fixture.detectChanges();
it('should never show the header if noPermission is true', () => {
expect(element.querySelector('.adf-datatable-header')).toBeDefined();
dataTable.loading = false;
dataTable.noPermission = true;
dataTable.ngOnChanges({
data: new SimpleChange(null, emptyData, false)
});
dataTable.showHeader = ShowHeaderMode.Data;
fixture.detectChanges();
expect(element.querySelector('.adf-datatable-header')).toBeNull();
dataTable.showHeader = ShowHeaderMode.Always;
fixture.detectChanges();
expect(element.querySelector('.adf-datatable-header')).toBeNull();
dataTable.showHeader = ShowHeaderMode.Never;
fixture.detectChanges();
expect(element.querySelector('.adf-datatable-header')).toBeNull();
});
it('should never show the header if loading is true', () => {
dataTable.loading = true;
dataTable.ngOnChanges({
data: new SimpleChange(null, emptyData, false)
});
dataTable.showHeader = ShowHeaderMode.Data;
fixture.detectChanges();
expect(element.querySelector('.adf-datatable-header')).toBeNull();
dataTable.showHeader = ShowHeaderMode.Always;
fixture.detectChanges();
expect(element.querySelector('.adf-datatable-header')).toBeNull();
dataTable.showHeader = ShowHeaderMode.Never;
fixture.detectChanges();
expect(element.querySelector('.adf-datatable-header')).toBeNull();
});
});
it('should emit "sorting-changed" DOM event', (done) => {
@@ -1394,7 +1443,7 @@ describe('Accesibility', () => {
expect(document.activeElement.getAttribute('data-automation-id')).toBe('datatable-row-0');
});
it('should select header row when `showHeader` is true', () => {
it('should select header row when `showHeader` is `Always`', () => {
const event = new KeyboardEvent('keyup', {
code: 'ArrowUp',
key: 'ArrowUp',
@@ -1408,7 +1457,7 @@ describe('Accesibility', () => {
[new ObjectDataColumn({ key: 'name' })]
);
dataTable.showHeader = true;
dataTable.showHeader = ShowHeaderMode.Always;
dataTable.ngOnChanges({
rows: new SimpleChange(null, dataRows, false)
@@ -1426,7 +1475,7 @@ describe('Accesibility', () => {
expect(document.activeElement.getAttribute('data-automation-id')).toBe('datatable-row-header');
});
it('should not select header row when `showHeader` is false', () => {
it('should not select header row when `showHeader` is `Never`', () => {
const event = new KeyboardEvent('keyup', {
code: 'ArrowUp',
key: 'ArrowUp',
@@ -1440,7 +1489,7 @@ describe('Accesibility', () => {
[new ObjectDataColumn({ key: 'name' })]
);
dataTable.showHeader = false;
dataTable.showHeader = ShowHeaderMode.Never;
dataTable.ngOnChanges({
rows: new SimpleChange(null, dataRows, false)
@@ -1459,7 +1508,7 @@ describe('Accesibility', () => {
});
it('should remove cell focus when [focus] is set to false', () => {
dataTable.showHeader = false;
dataTable.showHeader = ShowHeaderMode.Never;
const dataRows = [ { name: 'name1' } ];
dataTable.data = new ObjectDataTableAdapter([],
@@ -1478,7 +1527,7 @@ describe('Accesibility', () => {
});
it('should allow element focus when [focus] is set to true', () => {
dataTable.showHeader = false;
dataTable.showHeader = ShowHeaderMode.Never;
const dataRows = [ { name: 'name1' } ];
dataTable.data = new ObjectDataTableAdapter([],

View File

@@ -43,6 +43,12 @@ export enum DisplayMode {
Gallery = 'gallery'
}
export enum ShowHeaderMode {
Never = 'never',
Always = 'always',
Data = 'data'
}
@Component({
selector: 'adf-datatable',
styleUrls: ['./datatable.component.scss'],
@@ -119,7 +125,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
/** Toggles the header. */
@Input()
showHeader: boolean = true;
showHeader: string = ShowHeaderMode.Data;
/** Toggles the sticky header mode. */
@Input()
@@ -175,9 +181,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
@Input()
allowFiltering: boolean = false;
@ContentChild(TemplateRef)
filterTemplateRef: TemplateRef<any>;
headerFilterTemplate: TemplateRef<any>;
noContentTemplate: TemplateRef<any>;
noPermissionTemplate: TemplateRef<any>;
loadingTemplate: TemplateRef<any>;
@@ -738,7 +742,16 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
}
isHeaderVisible() {
return !this.loading && !this.isEmpty() && !this.noPermission;
let headerVisibility: boolean;
if (this.showHeader === ShowHeaderMode.Data) {
headerVisibility = !this.loading && !this.noPermission && !this.isEmpty();
} else if (this.showHeader === ShowHeaderMode.Always) {
headerVisibility = !this.loading && !this.noPermission;
} else if (this.showHeader === ShowHeaderMode.Never) {
headerVisibility = false;
}
return headerVisibility;
}
isStickyHeaderEnabled() {