[ADF - 1030] Datatable - enable isLoading to show the spinner in all the components (#2063)

* added spinner module and  translate text for process-list component

* added spinner loader for data-table in processlist-variable component

* added spinner loader for data-table in processlist component

* added spinner loader for data-table in process-attachmentlist component

* added spinner module and translate text for tasklist component

* changed css for adf-datatable: selector changed in component

* added spinner loader for data-table in tasklist component

* added spinner loader for data-table in task-attachmentlist component

* removed no-content template from task/process attachment list

* fixed tasklist testcase issues

* changed imort order for test cases

* fixed testcase issue in processlist component
This commit is contained in:
Infad Kachancheri 2017-07-11 21:14:09 +05:30 committed by Eugenio Romano
parent 7772f92e64
commit ae3f5078d1
23 changed files with 224 additions and 69 deletions

View File

@ -20,6 +20,7 @@ import { ActivitiFormModule } from 'ng2-activiti-form';
import { ActivitiTaskListModule } from 'ng2-activiti-tasklist'; import { ActivitiTaskListModule } from 'ng2-activiti-tasklist';
import { CoreModule } from 'ng2-alfresco-core'; import { CoreModule } from 'ng2-alfresco-core';
import { DataTableModule } from 'ng2-alfresco-datatable'; import { DataTableModule } from 'ng2-alfresco-datatable';
import { MdProgressSpinnerModule } from '@angular/material';
import { import {
ActivitiCreateProcessAttachmentComponent, ActivitiCreateProcessAttachmentComponent,
@ -75,7 +76,8 @@ export const ACTIVITI_PROCESSLIST_PROVIDERS: [any] = [
CoreModule, CoreModule,
DataTableModule, DataTableModule,
ActivitiFormModule, ActivitiFormModule,
ActivitiTaskListModule ActivitiTaskListModule,
MdProgressSpinnerModule
], ],
declarations: [ declarations: [
...ACTIVITI_PROCESSLIST_DIRECTIVES ...ACTIVITI_PROCESSLIST_DIRECTIVES

View File

@ -0,0 +1,13 @@
.adf-variable-list-loading-margin {
margin-left: calc((100% - 100px) / 2);
margin-right: calc((100% - 100px) / 2);
}
.no-content-message {
font-family: Muli;
font-size: 16px;
font-weight: bold;
text-align: center;
opacity: 0.54;
color: #000;
}

View File

@ -4,14 +4,33 @@
</div> </div>
<div *ngIf="!isListEmpty()"> <div>
<adf-datatable [data]="data" [actions]="true" (showRowActionsMenu)="onShowRowActionsMenu($event)" <adf-datatable
(executeRowAction)="onExecuteRowAction($event)"></adf-datatable> [data]="data"
[actions]="true"
[loading]="isLoading()"
(showRowActionsMenu)="onShowRowActionsMenu($event)"
(executeRowAction)="onExecuteRowAction($event)">
<loading-content-template>
<ng-template>
<!--Add your custom loading template here-->
<md-progress-spinner
class="adf-variable-list-loading-margin"
[color]="'primary'"
[mode]="'indeterminate'">
</md-progress-spinner>
</ng-template>
</loading-content-template>
<no-content-template>
<!--Add your custom empty template here-->
<ng-template>
<div class="no-content-message">
{{ 'DETAILS.VARIABLES.NONE' | translate }}
</div>
</ng-template>
</no-content-template>
</adf-datatable>
</div> </div>
<div *ngIf="isListEmpty()" data-automation-id="variables-none">
{{ 'DETAILS.VARIABLES.NONE' | translate }}
</div>
<dialog class="mdl-dialog add-dialog" #addDialog> <dialog class="mdl-dialog add-dialog" #addDialog>
<h4 class="mdl-dialog__title">{{ 'DETAILS.VARIABLES.ADD_DIALOG.TITLE' |translate }}</h4> <h4 class="mdl-dialog__title">{{ 'DETAILS.VARIABLES.ADD_DIALOG.TITLE' |translate }}</h4>

View File

@ -17,6 +17,7 @@
import { DebugElement, SimpleChange } from '@angular/core'; import { DebugElement, SimpleChange } from '@angular/core';
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { MdProgressSpinnerModule } from '@angular/material';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
@ -41,7 +42,8 @@ describe('ActivitiProcessInstanceVariables', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
CoreModule.forRoot(), CoreModule.forRoot(),
DataTableModule.forRoot() DataTableModule.forRoot(),
MdProgressSpinnerModule
], ],
declarations: [ declarations: [
ActivitiProcessInstanceVariables ActivitiProcessInstanceVariables
@ -98,14 +100,6 @@ describe('ActivitiProcessInstanceVariables', () => {
expect(getVariablesSpy).not.toHaveBeenCalled(); expect(getVariablesSpy).not.toHaveBeenCalled();
}); });
it('should not display list when no processInstanceId is specified', fakeAsync(() => {
fixture.detectChanges();
fixture.whenStable();
tick();
let datatable: DebugElement = fixture.debugElement.query(By.css('adf-datatable'));
expect(datatable).toBeNull();
}));
it('should use the default schemaColumn as default', () => { it('should use the default schemaColumn as default', () => {
fixture.detectChanges(); fixture.detectChanges();
expect(component.data.getColumns()).toBeDefined(); expect(component.data.getColumns()).toBeDefined();
@ -173,8 +167,10 @@ describe('ActivitiProcessInstanceVariables', () => {
it('should set a placeholder message when processInstanceId changed to null', () => { it('should set a placeholder message when processInstanceId changed to null', () => {
component.ngOnChanges({ 'processInstanceId': nullChange }); component.ngOnChanges({ 'processInstanceId': nullChange });
fixture.detectChanges(); fixture.whenStable().then(() => {
expect(fixture.debugElement.query(By.css('[data-automation-id="variables-none"]'))).not.toBeNull(); fixture.detectChanges();
expect(fixture.nativeElement.querySelector('adf-empty-list .empty-list__this-space-is-empty').innerHTML).toEqual('This list is empty');
});
}); });
}); });

View File

@ -28,7 +28,7 @@ declare let dialogPolyfill: any;
@Component({ @Component({
selector: 'adf-process-instance-variables, activiti-process-instance-variables', selector: 'adf-process-instance-variables, activiti-process-instance-variables',
templateUrl: './activiti-process-instance-variables.component.html', templateUrl: './activiti-process-instance-variables.component.html',
styleUrls: [], styleUrls: ['./activiti-process-instance-variables.component.css'],
providers: [ActivitiProcessService] providers: [ActivitiProcessService]
}) })
export class ActivitiProcessInstanceVariables implements OnInit, OnChanges { export class ActivitiProcessInstanceVariables implements OnInit, OnChanges {
@ -61,6 +61,8 @@ export class ActivitiProcessInstanceVariables implements OnInit, OnChanges {
variableValue: string; variableValue: string;
variableScope: string; variableScope: string;
loadingFlag: boolean = true;
/** /**
* Constructor * Constructor
* @param translate Translation service * @param translate Translation service
@ -144,13 +146,16 @@ export class ActivitiProcessInstanceVariables implements OnInit, OnChanges {
private getProcessInstanceVariables(processInstanceId: string) { private getProcessInstanceVariables(processInstanceId: string) {
if (processInstanceId) { if (processInstanceId) {
this.loadingFlag = true;
this.activitiProcess.getProcessInstanceVariables(processInstanceId).subscribe( this.activitiProcess.getProcessInstanceVariables(processInstanceId).subscribe(
(res: ProcessInstanceVariable[]) => { (res: ProcessInstanceVariable[]) => {
let instancesRow = this.createDataRow(res); let instancesRow = this.createDataRow(res);
this.renderInstances(instancesRow); this.renderInstances(instancesRow);
this.loadingFlag = false;
}, },
(err) => { (err) => {
this.error.emit(err); this.error.emit(err);
this.loadingFlag = false;
} }
); );
} else { } else {
@ -270,4 +275,8 @@ export class ActivitiProcessInstanceVariables implements OnInit, OnChanges {
{ id: 'edit', title: 'Edit' } { id: 'edit', title: 'Edit' }
]; ];
} }
isLoading() {
return this.loadingFlag;
}
} }

View File

@ -1,15 +1,29 @@
alfresco-datatable >>> .column-header { adf-datatable >>> .column-header {
color: #232323; color: #232323;
font-size: 15px; font-size: 15px;
} }
alfresco-datatable >>> .data-cell { adf-datatable >>> .data-cell {
cursor: pointer !important; cursor: pointer !important;
} }
alfresco-datatable >>> .cell-value{ adf-datatable >>> .cell-value{
width: 250px; width: 250px;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis text-overflow: ellipsis
} }
.adf-process-list-loading-margin {
margin-left: calc((100% - 100px) / 2);
margin-right: calc((100% - 100px) / 2);
}
.no-content-message {
font-family: Muli;
font-size: 16px;
font-weight: bold;
text-align: center;
opacity: 0.54;
color: #000;
}

View File

@ -1,12 +1,28 @@
<div *ngIf="!requestNode">{{ 'FILTERS.MESSAGES.NONE' | translate }}</div> <div *ngIf="!requestNode">{{ 'FILTERS.MESSAGES.NONE' | translate }}</div>
<div *ngIf="requestNode"> <div *ngIf="requestNode">
<div *ngIf="!isListEmpty()"> <div>
<adf-datatable <adf-datatable
[data]="data" [data]="data"
[loading]="isLoading()"
(rowClick)="onRowClick($event)"> (rowClick)="onRowClick($event)">
<loading-content-template>
<ng-template>
<!--Add your custom loading template here-->
<md-progress-spinner
class="adf-process-list-loading-margin"
[color]="'primary'"
[mode]="'indeterminate'">
</md-progress-spinner>
</ng-template>
</loading-content-template>
<no-content-template>
<!--Add your custom empty template here-->
<ng-template>
<div class="no-content-message">
{{ 'PROCESSLIST.NONE' | translate }}
</div>
</ng-template>
</no-content-template>
</adf-datatable> </adf-datatable>
</div> </div>
<div *ngIf="isListEmpty()">
{{ 'PROCESSLIST.NONE' | translate }}
</div>
</div> </div>

View File

@ -17,6 +17,7 @@
import { SimpleChange } from '@angular/core'; import { SimpleChange } from '@angular/core';
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { MdProgressSpinnerModule } from '@angular/material';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { ActivitiProcessInstanceListComponent } from './activiti-processlist.component'; import { ActivitiProcessInstanceListComponent } from './activiti-processlist.component';
@ -39,7 +40,8 @@ describe('ActivitiProcessInstanceListComponent', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
CoreModule.forRoot(), CoreModule.forRoot(),
DataTableModule.forRoot() DataTableModule.forRoot(),
MdProgressSpinnerModule
], ],
declarations: [ ActivitiProcessInstanceListComponent ], declarations: [ ActivitiProcessInstanceListComponent ],
providers: [ providers: [

View File

@ -62,6 +62,7 @@ export class ActivitiProcessInstanceListComponent implements OnChanges, AfterCon
onError: EventEmitter<any> = new EventEmitter<any>(); onError: EventEmitter<any> = new EventEmitter<any>();
currentInstanceId: string; currentInstanceId: string;
loadingFlag: boolean = true;
private defaultSchema: DataColumn[] = [ private defaultSchema: DataColumn[] = [
{ type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true }, { type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true },
@ -140,6 +141,7 @@ export class ActivitiProcessInstanceListComponent implements OnChanges, AfterCon
} }
private load(requestNode: ProcessFilterRequestRepresentation) { private load(requestNode: ProcessFilterRequestRepresentation) {
this.loadingFlag = true;
this.processService.getProcessInstances(requestNode) this.processService.getProcessInstances(requestNode)
.subscribe( .subscribe(
(response) => { (response) => {
@ -147,9 +149,11 @@ export class ActivitiProcessInstanceListComponent implements OnChanges, AfterCon
this.renderInstances(instancesRow); this.renderInstances(instancesRow);
this.selectFirst(); this.selectFirst();
this.onSuccess.emit(response); this.onSuccess.emit(response);
this.loadingFlag = false;
}, },
error => { error => {
this.onError.emit(error); this.onError.emit(error);
this.loadingFlag = false;
}); });
} }
@ -275,4 +279,8 @@ export class ActivitiProcessInstanceListComponent implements OnChanges, AfterCon
}; };
return new ProcessFilterRequestRepresentation(requestNode); return new ProcessFilterRequestRepresentation(requestNode);
} }
isLoading() {
return this.loadingFlag;
}
} }

View File

@ -1,17 +1,13 @@
alfresco-datatable >>> .column-header { adf-datatable >>> .column-header {
color: #232323; color: #232323;
font-size: 15px; font-size: 15px;
} }
alfresco-datatable >>> .data-cell { adf-datatable >>> .data-cell {
cursor: pointer !important; cursor: pointer !important;
} }
.no-attachment-message { .adf-attachment-list-loading-margin {
border: 1px solid rgb(224, 224, 224); margin-left: calc((100% - 100px) / 2);
background: #fff; margin-right: calc((100% - 100px) / 2);
text-align: left;
border-top: none;
padding: 10px;
text-align: center;
} }

View File

@ -1,6 +1,7 @@
<adf-datatable <adf-datatable
[rows]="attachments" [rows]="attachments"
[actions]="true" [actions]="true"
[loading]="isLoading()"
(rowDblClick)="openContent($event)" (rowDblClick)="openContent($event)"
(showRowActionsMenu)="onShowRowActionsMenu($event)" (showRowActionsMenu)="onShowRowActionsMenu($event)"
(executeRowAction)="onExecuteRowAction($event)"> (executeRowAction)="onExecuteRowAction($event)">
@ -10,4 +11,14 @@
<data-column key="name" type="text" title="Name" class="full-width ellipsis-cell" [sortable]="true"></data-column> <data-column key="name" type="text" title="Name" class="full-width ellipsis-cell" [sortable]="true"></data-column>
<data-column key="created" type="date" format="shortDate" title="Created On"></data-column> <data-column key="created" type="date" format="shortDate" title="Created On"></data-column>
</data-columns> </data-columns>
<loading-content-template>
<ng-template>
<!--Add your custom loading template here-->
<md-progress-spinner
class="adf-attachment-list-loading-margin"
[color]="'primary'"
[mode]="'indeterminate'">
</md-progress-spinner>
</ng-template>
</loading-content-template>
</adf-datatable> </adf-datatable>

View File

@ -17,6 +17,7 @@
import { SimpleChange } from '@angular/core'; import { SimpleChange } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MdProgressSpinnerModule } from '@angular/material';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { ActivitiContentService } from 'ng2-activiti-form'; import { ActivitiContentService } from 'ng2-activiti-form';
@ -42,7 +43,8 @@ describe('ActivitiProcessAttachmentListComponent', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
CoreModule.forRoot(), CoreModule.forRoot(),
DataTableModule.forRoot() DataTableModule.forRoot(),
MdProgressSpinnerModule
], ],
declarations: [ declarations: [
ActivitiProcessAttachmentListComponent ActivitiProcessAttachmentListComponent
@ -167,14 +169,14 @@ describe('ActivitiProcessAttachmentListComponent', () => {
})); }));
it('should show the empty list component when the attachments list is empty', async(() => { it('should show the empty list component when the attachments list is empty', async(() => {
component.processInstanceId = '123';
getProcessRelatedContentSpy.and.returnValue(Observable.of({ getProcessRelatedContentSpy.and.returnValue(Observable.of({
'size': 0, 'size': 0,
'total': 0, 'total': 0,
'start': 0, 'start': 0,
'data': [] 'data': []
})); }));
fixture.detectChanges(); let change = new SimpleChange(null, '123', true);
component.ngOnChanges({'processInstanceId': change});
fixture.whenStable().then(() => { fixture.whenStable().then(() => {
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.querySelector('adf-empty-list .empty-list__this-space-is-empty').innerHTML).toEqual('ADF-DATATABLE.EMPTY.HEADER'); expect(fixture.nativeElement.querySelector('adf-empty-list .empty-list__this-space-is-empty').innerHTML).toEqual('ADF-DATATABLE.EMPTY.HEADER');
@ -188,7 +190,6 @@ describe('ActivitiProcessAttachmentListComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
component.processInstanceId = '123'; component.processInstanceId = '123';
fixture.detectChanges();
fixture.whenStable().then(() => { fixture.whenStable().then(() => {
getProcessRelatedContentSpy.calls.reset(); getProcessRelatedContentSpy.calls.reset();
}); });
@ -214,7 +215,6 @@ describe('ActivitiProcessAttachmentListComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
component.processInstanceId = '123'; component.processInstanceId = '123';
fixture.detectChanges();
fixture.whenStable(); fixture.whenStable();
})); }));

View File

@ -39,6 +39,7 @@ export class ActivitiProcessAttachmentListComponent implements OnChanges {
error: EventEmitter<any> = new EventEmitter<any>(); error: EventEmitter<any> = new EventEmitter<any>();
attachments: any[] = []; attachments: any[] = [];
loadingFlag: boolean = true;
constructor(private translateService: AlfrescoTranslationService, constructor(private translateService: AlfrescoTranslationService,
private activitiContentService: ActivitiContentService, private activitiContentService: ActivitiContentService,
@ -77,6 +78,7 @@ export class ActivitiProcessAttachmentListComponent implements OnChanges {
private loadAttachmentsByProcessInstanceId(processInstanceId: string) { private loadAttachmentsByProcessInstanceId(processInstanceId: string) {
if (processInstanceId) { if (processInstanceId) {
this.reset(); this.reset();
this.loadingFlag = true;
this.activitiContentService.getProcessRelatedContent(processInstanceId).subscribe( this.activitiContentService.getProcessRelatedContent(processInstanceId).subscribe(
(res: any) => { (res: any) => {
res.data.forEach(content => { res.data.forEach(content => {
@ -89,9 +91,11 @@ export class ActivitiProcessAttachmentListComponent implements OnChanges {
}); });
}); });
this.success.emit(this.attachments); this.success.emit(this.attachments);
this.loadingFlag = false;
}, },
(err) => { (err) => {
this.error.emit(err); this.error.emit(err);
this.loadingFlag = false;
}); });
} }
} }
@ -174,4 +178,8 @@ export class ActivitiProcessAttachmentListComponent implements OnChanges {
} }
); );
} }
isLoading() {
return this.loadingFlag;
}
} }

View File

@ -17,7 +17,7 @@
import { DatePipe } from '@angular/common'; import { DatePipe } from '@angular/common';
import { ModuleWithProviders, NgModule } from '@angular/core'; import { ModuleWithProviders, NgModule } from '@angular/core';
import { MdButtonModule, MdIconModule, MdInputModule } from '@angular/material'; import { MdButtonModule, MdIconModule, MdInputModule, MdProgressSpinnerModule } from '@angular/material';
import { ActivitiFormModule } from 'ng2-activiti-form'; import { ActivitiFormModule } from 'ng2-activiti-form';
import { CoreModule } from 'ng2-alfresco-core'; import { CoreModule } from 'ng2-alfresco-core';
import { DataTableModule } from 'ng2-alfresco-datatable'; import { DataTableModule } from 'ng2-alfresco-datatable';
@ -80,7 +80,8 @@ export const ACTIVITI_TASKLIST_PROVIDERS: any[] = [
ActivitiFormModule, ActivitiFormModule,
MdIconModule, MdIconModule,
MdButtonModule, MdButtonModule,
MdInputModule MdInputModule,
MdProgressSpinnerModule
], ],
declarations: [ declarations: [
...ACTIVITI_TASKLIST_DIRECTIVES ...ACTIVITI_TASKLIST_DIRECTIVES

View File

@ -38,26 +38,27 @@
.assignment-list-container { .assignment-list-container {
padding: 0px; padding: 0px;
width: 100%;
} }
adf-people-list >>> alfresco-datatable >>> thead { adf-people-list >>> adf-datatable >>> thead {
display: none; display: none;
} }
adf-people-list >>> alfresco-datatable >>> .people-full-name { adf-people-list >>> adf-datatable >>> .people-full-name {
font-family: 'Muli'; font-family: 'Muli';
} }
adf-people-list >>> alfresco-datatable >>> .people-email { adf-people-list >>> adf-datatable >>> .people-email {
font-family: 'Muli'; font-family: 'Muli';
opacity: 0.54; opacity: 0.54;
} }
adf-people-list >>> alfresco-datatable >>> .people-edit-label { adf-people-list >>> adf-datatable >>> .people-edit-label {
font-family: 'Muli'; font-family: 'Muli';
} }
adf-people-list >>> alfresco-datatable >>> .people-pic { adf-people-list >>> adf-datatable >>> .people-pic {
background: #ffc800; background: #ffc800;
padding: 12px 10px; padding: 12px 10px;
border-radius: 100px; border-radius: 100px;
@ -69,6 +70,6 @@ adf-people-list >>> alfresco-datatable >>> .people-pic {
text-transform: uppercase text-transform: uppercase
} }
adf-people-list >>> alfresco-datatable >>> td.mdl-data-table__cell--non-numeric.non-selectable.data-cell{ adf-people-list >>> adf-datatable >>> td.mdl-data-table__cell--non-numeric.non-selectable.data-cell{
padding: 10px; padding: 10px;
} }

View File

@ -13,3 +13,17 @@ alfresco-datatable >>> .cell-value{
overflow: hidden; overflow: hidden;
text-overflow: ellipsis text-overflow: ellipsis
} }
.adf-task-list-loading-margin {
margin-left: calc((100% - 100px) / 2);
margin-right: calc((100% - 100px) / 2);
}
.no-content-message {
font-family: Muli;
font-size: 16px;
font-weight: bold;
text-align: center;
opacity: 0.54;
color: #000;
}

View File

@ -1,12 +1,28 @@
<div *ngIf="!requestNode">{{ 'TASK_FILTERS.MESSAGES.NONE' | translate }}</div> <div *ngIf="!requestNode">{{ 'TASK_FILTERS.MESSAGES.NONE' | translate }}</div>
<div *ngIf="requestNode"> <div *ngIf="requestNode">
<div *ngIf="!isListEmpty()"> <div>
<adf-datatable <adf-datatable
[data]="data" [data]="data"
[loading]="isLoading()"
(rowClick)="onRowClick($event)"> (rowClick)="onRowClick($event)">
<loading-content-template>
<ng-template>
<!--Add your custom loading template here-->
<md-progress-spinner
class="adf-task-list-loading-margin"
[color]="'primary'"
[mode]="'indeterminate'">
</md-progress-spinner>
</ng-template>
</loading-content-template>
<no-content-template>
<!--Add your custom empty template here-->
<ng-template>
<div class="no-content-message">
{{ 'TASK_LIST.MESSAGES.NONE' | translate }}
</div>
</ng-template>
</no-content-template>
</adf-datatable> </adf-datatable>
</div> </div>
<div *ngIf="isListEmpty()">
{{ 'TASK_LIST.MESSAGES.NONE' | translate }}
</div>
</div> </div>

View File

@ -17,6 +17,7 @@
import { SimpleChange } from '@angular/core'; import { SimpleChange } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MdProgressSpinnerModule } from '@angular/material';
import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core'; import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
import { DataTableModule } from 'ng2-alfresco-datatable'; import { DataTableModule } from 'ng2-alfresco-datatable';
import { DataRowEvent, ObjectDataRow, ObjectDataTableAdapter } from 'ng2-alfresco-datatable'; import { DataRowEvent, ObjectDataRow, ObjectDataTableAdapter } from 'ng2-alfresco-datatable';
@ -87,7 +88,8 @@ describe('ActivitiTaskList', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
CoreModule.forRoot(), CoreModule.forRoot(),
DataTableModule DataTableModule,
MdProgressSpinnerModule
], ],
declarations: [ declarations: [
ActivitiTaskList ActivitiTaskList

View File

@ -82,6 +82,8 @@ export class ActivitiTaskList implements OnChanges, AfterContentInit {
currentInstanceId: string; currentInstanceId: string;
loadingFlag: boolean = true;
/** /**
* Toggles custom data source mode. * Toggles custom data source mode.
* When enabled the component reloads data from it's current source instead of the server side. * When enabled the component reloads data from it's current source instead of the server side.
@ -180,6 +182,7 @@ export class ActivitiTaskList implements OnChanges, AfterContentInit {
} }
private load(requestNode: TaskQueryRequestRepresentationModel) { private load(requestNode: TaskQueryRequestRepresentationModel) {
this.loadingFlag = true;
this.taskListService.getTotalTasks(requestNode).subscribe( this.taskListService.getTotalTasks(requestNode).subscribe(
(res) => { (res) => {
requestNode.size = res.total; requestNode.size = res.total;
@ -189,11 +192,14 @@ export class ActivitiTaskList implements OnChanges, AfterContentInit {
this.renderInstances(instancesRow); this.renderInstances(instancesRow);
this.selectTask(requestNode.landingTaskId); this.selectTask(requestNode.landingTaskId);
this.onSuccess.emit(response); this.onSuccess.emit(response);
this.loadingFlag = false;
}, (error) => { }, (error) => {
this.onError.emit(error); this.onError.emit(error);
this.loadingFlag = false;
}); });
}, (err) => { }, (err) => {
this.onError.emit(err); this.onError.emit(err);
this.loadingFlag = false;
}); });
} }
@ -300,4 +306,8 @@ export class ActivitiTaskList implements OnChanges, AfterContentInit {
}; };
return new TaskQueryRequestRepresentationModel(requestNode); return new TaskQueryRequestRepresentationModel(requestNode);
} }
isLoading() {
return this.loadingFlag;
}
} }

View File

@ -1,17 +1,13 @@
alfresco-datatable >>> .column-header { adf-datatable >>> .column-header {
color: #232323; color: #232323;
font-size: 15px; font-size: 15px;
} }
alfresco-datatable >>> .data-cell { adf-datatable >>> .data-cell {
cursor: pointer !important; cursor: pointer !important;
} }
.no-attachment-message { .adf-attachment-list-loading-margin {
border: 1px solid rgb(224, 224, 224); margin-left: calc((100% - 100px) / 2);
background: #fff; margin-right: calc((100% - 100px) / 2);
text-align: left;
border-top: none;
padding: 10px;
text-align: center;
} }

View File

@ -1,6 +1,7 @@
<adf-datatable <adf-datatable
[rows]="attachments" [rows]="attachments"
[actions]="true" [actions]="true"
[loading]="isLoading()"
(rowDblClick)="openContent($event)" (rowDblClick)="openContent($event)"
(showRowActionsMenu)="onShowRowActionsMenu($event)" (showRowActionsMenu)="onShowRowActionsMenu($event)"
(executeRowAction)="onExecuteRowAction($event)"> (executeRowAction)="onExecuteRowAction($event)">
@ -10,4 +11,14 @@
<data-column key="name" type="text" title="Name" class="full-width ellipsis-cell" [sortable]="true"></data-column> <data-column key="name" type="text" title="Name" class="full-width ellipsis-cell" [sortable]="true"></data-column>
<data-column key="created" type="date" format="shortDate" title="Date"></data-column> <data-column key="created" type="date" format="shortDate" title="Date"></data-column>
</data-columns> </data-columns>
<loading-content-template>
<ng-template>
<!--Add your custom loading template here-->
<md-progress-spinner
class="adf-attachment-list-loading-margin"
[color]="'primary'"
[mode]="'indeterminate'">
</md-progress-spinner>
</ng-template>
</loading-content-template>
</adf-datatable> </adf-datatable>

View File

@ -17,6 +17,7 @@
import { SimpleChange } from '@angular/core'; import { SimpleChange } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MdProgressSpinnerModule } from '@angular/material';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { ActivitiContentService } from 'ng2-activiti-form'; import { ActivitiContentService } from 'ng2-activiti-form';
@ -42,7 +43,8 @@ describe('TaskAttachmentList', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
CoreModule.forRoot(), CoreModule.forRoot(),
DataTableModule.forRoot() DataTableModule.forRoot(),
MdProgressSpinnerModule
], ],
declarations: [ declarations: [
TaskAttachmentListComponent TaskAttachmentListComponent
@ -163,14 +165,15 @@ describe('TaskAttachmentList', () => {
})); }));
it('should show the empty list component when the attachments list is empty', async(() => { it('should show the empty list component when the attachments list is empty', async(() => {
component.taskId = '123';
getTaskRelatedContentSpy.and.returnValue(Observable.of({ getTaskRelatedContentSpy.and.returnValue(Observable.of({
'size': 0, 'size': 0,
'total': 0, 'total': 0,
'start': 0, 'start': 0,
'data': [] 'data': []
})); }));
fixture.detectChanges(); let change = new SimpleChange(null, '123', true);
component.ngOnChanges({'taskId': change});
fixture.whenStable().then(() => { fixture.whenStable().then(() => {
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.querySelector('adf-empty-list .empty-list__this-space-is-empty').innerHTML).toEqual('ADF-DATATABLE.EMPTY.HEADER'); expect(fixture.nativeElement.querySelector('adf-empty-list .empty-list__this-space-is-empty').innerHTML).toEqual('ADF-DATATABLE.EMPTY.HEADER');
@ -184,7 +187,6 @@ describe('TaskAttachmentList', () => {
beforeEach(async(() => { beforeEach(async(() => {
component.taskId = '123'; component.taskId = '123';
fixture.detectChanges();
fixture.whenStable().then(() => { fixture.whenStable().then(() => {
getTaskRelatedContentSpy.calls.reset(); getTaskRelatedContentSpy.calls.reset();
}); });
@ -210,7 +212,6 @@ describe('TaskAttachmentList', () => {
beforeEach(async(() => { beforeEach(async(() => {
component.taskId = '123'; component.taskId = '123';
fixture.detectChanges();
fixture.whenStable(); fixture.whenStable();
})); }));

View File

@ -39,6 +39,7 @@ export class TaskAttachmentListComponent implements OnChanges {
error: EventEmitter<any> = new EventEmitter<any>(); error: EventEmitter<any> = new EventEmitter<any>();
attachments: any[] = []; attachments: any[] = [];
loadingFlag: boolean = true;
constructor(private translateService: AlfrescoTranslationService, constructor(private translateService: AlfrescoTranslationService,
private activitiContentService: ActivitiContentService, private activitiContentService: ActivitiContentService,
@ -76,6 +77,8 @@ export class TaskAttachmentListComponent implements OnChanges {
private loadAttachmentsByTaskId(taskId: string) { private loadAttachmentsByTaskId(taskId: string) {
if (taskId) { if (taskId) {
this.loadingFlag = true;
this.reset();
this.activitiContentService.getTaskRelatedContent(taskId).subscribe( this.activitiContentService.getTaskRelatedContent(taskId).subscribe(
(res: any) => { (res: any) => {
let attachList = []; let attachList = [];
@ -90,9 +93,11 @@ export class TaskAttachmentListComponent implements OnChanges {
}); });
this.attachments = attachList; this.attachments = attachList;
this.success.emit(this.attachments); this.success.emit(this.attachments);
this.loadingFlag = false;
}, },
(err) => { (err) => {
this.error.emit(err); this.error.emit(err);
this.loadingFlag = false;
}); });
} }
} }
@ -175,4 +180,8 @@ export class TaskAttachmentListComponent implements OnChanges {
} }
); );
} }
isLoading() {
return this.loadingFlag;
}
} }