[ADF-494] fixed readonly rendering for forms (#1972)

* [ADF-494] improved disabling for form

* [ADF-494] fixed readonly rendering for forms
This commit is contained in:
Vito
2017-06-15 05:04:36 -07:00
committed by Eugenio Romano
parent 590a7eb650
commit b045044d12
8 changed files with 108 additions and 8 deletions

View File

@@ -2,11 +2,11 @@
<label [attr.for]="field.id">{{field.name}}<span *ngIf="isRequired()">*</span></label> <label [attr.for]="field.id">{{field.name}}<span *ngIf="isRequired()">*</span></label>
<div> <div>
<span *ngIf="hasFile()" class="attach-widget__file mdl-chip"><span class="mdl-chip__text">{{getLinkedFileName()}}</span></span> <span *ngIf="hasFile()" class="attach-widget__file mdl-chip"><span class="mdl-chip__text">{{getLinkedFileName()}}</span></span>
<button #browseFile (click)="showDialog();" class="mdl-button mdl-js-button mdl-js-ripple-effect attach-widget__browser"> <button #browseFile [disabled]="field.readOnly" (click)="showDialog();" class="mdl-button mdl-js-button mdl-js-ripple-effect attach-widget__browser">
<i class="material-icons">image</i> <i class="material-icons">image</i>
Browse {{selectedFolderSiteName}} Browse {{selectedFolderSiteName}}
</button> </button>
<button *ngIf="hasFile" (click)="reset(file);" class="mdl-button mdl-js-button mdl-js-ripple-effect attach-widget__reset">Clear</button> <button *ngIf="hasFile" [disabled]="field.readOnly" (click)="reset(file);" class="mdl-button mdl-js-button mdl-js-ripple-effect attach-widget__reset">Clear</button>
</div> </div>
</div> </div>

View File

@@ -4,6 +4,7 @@
<select class="dropdown-widget__select" <select class="dropdown-widget__select"
[attr.id]="field.id" [attr.id]="field.id"
[(ngModel)]="field.value" [(ngModel)]="field.value"
[disabled]="field.readOnly"
(ngModelChange)="checkVisibility(field)"> (ngModelChange)="checkVisibility(field)">
<option *ngFor="let opt of field.options" [value]="getOptionValue(opt, field.value)" [id]="opt.id">{{opt.name}}</option> <option *ngFor="let opt of field.options" [value]="getOptionValue(opt, field.value)" [id]="opt.id">{{opt.name}}</option>
</select> </select>

View File

@@ -253,6 +253,24 @@ describe('DropdownWidget', () => {
expect(dropDownElement.selectedOptions[0].textContent).toBe('Choose one...'); expect(dropDownElement.selectedOptions[0].textContent).toBe('Choose one...');
}); });
})); }));
it('should be disabled when the field is readonly', async(() => {
dropDownWidget.field = new FormFieldModel(new FormModel({ processDefinitionId: 'fake-process-id' }), {
id: 'dropdown-id',
name: 'date-name',
type: 'dropdown',
readOnly: 'true',
restUrl: 'fake-rest-url'
});
fixture.detectChanges();
fixture.whenStable()
.then(() => {
let dropDownElement: HTMLSelectElement = <HTMLSelectElement> element.querySelector('#dropdown-id');
expect(dropDownElement).not.toBeNull();
expect(dropDownElement.disabled).toBeTruthy();
});
}));
}); });
}); });
}); });

View File

@@ -8,7 +8,7 @@
[value]="field.value" [value]="field.value"
[(ngModel)]="field.value" [(ngModel)]="field.value"
(ngModelChange)="onFieldChanged(field)" (ngModelChange)="onFieldChanged(field)"
[disabled]="field.readOnly" [attr.disabled]="field.readOnly ? true : null"
[textMask]="{mask: mask, isReversed: isMaskReversed}" [textMask]="{mask: mask, isReversed: isMaskReversed}"
placeholder="{{field.placeholder}}"> placeholder="{{field.placeholder}}">
<span *ngIf="field.validationSummary" class="mdl-textfield__error">{{field.validationSummary}}</span> <span *ngIf="field.validationSummary" class="mdl-textfield__error">{{field.validationSummary}}</span>

View File

@@ -92,6 +92,17 @@ describe('TextWidget', () => {
expect(textWidget.field.value).toBe('TEXT'); expect(textWidget.field.value).toBe('TEXT');
}); });
})); }));
it('should be disabled on readonly forms', async(() => {
textWidget.field.form.readOnly = true;
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(inputElement).toBeDefined();
expect(inputElement).not.toBeNull();
expect(inputElement.disabled).toBeTruthy();
});
}));
}); });
describe('and mask is configured on text element', () => { describe('and mask is configured on text element', () => {

View File

@@ -8,6 +8,7 @@
#file #file
type="file" type="file"
[attr.id]="field.id" [attr.id]="field.id"
[disabled]="field.readOnly"
class="upload-widget__file" class="upload-widget__file"
(change)="onFileChanged($event)"> (change)="onFileChanged($event)">
<button *ngIf="hasFile" (click)="reset(file);" <button *ngIf="hasFile" (click)="reset(file);"

View File

@@ -19,9 +19,14 @@ import { UploadWidget } from './upload.widget';
import { FormFieldModel } from './../core/form-field.model'; import { FormFieldModel } from './../core/form-field.model';
import { FormFieldTypes } from '../core/form-field-types'; import { FormFieldTypes } from '../core/form-field-types';
import { FormService } from '../../../services/form.service'; import { FormService } from '../../../services/form.service';
import { EcmModelService } from '../../../services/ecm-model.service';
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { CoreModule } from 'ng2-alfresco-core';
import { FormModel } from '../core/form.model';
describe('UploadWidget', () => { describe('UploadWidget', () => {
let componentHandler;
let widget: UploadWidget; let widget: UploadWidget;
let formService: FormService; let formService: FormService;
@@ -79,4 +84,58 @@ describe('UploadWidget', () => {
expect(widget.field.json.value).toBeNull(); expect(widget.field.json.value).toBeNull();
}); });
describe('when template is ready', () => {
let uploadWidget: UploadWidget;
let fixture: ComponentFixture<UploadWidget>;
let element: HTMLInputElement;
let inputElement: HTMLInputElement;
beforeEach(async(() => {
componentHandler = jasmine.createSpyObj('componentHandler', ['upgradeAllRegistered', 'upgradeElement']);
window['componentHandler'] = componentHandler;
}));
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [CoreModule],
declarations: [UploadWidget],
providers: [FormService, EcmModelService]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(UploadWidget);
uploadWidget = fixture.componentInstance;
element = fixture.nativeElement;
});
}));
afterEach(() => {
fixture.destroy();
TestBed.resetTestingModule();
});
beforeEach(() => {
uploadWidget.field = new FormFieldModel(new FormModel({ taskId: 'fake-upload-id' }), {
id: 'upload-id',
name: 'upload-name',
value: '',
type: FormFieldTypes.UPLOAD,
readOnly: false
});
fixture.detectChanges();
inputElement = <HTMLInputElement>element.querySelector('#upload-id');
});
it('should be disabled on readonly forms', async(() => {
uploadWidget.field.form.readOnly = true;
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(inputElement).toBeDefined();
expect(inputElement).not.toBeNull();
expect(inputElement.disabled).toBeTruthy();
});
}));
});
}); });

View File

@@ -15,7 +15,18 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component, Input, OnInit, ViewChild, Output, EventEmitter, TemplateRef, OnChanges, SimpleChanges, DebugElement} from '@angular/core'; import {
Component,
Input,
OnInit,
ViewChild,
Output,
EventEmitter,
TemplateRef,
OnChanges,
SimpleChanges,
DebugElement
} from '@angular/core';
import { AlfrescoTranslationService, LogService } from 'ng2-alfresco-core'; import { AlfrescoTranslationService, LogService } from 'ng2-alfresco-core';
import { ActivitiTaskListService } from './../services/activiti-tasklist.service'; import { ActivitiTaskListService } from './../services/activiti-tasklist.service';
import { TaskDetailsModel } from '../models/task-details.model'; import { TaskDetailsModel } from '../models/task-details.model';
@@ -187,8 +198,7 @@ export class ActivitiTaskDetails implements OnInit, OnChanges {
} }
let endDate: any = res.endDate; let endDate: any = res.endDate;
this.readOnlyForm = !!(endDate && !isNaN(endDate.getTime())); this.readOnlyForm = this.readOnlyForm ? this.readOnlyForm : !!(endDate && !isNaN(endDate.getTime()));
if (this.taskDetails && this.taskDetails.involvedPeople) { if (this.taskDetails && this.taskDetails.involvedPeople) {
this.taskDetails.involvedPeople.forEach((user) => { this.taskDetails.involvedPeople.forEach((user) => {
this.taskPeople.push(new User(user)); this.taskPeople.push(new User(user));