diff --git a/docs/process-services/attach-form.component.md b/docs/process-services/attach-form.component.md new file mode 100644 index 0000000000..de48397e36 --- /dev/null +++ b/docs/process-services/attach-form.component.md @@ -0,0 +1,31 @@ +--- +Added: v2.0.0 +Status: Active +--- + +# Attach Form component + +This component can be used when there is no form attached to a task and we want to add one. + +## Basic Usage + +```html + + +``` + +## Class members + +### Properties + +| Name | Type | Default value | Description | +| -- | -- | -- | -- | +| taskId | `string` | | Id of the task. | + +### Events + +| Name | Type | Description | +| -- | -- | -- | +| cancelAttachForm | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when the "Cancel" button is clicked. | +| completeAttachForm | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when the form associated with the task is completed. | diff --git a/docs/process-services/task-standalone.component.md b/docs/process-services/task-standalone.component.md index b471db701e..5162e2c9f9 100644 --- a/docs/process-services/task-standalone.component.md +++ b/docs/process-services/task-standalone.component.md @@ -25,6 +25,7 @@ This component can be used when there is no form attached to a task. | hideCancelButton | `boolean` | true | Toggles rendering of the `Cancel` button. | | isCompleted | `boolean` | false | If true then Task completed message is shown and `Complete` and `Cancel` buttons are hidden. | | taskName | `string` | | Name of the task. | +| taskId | `number` | | Id of the task. | ### Events diff --git a/lib/process-services/i18n/en.json b/lib/process-services/i18n/en.json index e10eb91517..66758a4497 100644 --- a/lib/process-services/i18n/en.json +++ b/lib/process-services/i18n/en.json @@ -152,6 +152,9 @@ "NO_FORM_MESSAGE": "No forms attached", "COMPLETE_TASK_MESSAGE": "Task {{taskName}} completed", "COMPLETE_TASK_SUB_MESSAGE": "No forms to be added" + }, + "ATTACH_FORM":{ + "SELECT_FORM": "Select Form To Attach" } }, "ADF_PROCESS_LIST": { diff --git a/lib/process-services/task-list/components/attach-form.component.html b/lib/process-services/task-list/components/attach-form.component.html new file mode 100644 index 0000000000..356f11c23a --- /dev/null +++ b/lib/process-services/task-list/components/attach-form.component.html @@ -0,0 +1,30 @@ +
+ + +
+ +

{{ 'ADF_TASK_LIST.ATTACH_FORM.SELECT_FORM' | translate }}

+
+
+ + + {{ form.name }} + + +
+ + + +
+
+ + + + + +
+
diff --git a/lib/process-services/task-list/components/attach-form.component.scss b/lib/process-services/task-list/components/attach-form.component.scss new file mode 100644 index 0000000000..972a4d9da0 --- /dev/null +++ b/lib/process-services/task-list/components/attach-form.component.scss @@ -0,0 +1,17 @@ +.adf-attach-form { + .mat-form-field { + width: 100%; + } + + &-row { + display: flex; + justify-content: space-between; + margin: 20px 0; + } + + .adf-no-form-mat-card-actions { + justify-content: flex-end; + margin-top: 30px; + text-align: right; + } +} diff --git a/lib/process-services/task-list/components/attach-form.component.spec.ts b/lib/process-services/task-list/components/attach-form.component.spec.ts new file mode 100644 index 0000000000..a23aa16595 --- /dev/null +++ b/lib/process-services/task-list/components/attach-form.component.spec.ts @@ -0,0 +1,78 @@ +/*! + * @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 { AttachFormComponent } from './attach-form.component'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { setupTestBed } from '@alfresco/adf-core'; +import { ProcessTestingModule } from '../../testing/process.testing.module'; +import { TaskListService } from './../services/tasklist.service'; +import { Observable } from 'rxjs/Observable'; + +describe('AttachFormComponent', () => { + let component: AttachFormComponent; + let fixture: ComponentFixture; + let element: HTMLElement; + let taskService: TaskListService; + + setupTestBed({ + imports: [ + ProcessTestingModule + ] + }); + + beforeEach(async(() => { + fixture = TestBed.createComponent(AttachFormComponent); + component = fixture.componentInstance; + element = fixture.nativeElement; + taskService = TestBed.get(TaskListService); + fixture.detectChanges(); + })); + + it('should emit cancel event if clicked on Cancel Button ', async(() => { + fixture.detectChanges(); + fixture.whenStable().then(() => { + const emitSpy = spyOn(component.cancelAttachForm, 'emit'); + const el = fixture.nativeElement.querySelector('#adf-no-form-cancel-button'); + el.click(); + expect(emitSpy).toHaveBeenCalled(); + }); + })); + + it('should call attachFormToATask if clicked on Complete Button', async(() => { + component.taskId = 1; + component.formKey = 2; + spyOn(taskService, 'attachFormToATask').and.returnValue(Observable.of(true)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(element.querySelector('#adf-no-form-attach-form-button')).toBeDefined(); + const el = fixture.nativeElement.querySelector('#adf-no-form-attach-form-button'); + el.click(); + expect(taskService.attachFormToATask).toHaveBeenCalledWith(1, 2); + }); + })); + + it('should show the adf-form of the selected form', async(() => { + component.taskId = 1; + component.formKey = 12; + fixture.detectChanges(); + const formContainer = fixture.debugElement.nativeElement.querySelector('adf-form'); + fixture.whenStable().then(() => { + expect(formContainer).toBeDefined(); + expect(formContainer).not.toBeNull(); + }); + })); +}); diff --git a/lib/process-services/task-list/components/attach-form.component.ts b/lib/process-services/task-list/components/attach-form.component.ts new file mode 100644 index 0000000000..dce017980c --- /dev/null +++ b/lib/process-services/task-list/components/attach-form.component.ts @@ -0,0 +1,87 @@ +/*! + * @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 { LogService } from '@alfresco/adf-core'; +import { Component, EventEmitter, Input, OnInit, OnChanges, Output } from '@angular/core'; +import { Form } from '../models/form.model'; +import { TaskListService } from './../services/tasklist.service'; + +@Component({ + selector: 'adf-attach-form', + templateUrl: './attach-form.component.html', + styleUrls: ['./attach-form.component.scss'] +}) + +export class AttachFormComponent implements OnInit, OnChanges { + constructor(private taskService: TaskListService, + private logService: LogService) { } + + /** The id of the task whose details we are asking for. */ + @Input() + taskId; + + /** Emitted when the "Cancel" button is clicked. */ + @Output() + cancelAttachForm: EventEmitter = new EventEmitter(); + + /** Emitted when the form associated with the form task is attached. */ + @Output() + completeAttachForm: EventEmitter = new EventEmitter(); + + /** Emitted when an error occurs. */ + @Output() + error: EventEmitter = new EventEmitter(); + + forms: Form[]; + + formKey: number; + + ngOnInit() { + this.loadFormsTask(); + } + + ngOnChanges() { + this.loadFormsTask(); + } + + onCancelButtonClick(): void { + this.cancelAttachForm.emit(); + } + + onAttachFormButtonClick(): void { + this.attachForm(this.taskId, this.formKey); + } + + 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'); + }); + } + + private attachForm(taskId: string, formKey: number) { + if (taskId && formKey) { + this.taskService.attachFormToATask(taskId, formKey) + .subscribe((res) => { + this.completeAttachForm.emit(); + }); + } + } +} diff --git a/lib/process-services/task-list/components/task-details.component.html b/lib/process-services/task-list/components/task-details.component.html index bf7c480028..d1e951a732 100644 --- a/lib/process-services/task-list/components/task-details.component.html +++ b/lib/process-services/task-list/components/task-details.component.html @@ -39,12 +39,14 @@ (error)='onFormError($event)' (executeOutcome)='onFormExecuteOutcome($event)'> - +
diff --git a/lib/process-services/task-list/components/task-details.component.scss b/lib/process-services/task-list/components/task-details.component.scss index 2f5678f048..662e731e20 100644 --- a/lib/process-services/task-list/components/task-details.component.scss +++ b/lib/process-services/task-list/components/task-details.component.scss @@ -74,10 +74,12 @@ adf-task-header.assign-edit-view ::ng-deep adf-card-view ::ng-deep .adf-property flex-grow: 1; & ::ng-deep .adf-form-debug-container { - padding: 20px 0 0 0; + display: flex; + flex-direction: column; + padding: 20px 0; .mat-slide-toggle { - float: right; + margin-left: auto; & + div { background-color: black; diff --git a/lib/process-services/task-list/components/task-details.component.spec.ts b/lib/process-services/task-list/components/task-details.component.spec.ts index f11f2bc4e0..2890595c1e 100644 --- a/lib/process-services/task-list/components/task-details.component.spec.ts +++ b/lib/process-services/task-list/components/task-details.component.spec.ts @@ -160,9 +160,12 @@ describe('TaskDetailsComponent', () => { it('should not display task standalone component when the task have an associated form', async(() => { component.taskId = '123'; + component.taskDetails = new TaskDetailsModel(taskDetailsMock); + component.taskDetails.formKey = '10'; fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); + expect(fixture.debugElement.query(By.css('adf-task-standalone'))).toBeDefined(); expect(fixture.debugElement.query(By.css('adf-task-standalone'))).not.toBeNull(); }); })); diff --git a/lib/process-services/task-list/components/task-details.component.ts b/lib/process-services/task-list/components/task-details.component.ts index 856718f5b7..b3c121c3ce 100644 --- a/lib/process-services/task-list/components/task-details.component.ts +++ b/lib/process-services/task-list/components/task-details.component.ts @@ -21,6 +21,7 @@ import { CardViewUpdateService, ClickNotification, LogService, + FormService, UpdateNotification, FormRenderingService, CommentsComponent @@ -186,6 +187,7 @@ export class TaskDetailsComponent implements OnInit, OnChanges { private authService: AuthenticationService, private peopleProcessService: PeopleProcessService, private formRenderingService: FormRenderingService, + private formService: FormService, private logService: LogService, private cardViewUpdateService: CardViewUpdateService, private dialog: MatDialog) { @@ -363,6 +365,13 @@ export class TaskDetailsComponent implements OnInit, OnChanges { ); } + onFormAttached() { + this.formService.getTaskForm(this.taskId) + .subscribe((res) => { + this.loadDetails(this.taskId); + }, error => this.logService.error('Could not load forms')); + } + onFormContentClick(content: ContentLinkModel): void { this.formContentClicked.emit(content); } diff --git a/lib/process-services/task-list/components/task-standalone.component.html b/lib/process-services/task-list/components/task-standalone.component.html index e7ff34cf68..d77a91d09a 100644 --- a/lib/process-services/task-list/components/task-standalone.component.html +++ b/lib/process-services/task-list/components/task-standalone.component.html @@ -1,4 +1,4 @@ - +
@@ -18,7 +18,16 @@ - - + +
+ + +
- \ No newline at end of file + + + + diff --git a/lib/process-services/task-list/components/task-standalone.component.scss b/lib/process-services/task-list/components/task-standalone.component.scss index bfee7edc17..e12364a677 100644 --- a/lib/process-services/task-list/components/task-standalone.component.scss +++ b/lib/process-services/task-list/components/task-standalone.component.scss @@ -2,7 +2,7 @@ $config: mat-typography-config(); $background: map-get($theme, background); - + .adf { &-message-card { width: 60%; @@ -13,7 +13,7 @@ } } &-no-form-message-container { - height:256px; + height: 256px; width: 100%; display: table; } @@ -37,8 +37,9 @@ margin: auto; width: fit-content !important; } - &-no-form-mat-card-actions { - text-align: right; + &-no-form-mat-card-actions.mat-card-actions { + display: flex; + justify-content: space-between; & .mat-button { text-transform: uppercase; border-radius: 5px; @@ -50,4 +51,4 @@ } } } -} \ No newline at end of file +} diff --git a/lib/process-services/task-list/components/task-standalone.component.ts b/lib/process-services/task-list/components/task-standalone.component.ts index 3e0ea75720..680cda8c1b 100644 --- a/lib/process-services/task-list/components/task-standalone.component.ts +++ b/lib/process-services/task-list/components/task-standalone.component.ts @@ -28,7 +28,11 @@ export class TaskStandaloneComponent { /** Name of the task. */ @Input() - taskName: string; + taskName; + + /** Id of the task. */ + @Input() + taskId; /** If true then Task completed message is shown and `Complete` and `Cancel` buttons are hidden. */ @Input() @@ -50,6 +54,11 @@ export class TaskStandaloneComponent { @Output() complete: EventEmitter = new EventEmitter(); + @Output() + formAttached: EventEmitter = new EventEmitter(); + + showAttachForm: boolean = false; + constructor() { } onCancelButtonClick(): void { @@ -67,4 +76,21 @@ export class TaskStandaloneComponent { hasCancelButton(): boolean { return !this.hideCancelButton && !this.isCompleted; } + + hasAttachFormButton(): boolean { + return !this.isCompleted; + } + + onShowAttachForm() { + this.showAttachForm = true; + } + + onCancelAttachForm() { + this.showAttachForm = false; + } + + onCompleteAttachForm() { + this.showAttachForm = false; + this.formAttached.emit(); + } } diff --git a/lib/process-services/task-list/public-api.ts b/lib/process-services/task-list/public-api.ts index fcfc927ea9..b8bbf74a1f 100644 --- a/lib/process-services/task-list/public-api.ts +++ b/lib/process-services/task-list/public-api.ts @@ -24,6 +24,7 @@ export * from './components/task-details.component'; export * from './components/task-audit.directive'; export * from './components/start-task.component'; export * from './components/task-standalone.component'; +export * from './components/attach-form.component'; export * from './services/tasklist.service'; export * from './services/process-upload.service'; diff --git a/lib/process-services/task-list/task-list.module.ts b/lib/process-services/task-list/task-list.module.ts index d4a176d9f4..2fea44c18d 100644 --- a/lib/process-services/task-list/task-list.module.ts +++ b/lib/process-services/task-list/task-list.module.ts @@ -40,6 +40,7 @@ import { TaskFiltersComponent } from './components/task-filters.component'; import { TaskHeaderComponent } from './components/task-header.component'; import { TaskListComponent } from './components/task-list.component'; import { TaskStandaloneComponent } from './components/task-standalone.component'; +import { AttachFormComponent } from './components/attach-form.component'; @NgModule({ imports: [ @@ -63,7 +64,8 @@ import { TaskStandaloneComponent } from './components/task-standalone.component' ChecklistComponent, TaskHeaderComponent, StartTaskComponent, - TaskStandaloneComponent + TaskStandaloneComponent, + AttachFormComponent ], providers: [ TaskListService, @@ -80,7 +82,8 @@ import { TaskStandaloneComponent } from './components/task-standalone.component' ChecklistComponent, TaskHeaderComponent, StartTaskComponent, - TaskStandaloneComponent + TaskStandaloneComponent, + AttachFormComponent ] }) export class TaskListModule {