mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-3538] [ADF-3547] Migration - Task Filters - Task List - New Process cloud page on demoshell (#3914)
* [ADF-3538] start creating new folder for cloud components * [ADF-3538] added new package to the script and the builds * [ADF-3538] added some more changes to scripts * [ADF-3538] - starting the new package * change index * fix package * Fix module structure with Cli * add basic structure * Create a library with angular cli * Add a cloud component as example * Skip the scss style * add the import scss * remove useless codes * Add i18n example * remove useless code * Simplify the hello component Fix the wrong path * add the app-list-cloud-component add the app-details-cloud-component * Expose and use the new component * Consume the new package and component from the demoshell * Fix process service cloud path * [ADF-3538] Alfresco Process Service Cloud - new package with CLI (#3872) * [ADF-3538] start creating new folder for cloud components * [ADF-3538] added new package to the script and the builds * [ADF-3538] added some more changes to scripts * [ADF-3538] - starting the new package * change index * fix package * Fix module structure with Cli * add basic structure * Create a library with angular cli * Add a cloud component as example * Skip the scss style * add the import scss * remove useless codes * Add i18n example * remove useless code * Simplify the hello component Fix the wrong path * Fix process service cloud path * Download process-service-cloud from the CS * [ADF-3538] generated task-list cloud by cli * [ADF-3550] Added Task Filter Cloud component * [ADF-3550] Task Filter Cloud component relocated * [ADF-3538] rebased task list cloud 2.0 * [ADF-3538] fixed ng-package.json * [ADF-3538] reverted worng changes * [ADF-3538] removed wrong rebased files * [ADF-3538] forcing update of app-list file * [ADF-3538] wrong file after rebase removed * [ADF-3538] wrong file after rebase fixe * Merge the applist component with task list * [ADF-3550] Added Task Filter Cloud component * emit the event * Add the route process cloud and fix the page issues * fixed wrong pagination initialisation * improved initialisation of page size * removed unused import * fixed tsconfig with double definition * Use standard name for scss * fix sorting issue and remove useless models * Fix tslint * Use 1 single testing module file * [ADF-3538] [ADF-3547] Fix selected task filter and unit tests * Fix unit tests and remove useless imports * Uncomment unit tests * Remove useless component * Use main module instead of submodules * Remove useless jsdoc and improve doc * Remove useless jsdoc * Remove useless interface * remove AfterViewInit import * remove js doc params
This commit is contained in:
committed by
Eugenio Romano
parent
ee7af9d797
commit
38f4916e06
@@ -61,6 +61,7 @@
|
|||||||
"NOTIFICATIONS": "Notifications",
|
"NOTIFICATIONS": "Notifications",
|
||||||
"TASK_LIST": "Task List",
|
"TASK_LIST": "Task List",
|
||||||
"PROCESS_LIST": "Process List",
|
"PROCESS_LIST": "Process List",
|
||||||
|
"PROCESS_CLOUD": "Process Cloud",
|
||||||
"CARD_VIEW": "CardView",
|
"CARD_VIEW": "CardView",
|
||||||
"PROCESS_SERVICES": "Process Services",
|
"PROCESS_SERVICES": "Process Services",
|
||||||
"LOGIN": "Login",
|
"LOGIN": "Login",
|
||||||
|
@@ -63,8 +63,9 @@ import { ContentModule } from '@alfresco/adf-content-services';
|
|||||||
import { InsightsModule } from '@alfresco/adf-insights';
|
import { InsightsModule } from '@alfresco/adf-insights';
|
||||||
import { ProcessModule } from '@alfresco/adf-process-services';
|
import { ProcessModule } from '@alfresco/adf-process-services';
|
||||||
import { AuthBearerInterceptor } from './services';
|
import { AuthBearerInterceptor } from './services';
|
||||||
import { AppListCloudModule } from '@alfresco/adf-process-services-cloud';
|
import { ProcessServicesCloudModule } from '@alfresco/adf-process-services-cloud';
|
||||||
import { CloudComponent } from './components/cloud/cloud.component';
|
import { CloudComponent } from './components/cloud/cloud.component';
|
||||||
|
import { TaskListCloudDemoComponent } from './components/task-list-cloud-demo/task-list-cloud-demo.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -83,7 +84,7 @@ import { CloudComponent } from './components/cloud/cloud.component';
|
|||||||
ThemePickerModule,
|
ThemePickerModule,
|
||||||
ChartsModule,
|
ChartsModule,
|
||||||
MonacoEditorModule.forRoot(),
|
MonacoEditorModule.forRoot(),
|
||||||
AppListCloudModule
|
ProcessServicesCloudModule
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
@@ -113,7 +114,8 @@ import { CloudComponent } from './components/cloud/cloud.component';
|
|||||||
FormLoadingComponent,
|
FormLoadingComponent,
|
||||||
DemoPermissionComponent,
|
DemoPermissionComponent,
|
||||||
FormLoadingComponent,
|
FormLoadingComponent,
|
||||||
ReportIssueComponent
|
ReportIssueComponent,
|
||||||
|
TaskListCloudDemoComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
|
@@ -41,6 +41,7 @@ import { DemoPermissionComponent } from './components/permissions/demo-permissio
|
|||||||
import { ReportIssueComponent } from './components/report-issue/report-issue.component';
|
import { ReportIssueComponent } from './components/report-issue/report-issue.component';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { CloudComponent } from './components/cloud/cloud.component';
|
import { CloudComponent } from './components/cloud/cloud.component';
|
||||||
|
import { TaskListCloudDemoComponent } from './components/task-list-cloud-demo/task-list-cloud-demo.component';
|
||||||
|
|
||||||
export const appRoutes: Routes = [
|
export const appRoutes: Routes = [
|
||||||
{ path: 'login', component: LoginComponent },
|
{ path: 'login', component: LoginComponent },
|
||||||
@@ -135,7 +136,16 @@ export const appRoutes: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'cloud',
|
path: 'cloud',
|
||||||
component: CloudComponent
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: CloudComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':applicationName/tasks',
|
||||||
|
component: TaskListCloudDemoComponent
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'node-selector',
|
path: 'node-selector',
|
||||||
|
@@ -40,6 +40,7 @@ export class AppLayoutComponent implements OnInit {
|
|||||||
{ href: '/node-selector', icon: 'attachment', title: 'APP_LAYOUT.NODE-SELECTOR' },
|
{ href: '/node-selector', icon: 'attachment', title: 'APP_LAYOUT.NODE-SELECTOR' },
|
||||||
{ href: '/task-list', icon: 'assignment', title: 'APP_LAYOUT.TASK_LIST' },
|
{ href: '/task-list', icon: 'assignment', title: 'APP_LAYOUT.TASK_LIST' },
|
||||||
{ href: '/process-list', icon: 'assignment', title: 'APP_LAYOUT.PROCESS_LIST' },
|
{ href: '/process-list', icon: 'assignment', title: 'APP_LAYOUT.PROCESS_LIST' },
|
||||||
|
{ href: '/cloud', icon: 'cloud', title: 'APP_LAYOUT.PROCESS_CLOUD' },
|
||||||
{ href: '/activiti', icon: 'device_hub', title: 'APP_LAYOUT.PROCESS_SERVICES' },
|
{ href: '/activiti', icon: 'device_hub', title: 'APP_LAYOUT.PROCESS_SERVICES' },
|
||||||
{ href: '/login', icon: 'vpn_key', title: 'APP_LAYOUT.LOGIN' },
|
{ href: '/login', icon: 'vpn_key', title: 'APP_LAYOUT.LOGIN' },
|
||||||
{ href: '/trashcan', icon: 'delete', title: 'APP_LAYOUT.TRASHCAN' },
|
{ href: '/trashcan', icon: 'delete', title: 'APP_LAYOUT.TRASHCAN' },
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
|
|
||||||
<adf-cloud-app-list></adf-cloud-app-list>
|
<adf-cloud-app-list (appClick)="onAppClick($event)"></adf-cloud-app-list>
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-cloud',
|
selector: 'app-cloud',
|
||||||
templateUrl: './cloud.component.html',
|
templateUrl: './cloud.component.html',
|
||||||
@@ -24,9 +24,13 @@ import { Component, OnInit } from '@angular/core';
|
|||||||
})
|
})
|
||||||
export class CloudComponent implements OnInit {
|
export class CloudComponent implements OnInit {
|
||||||
|
|
||||||
constructor() {
|
constructor(private router: Router) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAppClick(app) {
|
||||||
|
this.router.navigate([`/cloud/${app.name}/tasks/`]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,86 @@
|
|||||||
|
<h2>TASK LIST CLOUD DEMO</h2>
|
||||||
|
<adf-cloud-task-filters
|
||||||
|
[appName]="'my-app'"
|
||||||
|
[showIcons]="true"
|
||||||
|
(filterClick)="onFilterSelected($event)">
|
||||||
|
</adf-cloud-task-filters>
|
||||||
|
|
||||||
|
<mat-accordion>
|
||||||
|
<mat-expansion-panel>
|
||||||
|
<mat-expansion-panel-header>
|
||||||
|
<mat-panel-title>
|
||||||
|
{{filterName}}
|
||||||
|
</mat-panel-title>
|
||||||
|
<mat-panel-description>
|
||||||
|
Customise your filter
|
||||||
|
</mat-panel-description>
|
||||||
|
</mat-expansion-panel-header>
|
||||||
|
<div class="task-cloud-demo-select">
|
||||||
|
<mat-form-field style="margin: 8px;">
|
||||||
|
<mat-select placeholder="Status" [(ngModel)]="status">
|
||||||
|
<mat-option value="">
|
||||||
|
ALL
|
||||||
|
</mat-option>
|
||||||
|
<mat-option value="CREATED">
|
||||||
|
CREATED
|
||||||
|
</mat-option>
|
||||||
|
<mat-option value="CANCELLED">
|
||||||
|
CANCELLED
|
||||||
|
</mat-option>
|
||||||
|
<mat-option value="ASSIGNED">
|
||||||
|
ASSIGNED
|
||||||
|
</mat-option>
|
||||||
|
<mat-option value="SUSPENDED">
|
||||||
|
SUSPENDED
|
||||||
|
</mat-option>
|
||||||
|
<mat-option value="COMPLETED">
|
||||||
|
COMPLETED
|
||||||
|
</mat-option>
|
||||||
|
<mat-option value="DELETED">
|
||||||
|
DELETED
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-select [formControl]="sortFormControl">
|
||||||
|
<mat-option [value]="''">Select a column</mat-option>
|
||||||
|
<mat-option *ngFor="let column of columns" [value]="column.key">
|
||||||
|
{{column.label}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-select [formControl]="sortDirectionFormControl">
|
||||||
|
<mat-option [value]="''">Select a direction</mat-option>
|
||||||
|
<mat-option value="ASC">
|
||||||
|
ASC
|
||||||
|
</mat-option>
|
||||||
|
<mat-option value="DESC">
|
||||||
|
DESC
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</mat-expansion-panel>
|
||||||
|
</mat-accordion>
|
||||||
|
<div>
|
||||||
|
<adf-cloud-task-list *ngIf="isFilterLoaded" #taskCloud
|
||||||
|
[applicationName]="applicationName"
|
||||||
|
[status]="status"
|
||||||
|
[landingTaskId]="selectTask"
|
||||||
|
[sorting]="sortArray"
|
||||||
|
(rowClick)="onRowClick($event)">
|
||||||
|
<data-columns>
|
||||||
|
<data-column key="entry.id" title="Id"></data-column>
|
||||||
|
<data-column key="entry.name" title="Name"></data-column>
|
||||||
|
<data-column key="entry.status" title="Status"></data-column>
|
||||||
|
<data-column key="entry.processDefinitionId" title="Process Definition Id"></data-column>
|
||||||
|
<data-column key="entry.priority" title="Priority"></data-column>
|
||||||
|
<data-column key="entry.createdDate" title="Created Date"></data-column>
|
||||||
|
</data-columns>
|
||||||
|
</adf-cloud-task-list>
|
||||||
|
<adf-pagination [target]="taskCloud"
|
||||||
|
(changePageSize)="onChangePageSize($event)">
|
||||||
|
</adf-pagination>
|
||||||
|
</div>
|
@@ -0,0 +1,15 @@
|
|||||||
|
.task-cloud-demo-select {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-cloud-demo-select .mat-expansion-panel-body {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-task-list-cloud-demo-selection{
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-row-clicked {
|
||||||
|
align-self: center;
|
||||||
|
}
|
@@ -0,0 +1,126 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { Component, ViewChild, OnInit } from '@angular/core';
|
||||||
|
import { TaskListCloudComponent, TaskListCloudSortingModel } from '@alfresco/adf-process-services-cloud';
|
||||||
|
import { UserPreferencesService } from '@alfresco/adf-core';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { FormControl } from '@angular/forms';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-task-list-cloud-demo',
|
||||||
|
templateUrl: 'task-list-cloud-demo.component.html',
|
||||||
|
styleUrls: ['task-list-cloud-demo.component.scss']
|
||||||
|
})
|
||||||
|
export class TaskListCloudDemoComponent implements OnInit {
|
||||||
|
|
||||||
|
@ViewChild('taskCloud')
|
||||||
|
taskCloud: TaskListCloudComponent;
|
||||||
|
|
||||||
|
sortFormControl: FormControl;
|
||||||
|
sortDirectionFormControl: FormControl;
|
||||||
|
|
||||||
|
appDefinitionList: Observable<any>;
|
||||||
|
applicationName: string = '';
|
||||||
|
status: string = '';
|
||||||
|
sort: string = '';
|
||||||
|
isFilterLoaded = false;
|
||||||
|
sortDirection: string = 'ASC';
|
||||||
|
filterName: string;
|
||||||
|
clickedRow: string = '';
|
||||||
|
selectTask: string = '';
|
||||||
|
sortArray: TaskListCloudSortingModel [];
|
||||||
|
|
||||||
|
columns = [
|
||||||
|
{key: 'id', label: 'ID'},
|
||||||
|
{key: 'name', label: 'NAME'},
|
||||||
|
{key: 'createdDate', label: 'Created Date'},
|
||||||
|
{key: 'priority', label: 'PRIORITY'},
|
||||||
|
{key: 'processDefinitionId', label: 'PROCESS DEFINITION ID'}
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private router: Router,
|
||||||
|
private userPreference: UserPreferencesService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.isFilterLoaded = false;
|
||||||
|
this.route.params.subscribe(params => {
|
||||||
|
this.applicationName = params.applicationName;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.sortFormControl = new FormControl('');
|
||||||
|
|
||||||
|
this.sortFormControl.valueChanges.subscribe(
|
||||||
|
(sortValue) => {
|
||||||
|
this.sort = sortValue;
|
||||||
|
|
||||||
|
this.sortArray = [{
|
||||||
|
orderBy: this.sort,
|
||||||
|
direction: this.sortDirection
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this.sortDirectionFormControl = new FormControl('');
|
||||||
|
|
||||||
|
this.sortDirectionFormControl.valueChanges.subscribe(
|
||||||
|
(sortDirectionValue) => {
|
||||||
|
this.sortDirection = sortDirectionValue;
|
||||||
|
|
||||||
|
this.sortArray = [{
|
||||||
|
orderBy: this.sort,
|
||||||
|
direction: this.sortDirection
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.route.queryParams
|
||||||
|
.subscribe(params => {
|
||||||
|
if (params.status) {
|
||||||
|
this.status = params.status;
|
||||||
|
this.sort = params.sort;
|
||||||
|
this.sortDirection = params.order;
|
||||||
|
this.filterName = params.filterName;
|
||||||
|
this.isFilterLoaded = true;
|
||||||
|
this.sortDirectionFormControl.setValue(this.sortDirection);
|
||||||
|
this.sortFormControl.setValue(this.sort);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onFilterSelected(filter) {
|
||||||
|
const queryParams = {
|
||||||
|
status: filter.query.state,
|
||||||
|
filterName: filter.name,
|
||||||
|
sort: filter.query.sort,
|
||||||
|
order: filter.query.order
|
||||||
|
};
|
||||||
|
this.router.navigate([`/cloud/${this.applicationName}/tasks/`], {queryParams: queryParams});
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangePageSize(event) {
|
||||||
|
this.userPreference.paginationSize = event.maxItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
onRowClick($event) {
|
||||||
|
this.clickedRow = $event;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
217
docs/process-services-cloud/task-list-cloud.md
Normal file
217
docs/process-services-cloud/task-list-cloud.md
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
---
|
||||||
|
Added: v2.0.0
|
||||||
|
Status: Active
|
||||||
|
Last reviewed: 2018-04-16
|
||||||
|
---
|
||||||
|
|
||||||
|
# Task List component
|
||||||
|
|
||||||
|
Renders a list containing all the tasks matched by the parameters specified.
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
- [Basic Usage](#basic-usage)
|
||||||
|
- [Transclusions](#transclusions)
|
||||||
|
- [Class members](#class-members)
|
||||||
|
- [Properties](#properties)
|
||||||
|
- [Events](#events)
|
||||||
|
- [Details](#details)
|
||||||
|
- [Setting the column schema](#setting-the-column-schema)
|
||||||
|
- [Setting Sorting Order for the list](#setting-sorting-order-for-the-list)
|
||||||
|
- [Pagination strategy](#pagination-strategy)
|
||||||
|
- [DataTableAdapter example](#datatableadapter-example)
|
||||||
|
- [DataColumn Features](#datacolumn-features)
|
||||||
|
- [See also](#see-also)
|
||||||
|
|
||||||
|
## Basic Usage
|
||||||
|
|
||||||
|
```html
|
||||||
|
<adf-cloud-task-list
|
||||||
|
[applicationName]="'APPLICATION-NAME'" >
|
||||||
|
</adf-cloud-task-list>
|
||||||
|
```
|
||||||
|
|
||||||
|
### [Transclusions](../user-guide/transclusion.md)
|
||||||
|
|
||||||
|
Any content inside an `<adf-empty-custom-content>` sub-component will be shown
|
||||||
|
when the task list is empty:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<adf-cloud-task-list>
|
||||||
|
<adf-empty-custom-content>
|
||||||
|
Your Content
|
||||||
|
</adf-empty-custom-content>
|
||||||
|
<adf-cloud-task-list>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Class members
|
||||||
|
|
||||||
|
### Properties
|
||||||
|
|
||||||
|
| Name | Type | Default value | Description |
|
||||||
|
| ---- | ---- | ------------- | ----------- |
|
||||||
|
| applicationName | `string` | | The name of the application. |
|
||||||
|
| assignee | `string` | | The assigee of the process. Possible values are: "assignee" (the current user is the assignee), candidate (the current user is a task candidate", "group_x" (the task is assigned to a group where the current user is a member, no value(the current user is involved). |
|
||||||
|
| createdDate | `Date` | | filter the tasks for the date when the task should have been created |
|
||||||
|
| dueDate | `Date` | | Filter the tasks. Display only tasks with dueDate equal to the one insterted. |
|
||||||
|
| id | `string` | | Filter the tasks. Display only tasks with id equal to the one insterted. |
|
||||||
|
| name | `string` | | Filter the tasks. Display only tasks with name equal to the one insterted. |
|
||||||
|
| parentTaskId | `string` | | Filter the tasks. Display only tasks with parentTaskId equal to the one insterted. |
|
||||||
|
| processDefinitionId | `string` | | Filter the tasks. Display only tasks with processDefinitionId equal to the one insterted. |
|
||||||
|
| processInstanceId | `string` | | Filter the tasks. Display only tasks with processInstanceId equal to the one insterted. |
|
||||||
|
| status | `string` | | Filter the tasks. Display only tasks with status equal to the one insterted. |
|
||||||
|
| processDefinitionId | `string` | | Filter the tasks. Display only tasks with processDefinitionId equal to the one insterted. |
|
||||||
|
| landingTaskId | `string` | | Define which task id should be selected after reloading. If the task id doesn't exist or nothing is passed then the first task will be selected. |
|
||||||
|
| 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. |
|
||||||
|
| multiselect | `boolean` | false | Toggles multiple row selection, renders checkboxes at the beginning of each row |
|
||||||
|
| sorting | `[TaskListCloudSortingModel]` | | This array of `TaskListCloudSortingModel` specify how the sorting on our table should be provided. This parameters are for BE sorting. |
|
||||||
|
|
||||||
|
### Events
|
||||||
|
|
||||||
|
| Name | Type | Description |
|
||||||
|
| ---- | ---- | ----------- |
|
||||||
|
| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when an error occurs. |
|
||||||
|
| rowClick | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string>` | Emitted when a task in the list is clicked |
|
||||||
|
| rowsSelected | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any[]>` | Emitted when rows are selected/unselected |
|
||||||
|
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the task list is loaded |
|
||||||
|
|
||||||
|
## Details
|
||||||
|
|
||||||
|
This component displays lists of tasks related to the application name insterted. Extra filtering can be provided by applying extra input parameters
|
||||||
|
|
||||||
|
### Setting the column schema
|
||||||
|
|
||||||
|
You can use an HTML-based schema declaration to set a column schema for the tasklist as shown below :
|
||||||
|
|
||||||
|
```html
|
||||||
|
<adf-cloud-task-list ...>
|
||||||
|
<data-columns>
|
||||||
|
<data-column key="name" title="NAME" class="full-width name-column"></data-column>
|
||||||
|
<data-column key="created" title="Created" class="hidden"></data-column>
|
||||||
|
</data-columns>
|
||||||
|
</adf-cloud-task-list>
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also set a static custom schema declaration in `app.config.json` as shown below:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"adf-cloud-task-list": {
|
||||||
|
"presets": {
|
||||||
|
"customSchema": [
|
||||||
|
{
|
||||||
|
"key": "name",
|
||||||
|
"type": "text",
|
||||||
|
"title": "name",
|
||||||
|
"sortable": true
|
||||||
|
}],
|
||||||
|
"default": [
|
||||||
|
{
|
||||||
|
"key": "name",
|
||||||
|
"type": "text",
|
||||||
|
"title": "name",
|
||||||
|
"sortable": true
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<adf-cloud-task-list
|
||||||
|
[appId]="'1'"
|
||||||
|
[presetColumn]="'customSchema'">
|
||||||
|
</adf-cloud-task-list>
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use an HTML-based schema and an `app.config.json` custom schema declaration at the same time:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"adf-cloud-task-list": {
|
||||||
|
"presets": {
|
||||||
|
"customSchema": [
|
||||||
|
{
|
||||||
|
"key": "id",
|
||||||
|
"type": "text",
|
||||||
|
"title": "Id",
|
||||||
|
"sortable": true
|
||||||
|
}],
|
||||||
|
"default": [
|
||||||
|
{
|
||||||
|
"key": "name",
|
||||||
|
"type": "text",
|
||||||
|
"title": "name",
|
||||||
|
"sortable": true
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- {% raw %} -->
|
||||||
|
|
||||||
|
```html
|
||||||
|
<adf-cloud-task-list
|
||||||
|
[applicationName]="'ApplicationName'">
|
||||||
|
<data-columns>
|
||||||
|
<data-column key="assignee" title="Assignee" class="full-width name-column">
|
||||||
|
<ng-template let-entry="$implicit">
|
||||||
|
<div>{{getFullName(entry.row.obj.assignee)}}</div>
|
||||||
|
</ng-template>
|
||||||
|
</data-column>
|
||||||
|
</data-columns>
|
||||||
|
</adf-cloud-task-list>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setting Sorting Order for the list
|
||||||
|
|
||||||
|
you can pass sorting order as shown in the example below:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
let sorting = { orderBy: 'created', direction: 'desc' };
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<adf-cloud-task-list
|
||||||
|
[appId]="'1'"
|
||||||
|
[sorting]="[sorting]">
|
||||||
|
</adf-cloud-task-list>
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- {% endraw %} -->
|
||||||
|
|
||||||
|
### Pagination strategy
|
||||||
|
|
||||||
|
The Tasklist also supports pagination as shown in the example below:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<adf-cloud-task-list #taskCloud
|
||||||
|
[applicationName]="'APPLICATION-NAME'">
|
||||||
|
</adf-cloud-task-list>
|
||||||
|
<adf-pagination [target]="taskCloud"
|
||||||
|
(changePageSize)="onChangePageSize($event)">
|
||||||
|
</adf-pagination>
|
||||||
|
```
|
||||||
|
|
||||||
|
### DataTableAdapter example
|
||||||
|
|
||||||
|
See the [`DataTableAdapter`](../../lib/core/datatable/data/datatable-adapter.ts) page for full details of the interface and its standard
|
||||||
|
implementation, [`ObjectDataTableAdapter`](../../lib/core/datatable/data/object-datatable-adapter.ts). Below is an example of how you can set up the adapter for a
|
||||||
|
typical tasklist.
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{"type": "text", "key": "id", "title": "Id"},
|
||||||
|
{"type": "text", "key": "name", "title": "Name", "cssClass": "full-width name-column", "sortable": true},
|
||||||
|
{"type": "text", "key": "formKey", "title": "Form Key", "sortable": true},
|
||||||
|
{"type": "text", "key": "created", "title": "Created", "sortable": true}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### DataColumn Features
|
||||||
|
|
||||||
|
You can customize the styling of a column and also add features like tooltips and automatic translation of column titles. See the [`DataColumn`](../../lib/core/datatable/data/data-column.model.ts) page for more information about these features.
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [Data column component](../core/data-column.component.md)
|
||||||
|
- [`DataTableAdapter`](../../lib/core/datatable/data/datatable-adapter.ts)
|
||||||
|
- [Pagination component](../core/pagination.component.md)
|
19
lib/core/assets/images/ft_ic_link_folder.svg
Normal file
19
lib/core/assets/images/ft_ic_link_folder.svg
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="20px" height="16px" viewBox="0 0 20 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>System Icon Links</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Style" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="icons" transform="translate(-289.000000, -4488.000000)">
|
||||||
|
<g id="File" transform="translate(140.000000, 4130.000000)">
|
||||||
|
<g id="Icon-Links-Folder" transform="translate(120.000000, 328.000000)">
|
||||||
|
<g id="System-Icon-Links" transform="translate(28.000000, 30.000000)">
|
||||||
|
<path d="M1.70933755,0.543276016 L1,1.924926 L1,14.8121399 L1.69466158,15.5150573 L1.69466158,15.5150573 C1.88252616,15.7051546 2.13866895,15.8121399 2.40593302,15.8121399 L19.6045166,15.8121399 L20.3116234,15.1050331 L20.3116234,15.1050331 C20.4991598,14.9174967 20.6045166,14.6631428 20.6045166,14.3979263 L20.6045166,3.00924449 L19.9015261,2.24697884 L19.9015261,2.24697884 C19.7122055,2.04169503 19.4456711,1.924926 19.1664154,1.924926 L10.1733882,1.924926 L10.1733882,1.924926 C9.85108856,1.924926 9.548546,1.76958526 9.36072924,1.50766556 L8.57882415,0.417260445 L8.57882415,0.417260445 C8.39100739,0.155340737 8.08846483,-6.31724684e-16 7.76616517,0 L2.59894601,0 L2.59894601,-1.11022302e-16 C2.2240117,-4.21479881e-17 1.88057904,0.209731289 1.70933755,0.543276016 Z" id="Path-2-Copy" fill="#000000" opacity="0.54"></path>
|
||||||
|
<path d="M10,6 L7.6,6 L7.6,7.14 L10,7.14 C11.026,7.14 11.86,7.974 11.86,9 C11.86,10.026 11.026,10.86 10,10.86 L7.6,10.86 L7.6,12 L10,12 C11.656,12 13,10.656 13,9 C13,7.344 11.656,6 10,6 L10,6 Z M4.6,9.6 L9.4,9.6 L9.4,8.4 L4.6,8.4 L4.6,9.6 Z M2.14,9 C2.14,7.974 2.974,7.14 4,7.14 L6.4,7.14 L6.4,6 L4,6 C2.344,6 1,7.344 1,9 C1,10.656 2.344,12 4,12 L6.4,12 L6.4,10.86 L4,10.86 C2.974,10.86 2.14,10.026 2.14,9 L2.14,9 Z" id="Fill-2" fill="#FFFFFF" transform="translate(7.000000, 9.000000) rotate(-45.000000) translate(-7.000000, -9.000000) "></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
@@ -18,5 +18,6 @@
|
|||||||
export * from './context-menu-holder.component';
|
export * from './context-menu-holder.component';
|
||||||
export * from './context-menu.directive';
|
export * from './context-menu.directive';
|
||||||
export * from './context-menu.service';
|
export * from './context-menu.service';
|
||||||
|
export * from './context-menu-overlay.service';
|
||||||
|
|
||||||
export * from './context-menu.module';
|
export * from './context-menu.module';
|
||||||
|
@@ -1,30 +0,0 @@
|
|||||||
npm-debug.log
|
|
||||||
.idea
|
|
||||||
.npmrc
|
|
||||||
|
|
||||||
/.editorconfig
|
|
||||||
/.travis.yml
|
|
||||||
/*.json
|
|
||||||
/karma-test-shim.js
|
|
||||||
/karma.conf.js
|
|
||||||
/gulpfile.ts
|
|
||||||
/.npmignore
|
|
||||||
/.happypack
|
|
||||||
**/*.html
|
|
||||||
**/*.js
|
|
||||||
**/*.ts
|
|
||||||
!**/*.d.ts
|
|
||||||
!**/adf-process-services-cloud.js
|
|
||||||
|
|
||||||
**/*.scss
|
|
||||||
**/*.css
|
|
||||||
!**/_theming.scss
|
|
||||||
|
|
||||||
coverage/
|
|
||||||
demo/
|
|
||||||
dist/
|
|
||||||
node_modules
|
|
||||||
typings/
|
|
||||||
fonts/
|
|
||||||
i18n/
|
|
||||||
assets/
|
|
@@ -15,4 +15,4 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export * from './src/public_api';
|
export * from './src/public-api';
|
||||||
|
@@ -1,44 +0,0 @@
|
|||||||
/*!
|
|
||||||
* @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 { NgModule } from '@angular/core';
|
|
||||||
import {
|
|
||||||
MAT_LABEL_GLOBAL_OPTIONS, MatAutocompleteModule, MatButtonModule, MatCardModule, MatCheckboxModule,
|
|
||||||
MatChipsModule, MatDatepickerModule, MatDialogModule, MatGridListModule, MatIconModule,
|
|
||||||
MatInputModule, MatListModule, MatNativeDateModule, MatOptionModule, MatProgressSpinnerModule, MatRadioModule,
|
|
||||||
MatRippleModule, MatSelectModule, MatSlideToggleModule, MatTableModule, MatTabsModule,
|
|
||||||
MatTooltipModule, MatMenuModule
|
|
||||||
} from '@angular/material';
|
|
||||||
|
|
||||||
export function modules() {
|
|
||||||
return [
|
|
||||||
MatAutocompleteModule, MatButtonModule, MatCardModule, MatDialogModule,
|
|
||||||
MatCheckboxModule, MatDatepickerModule, MatGridListModule, MatIconModule, MatInputModule,
|
|
||||||
MatListModule, MatOptionModule, MatRadioModule, MatSelectModule, MatSlideToggleModule, MatTableModule,
|
|
||||||
MatTabsModule, MatProgressSpinnerModule, MatNativeDateModule, MatRippleModule, MatTooltipModule,
|
|
||||||
MatChipsModule, MatMenuModule
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
providers: [
|
|
||||||
{provide: MAT_LABEL_GLOBAL_OPTIONS, useValue: { float: 'never' }}
|
|
||||||
],
|
|
||||||
imports: modules(),
|
|
||||||
exports: modules()
|
|
||||||
})
|
|
||||||
export class MaterialModule {}
|
|
@@ -3,7 +3,7 @@
|
|||||||
"dest": "../dist/process-services-cloud",
|
"dest": "../dist/process-services-cloud",
|
||||||
"lib": {
|
"lib": {
|
||||||
"languageLevel": ["dom", "es2017"],
|
"languageLevel": ["dom", "es2017"],
|
||||||
"entryFile": "src/public_api.ts",
|
"entryFile": "src/public-api.ts",
|
||||||
"flatModuleFile": "adf-process-services-cloud",
|
"flatModuleFile": "adf-process-services-cloud",
|
||||||
"umdModuleIds": {
|
"umdModuleIds": {
|
||||||
"alfresco-js-api": "alfresco-js-api"
|
"alfresco-js-api": "alfresco-js-api"
|
||||||
|
@@ -1,99 +0,0 @@
|
|||||||
/*!
|
|
||||||
* @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 { CommonModule } from '@angular/common';
|
|
||||||
import { NgModule, ModuleWithProviders } from '@angular/core';
|
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
||||||
import { CoreModule, TRANSLATION_PROVIDER } from '@alfresco/adf-core';
|
|
||||||
|
|
||||||
import { MaterialModule } from './material.module';
|
|
||||||
import { HelloCloudModule } from './hello/hello.module';
|
|
||||||
|
|
||||||
export function providers() {
|
|
||||||
return [
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
CoreModule.forChild(),
|
|
||||||
CommonModule,
|
|
||||||
FormsModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
MaterialModule,
|
|
||||||
HelloCloudModule
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
...providers(),
|
|
||||||
{
|
|
||||||
provide: TRANSLATION_PROVIDER,
|
|
||||||
multi: true,
|
|
||||||
useValue: {
|
|
||||||
name: 'adf-process-services-cloud',
|
|
||||||
source: 'assets/adf-process-services-cloud'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
exports: [
|
|
||||||
CommonModule,
|
|
||||||
FormsModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
HelloCloudModule
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class ProcessCloudModule {
|
|
||||||
static forRoot(): ModuleWithProviders {
|
|
||||||
return {
|
|
||||||
ngModule: ProcessCloudModule,
|
|
||||||
providers: [
|
|
||||||
...providers(),
|
|
||||||
{
|
|
||||||
provide: TRANSLATION_PROVIDER,
|
|
||||||
multi: true,
|
|
||||||
useValue: {
|
|
||||||
name: 'adf-process-services-cloud',
|
|
||||||
source: 'assets/adf-process-services-cloud'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static forChild(): ModuleWithProviders {
|
|
||||||
return {
|
|
||||||
ngModule: ProcessCloudModuleLazy
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
CoreModule.forChild(),
|
|
||||||
CommonModule,
|
|
||||||
FormsModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
MaterialModule,
|
|
||||||
HelloCloudModule
|
|
||||||
],
|
|
||||||
exports: [
|
|
||||||
CommonModule,
|
|
||||||
FormsModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
HelloCloudModule
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class ProcessCloudModuleLazy {}
|
|
@@ -20,7 +20,8 @@ import { setupTestBed } from '@alfresco/adf-core';
|
|||||||
|
|
||||||
import { fakeApplicationInstance } from '../mock/app-model.mock';
|
import { fakeApplicationInstance } from '../mock/app-model.mock';
|
||||||
import { AppDetailsCloudComponent } from './app-details-cloud.component';
|
import { AppDetailsCloudComponent } from './app-details-cloud.component';
|
||||||
import { AppListTestingModule } from '../testing/app-list.testing.module';
|
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
|
||||||
|
import { AppListCloudModule } from '../app-list-cloud.module';
|
||||||
|
|
||||||
describe('AppDetailsCloudComponent', () => {
|
describe('AppDetailsCloudComponent', () => {
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ describe('AppDetailsCloudComponent', () => {
|
|||||||
let fixture: ComponentFixture<AppDetailsCloudComponent>;
|
let fixture: ComponentFixture<AppDetailsCloudComponent>;
|
||||||
|
|
||||||
setupTestBed({
|
setupTestBed({
|
||||||
imports: [AppListTestingModule]
|
imports: [ProcessServiceCloudTestingModule, AppListCloudModule]
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@@ -23,8 +23,9 @@ import { of } from 'rxjs';
|
|||||||
import { fakeApplicationInstance } from '../mock/app-model.mock';
|
import { fakeApplicationInstance } from '../mock/app-model.mock';
|
||||||
import { AppListCloudComponent } from './app-list-cloud.component';
|
import { AppListCloudComponent } from './app-list-cloud.component';
|
||||||
import { AppsProcessCloudService } from '../services/apps-process-cloud.service';
|
import { AppsProcessCloudService } from '../services/apps-process-cloud.service';
|
||||||
import { AppListTestingModule } from '../testing/app-list.testing.module';
|
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
|
||||||
import { ApplicationInstanceModel } from '../models/application-instance.model';
|
import { ApplicationInstanceModel } from '../models/application-instance.model';
|
||||||
|
import { AppListCloudModule } from '../app-list-cloud.module';
|
||||||
|
|
||||||
describe('AppListCloudComponent', () => {
|
describe('AppListCloudComponent', () => {
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ describe('AppListCloudComponent', () => {
|
|||||||
let getAppsSpy: jasmine.Spy;
|
let getAppsSpy: jasmine.Spy;
|
||||||
|
|
||||||
setupTestBed({
|
setupTestBed({
|
||||||
imports: [AppListTestingModule],
|
imports: [ProcessServiceCloudTestingModule, AppListCloudModule],
|
||||||
providers: [AppsProcessCloudService]
|
providers: [AppsProcessCloudService]
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -184,7 +185,7 @@ describe('Custom CustomEmptyAppListCloudTemplateComponent', () => {
|
|||||||
let fixture: ComponentFixture<CustomEmptyAppListCloudTemplateComponent>;
|
let fixture: ComponentFixture<CustomEmptyAppListCloudTemplateComponent>;
|
||||||
|
|
||||||
setupTestBed({
|
setupTestBed({
|
||||||
imports: [AppListTestingModule],
|
imports: [ProcessServiceCloudTestingModule],
|
||||||
declarations: [CustomEmptyAppListCloudTemplateComponent],
|
declarations: [CustomEmptyAppListCloudTemplateComponent],
|
||||||
schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
|
schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
|
||||||
});
|
});
|
||||||
|
@@ -17,4 +17,4 @@
|
|||||||
|
|
||||||
export * from './components/app-list-cloud.component';
|
export * from './components/app-list-cloud.component';
|
||||||
export * from './models/application-instance.model';
|
export * from './models/application-instance.model';
|
||||||
export * from './apps-list-cloud.module';
|
export * from './app-list-cloud.module';
|
@@ -22,14 +22,14 @@ import { HttpErrorResponse } from '@angular/common/http';
|
|||||||
import { AppsProcessCloudService } from './apps-process-cloud.service';
|
import { AppsProcessCloudService } from './apps-process-cloud.service';
|
||||||
import { fakeApplicationInstance } from '../mock/app-model.mock';
|
import { fakeApplicationInstance } from '../mock/app-model.mock';
|
||||||
import { ApplicationInstanceModel } from '../models/application-instance.model';
|
import { ApplicationInstanceModel } from '../models/application-instance.model';
|
||||||
import { AppListTestingModule } from '../testing/app-list.testing.module';
|
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
|
||||||
|
|
||||||
describe('AppsProcessCloudService', () => {
|
describe('AppsProcessCloudService', () => {
|
||||||
|
|
||||||
let service: AppsProcessCloudService;
|
let service: AppsProcessCloudService;
|
||||||
|
|
||||||
setupTestBed({
|
setupTestBed({
|
||||||
imports: [AppListTestingModule],
|
imports: [ProcessServiceCloudTestingModule],
|
||||||
providers: [AppsProcessCloudService]
|
providers: [AppsProcessCloudService]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,4 +0,0 @@
|
|||||||
<p>
|
|
||||||
hello cloud world!
|
|
||||||
</p>
|
|
||||||
|
|
@@ -1,25 +0,0 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { HelloComponent } from './hello.component';
|
|
||||||
|
|
||||||
describe('HelloComponent', () => {
|
|
||||||
let component: HelloComponent;
|
|
||||||
let fixture: ComponentFixture<HelloComponent>;
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
declarations: [ HelloComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(HelloComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@@ -1,15 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'adf-cloud-hello',
|
|
||||||
templateUrl: './hello.component.html',
|
|
||||||
styleUrls: ['./hello.component.css']
|
|
||||||
})
|
|
||||||
export class HelloComponent implements OnInit {
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,13 +0,0 @@
|
|||||||
import { HelloModule } from './hello.module';
|
|
||||||
|
|
||||||
describe('HelloModule', () => {
|
|
||||||
let helloModule: HelloModule;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
helloModule = new HelloModule();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create an instance', () => {
|
|
||||||
expect(helloModule).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@@ -1,13 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { HelloComponent } from './hello.component';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
TranslateModule
|
|
||||||
],
|
|
||||||
declarations: [HelloComponent],
|
|
||||||
exports: [HelloComponent]
|
|
||||||
})
|
|
||||||
export class HelloModule { }
|
|
@@ -1,10 +1,14 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { TRANSLATION_PROVIDER } from '@alfresco/adf-core';
|
import { TRANSLATION_PROVIDER } from '@alfresco/adf-core';
|
||||||
import { AppListCloudModule } from './app-list-cloud/app-list-cloud.module';
|
import { AppListCloudModule } from './app-list-cloud/app-list-cloud.module';
|
||||||
|
import { TaskListCloudModule } from './task-list-cloud/task-list-cloud.module';
|
||||||
|
import { TaskCloudModule } from './task-cloud/task-cloud.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
AppListCloudModule
|
AppListCloudModule,
|
||||||
|
TaskListCloudModule,
|
||||||
|
TaskCloudModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
@@ -17,6 +21,6 @@ import { AppListCloudModule } from './app-list-cloud/app-list-cloud.module';
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
declarations: [],
|
declarations: [],
|
||||||
exports: [AppListCloudModule]
|
exports: [AppListCloudModule, TaskListCloudModule, TaskCloudModule]
|
||||||
})
|
})
|
||||||
export class ProcessServicesCloudModule { }
|
export class ProcessServicesCloudModule { }
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
@import './../app-list-cloud/components/app-details-cloud.component';
|
@import './../app-list-cloud/components/app-details-cloud.component';
|
||||||
@import './../app-list-cloud/components/app-list-cloud.component';
|
@import './../app-list-cloud/components/app-list-cloud.component';
|
||||||
|
@import './../task-cloud/task-filters-cloud/task-filters-cloud.component.scss';
|
||||||
|
|
||||||
@mixin adf-process-services-cloud-theme($theme) {
|
@mixin adf-process-services-cloud-theme($theme) {
|
||||||
@include adf-cloud-app-list-theme($theme);
|
@include adf-cloud-app-list-theme($theme);
|
||||||
@include adf-cloud-app-details-theme($theme);
|
@include adf-cloud-app-details-theme($theme);
|
||||||
|
@include adf-cloud-task-filters-theme($theme);
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,267 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { FilterRepresentationModel, AppDefinitionRepresentationModel } from '../models/filter-cloud.model';
|
||||||
|
|
||||||
|
export let fakeFilters = {
|
||||||
|
size: 2, total: 2, start: 0,
|
||||||
|
data: [
|
||||||
|
new AppDefinitionRepresentationModel(
|
||||||
|
{
|
||||||
|
id: 1, name: 'FakeInvolvedTasks', recent: false, icon: 'glyphicon-align-left',
|
||||||
|
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-involved' }
|
||||||
|
}
|
||||||
|
),
|
||||||
|
{
|
||||||
|
id: 2, name: 'FakeMyTasks', recent: false, icon: 'glyphicon-align-left',
|
||||||
|
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-assignee' }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeAppFilter = {
|
||||||
|
size: 1, total: 1, start: 0,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
id: 1, name: 'FakeInvolvedTasks', recent: false, icon: 'glyphicon-align-left',
|
||||||
|
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-involved' }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeApps = {
|
||||||
|
size: 2, total: 2, start: 0,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
id: 1, defaultAppId: null, name: 'Sales-Fakes-App', description: 'desc-fake1', modelId: 22,
|
||||||
|
theme: 'theme-1-fake', icon: 'glyphicon-asterisk', 'deploymentId': '111', 'tenantId': null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2, defaultAppId: null, name: 'health-care-Fake', description: 'desc-fake2', modelId: 33,
|
||||||
|
theme: 'theme-2-fake', icon: 'glyphicon-asterisk', 'deploymentId': '444', 'tenantId': null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeFilter = {
|
||||||
|
sort: 'created-desc', text: '', state: 'open', assignment: 'fake-assignee'
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeUser1 = { id: 1, email: 'fake-email@dom.com', firstName: 'firstName', lastName: 'lastName' };
|
||||||
|
|
||||||
|
export let fakeUser2 = { id: 1001, email: 'some-one@somegroup.com', firstName: 'some', lastName: 'one' };
|
||||||
|
|
||||||
|
export let fakeTaskList = {
|
||||||
|
size: 1, total: 1, start: 0,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
id: '1', name: 'FakeNameTask', description: null, category: null,
|
||||||
|
assignee: fakeUser1,
|
||||||
|
created: '2016-07-15T11:19:17.440+0000'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeTaskListDifferentProcessDefinitionKey = {
|
||||||
|
size: 2, total: 1, start: 0,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
id: '1', name: 'FakeNameTask', description: null, category: null,
|
||||||
|
assignee: fakeUser1,
|
||||||
|
processDefinitionKey: '1',
|
||||||
|
created: '2016-07-15T11:19:17.440+0000'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2', name: 'FakeNameTask2', description: null, category: null,
|
||||||
|
assignee: fakeUser1,
|
||||||
|
processDefinitionKey: '2',
|
||||||
|
created: '2016-07-15T11:19:17.440+0000'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export let secondFakeTaskList = {
|
||||||
|
size: 1, total: 1, start: 0,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
id: '200', name: 'FakeNameTask', description: null, category: null,
|
||||||
|
assignee: fakeUser1,
|
||||||
|
created: '2016-07-15T11:19:17.440+0000'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export let mockErrorTaskList = {
|
||||||
|
error: 'wrong request'
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeTaskDetails = { id: '999', name: 'fake-task-name', formKey: '99', assignee: fakeUser1 };
|
||||||
|
|
||||||
|
export let fakeTasksComment = {
|
||||||
|
size: 2, total: 2, start: 0,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
id: 1, message: 'fake-message-1', created: '', createdBy: fakeUser1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2, message: 'fake-message-2', created: '', createdBy: fakeUser1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeTasksChecklist = {
|
||||||
|
size: 1, total: 1, start: 0,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
id: 1, name: 'FakeCheckTask1', description: null, category: null,
|
||||||
|
assignee: fakeUser1,
|
||||||
|
created: '2016-07-15T11:19:17.440+0000'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2, name: 'FakeCheckTask2', description: null, category: null,
|
||||||
|
assignee: fakeUser1,
|
||||||
|
created: '2016-07-15T11:19:17.440+0000'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeRepresentationFilter1: FilterRepresentationModel = new FilterRepresentationModel({
|
||||||
|
appId: 1,
|
||||||
|
name: 'CONTAIN FILTER',
|
||||||
|
recent: true,
|
||||||
|
icon: 'glyphicon-align-left',
|
||||||
|
filter: {
|
||||||
|
processDefinitionId: null,
|
||||||
|
processDefinitionKey: null,
|
||||||
|
name: null,
|
||||||
|
state: 'open',
|
||||||
|
sort: 'created-desc',
|
||||||
|
assignment: 'involved',
|
||||||
|
dueAfter: null,
|
||||||
|
dueBefore: null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export let fakeRepresentationFilter2: FilterRepresentationModel = new FilterRepresentationModel({
|
||||||
|
appId: 2,
|
||||||
|
name: 'NO TASK FILTER',
|
||||||
|
recent: false,
|
||||||
|
icon: 'glyphicon-inbox',
|
||||||
|
filter: {
|
||||||
|
processDefinitionId: null,
|
||||||
|
processDefinitionKey: null,
|
||||||
|
name: null,
|
||||||
|
state: 'open',
|
||||||
|
sort: 'created-desc',
|
||||||
|
assignment: 'assignee',
|
||||||
|
dueAfter: null,
|
||||||
|
dueBefore: null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export let fakeAppPromise = new Promise(function (resolve, reject) {
|
||||||
|
resolve(fakeAppFilter);
|
||||||
|
});
|
||||||
|
|
||||||
|
export let fakeFormList = {
|
||||||
|
size: 2,
|
||||||
|
total: 2,
|
||||||
|
start: 0,
|
||||||
|
data: [{
|
||||||
|
id: 1,
|
||||||
|
name: 'form with all widgets',
|
||||||
|
description: '',
|
||||||
|
createdBy: 2,
|
||||||
|
createdByFullName: 'Admin Admin',
|
||||||
|
lastUpdatedBy: 2,
|
||||||
|
lastUpdatedByFullName: 'Admin Admin',
|
||||||
|
lastUpdated: 1491400951205,
|
||||||
|
latestVersion: true,
|
||||||
|
version: 4,
|
||||||
|
comment: null,
|
||||||
|
stencilSet: null,
|
||||||
|
referenceId: null,
|
||||||
|
modelType: 2,
|
||||||
|
favorite: null,
|
||||||
|
permission: 'write',
|
||||||
|
tenantId: null
|
||||||
|
}, {
|
||||||
|
id: 2,
|
||||||
|
name: 'uppy',
|
||||||
|
description: '',
|
||||||
|
createdBy: 2,
|
||||||
|
createdByFullName: 'Admin Admin',
|
||||||
|
lastUpdatedBy: 2,
|
||||||
|
lastUpdatedByFullName: 'Admin Admin',
|
||||||
|
lastUpdated: 1490951054477,
|
||||||
|
latestVersion: true,
|
||||||
|
version: 2,
|
||||||
|
comment: null,
|
||||||
|
stencilSet: null,
|
||||||
|
referenceId: null,
|
||||||
|
modelType: 2,
|
||||||
|
favorite: null,
|
||||||
|
permission: 'write',
|
||||||
|
tenantId: null
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeTaskOpen1 = {
|
||||||
|
id: '1', name: 'FakeOpenTask1', description: null, category: null,
|
||||||
|
assignee: fakeUser1,
|
||||||
|
created: '2017-07-15T11:19:17.440+0000',
|
||||||
|
dueDate: null,
|
||||||
|
endDate: null
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeTaskOpen2 = {
|
||||||
|
id: '1', name: 'FakeOpenTask2', description: null, category: null,
|
||||||
|
assignee: { id: 1, email: 'fake-open-email@dom.com', firstName: 'firstName', lastName: 'lastName' },
|
||||||
|
created: '2017-07-15T11:19:17.440+0000',
|
||||||
|
dueDate: null,
|
||||||
|
endDate: null
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeTaskCompleted1 = {
|
||||||
|
id: '1', name: 'FakeCompletedTaskName1', description: null, category: null,
|
||||||
|
assignee: { id: 1, email: 'fake-completed-email@dom.com', firstName: 'firstName', lastName: 'lastName' },
|
||||||
|
created: '2016-07-15T11:19:17.440+0000',
|
||||||
|
dueDate: null,
|
||||||
|
endDate: '2016-11-03T15:25:42.749+0000'
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeTaskCompleted2 = {
|
||||||
|
id: '1', name: 'FakeCompletedTaskName2', description: null, category: null,
|
||||||
|
assignee: fakeUser1,
|
||||||
|
created: null,
|
||||||
|
dueDate: null,
|
||||||
|
endDate: '2016-11-03T15:25:42.749+0000'
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeOpenTaskList = {
|
||||||
|
size: 2,
|
||||||
|
total: 2,
|
||||||
|
start: 0,
|
||||||
|
data: [fakeTaskOpen1, fakeTaskOpen2]
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeCompletedTaskList = {
|
||||||
|
size: 2,
|
||||||
|
total: 2,
|
||||||
|
start: 0,
|
||||||
|
data: [fakeTaskCompleted1, fakeTaskCompleted2]
|
||||||
|
};
|
@@ -0,0 +1,52 @@
|
|||||||
|
/*!
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
export class QueryModel {
|
||||||
|
processDefinitionId: string;
|
||||||
|
appName: string;
|
||||||
|
state: string;
|
||||||
|
sort: string;
|
||||||
|
assignment: string;
|
||||||
|
order: string;
|
||||||
|
|
||||||
|
constructor(obj?: any) {
|
||||||
|
if (obj) {
|
||||||
|
this.appName = obj.appName || null;
|
||||||
|
this.processDefinitionId = obj.processDefinitionId || null;
|
||||||
|
this.state = obj.state || null;
|
||||||
|
this.sort = obj.sort || null;
|
||||||
|
this.assignment = obj.assignment || null;
|
||||||
|
this.order = obj.order || null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class FilterRepresentationModel {
|
||||||
|
name: string;
|
||||||
|
icon: string;
|
||||||
|
query: QueryModel;
|
||||||
|
|
||||||
|
constructor(obj?: any) {
|
||||||
|
if (obj) {
|
||||||
|
this.name = obj.name || null;
|
||||||
|
this.icon = obj.icon || null;
|
||||||
|
this.query = new QueryModel(obj.query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hasFilter() {
|
||||||
|
return !!this.query;
|
||||||
|
}
|
||||||
|
}
|
@@ -15,4 +15,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export * from './index';
|
export * from './task-filters-cloud/task-filters-cloud.component';
|
||||||
|
export * from './models/filter-cloud.model';
|
||||||
|
export * from './task-cloud.module';
|
@@ -0,0 +1,181 @@
|
|||||||
|
/*!
|
||||||
|
* @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, StorageService } from '@alfresco/adf-core';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Observable, forkJoin } from 'rxjs';
|
||||||
|
import { FilterRepresentationModel, QueryModel } from '../models/filter-cloud.model';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TaskFilterCloudService {
|
||||||
|
|
||||||
|
constructor(private logService: LogService,
|
||||||
|
private storage: StorageService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns the default filters for a process app.
|
||||||
|
* @param appName Name of the target app
|
||||||
|
* @returns Observable of default filters just created
|
||||||
|
*/
|
||||||
|
public createDefaultFilters(appName: string): Observable<FilterRepresentationModel[]> {
|
||||||
|
let involvedTasksFilter = this.getInvolvedTasksFilterInstance(appName);
|
||||||
|
let involvedObservable = this.addFilter(involvedTasksFilter);
|
||||||
|
|
||||||
|
let myTasksFilter = this.getMyTasksFilterInstance(appName);
|
||||||
|
let myTaskObservable = this.addFilter(myTasksFilter);
|
||||||
|
|
||||||
|
let queuedTasksFilter = this.getQueuedTasksFilterInstance(appName);
|
||||||
|
let queuedObservable = this.addFilter(queuedTasksFilter);
|
||||||
|
|
||||||
|
let completedTasksFilter = this.getCompletedTasksFilterInstance(appName);
|
||||||
|
let completeObservable = this.addFilter(completedTasksFilter);
|
||||||
|
|
||||||
|
return new Observable(observer => {
|
||||||
|
forkJoin(
|
||||||
|
involvedObservable,
|
||||||
|
myTaskObservable,
|
||||||
|
queuedObservable,
|
||||||
|
completeObservable
|
||||||
|
).subscribe(
|
||||||
|
(filters) => {
|
||||||
|
observer.next(filters);
|
||||||
|
observer.complete();
|
||||||
|
},
|
||||||
|
(err: any) => {
|
||||||
|
this.logService.error(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all task filters for a process app.
|
||||||
|
* @param appName Name of the target app
|
||||||
|
* @returns Observable of task filter details
|
||||||
|
*/
|
||||||
|
getTaskListFilters(appName?: string): Observable<FilterRepresentationModel[]> {
|
||||||
|
let key = 'task-filters-' + appName;
|
||||||
|
const filters = JSON.parse(this.storage.getItem(key) || '[]');
|
||||||
|
return new Observable(function(observer) {
|
||||||
|
observer.next(filters);
|
||||||
|
observer.complete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new task filter
|
||||||
|
* @param filter The new filter to add
|
||||||
|
* @returns Details of task filter just added
|
||||||
|
*/
|
||||||
|
addFilter(filter: FilterRepresentationModel): Observable<FilterRepresentationModel> {
|
||||||
|
const key = 'task-filters-' + filter.query.appName || '0';
|
||||||
|
let filters = JSON.parse(this.storage.getItem(key) || '[]');
|
||||||
|
|
||||||
|
filters.push(filter);
|
||||||
|
|
||||||
|
this.storage.setItem(key, JSON.stringify(filters));
|
||||||
|
|
||||||
|
return new Observable(function(observer) {
|
||||||
|
observer.next(filter);
|
||||||
|
observer.complete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a filter for "Involved" task instances.
|
||||||
|
* @param appName Name of the target app
|
||||||
|
* @returns The newly created filter
|
||||||
|
*/
|
||||||
|
getInvolvedTasksFilterInstance(appName: string): FilterRepresentationModel {
|
||||||
|
return new FilterRepresentationModel({
|
||||||
|
name: 'Cancelled Tasks',
|
||||||
|
icon: 'view_headline',
|
||||||
|
query: new QueryModel(
|
||||||
|
{
|
||||||
|
appName: appName,
|
||||||
|
sort: 'id',
|
||||||
|
state: 'CANCELLED',
|
||||||
|
assignment: 'involved',
|
||||||
|
order: 'DESC'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a filter for "My Tasks" task instances.
|
||||||
|
* @param appName Name of the target app
|
||||||
|
* @returns The newly created filter
|
||||||
|
*/
|
||||||
|
getMyTasksFilterInstance(appName: string): FilterRepresentationModel {
|
||||||
|
return new FilterRepresentationModel({
|
||||||
|
name: 'My Tasks',
|
||||||
|
icon: 'inbox',
|
||||||
|
query: new QueryModel(
|
||||||
|
{
|
||||||
|
appName: appName,
|
||||||
|
sort: 'id',
|
||||||
|
state: 'CREATED',
|
||||||
|
assignment: 'assignee',
|
||||||
|
order: 'ASC'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a filter for "Queued Tasks" task instances.
|
||||||
|
* @param appName Name of the target app
|
||||||
|
* @returns The newly created filter
|
||||||
|
*/
|
||||||
|
getQueuedTasksFilterInstance(appName: string): FilterRepresentationModel {
|
||||||
|
return new FilterRepresentationModel({
|
||||||
|
name: 'Suspended Tasks',
|
||||||
|
icon: 'adjust',
|
||||||
|
query: new QueryModel(
|
||||||
|
{
|
||||||
|
appName: appName,
|
||||||
|
sort: 'createdDate',
|
||||||
|
state: 'SUSPENDED',
|
||||||
|
assignment: 'candidate',
|
||||||
|
order: 'DESC'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a filter for "Completed" task instances.
|
||||||
|
* @param appName Name of the target app
|
||||||
|
* @returns The newly created filter
|
||||||
|
*/
|
||||||
|
getCompletedTasksFilterInstance(appName: string): FilterRepresentationModel {
|
||||||
|
return new FilterRepresentationModel({
|
||||||
|
name: 'Completed Tasks',
|
||||||
|
icon: 'done',
|
||||||
|
query: new QueryModel(
|
||||||
|
{
|
||||||
|
appName: appName,
|
||||||
|
sort: 'createdDate',
|
||||||
|
state: 'COMPLETED',
|
||||||
|
assignment: 'involved',
|
||||||
|
order: 'ASC'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,13 @@
|
|||||||
|
import { TaskCloudModule } from './task-cloud.module';
|
||||||
|
|
||||||
|
describe('TaskCloudModule', () => {
|
||||||
|
let taskCloudModule: TaskCloudModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
taskCloudModule = new TaskCloudModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(taskCloudModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,26 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { TaskFiltersCloudComponent } from './task-filters-cloud/task-filters-cloud.component';
|
||||||
|
import { MaterialModule } from '../material.module';
|
||||||
|
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
||||||
|
import { TranslateLoaderService, LogService, StorageService } from '@alfresco/adf-core';
|
||||||
|
import { TaskFilterCloudService } from './services/task-filter-cloud.service';
|
||||||
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
HttpClientModule,
|
||||||
|
CommonModule,
|
||||||
|
TranslateModule.forRoot({
|
||||||
|
loader: {
|
||||||
|
provide: TranslateLoader,
|
||||||
|
useClass: TranslateLoaderService
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
MaterialModule
|
||||||
|
],
|
||||||
|
declarations: [TaskFiltersCloudComponent],
|
||||||
|
|
||||||
|
exports: [TaskFiltersCloudComponent],
|
||||||
|
providers: [TaskFilterCloudService, LogService, StorageService]
|
||||||
|
})
|
||||||
|
export class TaskCloudModule { }
|
@@ -0,0 +1,17 @@
|
|||||||
|
<div class="menu-container">
|
||||||
|
<mat-list class="adf-menu-list" *ngIf="filters$ | async; else loading">
|
||||||
|
<mat-list-item (click)="selectFilterAndEmit(filter)" *ngFor="let filter of filters$ | async"
|
||||||
|
class="adf-filters__entry" [class.active]="currentFilter === filter">
|
||||||
|
<mat-icon *ngIf="showIcons && filter.icon" matListIcon class="adf-filters__entry-icon">{{filter.icon}}
|
||||||
|
</mat-icon>
|
||||||
|
<span matLine [attr.data-automation-id]="filter.name + '_filter'">{{filter.name}}</span>
|
||||||
|
</mat-list-item>
|
||||||
|
</mat-list>
|
||||||
|
<ng-template #loading>
|
||||||
|
<ng-container>
|
||||||
|
<div class="adf-app-list-spinner">
|
||||||
|
<mat-spinner></mat-spinner>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</ng-template>
|
||||||
|
</div>
|
@@ -0,0 +1,34 @@
|
|||||||
|
@mixin adf-cloud-task-filters-theme($theme) {
|
||||||
|
$primary: map-get($theme, primary);
|
||||||
|
|
||||||
|
.adf {
|
||||||
|
|
||||||
|
&-filters__entry {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px!important;
|
||||||
|
font-weight: bold;
|
||||||
|
opacity: .54;
|
||||||
|
padding-left: 30px;
|
||||||
|
|
||||||
|
.mat-list-item-content {
|
||||||
|
height: 34px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-filters__entry-icon {
|
||||||
|
padding-right: 12px !important;
|
||||||
|
padding-left: 0px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-filters__entry {
|
||||||
|
&.active, &:hover {
|
||||||
|
color: mat-color($primary);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-menu-list {
|
||||||
|
padding-top: 0px!important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,359 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { SimpleChange } from '@angular/core';
|
||||||
|
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||||
|
import { setupTestBed } from '@alfresco/adf-core';
|
||||||
|
import { from, Observable } from 'rxjs';
|
||||||
|
import { FilterRepresentationModel } from '../models/filter-cloud.model';
|
||||||
|
import { TaskFilterCloudService } from '../services/task-filter-cloud.service';
|
||||||
|
import { TaskFiltersCloudComponent } from './task-filters-cloud.component';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
|
||||||
|
import { TaskCloudModule } from '../task-cloud.module';
|
||||||
|
|
||||||
|
describe('TaskFiltersCloudComponent', () => {
|
||||||
|
|
||||||
|
let taskFilterService: TaskFilterCloudService;
|
||||||
|
|
||||||
|
let fakeGlobalFilter = [
|
||||||
|
new FilterRepresentationModel({
|
||||||
|
name: 'FakeInvolvedTasks',
|
||||||
|
icon: 'adjust',
|
||||||
|
id: 10,
|
||||||
|
filter: {state: 'open', assignment: 'fake-involved'}
|
||||||
|
}),
|
||||||
|
new FilterRepresentationModel({
|
||||||
|
name: 'FakeMyTasks1',
|
||||||
|
icon: 'done',
|
||||||
|
id: 11,
|
||||||
|
filter: {state: 'open', assignment: 'fake-assignee'}
|
||||||
|
}),
|
||||||
|
new FilterRepresentationModel({
|
||||||
|
name: 'FakeMyTasks2',
|
||||||
|
icon: 'inbox',
|
||||||
|
id: 12,
|
||||||
|
filter: {state: 'open', assignment: 'fake-assignee'}
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
let fakeGlobalFilterObservable =
|
||||||
|
new Observable(function(observer) {
|
||||||
|
observer.next(fakeGlobalFilter);
|
||||||
|
observer.complete();
|
||||||
|
});
|
||||||
|
|
||||||
|
let fakeGlobalFilterPromise = new Promise(function (resolve, reject) {
|
||||||
|
resolve(fakeGlobalFilter);
|
||||||
|
});
|
||||||
|
|
||||||
|
let fakeGlobalEmptyFilter = {
|
||||||
|
message: 'invalid data'
|
||||||
|
};
|
||||||
|
|
||||||
|
let fakeGlobalEmptyFilterPromise = new Promise(function (resolve, reject) {
|
||||||
|
resolve(fakeGlobalEmptyFilter);
|
||||||
|
});
|
||||||
|
|
||||||
|
let mockErrorFilterList = {
|
||||||
|
error: 'wrong request'
|
||||||
|
};
|
||||||
|
|
||||||
|
let mockErrorFilterPromise = Promise.reject(mockErrorFilterList);
|
||||||
|
|
||||||
|
let component: TaskFiltersCloudComponent;
|
||||||
|
let fixture: ComponentFixture<TaskFiltersCloudComponent>;
|
||||||
|
|
||||||
|
setupTestBed({
|
||||||
|
imports: [ProcessServiceCloudTestingModule, TaskCloudModule],
|
||||||
|
providers: [TaskFilterCloudService]
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(TaskFiltersCloudComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
|
||||||
|
taskFilterService = TestBed.get(TaskFilterCloudService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should attach specific icon for each filter if hasIcon is true', async(() => {
|
||||||
|
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(fakeGlobalFilterObservable);
|
||||||
|
let change = new SimpleChange(undefined, 'my-app-1', true);
|
||||||
|
component.ngOnChanges({'appName': change});
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.showIcons = true;
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(component.filters.length).toBe(3);
|
||||||
|
let filters = fixture.nativeElement.querySelectorAll('.adf-filters__entry-icon');
|
||||||
|
expect(filters.length).toBe(3);
|
||||||
|
expect(filters[0].innerText).toContain('adjust');
|
||||||
|
expect(filters[1].innerText).toContain('done');
|
||||||
|
expect(filters[2].innerText).toContain('inbox');
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should not attach icons for each filter if hasIcon is false', (done) => {
|
||||||
|
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(from(fakeGlobalFilterPromise));
|
||||||
|
|
||||||
|
component.showIcons = false;
|
||||||
|
let change = new SimpleChange(undefined, 'my-app-1', true);
|
||||||
|
component.ngOnChanges({'appName': change});
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
let filters: any = fixture.debugElement.queryAll(By.css('.adf-filters__entry-icon'));
|
||||||
|
expect(filters.length).toBe(0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display the filters', async(() => {
|
||||||
|
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(fakeGlobalFilterObservable);
|
||||||
|
let change = new SimpleChange(undefined, 'my-app-1', true);
|
||||||
|
component.ngOnChanges({'appName': change});
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.showIcons = true;
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
let filters = fixture.debugElement.queryAll(By.css('mat-list-item[class*="adf-filters__entry"]'));
|
||||||
|
expect(component.filters.length).toBe(3);
|
||||||
|
expect(filters.length).toBe(3);
|
||||||
|
expect(filters[0].nativeElement.innerText).toContain('FakeInvolvedTasks');
|
||||||
|
expect(filters[1].nativeElement.innerText).toContain('FakeMyTasks1');
|
||||||
|
expect(filters[2].nativeElement.innerText).toContain('FakeMyTasks2');
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should emit an error with a bad response', (done) => {
|
||||||
|
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(from(mockErrorFilterPromise));
|
||||||
|
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
component.ngOnChanges({'appName': change});
|
||||||
|
|
||||||
|
component.error.subscribe((err) => {
|
||||||
|
expect(err).toBeDefined();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the filter task list', (done) => {
|
||||||
|
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(from(fakeGlobalFilterPromise));
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
component.success.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.filters).toBeDefined();
|
||||||
|
expect(component.filters.length).toEqual(3);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the filter task list, filtered By Name', (done) => {
|
||||||
|
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(from(fakeGlobalFilterPromise));
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
component.success.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.filters).toBeDefined();
|
||||||
|
expect(component.filters[0].name).toEqual('FakeInvolvedTasks');
|
||||||
|
expect(component.filters[1].name).toEqual('FakeMyTasks1');
|
||||||
|
expect(component.filters[2].name).toEqual('FakeMyTasks2');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select the first filter as default', async(() => {
|
||||||
|
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(fakeGlobalFilterObservable);
|
||||||
|
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
component.success.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.currentFilter).toBeDefined();
|
||||||
|
expect(component.currentFilter.name).toEqual('FakeInvolvedTasks');
|
||||||
|
});
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should be able to fetch and select the default filters if the input filter is not valid', (done) => {
|
||||||
|
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(from(fakeGlobalEmptyFilterPromise));
|
||||||
|
spyOn(component, 'createFilters').and.callThrough();
|
||||||
|
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
component.success.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.createFilters).not.toHaveBeenCalled();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select the task filter based on the input by name param', async(() => {
|
||||||
|
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(fakeGlobalFilterObservable);
|
||||||
|
|
||||||
|
component.filterParam = new FilterRepresentationModel({ name: 'FakeMyTasks1' });
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
component.success.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.currentFilter).toBeDefined();
|
||||||
|
expect(component.currentFilter.name).toEqual('FakeMyTasks1');
|
||||||
|
});
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should select the default task filter if filter input does not exist', async(() => {
|
||||||
|
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(fakeGlobalFilterObservable);
|
||||||
|
|
||||||
|
component.filterParam = new FilterRepresentationModel({ name: 'UnexistableFilter' });
|
||||||
|
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
component.success.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.currentFilter).toBeDefined();
|
||||||
|
expect(component.currentFilter.name).toEqual('FakeInvolvedTasks');
|
||||||
|
});
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should select the task filter based on the input by index param', async(() => {
|
||||||
|
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(fakeGlobalFilterObservable);
|
||||||
|
|
||||||
|
component.filterParam = new FilterRepresentationModel({ index: 2 });
|
||||||
|
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
component.success.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.currentFilter).toBeDefined();
|
||||||
|
expect(component.currentFilter.name).toEqual('FakeMyTasks2');
|
||||||
|
});
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should select the task filter based on the input by id param', async(() => {
|
||||||
|
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(fakeGlobalFilterObservable);
|
||||||
|
|
||||||
|
component.filterParam = new FilterRepresentationModel({ id: 12 });
|
||||||
|
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
component.success.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.currentFilter).toBeDefined();
|
||||||
|
expect(component.currentFilter.name).toEqual('FakeMyTasks2');
|
||||||
|
});
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should emit an event when a filter is selected', async(() => {
|
||||||
|
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(fakeGlobalFilterObservable);
|
||||||
|
|
||||||
|
component.filterParam = new FilterRepresentationModel({ id: 12 });
|
||||||
|
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
spyOn(component, 'selectFilterAndEmit').and.stub();
|
||||||
|
let filterButton = fixture.debugElement.nativeElement.querySelector('span[data-automation-id="FakeMyTasks1_filter"]');
|
||||||
|
filterButton.click();
|
||||||
|
expect(component.selectFilterAndEmit).toHaveBeenCalledWith(fakeGlobalFilter[1]);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should reload filters by appName on binding changes', () => {
|
||||||
|
spyOn(component, 'getFilters').and.stub();
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
expect(component.getFilters).toHaveBeenCalledWith(appName);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not reload filters by appName null on binding changes', () => {
|
||||||
|
spyOn(component, 'getFilters').and.stub();
|
||||||
|
const appName = null;
|
||||||
|
|
||||||
|
let change = new SimpleChange(undefined, appName, true);
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
expect(component.getFilters).not.toHaveBeenCalledWith(appName);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should change current filter when filterParam (name) changes', () => {
|
||||||
|
component.filters = fakeGlobalFilter;
|
||||||
|
component.currentFilter = null;
|
||||||
|
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
expect(component.currentFilter.name).toEqual(fakeGlobalFilter[2].name);
|
||||||
|
});
|
||||||
|
|
||||||
|
const change = new SimpleChange(null, { name: fakeGlobalFilter[2].name }, true);
|
||||||
|
component.ngOnChanges({ 'filterParam': change });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reload filters by app name on binding changes', () => {
|
||||||
|
spyOn(component, 'getFilters').and.stub();
|
||||||
|
const appName = 'fake-app-name';
|
||||||
|
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
expect(component.getFilters).toHaveBeenCalledWith(appName);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the current filter after one is selected', () => {
|
||||||
|
let filter = fakeGlobalFilter[1];
|
||||||
|
component.filters = fakeGlobalFilter;
|
||||||
|
|
||||||
|
expect(component.currentFilter).toBeUndefined();
|
||||||
|
component.selectFilter(filter);
|
||||||
|
expect(component.getCurrentFilter()).toBe(filter);
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,156 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { TaskFilterCloudService } from '../services/task-filter-cloud.service';
|
||||||
|
import { FilterRepresentationModel } from '../models/filter-cloud.model';
|
||||||
|
@Component({
|
||||||
|
selector: 'adf-cloud-task-filters',
|
||||||
|
templateUrl: './task-filters-cloud.component.html',
|
||||||
|
styleUrls: ['task-filters-cloud.component.scss']
|
||||||
|
})
|
||||||
|
export class TaskFiltersCloudComponent implements OnChanges {
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
appName: string;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
filterParam: FilterRepresentationModel;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
showIcons: boolean = false;
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
filterClick: EventEmitter<FilterRepresentationModel> = new EventEmitter<FilterRepresentationModel>();
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
success: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
error: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
filters$: Observable<FilterRepresentationModel[]>;
|
||||||
|
|
||||||
|
currentFilter: FilterRepresentationModel;
|
||||||
|
|
||||||
|
filters: FilterRepresentationModel [] = [];
|
||||||
|
|
||||||
|
constructor(private taskFilterCloudService: TaskFilterCloudService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
const appName = changes['appName'];
|
||||||
|
const filter = changes['filterParam'];
|
||||||
|
if (appName && appName.currentValue) {
|
||||||
|
this.getFilters(appName.currentValue);
|
||||||
|
} else if (filter && filter.currentValue !== filter.previousValue) {
|
||||||
|
this.selectFilter(filter.currentValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the filter list filtered by appName
|
||||||
|
*/
|
||||||
|
getFilters(appName: string) {
|
||||||
|
this.filters$ = this.taskFilterCloudService.getTaskListFilters(appName);
|
||||||
|
|
||||||
|
this.filters$.subscribe(
|
||||||
|
(res: FilterRepresentationModel[]) => {
|
||||||
|
if (res.length === 0) {
|
||||||
|
this.createFilters(appName);
|
||||||
|
} else {
|
||||||
|
this.resetFilter();
|
||||||
|
this.filters = res;
|
||||||
|
}
|
||||||
|
this.selectFilterAndEmit(this.filterParam);
|
||||||
|
this.success.emit(res);
|
||||||
|
},
|
||||||
|
(err: any) => {
|
||||||
|
this.error.emit(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create default filters by appId
|
||||||
|
*/
|
||||||
|
createFilters(appName?: string) {
|
||||||
|
this.filters$ = this.taskFilterCloudService.createDefaultFilters(appName);
|
||||||
|
|
||||||
|
this.filters$.subscribe(
|
||||||
|
(resDefault: FilterRepresentationModel[]) => {
|
||||||
|
this.resetFilter();
|
||||||
|
this.filters = resDefault;
|
||||||
|
},
|
||||||
|
(errDefault: any) => {
|
||||||
|
this.error.emit(errDefault);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass the selected filter as next
|
||||||
|
*/
|
||||||
|
public selectFilter(newFilter: FilterRepresentationModel) {
|
||||||
|
if (newFilter) {
|
||||||
|
this.currentFilter = this.filters.find((filter) =>
|
||||||
|
(newFilter.name &&
|
||||||
|
(newFilter.name.toLocaleLowerCase() === filter.name.toLocaleLowerCase())
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if (!this.currentFilter) {
|
||||||
|
this.selectDefaultTaskFilter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public selectFilterAndEmit(newFilter: FilterRepresentationModel) {
|
||||||
|
this.selectFilter(newFilter);
|
||||||
|
this.filterClick.emit(this.currentFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select as default task filter the first in the list
|
||||||
|
*/
|
||||||
|
public selectDefaultTaskFilter() {
|
||||||
|
if (!this.isFilterListEmpty()) {
|
||||||
|
this.currentFilter = this.filters[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current task
|
||||||
|
*/
|
||||||
|
getCurrentFilter(): FilterRepresentationModel {
|
||||||
|
return this.currentFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the filter list is empty
|
||||||
|
*/
|
||||||
|
isFilterListEmpty(): boolean {
|
||||||
|
return this.filters === undefined || (this.filters && this.filters.length === 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the filters properties
|
||||||
|
*/
|
||||||
|
private resetFilter() {
|
||||||
|
this.filters = [];
|
||||||
|
this.currentFilter = undefined;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,4 @@
|
|||||||
|
.adf-cloud-task-list-loading-margin {
|
||||||
|
margin-left: calc((100% - 100px) / 2);
|
||||||
|
margin-right: calc((100% - 100px) / 2);
|
||||||
|
}
|
@@ -0,0 +1,33 @@
|
|||||||
|
<div *ngIf="!rows">{{ 'ADF_TASK_LIST.FILTERS.MESSAGES.NONE' | translate }}</div>
|
||||||
|
<ng-container *ngIf="rows">
|
||||||
|
<adf-datatable
|
||||||
|
[rows]="rows"
|
||||||
|
[columns]="columns"
|
||||||
|
[loading]="isLoading"
|
||||||
|
[multiselect]="multiselect"
|
||||||
|
[selectionMode]="selectionMode"
|
||||||
|
(row-select)="onRowSelect($event)"
|
||||||
|
(row-unselect)="onRowUnselect($event)"
|
||||||
|
(rowClick)="onRowClick($event)"
|
||||||
|
(row-keyup)="onRowKeyUp($event)">
|
||||||
|
<loading-content-template>
|
||||||
|
<ng-template>
|
||||||
|
<!-- Add your custom loading template here -->
|
||||||
|
<mat-progress-spinner class="adf-cloud-task-list-loading-margin"
|
||||||
|
[color]="'primary'"
|
||||||
|
[mode]="'indeterminate'">
|
||||||
|
</mat-progress-spinner>
|
||||||
|
</ng-template>
|
||||||
|
</loading-content-template>
|
||||||
|
<no-content-template>
|
||||||
|
<ng-template>
|
||||||
|
<adf-empty-content *ngIf="!emptyCustomContent"
|
||||||
|
icon="assignment"
|
||||||
|
[title]="'ADF_TASK_LIST.LIST.MESSAGES.TITLE' | translate"
|
||||||
|
[subtitle]="'ADF_TASK_LIST.LIST.MESSAGES.SUBTITLE' | translate">
|
||||||
|
</adf-empty-content>
|
||||||
|
<ng-content select="adf-empty-custom-content"></ng-content>
|
||||||
|
</ng-template>
|
||||||
|
</no-content-template>
|
||||||
|
</adf-datatable>
|
||||||
|
</ng-container>
|
@@ -0,0 +1,312 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { Component, SimpleChange, ViewChild, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
|
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { AppConfigService, setupTestBed, CoreModule } from '@alfresco/adf-core';
|
||||||
|
import { DataRowEvent, ObjectDataRow } from '@alfresco/adf-core';
|
||||||
|
import { TaskListCloudService } from '../services/task-list-cloud.service';
|
||||||
|
import { TaskListCloudComponent } from './task-list-cloud.component';
|
||||||
|
import { fakeGlobalTask, fakeCustomSchema, fakeTaskCloudList } from '../mock/fakeTaskResponseMock';
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
|
||||||
|
import { TaskListCloudModule } from '../task-list-cloud.module';
|
||||||
|
@Component({
|
||||||
|
template: `
|
||||||
|
<adf-cloud-task-list #taskListCloud>
|
||||||
|
<data-columns>
|
||||||
|
<data-column key="name" title="ADF_TASK_LIST.PROPERTIES.NAME" class="full-width name-column"></data-column>
|
||||||
|
<data-column key="created" title="ADF_TASK_LIST.PROPERTIES.CREATED" class="hidden"></data-column>
|
||||||
|
<data-column key="startedBy" title="ADF_TASK_LIST.PROPERTIES.CREATED" class="desktop-only dw-dt-col-3 ellipsis-cell">
|
||||||
|
<ng-template let-entry="$implicit">
|
||||||
|
<div>{{getFullName(entry.row.obj.startedBy)}}</div>
|
||||||
|
</ng-template>
|
||||||
|
</data-column>
|
||||||
|
</data-columns>
|
||||||
|
</adf-cloud-task-list>`
|
||||||
|
})
|
||||||
|
class CustomTaskListComponent {
|
||||||
|
@ViewChild(TaskListCloudComponent)
|
||||||
|
taskList: TaskListCloudComponent;
|
||||||
|
}
|
||||||
|
@Component({
|
||||||
|
template: `
|
||||||
|
<adf-tasklist>
|
||||||
|
<adf-empty-content-holder>
|
||||||
|
<p id="custom-id"></p>
|
||||||
|
</adf-empty-content-holder>
|
||||||
|
</adf-tasklist>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
class EmptyTemplateComponent {
|
||||||
|
}
|
||||||
|
describe('TaskListCloudComponent', () => {
|
||||||
|
let component: TaskListCloudComponent;
|
||||||
|
let fixture: ComponentFixture<TaskListCloudComponent>;
|
||||||
|
let appConfig: AppConfigService;
|
||||||
|
let taskListCloudService: TaskListCloudService;
|
||||||
|
|
||||||
|
setupTestBed({
|
||||||
|
imports: [
|
||||||
|
ProcessServiceCloudTestingModule, TaskListCloudModule
|
||||||
|
],
|
||||||
|
providers: [TaskListCloudService]
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
appConfig = TestBed.get(AppConfigService);
|
||||||
|
taskListCloudService = TestBed.get(TaskListCloudService);
|
||||||
|
fixture = TestBed.createComponent(TaskListCloudComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
appConfig.config = Object.assign(appConfig.config, {
|
||||||
|
'adf-cloud-task-list': {
|
||||||
|
'presets': {
|
||||||
|
'fakeCustomSchema': [
|
||||||
|
{
|
||||||
|
'key': 'fakeName',
|
||||||
|
'type': 'text',
|
||||||
|
'title': 'ADF_TASK_LIST.PROPERTIES.FAKE',
|
||||||
|
'sortable': true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'key': 'fakeTaskName',
|
||||||
|
'type': 'text',
|
||||||
|
'title': 'ADF_TASK_LIST.PROPERTIES.TASK_FAKE',
|
||||||
|
'sortable': true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fixture.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use the default schemaColumn as default', () => {
|
||||||
|
component.ngAfterContentInit();
|
||||||
|
expect(component.columns).toBeDefined();
|
||||||
|
expect(component.columns.length).toEqual(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use the custom schemaColumn from app.config.json', () => {
|
||||||
|
component.presetColumn = 'fakeCustomSchema';
|
||||||
|
component.ngAfterContentInit();
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(component.columns).toEqual(fakeCustomSchema);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fetch custom schemaColumn when the input presetColumn is defined', () => {
|
||||||
|
component.presetColumn = 'fakeCustomSchema';
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(component.columns).toBeDefined();
|
||||||
|
expect(component.columns.length).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an empty task list when no input parameters are passed', () => {
|
||||||
|
component.ngAfterContentInit();
|
||||||
|
expect(component.rows).toBeDefined();
|
||||||
|
expect(component.isListEmpty()).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the results if an application name is given', (done) => {
|
||||||
|
spyOn(taskListCloudService, 'getTaskByRequest').and.returnValue(of(fakeGlobalTask));
|
||||||
|
let appName = new SimpleChange(null, 'FAKE-APP-NAME', true);
|
||||||
|
component.success.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.rows).toBeDefined();
|
||||||
|
expect(component.isListEmpty()).not.toBeTruthy();
|
||||||
|
expect(component.rows.length).toEqual(1);
|
||||||
|
expect(component.rows[0].entry['serviceName']).toEqual('test-ciprian2-rb');
|
||||||
|
expect(component.rows[0].entry['serviceFullName']).toEqual('test-ciprian2-rb');
|
||||||
|
expect(component.rows[0].entry['serviceVersion']).toBe('');
|
||||||
|
expect(component.rows[0].entry['appName']).toBe('test-ciprian2');
|
||||||
|
expect(component.rows[0].entry['appVersion']).toBe('');
|
||||||
|
expect(component.rows[0].entry['serviceType']).toBeNull();
|
||||||
|
expect(component.rows[0].entry['id']).toBe('11fe013d-c263-11e8-b75b-0a5864600540');
|
||||||
|
expect(component.rows[0].entry['assignee']).toBeNull();
|
||||||
|
expect(component.rows[0].entry['name']).toEqual('standalone-subtask');
|
||||||
|
expect(component.rows[0].entry['description']).toBeNull();
|
||||||
|
expect(component.rows[0].entry['createdDate']).toBe(1538059139420);
|
||||||
|
expect(component.rows[0].entry['dueDate']).toBeNull();
|
||||||
|
expect(component.rows[0].entry['claimedDate']).toBeNull();
|
||||||
|
expect(component.rows[0].entry['priority']).toBe(0);
|
||||||
|
expect(component.rows[0].entry['category']).toBeNull();
|
||||||
|
expect(component.rows[0].entry['processDefinitionId']).toBeNull();
|
||||||
|
expect(component.rows[0].entry['processInstanceId']).toBeNull();
|
||||||
|
expect(component.rows[0].entry['status']).toBe('CREATED');
|
||||||
|
expect(component.rows[0].entry['owner']).toBe('devopsuser');
|
||||||
|
expect(component.rows[0].entry['parentTaskId']).toBe('71fda20b-c25b-11e8-b75b-0a5864600540');
|
||||||
|
expect(component.rows[0].entry['lastModified']).toBe(1538059139420);
|
||||||
|
expect(component.rows[0].entry['lastModifiedTo']).toBeNull();
|
||||||
|
expect(component.rows[0].entry['lastModifiedFrom']).toBeNull();
|
||||||
|
expect(component.rows[0].entry['standAlone']).toBeTruthy();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
component.applicationName = appName.currentValue;
|
||||||
|
component.ngOnChanges({ 'appName': appName });
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a currentId null when the taskList is empty', () => {
|
||||||
|
component.selectTask(null);
|
||||||
|
expect(component.getCurrentId()).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return selected id for the selected task', () => {
|
||||||
|
component.rows = [
|
||||||
|
{ entry: { id: '999', name: 'Fake-name' } },
|
||||||
|
{ entry: { id: '888', name: 'Fake-name-888' } }
|
||||||
|
];
|
||||||
|
component.selectTask('888');
|
||||||
|
expect(component.rows).toBeDefined();
|
||||||
|
expect(component.currentInstanceId).toEqual('888');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reload tasks when reload() is called', (done) => {
|
||||||
|
component.applicationName = 'fake';
|
||||||
|
spyOn(taskListCloudService, 'getTaskByRequest').and.returnValue(of(fakeGlobalTask));
|
||||||
|
component.success.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.rows).toBeDefined();
|
||||||
|
expect(component.isListEmpty()).not.toBeTruthy();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.reload();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit row click event', (done) => {
|
||||||
|
let row = new ObjectDataRow({
|
||||||
|
entry: {
|
||||||
|
id: '999'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let rowEvent = new DataRowEvent(row, null);
|
||||||
|
component.rowClick.subscribe(taskId => {
|
||||||
|
expect(taskId).toEqual('999');
|
||||||
|
expect(component.getCurrentId()).toEqual('999');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
component.onRowClick(rowEvent);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('component changes', () => {
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
component.rows = fakeGlobalTask.list.entries;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT reload the tasks if the landingTaskId is the same of the current task', () => {
|
||||||
|
spyOn(component, 'reload').and.stub();
|
||||||
|
component.currentInstanceId = '999';
|
||||||
|
component.rows = [{ entry: { id: '999', name: 'Fake-name' } }];
|
||||||
|
const landingTaskId = '999';
|
||||||
|
let change = new SimpleChange('999', landingTaskId, true);
|
||||||
|
component.ngOnChanges({ 'landingTaskId': change });
|
||||||
|
expect(component.reload).not.toHaveBeenCalled();
|
||||||
|
expect(component.rows.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reload the tasks if the loadingTaskId is different from the current task', (done) => {
|
||||||
|
component.currentInstanceId = '999';
|
||||||
|
component.rows = [{ id: '999', name: 'Fake-name' }];
|
||||||
|
const landingTaskId = '888';
|
||||||
|
let change = new SimpleChange(null, landingTaskId, true);
|
||||||
|
component.applicationName = 'fake';
|
||||||
|
spyOn(taskListCloudService, 'getTaskByRequest').and.returnValue(of(fakeTaskCloudList));
|
||||||
|
component.success.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.rows).toBeDefined();
|
||||||
|
expect(component.rows.length).toEqual(2);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
component.ngOnChanges({ 'landingTaskId': change });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT reload the task list when no parameters changed', () => {
|
||||||
|
component.rows = null;
|
||||||
|
component.ngOnChanges({});
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(component.isListEmpty()).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Injecting custom colums for tasklist - CustomTaskListComponent', () => {
|
||||||
|
let fixtureCustom: ComponentFixture<CustomTaskListComponent>;
|
||||||
|
let componentCustom: CustomTaskListComponent;
|
||||||
|
|
||||||
|
setupTestBed({
|
||||||
|
imports: [CoreModule.forRoot()],
|
||||||
|
declarations: [TaskListCloudComponent, CustomTaskListComponent],
|
||||||
|
providers: [TaskListCloudService]
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixtureCustom = TestBed.createComponent(CustomTaskListComponent);
|
||||||
|
fixtureCustom.detectChanges();
|
||||||
|
componentCustom = fixtureCustom.componentInstance;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fixtureCustom.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create instance of CustomTaskListComponent', () => {
|
||||||
|
expect(componentCustom instanceof CustomTaskListComponent).toBe(true, 'should create CustomTaskListComponent');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fetch custom schemaColumn from html', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(componentCustom.taskList.columnList).toBeDefined();
|
||||||
|
expect(componentCustom.taskList.columns[0]['title']).toEqual('ADF_TASK_LIST.PROPERTIES.NAME');
|
||||||
|
expect(componentCustom.taskList.columns[1]['title']).toEqual('ADF_TASK_LIST.PROPERTIES.CREATED');
|
||||||
|
expect(componentCustom.taskList.columns.length).toEqual(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Creating an empty custom template - EmptyTemplateComponent', () => {
|
||||||
|
let fixtureEmpty: ComponentFixture<EmptyTemplateComponent>;
|
||||||
|
|
||||||
|
setupTestBed({
|
||||||
|
imports: [ProcessServiceCloudTestingModule, TaskListCloudModule],
|
||||||
|
declarations: [EmptyTemplateComponent],
|
||||||
|
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixtureEmpty = TestBed.createComponent(EmptyTemplateComponent);
|
||||||
|
fixtureEmpty.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fixtureEmpty.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render the custom template', async(() => {
|
||||||
|
fixtureEmpty.whenStable().then(() => {
|
||||||
|
fixtureEmpty.detectChanges();
|
||||||
|
expect(fixtureEmpty.debugElement.query(By.css('#custom-id'))).not.toBeNull();
|
||||||
|
expect(fixtureEmpty.debugElement.query(By.css('.adf-empty-content'))).toBeNull();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,260 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { Component, ViewEncapsulation, OnChanges, Input, SimpleChanges, Output, EventEmitter, ContentChild, AfterContentInit, SimpleChange } from '@angular/core';
|
||||||
|
import { AppConfigService, UserPreferencesService,
|
||||||
|
DataTableSchema, UserPreferenceValues,
|
||||||
|
PaginatedComponent, PaginationModel,
|
||||||
|
DataRowEvent, EmptyCustomContentDirective } from '@alfresco/adf-core';
|
||||||
|
import { taskPresetsCloudDefaultModel } from '../models/task-preset-cloud.model';
|
||||||
|
import { TaskQueryCloudRequestModel } from '../models/filter-cloud-model';
|
||||||
|
import { BehaviorSubject } from 'rxjs';
|
||||||
|
import { TaskListCloudService } from '../services/task-list-cloud.service';
|
||||||
|
import { MinimalNodeEntity } from 'alfresco-js-api';
|
||||||
|
import { TaskListCloudSortingModel } from '../models/task-list-sorting.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'adf-cloud-task-list',
|
||||||
|
templateUrl: './task-list-cloud.component.html',
|
||||||
|
styleUrls: ['./task-list-cloud.component.css'],
|
||||||
|
encapsulation: ViewEncapsulation.None
|
||||||
|
})
|
||||||
|
|
||||||
|
export class TaskListCloudComponent extends DataTableSchema implements OnChanges, AfterContentInit, PaginatedComponent {
|
||||||
|
|
||||||
|
static PRESET_KEY = 'adf-cloud-task-list.presets';
|
||||||
|
|
||||||
|
@ContentChild(EmptyCustomContentDirective)
|
||||||
|
emptyCustomContent: EmptyCustomContentDirective;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
applicationName: string = '';
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
assignee: string = '';
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
createdDate: string = '';
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
dueDate: string = '';
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
id: string = '';
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
name: string = '';
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
parentTaskId: string = '';
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
processDefinitionId: string = '';
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
processInstanceId: string = '';
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
status: string = '';
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
selectFirstRow: boolean = true;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
landingTaskId: string;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
selectionMode: string = 'single'; // none|single|multiple
|
||||||
|
|
||||||
|
/** Toggles multiple row selection, renders checkboxes at the beginning of each row */
|
||||||
|
@Input()
|
||||||
|
multiselect: boolean = false;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
sorting: TaskListCloudSortingModel[];
|
||||||
|
|
||||||
|
/** Emitted when a task in the list is clicked */
|
||||||
|
@Output()
|
||||||
|
rowClick: EventEmitter<string> = new EventEmitter<string>();
|
||||||
|
|
||||||
|
/** Emitted when rows are selected/unselected */
|
||||||
|
@Output()
|
||||||
|
rowsSelected: EventEmitter<any[]> = new EventEmitter<any[]>();
|
||||||
|
|
||||||
|
/** Emitted when the task list is loaded */
|
||||||
|
@Output()
|
||||||
|
success: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
/** Emitted when an error occurs. */
|
||||||
|
@Output()
|
||||||
|
error: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
pagination: BehaviorSubject<PaginationModel>;
|
||||||
|
|
||||||
|
requestNode: TaskQueryCloudRequestModel;
|
||||||
|
rows: any[] = [];
|
||||||
|
size: number;
|
||||||
|
skipCount: number = 0;
|
||||||
|
currentInstanceId: any;
|
||||||
|
isLoading = false;
|
||||||
|
selectedInstances: any[];
|
||||||
|
|
||||||
|
constructor(private taskListCloudService: TaskListCloudService,
|
||||||
|
appConfigService: AppConfigService,
|
||||||
|
private userPreferences: UserPreferencesService) {
|
||||||
|
super(appConfigService, TaskListCloudComponent.PRESET_KEY, taskPresetsCloudDefaultModel);
|
||||||
|
this.size = userPreferences.paginationSize;
|
||||||
|
this.userPreferences.select(UserPreferenceValues.PaginationSize).subscribe((pageSize) => {
|
||||||
|
this.size = pageSize;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.pagination = new BehaviorSubject<PaginationModel>(<PaginationModel> {
|
||||||
|
maxItems: this.size,
|
||||||
|
skipCount: 0,
|
||||||
|
totalItems: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
if (this.isPropertyChanged(changes) &&
|
||||||
|
!this.isEqualToCurrentId(changes['landingTaskId'])) {
|
||||||
|
this.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterContentInit() {
|
||||||
|
this.createDatatableSchema();
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentId(): string {
|
||||||
|
return this.currentInstanceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
isEqualToCurrentId(landingTaskChanged: SimpleChange): boolean {
|
||||||
|
return landingTaskChanged && this.currentInstanceId === landingTaskChanged.currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private isPropertyChanged(changes: SimpleChanges): boolean {
|
||||||
|
for (let property in changes) {
|
||||||
|
if (changes.hasOwnProperty(property)) {
|
||||||
|
if (changes[property] &&
|
||||||
|
(changes[property].currentValue !== changes[property].previousValue)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
reload() {
|
||||||
|
this.requestNode = this.createRequestNode();
|
||||||
|
if (this.requestNode.appName) {
|
||||||
|
this.load(this.requestNode);
|
||||||
|
} else {
|
||||||
|
this.rows = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private load(requestNode: TaskQueryCloudRequestModel) {
|
||||||
|
this.isLoading = true;
|
||||||
|
this.taskListCloudService.getTaskByRequest(requestNode).subscribe(
|
||||||
|
(tasks) => {
|
||||||
|
this.rows = tasks.list.entries;
|
||||||
|
this.selectTask(this.landingTaskId);
|
||||||
|
this.success.emit(tasks);
|
||||||
|
this.isLoading = false;
|
||||||
|
this.pagination.next(tasks.list.pagination);
|
||||||
|
}, (error) => {
|
||||||
|
this.error.emit(error);
|
||||||
|
this.isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
selectTask(taskIdSelected: string) {
|
||||||
|
if (!this.isListEmpty()) {
|
||||||
|
let dataRow: any = null;
|
||||||
|
if (taskIdSelected) {
|
||||||
|
dataRow = this.rows.find((currentRow: MinimalNodeEntity) => {
|
||||||
|
return currentRow.entry.id === taskIdSelected;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!dataRow && this.selectFirstRow) {
|
||||||
|
dataRow = this.rows[0];
|
||||||
|
}
|
||||||
|
if (dataRow) {
|
||||||
|
dataRow.isSelected = true;
|
||||||
|
this.currentInstanceId = dataRow.entry.id;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.currentInstanceId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isListEmpty(): boolean {
|
||||||
|
return !this.rows || this.rows.length === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePagination(pagination: PaginationModel) {
|
||||||
|
this.size = pagination.maxItems;
|
||||||
|
this.skipCount = pagination.skipCount;
|
||||||
|
this.pagination.next(pagination);
|
||||||
|
this.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
onRowClick(item: DataRowEvent) {
|
||||||
|
this.currentInstanceId = item.value.getValue('entry.id');
|
||||||
|
this.rowClick.emit(this.currentInstanceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
onRowSelect(event: CustomEvent) {
|
||||||
|
this.selectedInstances = [...event.detail.selection];
|
||||||
|
this.rowsSelected.emit(this.selectedInstances);
|
||||||
|
}
|
||||||
|
|
||||||
|
onRowUnselect(event: CustomEvent) {
|
||||||
|
this.selectedInstances = [...event.detail.selection];
|
||||||
|
this.rowsSelected.emit(this.selectedInstances);
|
||||||
|
}
|
||||||
|
|
||||||
|
onRowKeyUp(event: CustomEvent) {
|
||||||
|
if (event.detail.keyboardEvent.key === 'Enter') {
|
||||||
|
event.preventDefault();
|
||||||
|
this.currentInstanceId = event.detail.row.getValue('entry.id');
|
||||||
|
this.rowClick.emit(this.currentInstanceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private createRequestNode() {
|
||||||
|
|
||||||
|
let requestNode = {
|
||||||
|
appName: this.applicationName,
|
||||||
|
assignee: this.assignee,
|
||||||
|
id: this.id,
|
||||||
|
name: this.name,
|
||||||
|
parentTaskId: this.parentTaskId,
|
||||||
|
processDefinitionId: this.processDefinitionId,
|
||||||
|
processInstanceId: this.processInstanceId,
|
||||||
|
status: this.status,
|
||||||
|
maxItems: this.size,
|
||||||
|
skipCount: this.skipCount,
|
||||||
|
sorting: this.sorting
|
||||||
|
};
|
||||||
|
return new TaskQueryCloudRequestModel(requestNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,145 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { ObjectDataColumn } from '@alfresco/adf-core';
|
||||||
|
|
||||||
|
export const fakeTaskCloudList = {
|
||||||
|
list: {
|
||||||
|
entries: [
|
||||||
|
{
|
||||||
|
entry: {
|
||||||
|
serviceName: 'maurizio-test-rb',
|
||||||
|
serviceFullName: 'maurizio-test-rb',
|
||||||
|
serviceVersion: '',
|
||||||
|
appName: 'save-the-cheerleader',
|
||||||
|
appVersion: '',
|
||||||
|
serviceType: null,
|
||||||
|
id: '890b0e1c-c252-11e8-b5c5-0a58646004c7',
|
||||||
|
assignee: null,
|
||||||
|
name: 'SimpleStandaloneTask',
|
||||||
|
description: 'Task description',
|
||||||
|
createdDate: 1538052037711,
|
||||||
|
dueDate: null,
|
||||||
|
claimedDate: null,
|
||||||
|
priority: 0,
|
||||||
|
category: null,
|
||||||
|
processDefinitionId: null,
|
||||||
|
processInstanceId: null,
|
||||||
|
status: 'CREATED',
|
||||||
|
owner: 'superadminuser',
|
||||||
|
parentTaskId: null,
|
||||||
|
lastModified: 1538052037711,
|
||||||
|
lastModifiedTo: null,
|
||||||
|
lastModifiedFrom: null,
|
||||||
|
standAlone: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
entry: {
|
||||||
|
serviceName: 'maurizio-test-rb',
|
||||||
|
serviceFullName: 'maurizio-test-rb',
|
||||||
|
serviceVersion: '',
|
||||||
|
appName: 'save-the-cheerleader',
|
||||||
|
appVersion: '',
|
||||||
|
serviceType: null,
|
||||||
|
id: '8962cb0e-c252-11e8-b5c5-0a58646004c7',
|
||||||
|
assignee: null,
|
||||||
|
name: 'SimpleStandaloneTask',
|
||||||
|
description: 'Task description',
|
||||||
|
createdDate: 1538052038286,
|
||||||
|
dueDate: null,
|
||||||
|
claimedDate: null,
|
||||||
|
priority: 0,
|
||||||
|
category: null,
|
||||||
|
processDefinitionId: null,
|
||||||
|
processInstanceId: null,
|
||||||
|
status: 'CREATED',
|
||||||
|
owner: 'superadminuser',
|
||||||
|
parentTaskId: null,
|
||||||
|
lastModified: 1538052038286,
|
||||||
|
lastModifiedTo: null,
|
||||||
|
lastModifiedFrom: null,
|
||||||
|
standAlone: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
pagination: {
|
||||||
|
skipCount: 0,
|
||||||
|
maxItems: 100,
|
||||||
|
count: 2,
|
||||||
|
hasMoreItems: false,
|
||||||
|
totalItems: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeGlobalTask = {
|
||||||
|
list: {
|
||||||
|
entries: [
|
||||||
|
{
|
||||||
|
entry: {
|
||||||
|
serviceName: 'test-ciprian2-rb',
|
||||||
|
serviceFullName: 'test-ciprian2-rb',
|
||||||
|
serviceVersion: '',
|
||||||
|
appName: 'test-ciprian2',
|
||||||
|
appVersion: '',
|
||||||
|
serviceType: null,
|
||||||
|
id: '11fe013d-c263-11e8-b75b-0a5864600540',
|
||||||
|
assignee: null,
|
||||||
|
name: 'standalone-subtask',
|
||||||
|
description: null,
|
||||||
|
createdDate: 1538059139420,
|
||||||
|
dueDate: null,
|
||||||
|
claimedDate: null,
|
||||||
|
priority: 0,
|
||||||
|
category: null,
|
||||||
|
processDefinitionId: null,
|
||||||
|
processInstanceId: null,
|
||||||
|
status: 'CREATED',
|
||||||
|
owner: 'devopsuser',
|
||||||
|
parentTaskId: '71fda20b-c25b-11e8-b75b-0a5864600540',
|
||||||
|
lastModified: 1538059139420,
|
||||||
|
lastModifiedTo: null,
|
||||||
|
lastModifiedFrom: null,
|
||||||
|
standAlone: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
pagination: {
|
||||||
|
skipCount: 0,
|
||||||
|
maxItems: 100,
|
||||||
|
count: 1,
|
||||||
|
hasMoreItems: false,
|
||||||
|
totalItems: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let fakeCustomSchema =
|
||||||
|
[
|
||||||
|
new ObjectDataColumn({
|
||||||
|
'key': 'fakeName',
|
||||||
|
'type': 'text',
|
||||||
|
'title': 'ADF_TASK_LIST.PROPERTIES.FAKE',
|
||||||
|
'sortable': true
|
||||||
|
}),
|
||||||
|
new ObjectDataColumn({
|
||||||
|
'key': 'fakeTaskName',
|
||||||
|
'type': 'text',
|
||||||
|
'title': 'ADF_TASK_LIST.PROPERTIES.TASK_FAKE',
|
||||||
|
'sortable': true
|
||||||
|
})
|
||||||
|
];
|
@@ -0,0 +1,70 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { TaskListCloudSortingModel } from './task-list-sorting.model';
|
||||||
|
|
||||||
|
export class TaskQueryCloudRequestModel {
|
||||||
|
appName: string;
|
||||||
|
appVersion?: string;
|
||||||
|
assignee?: string;
|
||||||
|
claimedDate?: string;
|
||||||
|
createdDate?: Date;
|
||||||
|
description?: string;
|
||||||
|
dueDate?: null;
|
||||||
|
id?: string;
|
||||||
|
name?: string;
|
||||||
|
owner?: string;
|
||||||
|
parentTaskId?: string;
|
||||||
|
priority?: number;
|
||||||
|
processDefinitionId?: string;
|
||||||
|
processInstanceId?: string;
|
||||||
|
serviceFullName?: string;
|
||||||
|
serviceName?: string;
|
||||||
|
serviceType?: string;
|
||||||
|
serviceVersion?: string;
|
||||||
|
status?: string;
|
||||||
|
maxItems: number;
|
||||||
|
skipCount: number;
|
||||||
|
sorting?: TaskListCloudSortingModel[];
|
||||||
|
|
||||||
|
constructor(obj?: any) {
|
||||||
|
if (obj) {
|
||||||
|
this.appName = obj.appName;
|
||||||
|
this.appVersion = obj.appVersion;
|
||||||
|
this.assignee = obj.assignee;
|
||||||
|
this.claimedDate = obj.claimedDate;
|
||||||
|
this.createdDate = obj.createdDate;
|
||||||
|
this.description = obj.description;
|
||||||
|
this.dueDate = obj.dueDate;
|
||||||
|
this.id = obj.id;
|
||||||
|
this.name = obj.name;
|
||||||
|
this.owner = obj.owner;
|
||||||
|
this.parentTaskId = obj.parentTaskId;
|
||||||
|
this.priority = obj.priority;
|
||||||
|
this.processDefinitionId = obj.processDefinitionId;
|
||||||
|
this.processInstanceId = obj.processInstanceId;
|
||||||
|
this.serviceFullName = obj.serviceFullName;
|
||||||
|
this.serviceName = obj.serviceName;
|
||||||
|
this.serviceType = obj.serviceType;
|
||||||
|
this.serviceVersion = obj.serviceVersion;
|
||||||
|
this.status = obj.status;
|
||||||
|
this.maxItems = obj.maxItems;
|
||||||
|
this.skipCount = obj.skipCount;
|
||||||
|
this.sorting = obj.sorting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,28 @@
|
|||||||
|
/*!
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export class TaskListCloudSortingModel {
|
||||||
|
orderBy: string;
|
||||||
|
direction: string;
|
||||||
|
|
||||||
|
constructor(obj: any) {
|
||||||
|
if (obj) {
|
||||||
|
this.orderBy = obj.orderBy;
|
||||||
|
this.direction = obj.direction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,41 @@
|
|||||||
|
/*!
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export let taskPresetsCloudDefaultModel = {
|
||||||
|
'default': [
|
||||||
|
{
|
||||||
|
'key': 'name',
|
||||||
|
'type': 'text',
|
||||||
|
'title': 'ADF_TASK_LIST.PROPERTIES.NAME',
|
||||||
|
'sortable': true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'key': 'created',
|
||||||
|
'type': 'text',
|
||||||
|
'title': 'ADF_TASK_LIST.PROPERTIES.CREATED',
|
||||||
|
'cssClass': 'hidden',
|
||||||
|
'sortable': true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'key': 'assignee',
|
||||||
|
'type': 'text',
|
||||||
|
'title': 'ADF_TASK_LIST.PROPERTIES.ASSIGNEE',
|
||||||
|
'cssClass': 'hidden',
|
||||||
|
'sortable': true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
@@ -0,0 +1,24 @@
|
|||||||
|
/*!
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './components/task-list-cloud.component';
|
||||||
|
|
||||||
|
export * from './models/filter-cloud-model';
|
||||||
|
export * from './models/task-list-sorting.model';
|
||||||
|
export * from './models/task-preset-cloud.model';
|
||||||
|
|
||||||
|
export * from './task-list-cloud.module';
|
@@ -0,0 +1,134 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { async } from '@angular/core/testing';
|
||||||
|
import { setupTestBed } from '@alfresco/adf-core';
|
||||||
|
import { fakeTaskCloudList } from '../mock/fakeTaskResponseMock';
|
||||||
|
import { AlfrescoApiServiceMock, LogService, AppConfigService, StorageService, CoreModule } from '@alfresco/adf-core';
|
||||||
|
import { TaskListCloudService } from './task-list-cloud.service';
|
||||||
|
import { TaskQueryCloudRequestModel } from '../models/filter-cloud-model';
|
||||||
|
|
||||||
|
describe('Activiti TaskList Cloud Service', () => {
|
||||||
|
|
||||||
|
let service: TaskListCloudService;
|
||||||
|
let alfrescoApiMock: AlfrescoApiServiceMock;
|
||||||
|
|
||||||
|
function returFakeTaskListResults() {
|
||||||
|
return {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi : () => {
|
||||||
|
return Promise.resolve(fakeTaskCloudList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function returnCallQueryParameters() {
|
||||||
|
return {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi : (queryUrl, operation, context, queryParams) => {
|
||||||
|
return Promise.resolve(queryParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function returnCallUrl() {
|
||||||
|
return {
|
||||||
|
oauth2Auth: {
|
||||||
|
callCustomApi : (queryUrl, operation, context, queryParams) => {
|
||||||
|
return Promise.resolve(queryUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
setupTestBed({
|
||||||
|
imports: [
|
||||||
|
CoreModule.forRoot()
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
alfrescoApiMock = new AlfrescoApiServiceMock(new AppConfigService(null), new StorageService() );
|
||||||
|
service = new TaskListCloudService(alfrescoApiMock,
|
||||||
|
new AppConfigService(null),
|
||||||
|
new LogService(new AppConfigService(null)));
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should return the tasks', (done) => {
|
||||||
|
let taskRequest: TaskQueryCloudRequestModel = <TaskQueryCloudRequestModel> { appName: 'fakeName' };
|
||||||
|
spyOn(alfrescoApiMock, 'getInstance').and.callFake(returFakeTaskListResults);
|
||||||
|
service.getTaskByRequest(taskRequest).subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(res).not.toBeNull();
|
||||||
|
expect(res.list.entries.length).toBe(2);
|
||||||
|
expect(res.list.entries[0].entry.appName).toBe('save-the-cheerleader');
|
||||||
|
expect(res.list.entries[1].entry.appName).toBe('save-the-cheerleader');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should append to the call all the parameters', (done) => {
|
||||||
|
let taskRequest: TaskQueryCloudRequestModel = <TaskQueryCloudRequestModel> { appName: 'fakeName', skipCount: 0, maxItems: 20, service: 'fake-service' };
|
||||||
|
spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnCallQueryParameters);
|
||||||
|
service.getTaskByRequest(taskRequest).subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(res).not.toBeNull();
|
||||||
|
expect(res.skipCount).toBe(0);
|
||||||
|
expect(res.maxItems).toBe(20);
|
||||||
|
expect(res.service).toBe('fake-service');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should concat the app name to the request url', (done) => {
|
||||||
|
let taskRequest: TaskQueryCloudRequestModel = <TaskQueryCloudRequestModel> { appName: 'fakeName', skipCount: 0, maxItems: 20, service: 'fake-service' };
|
||||||
|
spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnCallUrl);
|
||||||
|
service.getTaskByRequest(taskRequest).subscribe((requestUrl) => {
|
||||||
|
expect(requestUrl).toBeDefined();
|
||||||
|
expect(requestUrl).not.toBeNull();
|
||||||
|
expect(requestUrl).toContain('/fakeName-query/v1/tasks');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should concat the sorting to append as parameters', (done) => {
|
||||||
|
let taskRequest: TaskQueryCloudRequestModel = <TaskQueryCloudRequestModel> { appName: 'fakeName', skipCount: 0, maxItems: 20, service: 'fake-service',
|
||||||
|
sorting: [{ orderBy: 'NAME', direction: 'DESC'}, { orderBy: 'TITLE', direction: 'ASC'}] };
|
||||||
|
spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnCallQueryParameters);
|
||||||
|
service.getTaskByRequest(taskRequest).subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(res).not.toBeNull();
|
||||||
|
expect(res.sort).toBe('NAME,DESC&TITLE,ASC');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an error when app name is not specified', (done) => {
|
||||||
|
let taskRequest: TaskQueryCloudRequestModel = <TaskQueryCloudRequestModel> { appName: null };
|
||||||
|
spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnCallUrl);
|
||||||
|
service.getTaskByRequest(taskRequest).subscribe(
|
||||||
|
() => { },
|
||||||
|
(error) => {
|
||||||
|
expect(error).toBe('Appname not configured');
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -0,0 +1,92 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { Injectable } from '@angular/core';
|
||||||
|
import { AlfrescoApiService, AppConfigService, LogService } from '@alfresco/adf-core';
|
||||||
|
import { TaskQueryCloudRequestModel } from '../models/filter-cloud-model';
|
||||||
|
import { Observable, from, throwError } from 'rxjs';
|
||||||
|
import { TaskListCloudSortingModel } from '../models/task-list-sorting.model';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TaskListCloudService {
|
||||||
|
|
||||||
|
constructor(private apiService: AlfrescoApiService,
|
||||||
|
private appConfigService: AppConfigService,
|
||||||
|
private logService: LogService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
contentTypes = ['application/json'];
|
||||||
|
accepts = ['application/json'];
|
||||||
|
|
||||||
|
getTaskByRequest(requestNode: TaskQueryCloudRequestModel): Observable<any> {
|
||||||
|
if (requestNode.appName) {
|
||||||
|
let queryUrl = this.buildQueryUrl(requestNode);
|
||||||
|
let queryParams = this.buildQueryParams(requestNode);
|
||||||
|
let sortingParams = this.buildSortingParam(requestNode.sorting);
|
||||||
|
if (sortingParams) {
|
||||||
|
queryParams['sort'] = sortingParams;
|
||||||
|
}
|
||||||
|
return from(this.apiService.getInstance()
|
||||||
|
.oauth2Auth.callCustomApi(queryUrl, 'GET',
|
||||||
|
null, queryParams, null,
|
||||||
|
null, null, null, ['application/json'],
|
||||||
|
['application/json'], Object, null, null)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.logService.error('Appname is mandatory for querying task');
|
||||||
|
return throwError('Appname not configured');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildQueryUrl(requestNode: TaskQueryCloudRequestModel) {
|
||||||
|
return `${this.appConfigService.get('bpmHost', '')}/${requestNode.appName}-query/v1/tasks`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildQueryParams(requestNode: TaskQueryCloudRequestModel) {
|
||||||
|
let queryParam = {};
|
||||||
|
for (let property in requestNode) {
|
||||||
|
if (requestNode.hasOwnProperty(property) &&
|
||||||
|
!this.isExcludedField(property) &&
|
||||||
|
this.isPropertyValueValid(requestNode, property)) {
|
||||||
|
queryParam[property] = requestNode[property];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return queryParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
private isExcludedField(property) {
|
||||||
|
return property === 'appName' || property === 'sorting';
|
||||||
|
}
|
||||||
|
|
||||||
|
private isPropertyValueValid(requestNode, property) {
|
||||||
|
return requestNode[property] !== '' && requestNode[property] !== null && requestNode[property] !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildSortingParam(sortings: TaskListCloudSortingModel[]): string {
|
||||||
|
let finalSorting: string = '';
|
||||||
|
if (sortings) {
|
||||||
|
for (let sort of sortings) {
|
||||||
|
if (!finalSorting) {
|
||||||
|
finalSorting = `${sort.orderBy},${sort.direction}`;
|
||||||
|
} else {
|
||||||
|
finalSorting = `${finalSorting}&${sort.orderBy},${sort.direction}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return encodeURI(finalSorting);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,13 @@
|
|||||||
|
import { TaskListCloudModule } from './task-list-cloud.module';
|
||||||
|
|
||||||
|
describe('TaskListCloudModule', () => {
|
||||||
|
let taskListCloudModule: TaskListCloudModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
taskListCloudModule = new TaskListCloudModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(taskListCloudModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,26 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { MaterialModule } from '../material.module';
|
||||||
|
import { TaskListCloudComponent } from './components/task-list-cloud.component';
|
||||||
|
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
||||||
|
import { TranslateLoaderService, DataTableModule, TemplateModule } from '@alfresco/adf-core';
|
||||||
|
import { TaskListCloudService } from './services/task-list-cloud.service';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
TranslateModule.forRoot({
|
||||||
|
loader: {
|
||||||
|
provide: TranslateLoader,
|
||||||
|
useClass: TranslateLoaderService
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
MaterialModule,
|
||||||
|
DataTableModule,
|
||||||
|
TemplateModule
|
||||||
|
],
|
||||||
|
declarations: [TaskListCloudComponent],
|
||||||
|
exports: [TaskListCloudComponent],
|
||||||
|
providers: [TaskListCloudService]
|
||||||
|
})
|
||||||
|
export class TaskListCloudModule { }
|
@@ -0,0 +1,51 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { NgModule } from '@angular/core';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
import { TaskListCloudModule } from '../task-list-cloud.module';
|
||||||
|
import {
|
||||||
|
AlfrescoApiService,
|
||||||
|
AlfrescoApiServiceMock,
|
||||||
|
AppConfigService,
|
||||||
|
AppConfigServiceMock,
|
||||||
|
StorageService,
|
||||||
|
LogService,
|
||||||
|
TranslationService,
|
||||||
|
TranslationMock,
|
||||||
|
UserPreferencesService,
|
||||||
|
ContextMenuModule
|
||||||
|
} from '@alfresco/adf-core';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
HttpClientModule,
|
||||||
|
NoopAnimationsModule,
|
||||||
|
TaskListCloudModule,
|
||||||
|
ContextMenuModule
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock },
|
||||||
|
{ provide: AppConfigService, useClass: AppConfigServiceMock },
|
||||||
|
{ provide: TranslationService, useClass: TranslationMock },
|
||||||
|
StorageService,
|
||||||
|
LogService,
|
||||||
|
UserPreferencesService
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class TaskListTestingModule {}
|
@@ -18,7 +18,6 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { HttpClientModule } from '@angular/common/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
import { AppListCloudModule } from '../app-list-cloud.module';
|
|
||||||
import {
|
import {
|
||||||
AlfrescoApiService,
|
AlfrescoApiService,
|
||||||
AlfrescoApiServiceMock,
|
AlfrescoApiServiceMock,
|
||||||
@@ -27,21 +26,24 @@ import {
|
|||||||
StorageService,
|
StorageService,
|
||||||
LogService,
|
LogService,
|
||||||
TranslationService,
|
TranslationService,
|
||||||
TranslationMock
|
TranslationMock,
|
||||||
|
UserPreferencesService,
|
||||||
|
ContextMenuModule
|
||||||
} from '@alfresco/adf-core';
|
} from '@alfresco/adf-core';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
NoopAnimationsModule,
|
NoopAnimationsModule,
|
||||||
AppListCloudModule
|
ContextMenuModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock },
|
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock },
|
||||||
{ provide: AppConfigService, useClass: AppConfigServiceMock },
|
{ provide: AppConfigService, useClass: AppConfigServiceMock },
|
||||||
{ provide: TranslationService, useClass: TranslationMock },
|
{ provide: TranslationService, useClass: TranslationMock },
|
||||||
StorageService,
|
StorageService,
|
||||||
LogService
|
LogService,
|
||||||
|
UserPreferencesService
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AppListTestingModule {}
|
export class ProcessServiceCloudTestingModule {}
|
@@ -16,4 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export * from './lib/process-services-cloud.module';
|
export * from './lib/process-services-cloud.module';
|
||||||
export * from './lib/app-list-cloud/app-list-cloud.module';
|
export * from './lib/app-list-cloud/public-api';
|
||||||
|
export * from './lib/task-list-cloud/public-api';
|
||||||
|
export * from './lib/task-cloud/public-api';
|
@@ -1,41 +0,0 @@
|
|||||||
/*!
|
|
||||||
* @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 'core-js/es7/reflect';
|
|
||||||
import 'zone.js/dist/zone';
|
|
||||||
import 'zone.js/dist/zone-testing';
|
|
||||||
import { getTestBed } from '@angular/core/testing';
|
|
||||||
import {
|
|
||||||
BrowserDynamicTestingModule,
|
|
||||||
platformBrowserDynamicTesting
|
|
||||||
} from '@angular/platform-browser-dynamic/testing';
|
|
||||||
|
|
||||||
declare const require: any;
|
|
||||||
|
|
||||||
// First, initialize the Angular testing environment.
|
|
||||||
getTestBed().initTestEnvironment(
|
|
||||||
BrowserDynamicTestingModule,
|
|
||||||
platformBrowserDynamicTesting()
|
|
||||||
);
|
|
||||||
|
|
||||||
declare const pdfjsLib: any;
|
|
||||||
pdfjsLib.GlobalWorkerOptions.workerSrc = 'node_modules/pdfjs-dist/build/pdf.worker.min.js';
|
|
||||||
|
|
||||||
// Then we find all the tests.
|
|
||||||
const context = require.context('./', true, /\.spec\.ts$/);
|
|
||||||
// And load the modules.
|
|
||||||
context.keys().map(context);
|
|
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.json",
|
"extends": "./tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "../../out-tsc/spec",
|
"outDir": "../../out-tsc/spec",
|
||||||
"types": [
|
"types": [
|
||||||
|
Reference in New Issue
Block a user