mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
[ADF-1090] support custom dynamic table row validation (#2308)
* support custom dynamic table row validation * test fixes * export missing models
This commit is contained in:
parent
1f766f3ade
commit
a8dfbeb572
@ -1,8 +1,3 @@
|
|||||||
.material-icons {
|
|
||||||
position: relative;
|
|
||||||
top: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-profile {
|
.user-profile {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,10 @@ import { AfterViewInit, Component, ElementRef, Input, OnDestroy, OnInit, ViewChi
|
|||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { Pagination } from 'alfresco-js-api';
|
import { Pagination } from 'alfresco-js-api';
|
||||||
import { AnalyticsReportListComponent } from 'ng2-activiti-analytics';
|
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 {
|
import {
|
||||||
FilterProcessRepresentationModel,
|
FilterProcessRepresentationModel,
|
||||||
ProcessFiltersComponent,
|
ProcessFiltersComponent,
|
||||||
@ -54,7 +57,7 @@ const currentProcessIdNew = '__NEW__';
|
|||||||
const currentTaskIdNew = '__NEW__';
|
const currentTaskIdNew = '__NEW__';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'activiti-demo',
|
selector: 'adf-activiti-demo',
|
||||||
templateUrl: './activiti-demo.component.html',
|
templateUrl: './activiti-demo.component.html',
|
||||||
styleUrls: ['./activiti-demo.component.scss'],
|
styleUrls: ['./activiti-demo.component.scss'],
|
||||||
encapsulation: ViewEncapsulation.None
|
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}`);
|
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
|
// Uncomment this block to see form event handling in action
|
||||||
/*
|
/*
|
||||||
formService.formEvents.subscribe((event: Event) => {
|
formService.formEvents.subscribe((event: Event) => {
|
||||||
|
@ -28,28 +28,28 @@
|
|||||||
<button md-button
|
<button md-button
|
||||||
[disabled]="!hasSelection()"
|
[disabled]="!hasSelection()"
|
||||||
(click)="moveSelectionUp()">
|
(click)="moveSelectionUp()">
|
||||||
<i class="material-icons">arrow_upward</i>
|
<md-icon>arrow_upward</md-icon>
|
||||||
</button>
|
</button>
|
||||||
<button md-button
|
<button md-button
|
||||||
[disabled]="!hasSelection()"
|
[disabled]="!hasSelection()"
|
||||||
(click)="moveSelectionDown()">
|
(click)="moveSelectionDown()">
|
||||||
<i class="material-icons">arrow_downward</i>
|
<md-icon>arrow_downward</md-icon>
|
||||||
</button>
|
</button>
|
||||||
<button md-button
|
<button md-button
|
||||||
[disabled]="field.readOnly"
|
[disabled]="field.readOnly"
|
||||||
id="{{content.id}}-add-row"
|
id="{{content.id}}-add-row"
|
||||||
(click)="addNewRow()">
|
(click)="addNewRow()">
|
||||||
<i class="material-icons">add_circle_outline</i>
|
<md-icon>add_circle_outline</md-icon>
|
||||||
</button>
|
</button>
|
||||||
<button md-button
|
<button md-button
|
||||||
[disabled]="!hasSelection()"
|
[disabled]="!hasSelection()"
|
||||||
(click)="deleteSelection()">
|
(click)="deleteSelection()">
|
||||||
<i class="material-icons">remove_circle_outline</i>
|
<md-icon>remove_circle_outline</md-icon>
|
||||||
</button>
|
</button>
|
||||||
<button md-button
|
<button md-button
|
||||||
[disabled]="!hasSelection()"
|
[disabled]="!hasSelection()"
|
||||||
(click)="editSelection()">
|
(click)="editSelection()">
|
||||||
<i class="material-icons">edit</i>
|
<md-icon>edit</md-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
/* tslint:disable:component-selector */
|
/* tslint:disable:component-selector */
|
||||||
|
|
||||||
import * as moment from 'moment';
|
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 { FormFieldModel } from './../core/form-field.model';
|
||||||
import { FormWidgetModel } from './../core/form-widget.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);
|
super(field.form, field.json);
|
||||||
this.field = field;
|
this.field = field;
|
||||||
|
|
||||||
@ -136,11 +138,18 @@ export class DynamicTableModel extends FormWidgetModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
validateRow(row: DynamicTableRow): DynamicRowValidationSummary {
|
validateRow(row: DynamicTableRow): DynamicRowValidationSummary {
|
||||||
let summary = <DynamicRowValidationSummary> {
|
const summary = <DynamicRowValidationSummary> {
|
||||||
isValid: true,
|
isValid: true,
|
||||||
text: null
|
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) {
|
if (row) {
|
||||||
for (let col of this.columns) {
|
for (let col of this.columns) {
|
||||||
for (let validator of this._validators) {
|
for (let validator of this._validators) {
|
||||||
|
@ -81,6 +81,7 @@ describe('DynamicTableWidgetComponent', () => {
|
|||||||
let element: HTMLElement;
|
let element: HTMLElement;
|
||||||
let table: DynamicTableModel;
|
let table: DynamicTableModel;
|
||||||
let logService: LogService;
|
let logService: LogService;
|
||||||
|
let formService: FormService;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
@ -104,7 +105,8 @@ describe('DynamicTableWidgetComponent', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const field = new FormFieldModel(new FormModel());
|
const field = new FormFieldModel(new FormModel());
|
||||||
logService = TestBed.get(LogService);
|
logService = TestBed.get(LogService);
|
||||||
table = new DynamicTableModel(field);
|
formService = TestBed.get(FormService);
|
||||||
|
table = new DynamicTableModel(field, formService);
|
||||||
let changeDetectorSpy = jasmine.createSpyObj('cd', ['detectChanges']);
|
let changeDetectorSpy = jasmine.createSpyObj('cd', ['detectChanges']);
|
||||||
let nativeElementSpy = jasmine.createSpyObj('nativeElement', ['querySelector']);
|
let nativeElementSpy = jasmine.createSpyObj('nativeElement', ['querySelector']);
|
||||||
changeDetectorSpy.nativeElement = nativeElementSpy;
|
changeDetectorSpy.nativeElement = nativeElementSpy;
|
||||||
@ -310,7 +312,7 @@ describe('DynamicTableWidgetComponent', () => {
|
|||||||
required: true,
|
required: true,
|
||||||
value: null
|
value: null
|
||||||
});
|
});
|
||||||
widget.content = new DynamicTableModel(field);
|
widget.content = new DynamicTableModel(field, formService);
|
||||||
|
|
||||||
expect(widget.content.field.validate()).toBeFalsy();
|
expect(widget.content.field.validate()).toBeFalsy();
|
||||||
expect(widget.isValid()).toBe(widget.content.field.isValid);
|
expect(widget.isValid()).toBe(widget.content.field.isValid);
|
||||||
|
@ -52,7 +52,7 @@ export class DynamicTableWidgetComponent extends WidgetComponent implements OnIn
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (this.field) {
|
if (this.field) {
|
||||||
this.content = new DynamicTableModel(this.field);
|
this.content = new DynamicTableModel(this.field, this.formService);
|
||||||
this.visibilityService.refreshVisibility(this.field.form);
|
this.visibilityService.refreshVisibility(this.field.form);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ describe('DateEditorComponent', () => {
|
|||||||
row = <DynamicTableRow> { value: { date: '1879-03-14T00:00:00.000Z' } };
|
row = <DynamicTableRow> { value: { date: '1879-03-14T00:00:00.000Z' } };
|
||||||
column = <DynamicTableColumn> { id: 'date', type: 'Date' };
|
column = <DynamicTableColumn> { id: 'date', type: 'Date' };
|
||||||
const field = new FormFieldModel(new FormModel());
|
const field = new FormFieldModel(new FormModel());
|
||||||
table = new DynamicTableModel(field);
|
table = new DynamicTableModel(field, null);
|
||||||
table.rows.push(row);
|
table.rows.push(row);
|
||||||
table.columns.push(column);
|
table.columns.push(column);
|
||||||
component = new DateEditorComponent(new MomentDateAdapter());
|
component = new DateEditorComponent(new MomentDateAdapter());
|
||||||
|
@ -53,7 +53,7 @@ describe('DropdownEditorComponent', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
form = new FormModel({taskId: '<task-id>'});
|
form = new FormModel({taskId: '<task-id>'});
|
||||||
table = new DynamicTableModel(new FormFieldModel(form, {id: '<field-id>'}));
|
table = new DynamicTableModel(new FormFieldModel(form, {id: '<field-id>'}), formService);
|
||||||
table.rows.push(row);
|
table.rows.push(row);
|
||||||
table.columns.push(column);
|
table.columns.push(column);
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ describe('DropdownEditorComponent', () => {
|
|||||||
it('should handle REST error getting option with processDefinitionId', () => {
|
it('should handle REST error getting option with processDefinitionId', () => {
|
||||||
column.optionType = 'rest';
|
column.optionType = 'rest';
|
||||||
let procForm = new FormModel({processDefinitionId: '<process-definition-id>'});
|
let procForm = new FormModel({processDefinitionId: '<process-definition-id>'});
|
||||||
let procTable = new DynamicTableModel(new FormFieldModel(procForm, {id: '<field-id>'}));
|
let procTable = new DynamicTableModel(new FormFieldModel(procForm, {id: '<field-id>'}), formService);
|
||||||
component.table = procTable;
|
component.table = procTable;
|
||||||
const error = 'error';
|
const error = 'error';
|
||||||
|
|
||||||
@ -223,7 +223,7 @@ describe('DropdownEditorComponent', () => {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
form = new FormModel({taskId: '<task-id>'});
|
form = new FormModel({taskId: '<task-id>'});
|
||||||
dynamicTable = new DynamicTableModel(new FormFieldModel(form, {id: '<field-id>'}));
|
dynamicTable = new DynamicTableModel(new FormFieldModel(form, {id: '<field-id>'}), formService);
|
||||||
dynamicTable.rows.push(row);
|
dynamicTable.rows.push(row);
|
||||||
dynamicTable.columns.push(column);
|
dynamicTable.columns.push(column);
|
||||||
dropDownEditorComponent.table = dynamicTable;
|
dropDownEditorComponent.table = dynamicTable;
|
||||||
@ -271,7 +271,7 @@ describe('DropdownEditorComponent', () => {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
form = new FormModel({processDefinitionId: '<proc-id>'});
|
form = new FormModel({processDefinitionId: '<proc-id>'});
|
||||||
dynamicTable = new DynamicTableModel(new FormFieldModel(form, {id: '<field-id>'}));
|
dynamicTable = new DynamicTableModel(new FormFieldModel(form, {id: '<field-id>'}), formService);
|
||||||
dynamicTable.rows.push(row);
|
dynamicTable.rows.push(row);
|
||||||
dynamicTable.columns.push(column);
|
dynamicTable.columns.push(column);
|
||||||
dropDownEditorComponent.table = dynamicTable;
|
dropDownEditorComponent.table = dynamicTable;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { FormFieldModel, FormModel } from '../../index';
|
import { FormFieldModel, FormModel } from '../../index';
|
||||||
|
import { FormService } from './../../../../services/form.service';
|
||||||
import { DynamicRowValidationSummary, DynamicTableColumn, DynamicTableModel, DynamicTableRow } from './../dynamic-table.widget.model';
|
import { DynamicRowValidationSummary, DynamicTableColumn, DynamicTableModel, DynamicTableRow } from './../dynamic-table.widget.model';
|
||||||
import { RowEditorComponent } from './row.editor';
|
import { RowEditorComponent } from './row.editor';
|
||||||
|
|
||||||
@ -26,7 +27,7 @@ describe('RowEditorComponent', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
component = new RowEditorComponent();
|
component = new RowEditorComponent();
|
||||||
const field = new FormFieldModel(new FormModel());
|
const field = new FormFieldModel(new FormModel());
|
||||||
component.table = new DynamicTableModel(field);
|
component.table = new DynamicTableModel(field, new FormService(null, null, null));
|
||||||
component.row = <DynamicTableRow> {};
|
component.row = <DynamicTableRow> {};
|
||||||
component.column = <DynamicTableColumn> {};
|
component.column = <DynamicTableColumn> {};
|
||||||
});
|
});
|
||||||
|
@ -74,6 +74,7 @@ export * from './error/error.component';
|
|||||||
export { DocumentWidgetComponent } from './document/document.widget';
|
export { DocumentWidgetComponent } from './document/document.widget';
|
||||||
|
|
||||||
// editors (dynamic table)
|
// editors (dynamic table)
|
||||||
|
export * from './dynamic-table/dynamic-table.widget.model';
|
||||||
export * from './dynamic-table/editors/row.editor';
|
export * from './dynamic-table/editors/row.editor';
|
||||||
export * from './dynamic-table/editors/date/date.editor';
|
export * from './dynamic-table/editors/date/date.editor';
|
||||||
export * from './dynamic-table/editors/dropdown/dropdown.editor';
|
export * from './dynamic-table/editors/dropdown/dropdown.editor';
|
||||||
|
@ -20,3 +20,4 @@ export { FormErrorEvent } from './form-error.event';
|
|||||||
export { FormFieldEvent } from './form-field.event';
|
export { FormFieldEvent } from './form-field.event';
|
||||||
export { ValidateFormFieldEvent } from './validate-form-field.event';
|
export { ValidateFormFieldEvent } from './validate-form-field.event';
|
||||||
export { ValidateFormEvent } from './validate-form.event';
|
export { ValidateFormEvent } from './validate-form.event';
|
||||||
|
export { ValidateDynamicTableRowEvent } from './validate-dynamic-table-row.event';
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -23,7 +23,10 @@ import { ContentLinkModel } from './../components/widgets/core/content-link.mode
|
|||||||
import { GroupUserModel } from './../components/widgets/core/group-user.model';
|
import { GroupUserModel } from './../components/widgets/core/group-user.model';
|
||||||
import { GroupModel } from './../components/widgets/core/group.model';
|
import { GroupModel } from './../components/widgets/core/group.model';
|
||||||
import { FormModel, FormOutcomeEvent, FormOutcomeModel, FormValues } from './../components/widgets/core/index';
|
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';
|
import { EcmModelService } from './ecm-model.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -44,6 +47,7 @@ export class FormService {
|
|||||||
|
|
||||||
validateForm = new Subject<ValidateFormEvent>();
|
validateForm = new Subject<ValidateFormEvent>();
|
||||||
validateFormField = new Subject<ValidateFormFieldEvent>();
|
validateFormField = new Subject<ValidateFormFieldEvent>();
|
||||||
|
validateDynamicTableRow = new Subject<ValidateDynamicTableRowEvent>();
|
||||||
|
|
||||||
executeOutcome = new Subject<FormOutcomeEvent>();
|
executeOutcome = new Subject<FormOutcomeEvent>();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user