Merge pull request #981 from Alfresco/dev-denys-637

Dynamic Table bug fixes
This commit is contained in:
Mario Romano
2016-11-02 15:19:38 +00:00
committed by GitHub
10 changed files with 131 additions and 36 deletions
@@ -69,6 +69,7 @@ export class DynamicTableModel extends FormWidgetModel {
this._validators = [ this._validators = [
new RequiredCellValidator(), new RequiredCellValidator(),
new DateCellValidator(),
new NumberCellValidator() new NumberCellValidator()
]; ];
} }
@@ -160,6 +161,15 @@ export class DynamicTableModel extends FormWidgetModel {
return result || ''; return result || '';
} }
getDisplayText(column: DynamicTableColumn): string {
let result = column.name;
if (column.type === 'Amount') {
let currency = column.amountCurrency || '$';
result = `${column.name} (${currency})`;
}
return result;
}
} }
export interface DynamicRowValidationSummary { export interface DynamicRowValidationSummary {
@@ -206,7 +216,34 @@ export class RequiredCellValidator implements CellValidator {
return true; return true;
} }
}
export class DateCellValidator implements CellValidator {
private supportedTypes: string[] = [
'Date'
];
isSupported(column: DynamicTableColumn): boolean {
return column && column.editable && this.supportedTypes.indexOf(column.type) > -1;
}
validate(row: DynamicTableRow, column: DynamicTableColumn, summary?: DynamicRowValidationSummary): boolean {
if (this.isSupported(column)) {
let value = row.value[column.id];
let dateValue = moment(value, 'D-M-YYYY');
if (!dateValue.isValid()) {
if (summary) {
summary.isValid = false;
summary.text = `Invalid '${column.name}' format.`;
}
return false;
}
}
return true;
}
} }
export class NumberCellValidator implements CellValidator { export class NumberCellValidator implements CellValidator {
@@ -38,7 +38,8 @@ export class DateWidget extends TextFieldWidgetComponent implements OnInit, Afte
let settings: any = { let settings: any = {
type: 'date', type: 'date',
future: moment().add(21, 'years') past: moment().subtract(100, 'years'),
future: moment().add(100, 'years')
}; };
if (this.field) { if (this.field) {
@@ -8,6 +8,11 @@
} }
.dynamic-table-widget__table { .dynamic-table-widget__table {
overflow-y: auto;
width: 100%;
}
.dynamic-table-widget__table > table {
width: 100%; width: 100%;
} }
@@ -2,7 +2,8 @@
<div>{{content.name}}</div> <div>{{content.name}}</div>
<div *ngIf="!editMode"> <div *ngIf="!editMode">
<table class="mdl-data-table mdl-js-data-table dynamic-table-widget__table"> <div class="dynamic-table-widget__table">
<table class="mdl-data-table mdl-js-data-table">
<thead> <thead>
<tr> <tr>
<th *ngFor="let column of content.visibleColumns" <th *ngFor="let column of content.visibleColumns"
@@ -22,6 +23,7 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
<div> <div>
<button class="mdl-button mdl-js-button mdl-button--icon" <button class="mdl-button mdl-js-button mdl-button--icon"
@@ -97,7 +97,11 @@ export class DynamicTableWidget extends WidgetComponent {
getCellValue(row: DynamicTableRow, column: DynamicTableColumn): any { getCellValue(row: DynamicTableRow, column: DynamicTableColumn): any {
if (this.content) { if (this.content) {
return this.content.getCellValue(row, column); let result = this.content.getCellValue(row, column);
if (column.type === 'Amount') {
return (column.amountCurrency || '$') + ' ' + (result || 0);
}
return result;
} }
return null; return null;
} }
@@ -4,16 +4,16 @@
<input id="dateInput" <input id="dateInput"
class="mdl-textfield__input" class="mdl-textfield__input"
type="text" type="text"
[value]="table.getCellValue(row, column)" [value]="value"
[attr.id]="column.id" [attr.id]="column.id"
[readonly]="true"
[required]="column.required" [required]="column.required"
[disabled]="!column.editable" [disabled]="!column.editable"
(keyup)="onDateChanged($event)"
(onOk)="onDateSelected($event)"> (onOk)="onDateSelected($event)">
<label class="mdl-textfield__label" [attr.for]="column.id">{{column.name}} (d-M-yyyy)</label> <label class="mdl-textfield__label" [attr.for]="column.id">{{column.name}} (d-M-yyyy)</label>
</div> </div>
</div> </div>
<div class="mdl-cell mdl-cell--1-col"> <div *ngIf="column.editable" class="mdl-cell mdl-cell--1-col">
<button <button
class="mdl-button mdl-js-button mdl-button--icon date-editor--button" class="mdl-button mdl-js-button mdl-button--icon date-editor--button"
(click)="datePicker.toggle()"> (click)="datePicker.toggle()">
@@ -17,7 +17,7 @@
import { ElementRef } from '@angular/core'; import { ElementRef } from '@angular/core';
import { DateEditorComponent } from './date.editor'; import { DateEditorComponent } from './date.editor';
import { DynamicTableModel, DynamicTableRow, DynamicTableColumn/*, DynamicRowValidationSummary*/ } from './../../../core/index'; import { DynamicTableModel, DynamicTableRow, DynamicTableColumn } from './../../../core/index';
describe('DateEditorComponent', () => { describe('DateEditorComponent', () => {
@@ -54,7 +54,7 @@ describe('DateEditorComponent', () => {
let settings = component.settings; let settings = component.settings;
expect(settings.type).toBe('date'); expect(settings.type).toBe('date');
expect(settings.future.year()).toBe(moment().year() + 21); expect(settings.future.year()).toBe(moment().year() + 100);
expect(settings.init.isSame(moment('14-03-1879', component.DATE_FORMAT))).toBeTruthy(); expect(settings.init.isSame(moment('14-03-1879', component.DATE_FORMAT))).toBeTruthy();
expect(component.datePicker.trigger).toBe(trigger); expect(component.datePicker.trigger).toBe(trigger);
}); });
@@ -135,4 +135,34 @@ describe('DateEditorComponent', () => {
expect(called).toBeTruthy(); expect(called).toBeTruthy();
}); });
it('should update picker when input changed', () => {
const input = '14-03-2016';
let event = { target: { value: input } };
component.ngOnInit();
component.onDateChanged(event);
expect(component.datePicker.time.isSame(moment(input, 'DD-MM-YYYY'))).toBeTruthy();
});
it('should update row value upon user input', () => {
const input = '14-03-2016';
let event = { target: { value: input } };
component.ngOnInit();
component.onDateChanged(event);
let actual = row.value[column.id];
expect(actual).toBe('2016-03-14T00:00:00.000Z');
});
it('should flush value on user input', () => {
spyOn(table, 'flushValue').and.callThrough();
let event = { target: { value: 'value' } };
component.ngOnInit();
component.onDateChanged(event);
expect(table.flushValue).toHaveBeenCalled();
});
}); });
@@ -30,6 +30,7 @@ export class DateEditorComponent extends CellEditorComponent implements OnInit {
datePicker: any; datePicker: any;
settings: any; settings: any;
value: any;
constructor(private elementRef: ElementRef) { constructor(private elementRef: ElementRef) {
super(); super();
@@ -38,12 +39,13 @@ export class DateEditorComponent extends CellEditorComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.settings = { this.settings = {
type: 'date', type: 'date',
future: moment().add(21, 'years') past: moment().subtract(100, 'years'),
future: moment().add(100, 'years')
}; };
let value = this.table.getCellValue(this.row, this.column); this.value = this.table.getCellValue(this.row, this.column);
if (value) { if (this.value) {
this.settings.init = moment(value, this.DATE_FORMAT); this.settings.init = moment(this.value, this.DATE_FORMAT);
} }
this.datePicker = new mdDateTimePicker.default(this.settings); this.datePicker = new mdDateTimePicker.default(this.settings);
@@ -52,9 +54,18 @@ export class DateEditorComponent extends CellEditorComponent implements OnInit {
} }
} }
onDateChanged(event: any) {
let newValue = (<HTMLInputElement> event.target).value;
let dateValue = moment(newValue, this.DATE_FORMAT);
this.datePicker.time = dateValue;
this.row.value[this.column.id] = `${dateValue.format('YYYY-MM-DD')}T00:00:00.000Z`;
this.table.flushValue();
};
onDateSelected(event: CustomEvent) { onDateSelected(event: CustomEvent) {
this.value = this.datePicker.time.format('DD-MM-YYYY');
let newValue = this.datePicker.time.format('YYYY-MM-DD'); let newValue = this.datePicker.time.format('YYYY-MM-DD');
this.row.value[this.column.id] = newValue + 'T00:00:00.000Z'; this.row.value[this.column.id] = `${newValue}T00:00:00.000Z`;
this.table.flushValue(); this.table.flushValue();
if (this.elementRef) { if (this.elementRef) {
@@ -75,5 +86,4 @@ export class DateEditorComponent extends CellEditorComponent implements OnInit {
} }
return false; return false;
} }
} }
@@ -7,5 +7,5 @@
[required]="column.required" [required]="column.required"
[disabled]="!column.editable" [disabled]="!column.editable"
[attr.id]="column.id"> [attr.id]="column.id">
<label class="mdl-textfield__label" [attr.for]="column.id">{{column.name}}</label> <label class="mdl-textfield__label" [attr.for]="column.id">{{displayName}}</label>
</div> </div>
@@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { CellEditorComponent } from './../cell.editor'; import { CellEditorComponent } from './../cell.editor';
import { DynamicTableRow, DynamicTableColumn } from './../../../core/index'; import { DynamicTableRow, DynamicTableColumn } from './../../../core/index';
@@ -25,7 +25,13 @@ import { DynamicTableRow, DynamicTableColumn } from './../../../core/index';
templateUrl: './text.editor.html', templateUrl: './text.editor.html',
styleUrls: ['./text.editor.css'] styleUrls: ['./text.editor.css']
}) })
export class TextEditorComponent extends CellEditorComponent { export class TextEditorComponent extends CellEditorComponent implements OnInit {
displayName: string;
ngOnInit() {
this.displayName = this.table.getDisplayText(this.column);
}
onValueChanged(row: DynamicTableRow, column: DynamicTableColumn, event: any) { onValueChanged(row: DynamicTableRow, column: DynamicTableColumn, event: any) {
let value: any = (<HTMLInputElement>event.target).value; let value: any = (<HTMLInputElement>event.target).value;