diff --git a/demo-shell-ng2/app/app.component.scss b/demo-shell-ng2/app/app.component.scss index 8948dda10c..66c299f901 100644 --- a/demo-shell-ng2/app/app.component.scss +++ b/demo-shell-ng2/app/app.component.scss @@ -1,8 +1,3 @@ -.material-icons { - position: relative; - top: 6px; -} - .user-profile { margin-right: 10px; } diff --git a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts index aedf470c6c..6e133fce8d 100644 --- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts +++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts @@ -20,7 +20,10 @@ import { AfterViewInit, Component, ElementRef, Input, OnDestroy, OnInit, ViewChi import { ActivatedRoute, Router } from '@angular/router'; import { Pagination } from 'alfresco-js-api'; import { AnalyticsReportListComponent } from 'ng2-activiti-analytics'; -import { FORM_FIELD_VALIDATORS, FormEvent, FormFieldEvent, FormRenderingService, FormService } from 'ng2-activiti-form'; +import { + DynamicTableRow, FORM_FIELD_VALIDATORS, FormEvent, FormFieldEvent, FormRenderingService, + FormService, ValidateDynamicTableRowEvent +} from 'ng2-activiti-form'; import { FilterProcessRepresentationModel, ProcessFiltersComponent, @@ -54,7 +57,7 @@ const currentProcessIdNew = '__NEW__'; const currentTaskIdNew = '__NEW__'; @Component({ - selector: 'activiti-demo', + selector: 'adf-activiti-demo', templateUrl: './activiti-demo.component.html', styleUrls: ['./activiti-demo.component.scss'], encapsulation: ViewEncapsulation.None @@ -160,6 +163,17 @@ export class ActivitiDemoComponent implements AfterViewInit, OnDestroy, OnInit { console.log(`Field value changed. Form: ${e.form.id}, Field: ${e.field.id}, Value: ${e.field.value}`); }); + formService.validateDynamicTableRow.subscribe( + (e: ValidateDynamicTableRowEvent) => { + const row: DynamicTableRow = e.row; + if (row && row.value && row.value.name === 'admin') { + e.summary.isValid = false; + e.summary.text = 'Sorry, wrong value. You cannot use "admin".'; + e.preventDefault(); + } + } + ); + // Uncomment this block to see form event handling in action /* formService.formEvents.subscribe((event: Event) => { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.html index dc2d3b8904..58c4be6330 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.html @@ -28,28 +28,28 @@ diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.model.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.model.ts index 1abaaaac10..77ea8b5973 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.model.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.model.ts @@ -18,6 +18,8 @@ /* tslint:disable:component-selector */ import * as moment from 'moment'; +import { ValidateDynamicTableRowEvent } from '../../../events/validate-dynamic-table-row.event'; +import { FormService } from './../../../services/form.service'; import { FormFieldModel } from './../core/form-field.model'; import { FormWidgetModel } from './../core/form-widget.model'; @@ -51,7 +53,7 @@ export class DynamicTableModel extends FormWidgetModel { } } - constructor(field: FormFieldModel) { + constructor(field: FormFieldModel, private formService: FormService) { super(field.form, field.json); this.field = field; @@ -136,11 +138,18 @@ export class DynamicTableModel extends FormWidgetModel { } validateRow(row: DynamicTableRow): DynamicRowValidationSummary { - let summary = { + const summary = { isValid: true, text: null }; + const event = new ValidateDynamicTableRowEvent(this.form, this.field, row, summary); + this.formService.validateDynamicTableRow.next(event); + + if (event.defaultPrevented || !summary.isValid) { + return summary; + } + if (row) { for (let col of this.columns) { for (let validator of this._validators) { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.spec.ts index 7a1f5a802d..3b623b4efc 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.spec.ts @@ -81,6 +81,7 @@ describe('DynamicTableWidgetComponent', () => { let element: HTMLElement; let table: DynamicTableModel; let logService: LogService; + let formService: FormService; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -104,7 +105,8 @@ describe('DynamicTableWidgetComponent', () => { beforeEach(() => { const field = new FormFieldModel(new FormModel()); logService = TestBed.get(LogService); - table = new DynamicTableModel(field); + formService = TestBed.get(FormService); + table = new DynamicTableModel(field, formService); let changeDetectorSpy = jasmine.createSpyObj('cd', ['detectChanges']); let nativeElementSpy = jasmine.createSpyObj('nativeElement', ['querySelector']); changeDetectorSpy.nativeElement = nativeElementSpy; @@ -310,7 +312,7 @@ describe('DynamicTableWidgetComponent', () => { required: true, value: null }); - widget.content = new DynamicTableModel(field); + widget.content = new DynamicTableModel(field, formService); expect(widget.content.field.validate()).toBeFalsy(); expect(widget.isValid()).toBe(widget.content.field.isValid); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.ts index 0ef2b4adaa..34cfce0244 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.ts @@ -52,7 +52,7 @@ export class DynamicTableWidgetComponent extends WidgetComponent implements OnIn ngOnInit() { if (this.field) { - this.content = new DynamicTableModel(this.field); + this.content = new DynamicTableModel(this.field, this.formService); this.visibilityService.refreshVisibility(this.field.form); } } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/date/date.editor.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/date/date.editor.spec.ts index 35e8de33ea..7268625715 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/date/date.editor.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/date/date.editor.spec.ts @@ -37,7 +37,7 @@ describe('DateEditorComponent', () => { row = { value: { date: '1879-03-14T00:00:00.000Z' } }; column = { id: 'date', type: 'Date' }; const field = new FormFieldModel(new FormModel()); - table = new DynamicTableModel(field); + table = new DynamicTableModel(field, null); table.rows.push(row); table.columns.push(column); component = new DateEditorComponent(new MomentDateAdapter()); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.spec.ts index 6a2aeac2b2..bebe5ee5ba 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.spec.ts @@ -53,7 +53,7 @@ describe('DropdownEditorComponent', () => { }; form = new FormModel({taskId: ''}); - table = new DynamicTableModel(new FormFieldModel(form, {id: ''})); + table = new DynamicTableModel(new FormFieldModel(form, {id: ''}), formService); table.rows.push(row); table.columns.push(column); @@ -151,7 +151,7 @@ describe('DropdownEditorComponent', () => { it('should handle REST error getting option with processDefinitionId', () => { column.optionType = 'rest'; let procForm = new FormModel({processDefinitionId: ''}); - let procTable = new DynamicTableModel(new FormFieldModel(procForm, {id: ''})); + let procTable = new DynamicTableModel(new FormFieldModel(procForm, {id: ''}), formService); component.table = procTable; const error = 'error'; @@ -223,7 +223,7 @@ describe('DropdownEditorComponent', () => { ] }; form = new FormModel({taskId: ''}); - dynamicTable = new DynamicTableModel(new FormFieldModel(form, {id: ''})); + dynamicTable = new DynamicTableModel(new FormFieldModel(form, {id: ''}), formService); dynamicTable.rows.push(row); dynamicTable.columns.push(column); dropDownEditorComponent.table = dynamicTable; @@ -271,7 +271,7 @@ describe('DropdownEditorComponent', () => { ] }; form = new FormModel({processDefinitionId: ''}); - dynamicTable = new DynamicTableModel(new FormFieldModel(form, {id: ''})); + dynamicTable = new DynamicTableModel(new FormFieldModel(form, {id: ''}), formService); dynamicTable.rows.push(row); dynamicTable.columns.push(column); dropDownEditorComponent.table = dynamicTable; diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/row.editor.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/row.editor.spec.ts index 5c2e0d9120..27076c8bc4 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/row.editor.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/row.editor.spec.ts @@ -16,6 +16,7 @@ */ import { FormFieldModel, FormModel } from '../../index'; +import { FormService } from './../../../../services/form.service'; import { DynamicRowValidationSummary, DynamicTableColumn, DynamicTableModel, DynamicTableRow } from './../dynamic-table.widget.model'; import { RowEditorComponent } from './row.editor'; @@ -26,7 +27,7 @@ describe('RowEditorComponent', () => { beforeEach(() => { component = new RowEditorComponent(); const field = new FormFieldModel(new FormModel()); - component.table = new DynamicTableModel(field); + component.table = new DynamicTableModel(field, new FormService(null, null, null)); component.row = {}; component.column = {}; }); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/index.ts b/ng2-components/ng2-activiti-form/src/components/widgets/index.ts index bb814ab8c9..d793a18cf5 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/index.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/index.ts @@ -74,6 +74,7 @@ export * from './error/error.component'; export { DocumentWidgetComponent } from './document/document.widget'; // editors (dynamic table) +export * from './dynamic-table/dynamic-table.widget.model'; export * from './dynamic-table/editors/row.editor'; export * from './dynamic-table/editors/date/date.editor'; export * from './dynamic-table/editors/dropdown/dropdown.editor'; diff --git a/ng2-components/ng2-activiti-form/src/events/index.ts b/ng2-components/ng2-activiti-form/src/events/index.ts index d36fa51615..5c63f0bb45 100644 --- a/ng2-components/ng2-activiti-form/src/events/index.ts +++ b/ng2-components/ng2-activiti-form/src/events/index.ts @@ -20,3 +20,4 @@ export { FormErrorEvent } from './form-error.event'; export { FormFieldEvent } from './form-field.event'; export { ValidateFormFieldEvent } from './validate-form-field.event'; export { ValidateFormEvent } from './validate-form.event'; +export { ValidateDynamicTableRowEvent } from './validate-dynamic-table-row.event'; diff --git a/ng2-components/ng2-activiti-form/src/events/validate-dynamic-table-row.event.ts b/ng2-components/ng2-activiti-form/src/events/validate-dynamic-table-row.event.ts new file mode 100644 index 0000000000..d7cb0bc483 --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/events/validate-dynamic-table-row.event.ts @@ -0,0 +1,33 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DynamicRowValidationSummary, DynamicTableRow } from '../components/widgets/dynamic-table/dynamic-table.widget.model'; +import { FormFieldModel, FormModel } from './../components/widgets/core/index'; +import { FormFieldEvent } from './form-field.event'; + +export class ValidateDynamicTableRowEvent extends FormFieldEvent { + + isValid = true; + + constructor(form: FormModel, + field: FormFieldModel, + public row: DynamicTableRow, + public summary: DynamicRowValidationSummary) { + super(form, field); + } + +} diff --git a/ng2-components/ng2-activiti-form/src/services/form.service.ts b/ng2-components/ng2-activiti-form/src/services/form.service.ts index d6d786bade..2f28a99838 100644 --- a/ng2-components/ng2-activiti-form/src/services/form.service.ts +++ b/ng2-components/ng2-activiti-form/src/services/form.service.ts @@ -23,7 +23,10 @@ import { ContentLinkModel } from './../components/widgets/core/content-link.mode import { GroupUserModel } from './../components/widgets/core/group-user.model'; import { GroupModel } from './../components/widgets/core/group.model'; import { FormModel, FormOutcomeEvent, FormOutcomeModel, FormValues } from './../components/widgets/core/index'; -import { FormErrorEvent, FormEvent, FormFieldEvent, ValidateFormEvent, ValidateFormFieldEvent } from './../events/index'; +import { + FormErrorEvent, FormEvent, FormFieldEvent, + ValidateDynamicTableRowEvent, ValidateFormEvent, ValidateFormFieldEvent +} from './../events/index'; import { EcmModelService } from './ecm-model.service'; @Injectable() @@ -44,6 +47,7 @@ export class FormService { validateForm = new Subject(); validateFormField = new Subject(); + validateDynamicTableRow = new Subject(); executeOutcome = new Subject();