mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-3103] Task List Demo Component (#3486)
* [ADF-3103] Added Process Definition Id to task list component * [ADF-3103] Added @input variable * [ADF-3103] Added search inputs * [ADF-2753] Fixed select inputs * [ADF-3103] Improved logic and funcionality overall * [ADF-3103] FormControl implementation * [ADF-3103] Added AppId input * [ADF-3103] Fixed Link errors * [ADF-3103] Task list table hides when invalid app is selected * [ADF-3103] Lint error * [ADF-3103] Improved user experience * [ADF-3103] changed formControlNames to [FormControl] * [ADF-3103] Improved logic and added localization * [ADF-3103] Removed whitespace * [ADF-3103] Improved logic of task list form * [ADF-3103] fixed trailing whitespaces * [ADF-3103] trailing whitespace fix * [ADF-3103] Added documentation and tests * [ADF-3103] Added tests and documentation * [ADF-3103] Tests fixed
This commit is contained in:
committed by
Eugenio Romano
parent
6508b145d0
commit
495f9937fe
@@ -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"
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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'
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
];
|
||||
|
@@ -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' },
|
||||
|
@@ -32,7 +32,7 @@
|
||||
*ngIf="taskFilter && !isStartTaskMode()">
|
||||
<adf-tasklist
|
||||
[appId]="taskFilter?.appId"
|
||||
[presetColumn]="presetColoum"
|
||||
[presetColumn]="presetColumn"
|
||||
[page]="taskPage"
|
||||
[size]="paginationPageSize"
|
||||
[processDefinitionKey]="taskFilter?.filter?.processDefinitionKey"
|
||||
@@ -138,7 +138,7 @@
|
||||
*ngIf="processFilter?.filter" [appId]="processFilter?.appId"
|
||||
[processDefinitionKey]="processFilter?.filter?.processDefinitionKey"
|
||||
[name]="processFilter?.filter?.name"
|
||||
[presetColumn]="presetColoum"
|
||||
[presetColumn]="presetColumn"
|
||||
[state]="processFilter?.filter?.state"
|
||||
[page]="processPage"
|
||||
[size]="paginationPageSize"
|
||||
|
@@ -0,0 +1,83 @@
|
||||
<div class="task-list-demo-inputs">
|
||||
|
||||
<form [formGroup]="taskListForm">
|
||||
<mat-form-field>
|
||||
<mat-label>App Id</mat-label>
|
||||
<input
|
||||
matInput
|
||||
class="form-control"
|
||||
[formControl]="taskAppId">
|
||||
<mat-error *ngIf="taskAppId.hasError('required')">
|
||||
{{ 'TASK_LIST_DEMO.APP_ID_REQUIRED_ERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="taskAppId.hasError('pattern')">
|
||||
{{ 'TASK_LIST_DEMO.APP_ID_TYPE_ERROR' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Task Name</mat-label>
|
||||
<input
|
||||
matInput
|
||||
class="form-control"
|
||||
[formControl]="taskName">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>ProcessDefinitionId</mat-label>
|
||||
<input
|
||||
matInput
|
||||
class="form-control"
|
||||
[formControl]="taskProcessDefinitionId">
|
||||
<mat-hint>SimpleProcess:1:2</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Assignment</mat-label>
|
||||
<mat-select
|
||||
class="form-control"
|
||||
[formControl]="taskAssignment">
|
||||
<mat-option *ngFor="let assignmentOption of assignmentOptions" [value]="assignmentOption.value">{{ assignmentOption.title }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>State</mat-label>
|
||||
<mat-select
|
||||
class="form-control"
|
||||
[formControl]="taskState">
|
||||
<mat-option *ngFor="let stateOption of stateOptions" [value]="stateOption.value">{{ stateOption.title }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Sort</mat-label>
|
||||
<mat-select
|
||||
class="form-control"
|
||||
[formControl]="taskSort">
|
||||
<mat-option *ngFor="let sortOption of sortOptions" [value]="sortOptions.value">{{ sortOption.title }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="adf-reset-button">
|
||||
<button mat-raised-button (click)="resetTaskForm()">Reset</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<adf-tasklist
|
||||
[appId]="appId"
|
||||
[name]="name"
|
||||
[processDefinitionId]="processDefinitionId"
|
||||
[assignment]="assignment"
|
||||
[state]="state"
|
||||
[sort]="sort"
|
||||
#taskList>
|
||||
</adf-tasklist>
|
||||
|
||||
<adf-pagination
|
||||
[target]="taskList">
|
||||
</adf-pagination>
|
||||
</div>
|
||||
|
@@ -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;
|
||||
}
|
@@ -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');
|
||||
}
|
||||
}
|
@@ -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. |
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user