diff --git a/demo-shell/resources/i18n/en.json b/demo-shell/resources/i18n/en.json
index 78139b5851..01d57fd935 100644
--- a/demo-shell/resources/i18n/en.json
+++ b/demo-shell/resources/i18n/en.json
@@ -43,6 +43,7 @@
"DESCRIPTION_UPLOAD" : "Enable upload",
"ENABLE_INFINITE_SCROLL":"Enable Infinite Scrolling",
"MULTISELECT_DESCRIPTION" : "Use Cmd (Mac) or Ctrl (Windows) to toggle selection of multiple items",
+ "RECENT" : "Recent Files",
"COLUMNS": {
"DISPLAY_NAME": "Display name",
"TAG": "Tag",
@@ -50,6 +51,13 @@
"CREATED_ON": "Created on",
"CREATED": "Created"
},
+ "TOOLBAR": {
+ "CARDVIEW":"Card view mode",
+ "NEW_FOLDER":"New folder",
+ "EDIT_FOLDER":"Edit folder",
+ "DOWNLOAD":"Download",
+ "DELETE":"Delete"
+ },
"ACTIONS": {
"DOWNLOAD": "Download",
"FOLDER": {
diff --git a/demo-shell/src/app/components/files/files.component.html b/demo-shell/src/app/components/files/files.component.html
index 3526931db5..32d936f184 100644
--- a/demo-shell/src/app/components/files/files.component.html
+++ b/demo-shell/src/app/components/files/files.component.html
@@ -1,15 +1,33 @@
+
+
+
+ history{{ 'DOCUMENT_LIST.RECENT' | translate }}
+
+
+
+
+
+
+
+ [disabled]="disableDragArea"
+ [parentId]="getDocumentListCurrentFolderId()"
+ [versioning]="versioning"
+ [adf-node-permission]="'create'"
+ [adf-nodes]="disableDragArea ? getCurrentDocumentListNode() : []">
+
diff --git a/lib/core/datatable/components/datatable/datatable.component.scss b/lib/core/datatable/components/datatable/datatable.component.scss
index 861858c4a8..566545937d 100644
--- a/lib/core/datatable/components/datatable/datatable.component.scss
+++ b/lib/core/datatable/components/datatable/datatable.component.scss
@@ -1,4 +1,3 @@
-
@mixin adf-datatable-theme($theme) {
$foreground: map-get($theme, foreground);
$background: map-get($theme, background);
@@ -26,7 +25,148 @@
$data-table-cell-top: $data-table-card-padding / 2;
$data-table-drag-border: 1px dashed rgb(68, 138, 255);
+ .adf-data-table-card {
+
+ border: 1px solid mat-color($foreground, divider);
+
+ .sr-only {
+ }
+
+ .adf-datatable-body {
+ flex-flow: row wrap;
+ display: flex;
+
+ width: 100%;
+ flex-direction: row;
+ justify-content: space-between;
+
+ &:after {
+ content: "";
+ flex: auto;
+ }
+
+ .adf-datatable-row {
+ transition: all 0.3s ease;
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ flex: 0 1 24%;
+
+ width: 288px !important;
+ max-width: 288px !important;
+ min-width: 288px !important;
+
+ height: 200px !important;
+
+ overflow: hidden !important;
+ margin: 6px;
+ padding: 15px;
+
+ @include mat-elevation-transition;
+ @include mat-overridable-elevation(2);
+ }
+
+ .is-selected {
+ background: mat-color($primary, 100);
+ padding-bottom: 31px;
+ }
+
+ .adf-data-table-card-permission {
+ width: 100%;
+ min-height: 250px;
+
+ .adf-datatable-table-cell {
+ height: 240px !important;
+ }
+ }
+
+ .adf-data-table-card-loading {
+ width: 100%;
+ min-height: 250px;
+
+ .adf-datatable-table-cell {
+ height: 240px !important;
+ }
+ }
+
+ .adf-data-table-card-empty {
+ width: 100%;
+ min-height: 380px;
+
+ .adf-datatable-table-cell {
+ height: 370px !important;
+ }
+ }
+
+ .adf-datatable-table-cell {
+ text-align: left;
+ flex: 0 1 24%;
+ height: 136px !important;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ outline: none;
+
+ &:before {
+ margin-left: 10px;
+ text-align: left;
+ content: attr(title);
+ color: mat-color($foreground, text, 0.4);
+ float: left;
+ width: 140px;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ }
+
+ }
+ .alfresco-datatable__actions-cell {
+ position: absolute;
+ height: 42px !important;
+ width: 42px !important;
+ right: 0px;
+ text-align: right;
+ }
+
+ .image-table-cell {
+ margin: 8px;
+ padding: 4px;
+ overflow: visible;
+ border-bottom-color: mat-color($foreground, divider);
+ border-bottom-width: 1px;
+ border-bottom-style: solid;
+
+ .cell-container {
+ float: left;
+ width: 42px;
+ }
+
+ &:after {
+ margin: 2px;
+ content: attr(filename);
+ float: left;
+ width: 140px;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ }
+ }
+
+ .adf-datatable-table-checkbox {
+ margin: 8px;
+ }
+
+ }
+
+ .adf-datatable-header {
+ margin-right: 18px;
+ float: right;
+ }
+
+ }
+
.adf-data-table {
+ display: table;
width: 100%;
position: relative;
border: $data-table-dividers;
@@ -38,12 +178,36 @@
border-collapse: unset;
border-spacing: 0;
- thead {
- padding-bottom: 3px;
+ .adf-datatable-row {
+ display: table-row;
+ vertical-align: inherit;
+ border-color: inherit;
}
- tbody {
- tr {
+ .adf-datatable-body {
+ display: table-row-group;
+ vertical-align: middle;
+ border-color: inherit;
+ }
+
+ .adf-datatable-table-cell {
+ display: table-cell;
+ }
+
+ .adf-datatable-table-cell-header {
+ display: table-cell;
+ }
+
+ .adf-datatable-header {
+ padding-bottom: 3px;
+ display: table-header-group;
+ vertical-align: middle;
+ border-color: inherit;
+ }
+
+ .adf-datatable-body {
+
+ .adf-datatable-row {
cursor: pointer;
position: relative;
height: $data-table-row-height;
@@ -73,7 +237,7 @@
}
}
- td, th {
+ .adf-datatable-table-cell, .adf-datatable-table-cell-header {
padding: 0 $data-table-column-padding 12px $data-table-column-padding;
text-align: right;
@@ -93,7 +257,7 @@
}
}
- td {
+ .adf-datatable-table-cell {
color: mat-color($foreground, text);
position: relative;
vertical-align: middle;
@@ -105,7 +269,7 @@
@include no-select;
}
- th {
+ .adf-datatable-table-cell-header {
@include no-select;
cursor: pointer;
position: relative;
@@ -153,7 +317,7 @@
.adf-data-table-cell {
text-align: left;
- height: 100%;
+ height: 100%;
&--text {
text-align: left;
@@ -182,7 +346,7 @@
.cell-container {
display: flex;
- align-items: center;
+ align-items: center;
}
}
@@ -202,6 +366,7 @@
/* Loading folder */
.adf-loading-content-container {
padding: 0 !important;
+ width: 100%;
& > img {
width: 100%;
diff --git a/lib/core/datatable/components/datatable/datatable.component.spec.ts b/lib/core/datatable/components/datatable/datatable.component.spec.ts
index 82bdba5d4c..75ed09edee 100644
--- a/lib/core/datatable/components/datatable/datatable.component.spec.ts
+++ b/lib/core/datatable/components/datatable/datatable.component.spec.ts
@@ -51,6 +51,86 @@ describe('DataTable', () => {
element = fixture.debugElement.nativeElement;
});
+ it('should use the cardview style if cardview is true', () => {
+ let newData = new ObjectDataTableAdapter(
+ [
+ { name: '1' },
+ { name: '2' }
+ ],
+ [new ObjectDataColumn({ key: 'name' })]
+ );
+
+ dataTable.cardview = true;
+ dataTable.ngOnChanges({
+ data: new SimpleChange(null, newData, false)
+ });
+
+ fixture.detectChanges();
+
+ expect(element.querySelector('.adf-data-table-card')).not.toBeNull();
+ expect(element.querySelector('.adf-data-table')).toBeNull();
+ });
+
+ it('should use the cardview style if cardview is false', () => {
+ let newData = new ObjectDataTableAdapter(
+ [
+ { name: '1' },
+ { name: '2' }
+ ],
+ [new ObjectDataColumn({ key: 'name' })]
+ );
+
+ dataTable.cardview = false;
+ dataTable.ngOnChanges({
+ data: new SimpleChange(null, newData, false)
+ });
+
+ fixture.detectChanges();
+
+ expect(element.querySelector('.adf-data-table-card')).toBeNull();
+ expect(element.querySelector('.adf-data-table')).not.toBeNull();
+ });
+
+ it('should hide the header if showHeader is false', () => {
+ let newData = new ObjectDataTableAdapter(
+ [
+ { name: '1' },
+ { name: '2' }
+ ],
+ [new ObjectDataColumn({ key: 'name' })]
+ );
+
+ dataTable.showHeader = false;
+ dataTable.loading = false;
+ dataTable.ngOnChanges({
+ data: new SimpleChange(null, newData, false)
+ });
+
+ fixture.detectChanges();
+
+ expect(element.querySelector('.adf-datatable-header')).toBe(null);
+ });
+
+ it('should show the header if showHeader is true', () => {
+ let newData = new ObjectDataTableAdapter(
+ [
+ { name: '1' },
+ { name: '2' }
+ ],
+ [new ObjectDataColumn({ key: 'name' })]
+ );
+ dataTable.showHeader = true;
+ dataTable.loading = false;
+
+ dataTable.ngOnChanges({
+ data: new SimpleChange(null, newData, false)
+ });
+
+ fixture.detectChanges();
+
+ expect(element.querySelector('.adf-datatable-header')).toBeDefined();
+ });
+
it('should emit "sorting-changed" DOM event', (done) => {
const column = new ObjectDataColumn({ key: 'name', sortable: true, direction: 'asc' });
dataTable.data = new ObjectDataTableAdapter(
@@ -206,32 +286,40 @@ describe('DataTable', () => {
});
it('should put actions menu to the right by default', () => {
- dataTable.data = new ObjectDataTableAdapter([], [
-
{},
- {},
- {}
- ]);
+ dataTable.data = new ObjectDataTableAdapter(
+ [
+ { name: '1' },
+ { name: '2' },
+ { name: '3' },
+ { name: '4' }
+ ],
+ [new ObjectDataColumn({ key: 'name' })]
+ );
+
dataTable.actions = true;
fixture.detectChanges();
- let headers = element.querySelectorAll('th');
- expect(headers.length).toBe(4);
- expect(headers[headers.length - 1].classList.contains('actions-column')).toBeTruthy();
+ let actions = element.querySelectorAll('[id^=action_menu_right]');
+ expect(actions.length).toBe(4);
});
it('should put actions menu to the left', () => {
- dataTable.data = new ObjectDataTableAdapter([], [
- {},
- {},
- {}
- ]);
+ dataTable.data = new ObjectDataTableAdapter(
+ [
+ { name: '1' },
+ { name: '2' },
+ { name: '3' },
+ { name: '4' }
+ ],
+ [new ObjectDataColumn({ key: 'name' })]
+ );
+
dataTable.actions = true;
dataTable.actionsPosition = 'left';
fixture.detectChanges();
- let headers = element.querySelectorAll('th');
- expect(headers.length).toBe(4);
- expect(headers[0].classList.contains('actions-column')).toBeTruthy();
+ let actions = element.querySelectorAll('[id^=action_menu_left]');
+ expect(actions.length).toBe(4);
});
it('should initialize default adapter', () => {
diff --git a/lib/core/datatable/components/datatable/datatable.component.ts b/lib/core/datatable/components/datatable/datatable.component.ts
index 073ce745e7..48e280a5e5 100644
--- a/lib/core/datatable/components/datatable/datatable.component.ts
+++ b/lib/core/datatable/components/datatable/datatable.component.ts
@@ -53,6 +53,10 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck
@Input()
data: DataTableAdapter;
+ /* Enable the cardview mode */
+ @Input()
+ cardview: boolean = false;
+
/* The rows that the datatable will show */
@Input()
rows: any[] = [];
@@ -483,6 +487,16 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck
return `${row.cssClass} ${this.rowStyleClass}`;
}
+ getFilename(row: DataRow): string {
+ return row.getValue('name');
+ }
+
+ getSortingKey(): string {
+ if (this.data.getSorting()) {
+ return this.data.getSorting().key;
+ }
+ }
+
private selectRow(row: DataRow, value: boolean) {
if (row) {
row.isSelected = value;
diff --git a/lib/core/form/components/form-list.component.spec.ts b/lib/core/form/components/form-list.component.spec.ts
index 60433dc3ba..7498b0982a 100644
--- a/lib/core/form/components/form-list.component.spec.ts
+++ b/lib/core/form/components/form-list.component.spec.ts
@@ -16,7 +16,6 @@
*/
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-import { By } from '@angular/platform-browser';
import { TranslationService } from '../../index';
import { DataTableModule } from '../../datatable/datatable.module';
import { DataColumnModule } from '../../data-column/data-column.module';
@@ -31,6 +30,7 @@ describe('TaskAttachmentList', () => {
let component: FormListComponent;
let fixture: ComponentFixture;
let service: FormService;
+ let element: any;
beforeEach(async(() => {
TestBed.configureTestingModule({
@@ -59,7 +59,7 @@ describe('TaskAttachmentList', () => {
fixture = TestBed.createComponent(FormListComponent);
component = fixture.componentInstance;
-
+ element = fixture.debugElement.nativeElement;
service = TestBed.get(FormService);
}));
@@ -71,12 +71,11 @@ describe('TaskAttachmentList', () => {
]));
component.ngOnChanges({});
+ fixture.detectChanges();
- fixture.whenStable()
- .then(() => {
- fixture.detectChanges();
- expect(fixture.debugElement.queryAll(By.css('adf-datatable tbody tr')).length).toBe(2);
- });
- }));
+ fixture.whenStable().then(() => {
+ expect(element.querySelectorAll('.adf-datatable-body > .adf-datatable-row').length).toBe(2);
+ });
+ });
});
diff --git a/lib/process-services/attachment/process-attachment-list.component.spec.ts b/lib/process-services/attachment/process-attachment-list.component.spec.ts
index a13283b6d7..f678535a26 100644
--- a/lib/process-services/attachment/process-attachment-list.component.spec.ts
+++ b/lib/process-services/attachment/process-attachment-list.component.spec.ts
@@ -155,10 +155,10 @@ describe('ProcessAttachmentListComponent', () => {
it('should display attachments when the process has attachments', async(() => {
let change = new SimpleChange(null, '123', true);
component.ngOnChanges({ 'processInstanceId': change });
+ fixture.detectChanges();
fixture.whenStable().then(() => {
- fixture.detectChanges();
- expect(fixture.debugElement.queryAll(By.css('adf-datatable tbody tr')).length).toBe(2);
+ expect(fixture.debugElement.queryAll(By.css('.adf-datatable-body > .adf-datatable-row')).length).toBe(2);
});
}));
diff --git a/lib/process-services/attachment/task-attachment-list.component.spec.ts b/lib/process-services/attachment/task-attachment-list.component.spec.ts
index 2910e8d08d..05f56402af 100644
--- a/lib/process-services/attachment/task-attachment-list.component.spec.ts
+++ b/lib/process-services/attachment/task-attachment-list.component.spec.ts
@@ -138,10 +138,10 @@ describe('TaskAttachmentList', () => {
it('should display attachments when the task has attachments', async(() => {
let change = new SimpleChange(null, '123', true);
component.ngOnChanges({ 'taskId': change });
+ fixture.detectChanges();
fixture.whenStable().then(() => {
- fixture.detectChanges();
- expect(fixture.debugElement.queryAll(By.css('adf-datatable tbody tr')).length).toBe(2);
+ expect(fixture.debugElement.queryAll(By.css('.adf-datatable-body > .adf-datatable-row')).length).toBe(2);
});
}));
diff --git a/lib/process-services/people/components/people-search/people-search.component.spec.ts b/lib/process-services/people/components/people-search/people-search.component.spec.ts
index 13a9ee92b6..9d7d54af93 100644
--- a/lib/process-services/people/components/people-search/people-search.component.spec.ts
+++ b/lib/process-services/people/components/people-search/people-search.component.spec.ts
@@ -94,7 +94,7 @@ describe('PeopleSearchComponent', () => {
fixture.whenStable().then(() => {
fixture.detectChanges();
- let gatewayElement: any = element.querySelector('#search-people-list tbody');
+ let gatewayElement: any = element.querySelector('#search-people-list .adf-datatable-body');
expect(gatewayElement).not.toBeNull();
expect(gatewayElement.children.length).toBe(2);
done();
@@ -136,7 +136,7 @@ describe('PeopleSearchComponent', () => {
fixture.whenStable()
.then(() => {
fixture.detectChanges();
- let gatewayElement: any = element.querySelector('#search-people-list tbody');
+ let gatewayElement: any = element.querySelector('#search-people-list .adf-datatable-body');
expect(gatewayElement).not.toBeNull();
expect(gatewayElement.children.length).toBe(1);
done();
diff --git a/lib/process-services/people/components/people/people.component.spec.ts b/lib/process-services/people/components/people/people.component.spec.ts
index 5c4a8d369e..361d3eca5e 100644
--- a/lib/process-services/people/components/people/people.component.spec.ts
+++ b/lib/process-services/people/components/people/people.component.spec.ts
@@ -113,7 +113,7 @@ describe('PeopleComponent', () => {
it('should show people involved', async(() => {
fixture.whenStable()
.then(() => {
- let gatewayElement: any = element.querySelector('#assignment-people-list tbody');
+ let gatewayElement: any = element.querySelector('#assignment-people-list .adf-datatable-body');
expect(gatewayElement).not.toBeNull();
expect(gatewayElement.children.length).toBe(2);
});
@@ -127,7 +127,7 @@ describe('PeopleComponent', () => {
fixture.whenStable()
.then(() => {
fixture.detectChanges();
- let gatewayElement: any = element.querySelector('#assignment-people-list tbody');
+ let gatewayElement: any = element.querySelector('#assignment-people-list .adf-datatable-body');
expect(gatewayElement).not.toBeNull();
expect(gatewayElement.children.length).toBe(1);
});
@@ -141,7 +141,7 @@ describe('PeopleComponent', () => {
fixture.whenStable()
.then(() => {
fixture.detectChanges();
- let gatewayElement: any = element.querySelector('#assignment-people-list tbody');
+ let gatewayElement: any = element.querySelector('#assignment-people-list .adf-datatable-body');
expect(gatewayElement).not.toBeNull();
expect(gatewayElement.children.length).toBe(3);
});
@@ -220,7 +220,7 @@ describe('PeopleComponent', () => {
fixture.whenStable()
.then(() => {
fixture.detectChanges();
- let gatewayElement: any = element.querySelector('#assignment-people-list tbody');
+ let gatewayElement: any = element.querySelector('#assignment-people-list .adf-datatable-body');
expect(gatewayElement).not.toBeNull();
expect(gatewayElement.children.length).toBe(2);
});
@@ -234,7 +234,7 @@ describe('PeopleComponent', () => {
fixture.whenStable()
.then(() => {
fixture.detectChanges();
- let gatewayElement: any = element.querySelector('#assignment-people-list tbody');
+ let gatewayElement: any = element.querySelector('#assignment-people-list .adf-datatable-body');
expect(gatewayElement).not.toBeNull();
expect(gatewayElement.children.length).toBe(2);
});
diff --git a/lib/process-services/task-list/components/task-list.component.ts b/lib/process-services/task-list/components/task-list.component.ts
index 524b1ff2c6..653707ff90 100644
--- a/lib/process-services/task-list/components/task-list.component.ts
+++ b/lib/process-services/task-list/components/task-list.component.ts
@@ -161,10 +161,10 @@ export class TaskListComponent implements OnChanges, OnInit, AfterContentInit, P
isStreamLoaded = false;
constructor(private taskListService: TaskListService,
- private appConfig: AppConfigService,
- private userPreferences: UserPreferencesService) {
+ private appConfig: AppConfigService,
+ private userPreferences: UserPreferencesService) {
this.size = this.userPreferences.paginationSize;
- this.pagination = new BehaviorSubject({
+ this.pagination = new BehaviorSubject( {
maxItems: this.size,
skipCount: 0,
totalItems: 0
@@ -450,4 +450,4 @@ export class TaskListComponent implements OnChanges, OnInit, AfterContentInit, P
get supportedPageSizes(): number[] {
return this.userPreferences.getDifferentPageSizes();
}
-}
\ No newline at end of file
+}
diff --git a/lib/tslint.json b/lib/tslint.json
index b96ad69c93..6c7d87e6a2 100644
--- a/lib/tslint.json
+++ b/lib/tslint.json
@@ -11,7 +11,8 @@
],
"ban": [
true,
- "eval"
+ "eval",
+ "fdescribe"
],
"class-name": true,
"comment-format": [