From 9c916f37972e41d7bd24f6b94f1bec882ada1b75 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 26 Oct 2016 13:41:16 +0100 Subject: [PATCH] Readonly mode for completed forms (dynamic table) --- ng2-components/ng2-activiti-form/README.md | 13 ++- .../components/activiti-form.component.html | 5 +- .../src/components/widgets/core/form.model.ts | 8 ++ .../display-value/display-value.widget.css | 8 ++ .../display-value/display-value.widget.html | 23 ++++ .../display-value.widget.spec.ts | 102 ++++++++++++++++++ .../display-value/display-value.widget.ts | 41 +++++++ .../editors/text/text.editor.spec.ts | 9 +- 8 files changed, 195 insertions(+), 14 deletions(-) diff --git a/ng2-components/ng2-activiti-form/README.md b/ng2-components/ng2-activiti-form/README.md index abd65ce003..2c440d58a5 100644 --- a/ng2-components/ng2-activiti-form/README.md +++ b/ng2-components/ng2-activiti-form/README.md @@ -244,22 +244,25 @@ will also be executed after your custom code.** ## Supported form widgets +Form renderer provides support for all basic widgets: + - [x] Tabs - [x] Text - [x] Multiline Text - [x] Number - [x] Checkbox -- [ ] Date +- [x] Date - Dropdown * [x] Manual * [x] REST service - * [ ] Data source - [x] Typeahead -- [ ] Amount -- [x] Radio buttons +- [x] Amount +- Radio buttons + * [x] Manual + * [x] REST service - [x] People - [x] Group of People -- [ ] Dynamic Table +- [x] Dynamic Table - [x] Hyperlink - Header * [x] Plain header diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html index 3d5d1d67b1..5184026de6 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html +++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html @@ -17,11 +17,14 @@
- +
+
+ +
UNKNOWN WIDGET TYPE: {{field.type}}
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts index 7255ade4df..5e9cc7b44d 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts @@ -174,6 +174,14 @@ export class FormModel { result.push(new ContainerModel(this, field)); } else if (field.type === FormFieldTypes.DYNAMIC_TABLE) { result.push(new DynamicTableModel(this, field)); + } else if (field.type === FormFieldTypes.DISPLAY_VALUE) { + // workaround for dynamic table on a completed/readonly form + if (field.params) { + let originalField = field.params['field']; + if (originalField.type === FormFieldTypes.DYNAMIC_TABLE) { + result.push(new DynamicTableModel(this, field)); + } + } } } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.css b/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.css index c3b7a552c9..ad833b2f12 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.css +++ b/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.css @@ -1,3 +1,11 @@ .display-value-widget { width: 100%; } + +.display-value-widget__dynamic-table { + padding: 8px; +} + +.display-value-widget__dynamic-table table { + width: 100%; +} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.html index cafbe19e6d..c268de84be 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.html @@ -38,6 +38,29 @@ {{linkText}}
+
+
+
{{field.name}}
+ + + + + + + + + + + +
+ {{column.name}} +
+ {{ getCellValue(row, column) }} +
+
+
{ @@ -539,4 +541,104 @@ describe('DisplayValueWidget', () => { expect(widget.value).toBe(value); }); + it('should setup [DYNAMIC_TABLE] field', () => { + let columns = [{ id: '1', visible: false }, { id: '2', visible: true }]; + let rows = [{}, {}]; + + widget.field = new FormFieldModel(null, { + type: FormFieldTypes.DISPLAY_VALUE, + params: { + field: { + type: FormFieldTypes.DYNAMIC_TABLE + } + }, + columnDefinitions: columns, + value: rows + }); + widget.ngOnInit(); + + expect(widget.columns.length).toBe(2); + expect(widget.columns[0].id).toBe(columns[0].id); + expect(widget.columns[1].id).toBe(columns[1].id); + + expect(widget.visibleColumns.length).toBe(1); + expect(widget.visibleColumns[0].id).toBe(columns[1].id); + + expect(widget.rows.length).toBe(2); + }); + + it('should setup [DYNAMIC_TABLE] field with empty schema', () => { + widget.field = new FormFieldModel(null, { + type: FormFieldTypes.DISPLAY_VALUE, + params: { + field: { + type: FormFieldTypes.DYNAMIC_TABLE + } + }, + columnDefinitions: null, + value: null + }); + widget.ngOnInit(); + + expect(widget.value).toBeNull(); + expect(widget.columns).toEqual([]); + expect(widget.rows).toEqual([]); + }); + + it('should retrieve default cell value', () => { + const value = ''; + let row = { value: { key: value } }; + let column = { id: 'key' }; + + expect(widget.getCellValue(row, column)).toBe(value); + }); + + it('should retrieve dropdown cell value', () => { + const value = { id: '1', name: 'one' }; + let row = { value: { key: value } }; + let column = { id: 'key', type: 'Dropdown' }; + + expect(widget.getCellValue(row, column)).toBe(value.name); + }); + + it('should fallback to empty cell value for dropdown', () => { + let row = { value: {} }; + let column = { id: 'key', type: 'Dropdown' }; + + expect(widget.getCellValue(row, column)).toBe(''); + }); + + it('should retrieve boolean cell value', () => { + let row1 = { value: { key: true } }; + let row2 = { value: { key: 'positive' } }; + let row3 = { value: { key: null } }; + let column = { id: 'key', type: 'Boolean' }; + + expect(widget.getCellValue(row1, column)).toBe(true); + expect(widget.getCellValue(row2, column)).toBe(true); + expect(widget.getCellValue(row3, column)).toBe(false); + }); + + it('should retrieve date cell value', () => { + const value = '2016-10-04T00:00:00.000Z'; + let row = { value: { key: value } }; + let column = { id: 'key', type: 'Date' }; + + expect(widget.getCellValue(row, column)).toBe('04-10-2016'); + }); + + it('should fallback to empty cell value for date', () => { + let row = { value: {} }; + let column = { id: 'key', type: 'Date' }; + + expect(widget.getCellValue(row, column)).toBe(''); + }); + + it('should retrieve empty text cell value', () => { + let row = { value: {} }; + let column = { id: 'key' }; + + expect(widget.getCellValue(row, column)).toBe(''); + }); + }); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.ts index e8efef2012..567d995fd3 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.ts @@ -20,6 +20,8 @@ import { WidgetComponent } from './../widget.component'; import { FormFieldTypes } from '../core/form-field-types'; import { FormService } from '../../../services/form.service'; import { FormFieldOption } from './../core/form-field-option'; +import { DynamicTableColumn } from './../core/dynamic-table-column'; +import { DynamicTableRow } from './../core/dynamic-table-row'; @Component({ moduleId: module.id, @@ -31,9 +33,16 @@ export class DisplayValueWidget extends WidgetComponent implements OnInit { value: any; fieldType: string; + + // hyperlink linkUrl: string; linkText: string; + // dynamic table + rows: DynamicTableRow[] = []; + columns: DynamicTableColumn[] = []; + visibleColumns: DynamicTableColumn[] = []; + constructor(private formService: FormService) { super(); } @@ -103,6 +112,16 @@ export class DisplayValueWidget extends WidgetComponent implements OnInit { this.linkUrl = this.getHyperlinkUrl(this.field); this.linkText = this.getHyperlinkText(this.field); break; + case FormFieldTypes.DYNAMIC_TABLE: + let json = this.field.json; + if (json.columnDefinitions) { + this.columns = json.columnDefinitions.map(obj => obj); + this.visibleColumns = this.columns.filter(col => col.visible); + } + if (json.value) { + this.rows = json.value.map(obj => { selected: false, value: obj }); + } + break; default: this.value = this.field.value; break; @@ -141,4 +160,26 @@ export class DisplayValueWidget extends WidgetComponent implements OnInit { } ); } + + getCellValue(row: DynamicTableRow, column: DynamicTableColumn): any { + let result = row.value[column.id]; + + if (column.type === 'Dropdown') { + if (result) { + return result.name; + } + } + + if (column.type === 'Boolean') { + return result ? true : false; + } + + if (column.type === 'Date') { + if (result) { + return moment(result.split('T')[0], 'YYYY-MM-DD').format('DD-MM-YYYY'); + } + } + + return result || ''; + } } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/text/text.editor.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/text/text.editor.spec.ts index 70873eaf01..cad08cc0ab 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/text/text.editor.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/text/text.editor.spec.ts @@ -16,14 +16,7 @@ */ import { TextEditorComponent } from './text.editor'; -import { - // DynamicTableModel, - DynamicTableRow, - DynamicTableColumn// , - // DynamicTableColumnOption, - // FormFieldModel, - // FormModel -} from './../../../core/index'; +import { DynamicTableRow, DynamicTableColumn } from './../../../core/index'; describe('TextEditorComponent', () => {