From 49738ad555432d485fe0a750665f2d613df48a6f Mon Sep 17 00:00:00 2001 From: davidcanonieto Date: Thu, 29 Nov 2018 14:57:36 +0000 Subject: [PATCH] [ADF-3282] Refactor Start Task Component (#4012) * [ADF-3282] Refactor Start Task Component * [ADF-3282] Fix e2e test * [ADF-3282] Remove maxTaskNameLength from start task doc --- demo-shell/src/app.config.json | 3 + .../process-service.component.html | 1 + .../process-service.component.ts | 2 + docs/process-services/start-task.component.md | 4 +- .../dialog/startTaskDialog.js | 1 + lib/process-services/i18n/en.json | 7 +- .../components/start-task.component.html | 148 +++++++------- .../components/start-task.component.scss | 56 +----- .../components/start-task.component.spec.ts | 186 +++++++++++------- .../components/start-task.component.ts | 154 +++++++++------ 10 files changed, 318 insertions(+), 244 deletions(-) diff --git a/demo-shell/src/app.config.json b/demo-shell/src/app.config.json index e237c03dc5..84f3cab91c 100644 --- a/demo-shell/src/app.config.json +++ b/demo-shell/src/app.config.json @@ -497,6 +497,9 @@ ] } }, + "adf-start-task": { + "name": "My Task Name" + }, "adf-task-list": { "presets": { "default": [ diff --git a/demo-shell/src/app/components/process-service/process-service.component.html b/demo-shell/src/app/components/process-service/process-service.component.html index ff8bcd75b7..705197e9b1 100644 --- a/demo-shell/src/app/components/process-service/process-service.component.html +++ b/demo-shell/src/app/components/process-service/process-service.component.html @@ -104,6 +104,7 @@
diff --git a/demo-shell/src/app/components/process-service/process-service.component.ts b/demo-shell/src/app/components/process-service/process-service.component.ts index 763ce2ff9e..16166a09d8 100644 --- a/demo-shell/src/app/components/process-service/process-service.component.ts +++ b/demo-shell/src/app/components/process-service/process-service.component.ts @@ -137,6 +137,7 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit defaultProcessDefinitionName: string; defaultProcessName: string; + defaultTaskName: string; activeTab: number = this.tabs.tasks; // tasks|processes|reports @@ -175,6 +176,7 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit this.defaultProcessName = this.appConfig.get('adf-start-process.name'); this.defaultProcessDefinitionName = this.appConfig.get('adf-start-process.processDefinitionName'); + this.defaultTaskName = this.appConfig.get('adf-start-task.name'); // Uncomment this line to replace all 'text' field editors with custom component // formRenderingService.setComponentTypeResolver('text', () => CustomEditorComponent, true); diff --git a/docs/process-services/start-task.component.md b/docs/process-services/start-task.component.md index 288f3a2ea9..79ad954128 100644 --- a/docs/process-services/start-task.component.md +++ b/docs/process-services/start-task.component.md @@ -15,7 +15,8 @@ Creates/Starts a new task for the specified app ```html + [appId]="YOUR_APP_ID" + [name]="My Task Name"> ``` @@ -26,6 +27,7 @@ Creates/Starts a new task for the specified app | Name | Type | Default value | Description | | ---- | ---- | ------------- | ----------- | | appId | `number` | | (required) The id of the app. | +| name | `string` | | Default Task Name | ### Events diff --git a/e2e/pages/adf/process_services/dialog/startTaskDialog.js b/e2e/pages/adf/process_services/dialog/startTaskDialog.js index 3cbd946198..607bea4d2a 100644 --- a/e2e/pages/adf/process_services/dialog/startTaskDialog.js +++ b/e2e/pages/adf/process_services/dialog/startTaskDialog.js @@ -31,6 +31,7 @@ var StartTaskDialog = function () { this.addName = function (userName) { Util.waitUntilElementIsVisible(name); + name.clear(); name.sendKeys(userName); return this; }; diff --git a/lib/process-services/i18n/en.json b/lib/process-services/i18n/en.json index cc4d227aa6..301a303f82 100644 --- a/lib/process-services/i18n/en.json +++ b/lib/process-services/i18n/en.json @@ -114,6 +114,7 @@ } }, "START_TASK": { + "DEFAULT_NAME": "My Default Task", "BUTTON": "CREATE TASK", "FORM": { "TITLE": "Start Task", @@ -130,8 +131,10 @@ "START": "Start", "CANCEL": "Cancel" }, - "DATE": { - "ERROR": "Date format DD/MM/YYYY" + "ERROR": { + "REQUIRED": "Field required", + "DATE": "Date format DD/MM/YYYY", + "MAXIMUM_LENGTH": "Length exceeded, {{characters}} characters max." } } }, diff --git a/lib/process-services/task-list/components/start-task.component.html b/lib/process-services/task-list/components/start-task.component.html index b82be1a26d..107da887ea 100644 --- a/lib/process-services/task-list/components/start-task.component.html +++ b/lib/process-services/task-list/components/start-task.component.html @@ -1,93 +1,95 @@ - - - -
{{'ADF_TASK_LIST.START_TASK.FORM.TITLE'|translate}}
-
-
+ + + {{'ADF_TASK_LIST.START_TASK.FORM.TITLE' | translate}} + -
-
- - +
+
+ + {{'ADF_TASK_LIST.START_TASK.FORM.LABEL.NAME' | translate}} + + + {{ 'ADF_TASK_LIST.START_TASK.FORM.ERROR.REQUIRED' | translate }} + + + {{ 'ADF_TASK_LIST.START_TASK.FORM.ERROR.MAXIMUM_LENGTH' | translate : { characters : maxTaskNameLength } }} +
- -
- +
+ + {{'ADF_TASK_LIST.START_TASK.FORM.LABEL.DESCRIPTION' | translate}}
- -
-
-
- - - - - -
-
-
{{'ADF_TASK_LIST.START_TASK.FORM.DATE.ERROR'|translate}}
- warning -
-
-
+
+ + + + + +
+
+
{{'ADF_TASK_LIST.START_TASK.FORM.ERROR.DATE'|translate}}
+ warning +
-
- - - {{'ADF_TASK_LIST.START_TASK.FORM.LABEL.NONE'|translate}} - {{ form.name }} - - -
-
- -
+ +
-
+
+ + {{'ADF_TASK_LIST.START_TASK.FORM.LABEL.FORM'|translate}} + + {{'ADF_TASK_LIST.START_TASK.FORM.LABEL.NONE'|translate}} + {{ form.name }} + + +
+ - - - - - + - diff --git a/lib/process-services/task-list/components/start-task.component.scss b/lib/process-services/task-list/components/start-task.component.scss index 92aeafde68..4bfcc1da8e 100644 --- a/lib/process-services/task-list/components/start-task.component.scss +++ b/lib/process-services/task-list/components/start-task.component.scss @@ -6,56 +6,26 @@ $header-border: 1px solid mat-color($foreground, divider); .adf-new-task-heading { - padding: 12px 20px; - font-weight: bold; + padding-top: 12px; border-bottom: $header-border; - font-size: 18px; - float: left; - text-align: left; - width: calc(100% - 40px); + .mat-card-title { + font-weight: bold; + font-size: 18px; + } + } + + .adf-new-task-form { + width: 100%; } .adf-new-task-layout-card { - - width: 66%; margin: 10px auto; - - &-content { - display: flex; - flex-flow: row; - flex-wrap: wrap; - justify-content: space-between; - - .adf-grid-row { - display: flex; - flex-flow: row; - flex-wrap: wrap; - justify-content: space-between; - margin-bottom: 8px; - } - - .adf-grid-column { - display: flex; - flex-flow: column; - } - - .adf-grid-full-width { - width: 100%; - } - - .adf-grid-half-width { - width: 49%; - } - } } .adf-new-task-footer { padding: 4px; font-size: 18px; border-top: 1px solid #eee; - float: left; - width: calc(100% - 40px); - text-align: right; } .adf-mat-select { @@ -154,11 +124,3 @@ } } } - -@media (max-width: 600px) { - .adf-new-task-layout-card { - width: 90%; - margin-left: auto; - margin-right: auto; - } -} diff --git a/lib/process-services/task-list/components/start-task.component.spec.ts b/lib/process-services/task-list/components/start-task.component.spec.ts index bb37a28c41..8dc57c9cbd 100644 --- a/lib/process-services/task-list/components/start-task.component.spec.ts +++ b/lib/process-services/task-list/components/start-task.component.spec.ts @@ -16,33 +16,36 @@ */ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { setupTestBed } from '@alfresco/adf-core'; -import { Observable, of, throwError } from 'rxjs'; -import { startTaskMock } from '../../mock'; -import { StartTaskModel } from '../models/start-task.model'; +import { setupTestBed, LogService } from '@alfresco/adf-core'; +import { of, throwError, Observable } from 'rxjs'; import { TaskListService } from '../services/tasklist.service'; import { StartTaskComponent } from './start-task.component'; import { ProcessTestingModule } from '../../testing/process.testing.module'; +import { taskDetailsMock } from '../../mock/task/task-details.mock'; +import { TaskDetailsModel } from '../models/task-details.model'; describe('StartTaskComponent', () => { let component: StartTaskComponent; let fixture: ComponentFixture; let service: TaskListService; + let logService: LogService; let element: HTMLElement; let getFormListSpy: jasmine.Spy; let createNewTaskSpy: jasmine.Spy; - let fakeForms = [ + let logSpy: jasmine.Spy; + let fakeForms$ = [ { id: 123, - name: 'Display Data' + name: 'Display Data' }, - { + { id: 1111, - name: 'Employee Info' + name: 'Employee Info' } ]; - let testUser = {id: 1001, firstName: 'fakeName', email: 'fake@app.activiti.com'}; + + let testUser = { id: 1001, firstName: 'fakeName', email: 'fake@app.activiti.com' }; setupTestBed({ imports: [ProcessTestingModule] @@ -54,21 +57,28 @@ describe('StartTaskComponent', () => { element = fixture.nativeElement; service = TestBed.get(TaskListService); - getFormListSpy = spyOn(service, 'getFormList').and.returnValue(of(fakeForms)); + logService = TestBed.get(LogService); + getFormListSpy = spyOn(service, 'getFormList').and.returnValue(new Observable((observer) => { + observer.next(fakeForms$); + observer.complete(); + })); fixture.detectChanges(); })); + afterEach(() => { + fixture.destroy(); + TestBed.resetTestingModule(); + }); + it('should create instance of StartTaskComponent', () => { - expect(fixture.componentInstance instanceof StartTaskComponent).toBe(true, 'should create StartTaskComponent'); + expect(component instanceof StartTaskComponent).toBe(true, 'should create StartTaskComponent'); }); it('should fetch fake form on init', () => { component.ngOnInit(); - expect(component.forms).toEqual(fakeForms); - expect(component.forms[0].name).toEqual('Display Data'); - expect(component.forms[1].name).toEqual('Employee Info'); - expect(component.forms[1].id).toEqual(1111); + fixture.detectChanges(); + expect(component.forms$).toBeDefined(); expect(getFormListSpy).toHaveBeenCalled(); }); @@ -87,8 +97,7 @@ describe('StartTaskComponent', () => { it('should create new task when start is clicked', () => { let successSpy = spyOn(component.success, 'emit'); - component.appId = 42; - component.startTaskModel = new StartTaskModel(startTaskMock); + component.taskForm.controls['name'].setValue('task'); fixture.detectChanges(); let createTaskButton = element.querySelector('#button-start'); createTaskButton.click(); @@ -97,8 +106,8 @@ describe('StartTaskComponent', () => { it('should send on success event when the task is started', () => { let successSpy = spyOn(component.success, 'emit'); - component.appId = 42; - component.startTaskModel = new StartTaskModel(startTaskMock); + component.taskDetailsModel = new TaskDetailsModel(taskDetailsMock); + component.taskForm.controls['name'].setValue('fakeName'); fixture.detectChanges(); let createTaskButton = element.querySelector('#button-start'); createTaskButton.click(); @@ -113,7 +122,7 @@ describe('StartTaskComponent', () => { it('should send on success event when only name is given', () => { let successSpy = spyOn(component.success, 'emit'); component.appId = 42; - component.startTaskModel.name = 'fakeName'; + component.taskForm.controls['name'].setValue('fakeName'); fixture.detectChanges(); let createTaskButton = element.querySelector('#button-start'); createTaskButton.click(); @@ -122,7 +131,7 @@ describe('StartTaskComponent', () => { it('should not emit success event when data not present', () => { let successSpy = spyOn(component.success, 'emit'); - component.startTaskModel = new StartTaskModel(null); + component.taskDetailsModel = new TaskDetailsModel(null); fixture.detectChanges(); let createTaskButton = element.querySelector('#button-start'); createTaskButton.click(); @@ -141,6 +150,9 @@ describe('StartTaskComponent', () => { assignee: null } )); + }); + + it('should attach form to the task when a form is selected', () => { spyOn(service, 'attachFormToATask').and.returnValue(of( { id: 91, @@ -149,13 +161,11 @@ describe('StartTaskComponent', () => { assignee: null } )); - }); - - it('should attach form to the task when a form is selected', () => { let successSpy = spyOn(component.success, 'emit'); + component.taskForm.controls['name'].setValue('fakeName'); + component.taskForm.controls['formKey'].setValue(1204); component.appId = 42; - component.startTaskModel = new StartTaskModel(startTaskMock); - component.formKey = '1204'; + component.taskDetailsModel = new TaskDetailsModel(taskDetailsMock); fixture.detectChanges(); let createTaskButton = element.querySelector('#button-start'); createTaskButton.click(); @@ -168,10 +178,19 @@ describe('StartTaskComponent', () => { }); it('should not attach form to the task when a no form is selected', () => { + spyOn(service, 'attachFormToATask').and.returnValue(of( + { + id: 91, + name: 'fakeName', + formKey: null, + assignee: null + } + )); let successSpy = spyOn(component.success, 'emit'); + component.taskForm.controls['name'].setValue('fakeName'); + component.taskForm.controls['formKey'].setValue(null); component.appId = 42; - component.startTaskModel = new StartTaskModel(startTaskMock); - component.formKey = null; + component.taskDetailsModel = new TaskDetailsModel(taskDetailsMock); fixture.detectChanges(); let createTaskButton = element.querySelector('#button-start'); createTaskButton.click(); @@ -214,9 +233,9 @@ describe('StartTaskComponent', () => { it('should assign task when an assignee is selected', () => { let successSpy = spyOn(component.success, 'emit'); + component.taskForm.controls['name'].setValue('fakeName'); + component.taskForm.controls['formKey'].setValue(1204); component.appId = 42; - component.startTaskModel = new StartTaskModel(startTaskMock); - component.formKey = '1204'; component.assigneeId = testUser.id; fixture.detectChanges(); let createTaskButton = element.querySelector('#button-start'); @@ -229,12 +248,31 @@ describe('StartTaskComponent', () => { }); }); + it('should assign task with id of selected user assigned', () => { + let successSpy = spyOn(component.success, 'emit'); + component.taskDetailsModel = new TaskDetailsModel(taskDetailsMock); + component.taskForm.controls['name'].setValue('fakeName'); + component.taskForm.controls['formKey'].setValue(1204); + component.appId = 42; + component.getAssigneeId(testUser.id); + fixture.detectChanges(); + let createTaskButton = element.querySelector('#button-start'); + createTaskButton.click(); + expect(successSpy).toHaveBeenCalledWith({ + id: 91, + name: 'fakeName', + formKey: 1204, + assignee: testUser + }); + }); + it('should not assign task when no assignee is selected', () => { let successSpy = spyOn(component.success, 'emit'); + component.taskForm.controls['name'].setValue('fakeName'); + component.taskForm.controls['formKey'].setValue(1204); component.appId = 42; - component.formKey = '1204'; component.assigneeId = null; - component.startTaskModel = new StartTaskModel(startTaskMock); + component.taskDetailsModel = new TaskDetailsModel(taskDetailsMock); fixture.detectChanges(); let createTaskButton = element.querySelector('#button-start'); createTaskButton.click(); @@ -245,27 +283,10 @@ describe('StartTaskComponent', () => { assignee: null }); }); - - it('should assign task with id of selected user assigned', () => { - let successSpy = spyOn(component.success, 'emit'); - component.appId = 42; - component.startTaskModel = new StartTaskModel(startTaskMock); - component.formKey = '1204'; - component.getAssigneeId(testUser.id); - fixture.detectChanges(); - let createTaskButton = element.querySelector('#button-start'); - createTaskButton.click(); - expect(successSpy).toHaveBeenCalledWith({ - id: 91, - name: 'fakeName', - formKey: 1204, - assignee: testUser - }); - }); }); it('should not attach a form when a form id is not selected', () => { - let attachFormToATask = spyOn(service, 'attachFormToATask').and.returnValue(of()); + let attachFormToATask = spyOn(service, 'attachFormToATask').and.returnValue([]); spyOn(service, 'createNewTask').and.callFake( function() { return new Observable((observer) => { @@ -273,14 +294,16 @@ describe('StartTaskComponent', () => { observer.complete(); }); }); + component.taskForm.controls['name'].setValue('fakeName'); + fixture.detectChanges(); let createTaskButton = element.querySelector('#button-start'); - component.startTaskModel.name = 'fake-name'; fixture.detectChanges(); createTaskButton.click(); expect(attachFormToATask).not.toHaveBeenCalled(); }); it('should show start task button', () => { + fixture.detectChanges(); expect(element.querySelector('#button-start')).toBeDefined(); expect(element.querySelector('#button-start')).not.toBeNull(); expect(element.querySelector('#button-start').textContent).toContain('ADF_TASK_LIST.START_TASK.FORM.ACTION.START'); @@ -294,16 +317,15 @@ describe('StartTaskComponent', () => { }); it('should disable start button if name is empty', () => { - component.startTaskModel.name = ''; + component.taskForm.controls['name'].setValue(''); fixture.detectChanges(); - let createTaskButton = fixture.nativeElement.querySelector('#button-start'); + let createTaskButton = fixture.nativeElement.querySelector('#button-start'); expect(createTaskButton.disabled).toBeTruthy(); }); it('should cancel start task on cancel button click', () => { let emitSpy = spyOn(component.cancel, 'emit'); - let cancelTaskButton = fixture.nativeElement.querySelector('#button-cancel'); - component.startTaskModel.name = ''; + let cancelTaskButton = element.querySelector('#button-cancel'); fixture.detectChanges(); cancelTaskButton.click(); expect(emitSpy).not.toBeNull(); @@ -311,24 +333,24 @@ describe('StartTaskComponent', () => { }); it('should enable start button if name is filled out', () => { - component.startTaskModel.name = 'fakeName'; + component.taskForm.controls['name'].setValue('fakeName'); fixture.detectChanges(); let createTaskButton = fixture.nativeElement.querySelector('#button-start'); expect(createTaskButton.disabled).toBeFalsy(); }); - it('should define the select option for Forms', () => { - component.forms = fakeForms; + it('should define the select options for Forms', () => { + component.forms$ = service.getFormList(); fixture.detectChanges(); - let selectElement = fixture.nativeElement.querySelector('#form_id'); - expect(selectElement.attributes['aria-label'].value).toContain('ADF_TASK_LIST.START_TASK.FORM.LABEL.FORM'); + let selectElement = fixture.nativeElement.querySelector('#form_label'); + expect(selectElement.innerHTML).toContain('ADF_TASK_LIST.START_TASK.FORM.LABEL.FORM'); }); - it('should get formatted full name', () => { - let testUser1 = {'id': 1001, 'firstName': 'Wilbur', 'lastName': 'Adams', 'email': 'wilbur@app.activiti.com'}; - let testUser2 = {'id': 1002, 'firstName': '', 'lastName': 'Adams', 'email': 'adams@app.activiti.com'}; - let testUser3 = {'id': 1003, 'firstName': 'Wilbur', 'lastName': '', 'email': 'wilbur@app.activiti.com'}; - let testUser4 = {'id': 1004, 'firstName': '', 'lastName': '', 'email': 'test@app.activiti.com'}; + it('should get formatted fullname', () => { + let testUser1 = { 'id': 1001, 'firstName': 'Wilbur', 'lastName': 'Adams', 'email': 'wilbur@app.activiti.com' }; + let testUser2 = { 'id': 1002, 'firstName': '', 'lastName': 'Adams', 'email': 'adams@app.activiti.com' }; + let testUser3 = { 'id': 1003, 'firstName': 'Wilbur', 'lastName': '', 'email': 'wilbur@app.activiti.com' }; + let testUser4 = { 'id': 1004, 'firstName': '', 'lastName': '', 'email': 'test@app.activiti.com' }; let testFullName1 = component.getDisplayUser(testUser1.firstName, testUser1.lastName, ' '); let testFullName2 = component.getDisplayUser(testUser2.firstName, testUser2.lastName, ' '); @@ -342,12 +364,44 @@ describe('StartTaskComponent', () => { }); it('should emit error when there is an error while creating task', () => { + component.taskForm.controls['name'].setValue('fakeName'); let errorSpy = spyOn(component.error, 'emit'); spyOn(service, 'createNewTask').and.returnValue(throwError({})); let createTaskButton = element.querySelector('#button-start'); - component.startTaskModel.name = 'fake-name'; fixture.detectChanges(); createTaskButton.click(); expect(errorSpy).toHaveBeenCalled(); }); + + it('should emit error when task name exceeds maximum length', () => { + component.maxTaskNameLength = 2; + component.ngOnInit(); + fixture.detectChanges(); + let name = component.taskForm.controls['name']; + name.setValue('task'); + fixture.detectChanges(); + expect(name.valid).toBeFalsy(); + name.setValue('ta'); + fixture.detectChanges(); + expect(name.valid).toBeTruthy(); + }); + + it('should emit error when task name field is empty', () => { + fixture.detectChanges(); + let name = component.taskForm.controls['name']; + name.setValue(''); + fixture.detectChanges(); + expect(name.valid).toBeFalsy(); + name.setValue('task'); + fixture.detectChanges(); + expect(name.valid).toBeTruthy(); + }); + + it('should call logService when task name exceeds maximum length', () => { + logSpy = spyOn(logService, 'log').and.callThrough(); + component.maxTaskNameLength = 300; + component.ngOnInit(); + fixture.detectChanges(); + expect(logSpy).toHaveBeenCalled(); + }); }); diff --git a/lib/process-services/task-list/components/start-task.component.ts b/lib/process-services/task-list/components/start-task.component.ts index be220f019f..1db8df58f0 100644 --- a/lib/process-services/task-list/components/start-task.component.ts +++ b/lib/process-services/task-list/components/start-task.component.ts @@ -23,10 +23,10 @@ import moment from 'moment-es6'; import { Moment } from 'moment'; import { Observable, of } from 'rxjs'; import { Form } from '../models/form.model'; -import { StartTaskModel } from '../models/start-task.model'; import { TaskDetailsModel } from '../models/task-details.model'; import { TaskListService } from './../services/tasklist.service'; import { switchMap, defaultIfEmpty } from 'rxjs/operators'; +import { FormBuilder, AbstractControl, Validators, FormGroup, FormControl } from '@angular/forms'; @Component({ selector: 'adf-start-task', @@ -40,36 +40,31 @@ import { switchMap, defaultIfEmpty } from 'rxjs/operators'; export class StartTaskComponent implements OnInit { public FORMAT_DATE: string = 'DD/MM/YYYY'; + MAX_LENGTH: number = 255; - /** (required) The id of the app. */ @Input() appId: number; - /** Emitted when the task is successfully created. */ + @Input() + name: string = ''; + @Output() success: EventEmitter = new EventEmitter(); - /** Emitted when the cancel button is clicked by the user. */ @Output() cancel: EventEmitter = new EventEmitter(); - /** Emitted when an error occurs. */ @Output() error: EventEmitter = new EventEmitter(); - startTaskModel: StartTaskModel = new StartTaskModel(); - - forms: Form[]; - + taskDetailsModel: TaskDetailsModel = new TaskDetailsModel(); + forms$: Observable; assigneeId: number; - - formKey: string; - - taskId: string; - - dateError: boolean; - field: FormFieldModel; + taskForm: FormGroup; + dateError: boolean = false; + maxTaskNameLength: number = this.MAX_LENGTH; + loading = false; /** * Constructor @@ -80,44 +75,74 @@ export class StartTaskComponent implements OnInit { constructor(private taskService: TaskListService, private dateAdapter: DateAdapter, private preferences: UserPreferencesService, + private formBuilder: FormBuilder, private logService: LogService) { } ngOnInit() { - this.field = new FormFieldModel(new FormModel(), {id: this.assigneeId, value: this.assigneeId, placeholder: 'Assignee'}); + if (this.name) { + this.taskDetailsModel.name = this.name; + } + + this.validateMaxTaskNameLength(); + + this.field = new FormFieldModel(new FormModel(), { id: this.assigneeId, value: this.assigneeId, placeholder: 'Assignee' }); this.preferences.locale$.subscribe((locale) => { this.dateAdapter.setLocale(locale); }); + this.loadFormsTask(); + this.buildForm(); } - public start(): void { - if (this.startTaskModel.name) { - if (this.appId) { - this.startTaskModel.category = this.appId.toString(); - } - this.taskService.createNewTask(new TaskDetailsModel(this.startTaskModel)) - .pipe( - switchMap((createRes: any) => - this.attachForm(createRes.id, this.formKey).pipe( - defaultIfEmpty(createRes), - switchMap((attachRes: any) => - this.assignTaskByUserId(createRes.id, this.assigneeId).pipe( - defaultIfEmpty(attachRes ? attachRes : createRes) - ) + buildForm() { + this.taskForm = this.formBuilder.group({ + name: new FormControl(this.taskDetailsModel.name, [Validators.required, Validators.maxLength(this.maxTaskNameLength)]), + description: new FormControl(''), + formKey: new FormControl('') + }); + + this.taskForm.valueChanges.subscribe((taskFormValues) => this.setTaskDetails(taskFormValues)); + } + + setTaskDetails(form) { + this.taskDetailsModel.name = form.name; + this.taskDetailsModel.description = form.description; + this.taskDetailsModel.formKey = form.formKey ? form.formKey.toString() : null; + } + + isFormValid() { + return this.taskForm.valid && !this.dateError && !this.loading; + } + + public saveTask(): void { + this.loading = true; + if (this.appId) { + this.taskDetailsModel.category = this.appId.toString(); + } + this.taskService.createNewTask(this.taskDetailsModel) + .pipe( + switchMap((createRes: any) => + this.attachForm(createRes.id, this.taskDetailsModel.formKey).pipe( + defaultIfEmpty(createRes), + switchMap((attachRes: any) => + this.assignTaskByUserId(createRes.id, this.assigneeId).pipe( + defaultIfEmpty(attachRes ? attachRes : createRes) ) ) ) ) - .subscribe( - (res: any) => { - this.success.emit(res); - }, - (err) => { - this.error.emit(err); - this.logService.error('An error occurred while creating new task'); - }); - } + ) + .subscribe( + (res: any) => { + this.loading = false; + this.success.emit(res); + }, + (err) => { + this.loading = false; + this.error.emit(err); + this.logService.error('An error occurred while creating new task'); + }); } getAssigneeId(userId) { @@ -145,13 +170,7 @@ export class StartTaskComponent implements OnInit { } private loadFormsTask(): void { - this.taskService.getFormList().subscribe((res: Form[]) => { - this.forms = res; - }, - (err) => { - this.error.emit(err); - this.logService.error('An error occurred while trying to get the forms'); - }); + this.forms$ = this.taskService.getFormList(); } public isUserNameEmpty(user: UserProcessModel): boolean { @@ -168,20 +187,45 @@ export class StartTaskComponent implements OnInit { return firstName + delimiter + lastName; } - onDateChanged(newDateValue): void { + onDateChanged(newDateValue: any) { this.dateError = false; if (newDateValue) { - let momentDate = moment(newDateValue, this.FORMAT_DATE, true); - if (!momentDate.isValid()) { - this.dateError = true; + let momentDate; + + if (typeof newDateValue === 'string') { + momentDate = moment(newDateValue, this.FORMAT_DATE, true); + } else { + momentDate = newDateValue; } + + if (momentDate.isValid()) { + this.taskDetailsModel.dueDate = momentDate.toDate(); + } else { + this.dateError = true; + this.taskDetailsModel.dueDate = null; + } + } else { + this.taskDetailsModel.dueDate = null; } } - clearDateInput() { - const emptyValue = ''; - this.startTaskModel.dueDate = emptyValue; - this.onDateChanged(emptyValue); + private validateMaxTaskNameLength() { + if (this.maxTaskNameLength > this.MAX_LENGTH) { + this.maxTaskNameLength = this.MAX_LENGTH; + this.logService.log(`the task name length cannot be greater than ${this.MAX_LENGTH}`); + } + } + + get nameController(): AbstractControl { + return this.taskForm.get('name'); + } + + get descriptionController(): AbstractControl { + return this.taskForm.get('description'); + } + + get formKeyController(): AbstractControl { + return this.taskForm.get('formKey'); } }