diff --git a/demo-shell/resources/i18n/en.json b/demo-shell/resources/i18n/en.json index 624568b65b..e0eb623c3c 100644 --- a/demo-shell/resources/i18n/en.json +++ b/demo-shell/resources/i18n/en.json @@ -55,6 +55,8 @@ "NODE-SELECTOR": "Node Selector", "CONTENT_SERVICES": "Content Services", "BREADCRUMB": "Breadcrumb", + "NOTIFICATIONS": "Notifications", + "TASK_LIST": "Task List", "CARD_VIEW": "CardView", "PROCESS_SERVICES": "Process Services", "LOGIN": "Login", @@ -202,5 +204,9 @@ "DEMO_PERMISSION": { "INHERIT_PERMISSION_BUTTON": "Inherit Permission", "INHERITED_PERMISSIONS_BUTTON": "Permission Inherited" + }, + "TASK_LIST_DEMO": { + "APP_ID_REQUIRED_ERROR": "Insert App Id", + "APP_ID_TYPE_ERROR": "App Id must be a number" } } diff --git a/demo-shell/src/app/app.module.ts b/demo-shell/src/app/app.module.ts index 65e7be4ced..9948a0d4c0 100644 --- a/demo-shell/src/app/app.module.ts +++ b/demo-shell/src/app/app.module.ts @@ -52,6 +52,7 @@ import { SharedLinkViewComponent } from './components/shared-link-view/shared-li import { DemoPermissionComponent } from './components/permissions/demo-permissions.component'; import { PreviewService } from './services/preview.service'; import { BreadcrumbDemoComponent } from './components/breadcrumb-demo/breadcrumb-demo.component'; +import { TaskListDemoComponent } from './components/task-list-demo/task-list-demo.component'; import { ContentNodeSelectorComponent } from './components/content-node-selector/content-node-selector.component'; import { NotificationsComponent } from './components/notifications/notifications.component'; import { ReportIssueComponent } from './components/report-issue/report-issue.component'; @@ -112,7 +113,8 @@ import { CardViewComponent } from './components/card-view/card-view.component'; NotificationsComponent, CardViewComponent, ContentNodeSelectorComponent, - ReportIssueComponent + ReportIssueComponent, + TaskListDemoComponent ], providers: [ { provide: AppConfigService, useClass: DebugAppConfigService }, // not use this service in production diff --git a/demo-shell/src/app/app.routes.ts b/demo-shell/src/app/app.routes.ts index cc77d65e77..95437dc135 100644 --- a/demo-shell/src/app/app.routes.ts +++ b/demo-shell/src/app/app.routes.ts @@ -49,6 +49,7 @@ import { FormLoadingComponent } from './components/form/form-loading.component'; import { DemoPermissionComponent } from './components/permissions/demo-permissions.component'; import { BlobPreviewComponent } from './components/blob-preview/blob-preview.component'; import { BreadcrumbDemoComponent } from './components/breadcrumb-demo/breadcrumb-demo.component'; +import { TaskListDemoComponent } from './components/task-list-demo/task-list-demo.component'; import { NotificationsComponent } from './components/notifications/notifications.component'; import { CardViewComponent } from './components/card-view/card-view.component'; import { ContentNodeSelectorComponent } from './components/content-node-selector/content-node-selector.component'; @@ -241,6 +242,16 @@ export const appRoutes: Routes = [ path: 'datatable-lazy', loadChildren: 'app/components/lazy-loading/lazy-loading.module#LazyLoadingModule' }, + { + path: 'task-list', + component: TaskListDemoComponent, + canActivate: [AuthGuardBpm] + }, + { + path: 'task-list/:id', + component: TaskListDemoComponent, + canActivate: [AuthGuardBpm] + }, { path: 'error/:id', component: ErrorContentComponent @@ -249,7 +260,6 @@ export const appRoutes: Routes = [ path: '**', redirectTo: 'error/404' } - ] } ]; diff --git a/demo-shell/src/app/components/app-layout/app-layout.component.ts b/demo-shell/src/app/components/app-layout/app-layout.component.ts index b5523c44c8..894ca1f646 100644 --- a/demo-shell/src/app/components/app-layout/app-layout.component.ts +++ b/demo-shell/src/app/components/app-layout/app-layout.component.ts @@ -36,6 +36,7 @@ export class AppLayoutComponent implements OnInit { { href: '/notifications', icon: 'alarm', title: 'APP_LAYOUT.NOTIFICATIONS'}, { href: '/card-view', icon: 'view_headline', title: 'APP_LAYOUT.CARD_VIEW'}, { href: '/node-selector', icon: 'attachment', title: 'APP_LAYOUT.NODE-SELECTOR' }, + { href: '/task-list', icon: 'assignment', title: 'APP_LAYOUT.TASK_LIST' }, { href: '/activiti', icon: 'device_hub', title: 'APP_LAYOUT.PROCESS_SERVICES' }, { href: '/login', icon: 'vpn_key', title: 'APP_LAYOUT.LOGIN' }, { href: '/trashcan', icon: 'delete', title: 'APP_LAYOUT.TRASHCAN' }, 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 cf5574ac17..05bb4d6024 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 @@ -32,7 +32,7 @@ *ngIf="taskFilter && !isStartTaskMode()"> + +
+ + App Id + + + {{ 'TASK_LIST_DEMO.APP_ID_REQUIRED_ERROR' | translate }} + + + {{ 'TASK_LIST_DEMO.APP_ID_TYPE_ERROR' | translate }} + + + + + Task Name + + + + + ProcessDefinitionId + + SimpleProcess:1:2 + + + + Assignment + + {{ assignmentOption.title }} + + + + + State + + {{ stateOption.title }} + + + + + Sort + + {{ sortOption.title }} + + + +
+ +
+
+ + +
+ + + + + +
+ diff --git a/demo-shell/src/app/components/task-list-demo/task-list-demo.component.scss b/demo-shell/src/app/components/task-list-demo/task-list-demo.component.scss new file mode 100644 index 0000000000..df46812d9d --- /dev/null +++ b/demo-shell/src/app/components/task-list-demo/task-list-demo.component.scss @@ -0,0 +1,17 @@ +.task-list-demo-inputs { + margin-top: 100px; + margin-bottom: 50px; + display: flex; + justify-content: space-evenly; +} + +.adf-reset-button { + margin-top: 50px; + display: flex; + justify-content: center; +} + +.task-list-demo-error-message { + color: red; + text-align: center; +} \ No newline at end of file diff --git a/demo-shell/src/app/components/task-list-demo/task-list-demo.component.ts b/demo-shell/src/app/components/task-list-demo/task-list-demo.component.ts new file mode 100644 index 0000000000..e60eebdde8 --- /dev/null +++ b/demo-shell/src/app/components/task-list-demo/task-list-demo.component.ts @@ -0,0 +1,147 @@ +/*! + * @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 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * distributed under the License is distributed on an "AS IS" BASIS, + * limitations under the License. + */ + +import { Component, OnInit } from '@angular/core'; +import { FormGroup, FormBuilder, Validators, FormControl, AbstractControl } from '@angular/forms'; +import { ActivatedRoute, Params } from '@angular/router'; + + +@Component({ + templateUrl: './task-list-demo.component.html', + styleUrls: [`./task-list-demo.component.scss`], +}) + +export class TaskListDemoComponent implements OnInit { + + defaultAppId: number; + + taskListForm: FormGroup; + + errorMessage: string; + + appId: number; + + processDefinitionId: string; + + state: string; + + assignment: string; + + name: string; + + sort: string; + + assignmentOptions = [ + {value: 'assignee', title: 'Assignee'}, + {value: 'candidate', title: 'Candidate'} + ]; + + stateOptions = [ + {value: 'all', title: 'All'}, + {value: 'active', title: 'Active'}, + {value: 'completed', title: 'Completed'} + ]; + + sortOptions = [ + {value: 'created-asc', title: 'Created (asc)'}, + {value: 'created-desc', title: 'Created (desc)'}, + {value: 'due-asc', title: 'Due (asc)'}, + {value: 'due-desc', title: 'Due (desc)'} + ]; + + constructor(private route: ActivatedRoute, + private formBuilder: FormBuilder) { + } + + ngOnInit() { + if (this.route) { + this.route.params.forEach((params: Params) => { + if (params['id']) { + this.defaultAppId = +params['id']; + } else { + this.defaultAppId = 0; + } + }); + } + + this.errorMessage = 'Insert App Id'; + + this.buildForm(); + + } + + buildForm() { + this.taskListForm = this.formBuilder.group({ + taskAppId: new FormControl(this.defaultAppId, [Validators.required, Validators.pattern('^[0-9]*$')]), + taskName: new FormControl(''), + taskProcessDefinitionId: new FormControl(''), + taskAssignment: new FormControl(''), + taskState: new FormControl(''), + taskSort: new FormControl('') + }); + + this.taskListForm.valueChanges + .debounceTime(500) + .subscribe(taskFilter => { + if (this.isFormValid()) { + this.filterTasks(taskFilter); + } + }); + + } + + filterTasks(taskFilter: any) { + this.appId = taskFilter.taskAppId; + this.processDefinitionId = taskFilter.taskProcessDefinitionId; + this.name = taskFilter.taskName; + this.assignment = taskFilter.taskAssignment; + this.state = taskFilter.taskState; + this.sort = taskFilter.taskSort; + } + + resetTaskForm() { + this.taskListForm.reset(); + } + + isFormValid() { + return this.taskListForm && this.taskListForm.dirty && this.taskListForm.valid; + } + + get taskAppId(): AbstractControl { + return this.taskListForm.get('taskAppId'); + } + + get taskProcessDefinitionId(): AbstractControl { + return this.taskListForm.get('taskProcessDefinitionId'); + } + + get taskName(): AbstractControl { + return this.taskListForm.get('taskName'); + } + + get taskAssignment(): AbstractControl { + return this.taskListForm.get('taskAssignment'); + } + + get taskState(): AbstractControl { + return this.taskListForm.get('taskState'); + } + + get taskSort(): AbstractControl { + return this.taskListForm.get('taskSort'); + } +} diff --git a/docs/process-services/task-list.component.md b/docs/process-services/task-list.component.md index f60d3add2d..15f0eeec91 100644 --- a/docs/process-services/task-list.component.md +++ b/docs/process-services/task-list.component.md @@ -52,6 +52,7 @@ Renders a list containing all the tasks matched by the parameters specified. | name | `string` | | Name of the tasklist. | | page | `number` | 0 | The page number of the tasks to fetch. | | processDefinitionKey | `string` | | (**Deprecated:** 2.4.0) The Definition Key of the process. | +| processDefinitionId | `string` | | The Definition Id of the process. | | processInstanceId | `string` | | The Instance Id of the process. | | selectFirstRow | `boolean` | true | Toggles default selection of the first row | | selectionMode | `string` | "single" | Row selection mode. Can be none, `single` or `multiple`. For `multiple` mode, you can use Cmd (macOS) or Ctrl (Win) modifier key to toggle selection for multiple rows. | diff --git a/lib/process-services/task-list/components/task-list.component.spec.ts b/lib/process-services/task-list/components/task-list.component.spec.ts index 664ef3f329..e793b67f5e 100644 --- a/lib/process-services/task-list/components/task-list.component.spec.ts +++ b/lib/process-services/task-list/components/task-list.component.spec.ts @@ -197,6 +197,32 @@ describe('TaskListComponent', () => { }); }); + it('should return the filtered task list by processDefinitionId', (done) => { + let state = new SimpleChange(null, 'open', true); + let processDefinitionId = new SimpleChange(null, 'fakeprocessDefinitionId', true); + let assignment = new SimpleChange(null, 'fake-assignee', true); + + component.success.subscribe((res) => { + expect(res).toBeDefined(); + expect(component.rows).toBeDefined(); + expect(component.isListEmpty()).not.toBeTruthy(); + expect(component.rows.length).toEqual(2); + expect(component.rows[0]['name']).toEqual('nameFake1'); + expect(component.rows[0]['processDefinitionId']).toEqual('myprocess:1:4'); + done(); + }); + + component.ngAfterContentInit(); + component.ngOnChanges({ 'state': state, 'processDefinitionId': processDefinitionId, 'assignment': assignment }); + fixture.detectChanges(); + + jasmine.Ajax.requests.mostRecent().respondWith({ + 'status': 200, + contentType: 'application/json', + responseText: JSON.stringify(fakeGlobalTask) + }); + }); + it('should return the filtered task list for all state', (done) => { let state = new SimpleChange(null, 'all', true); let processInstanceId = new SimpleChange(null, 'fakeprocessId', true); diff --git a/lib/process-services/task-list/components/task-list.component.ts b/lib/process-services/task-list/components/task-list.component.ts index 83736014e2..907ff5c95d 100644 --- a/lib/process-services/task-list/components/task-list.component.ts +++ b/lib/process-services/task-list/components/task-list.component.ts @@ -51,6 +51,10 @@ export class TaskListComponent extends DataTableSchema implements OnChanges, Aft @Input() processInstanceId: string; + /** The Definition Id of the process. */ + @Input() + processDefinitionId: string; + /** The Definition Key of the process. * @deprecated 2.4.0 */ @@ -334,6 +338,7 @@ export class TaskListComponent extends DataTableSchema implements OnChanges, Aft let requestNode = { appDefinitionId: this.appId, processInstanceId: this.processInstanceId, + processDefinitionId: this.processDefinitionId, processDefinitionKey: this.processDefinitionKey, text: this.name, assignment: this.assignment,