mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-19 17:14:57 +00:00
[ADF-3749] Process Filter Component - APS2 (#3998)
* [ADF-3749] Created new process filter component * [ADF-3749] Improved process filters * [ADF-3749] Improved process filters * [ADF-3749] Added tests * [ADF-3749] Included filter in process list cloud demo * [ADF-3749] Added documentation * [ADF-3749] Improved documentation * [ADF-3749] Added new query model and improved model names * [][ADF-3749] Added extra documentation * [ADF-3749] Added new key in the filter models * [ADF-3749] Added translation support for filters * [ADF-3749] Added new tests * [ADF-3749] Added new translation keys
This commit is contained in:
parent
86ae2f5c2b
commit
1387aff0f4
@ -62,6 +62,7 @@
|
|||||||
"TASK_LIST": "Task List",
|
"TASK_LIST": "Task List",
|
||||||
"PROCESS_LIST": "Process List",
|
"PROCESS_LIST": "Process List",
|
||||||
"PROCESS_CLOUD": "Process Cloud",
|
"PROCESS_CLOUD": "Process Cloud",
|
||||||
|
"PROCESS_LIST_CLOUD": "Process List Cloud",
|
||||||
"CARD_VIEW": "CardView",
|
"CARD_VIEW": "CardView",
|
||||||
"PROCESS_SERVICES": "Process Services",
|
"PROCESS_SERVICES": "Process Services",
|
||||||
"LOGIN": "Login",
|
"LOGIN": "Login",
|
||||||
@ -269,5 +270,8 @@
|
|||||||
"TEXT": "Back to home"
|
"TEXT": "Back to home"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"PROCESS_LIST_CLOUD": {
|
||||||
|
"TITLE": "PROCESS LIST CLOUD DEMO"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ export const appRoutes: Routes = [
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'process-cloud',
|
path: 'process-list-cloud',
|
||||||
component: ProcessListCloudExampleComponent
|
component: ProcessListCloudExampleComponent
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,7 @@ export class AppLayoutComponent implements OnInit {
|
|||||||
{ 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: '/cloud', icon: 'cloud', title: 'APP_LAYOUT.PROCESS_CLOUD' },
|
||||||
|
{ href: '/process-list-cloud', icon: 'cloud', title: 'APP_LAYOUT.PROCESS_LIST_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,4 +1,11 @@
|
|||||||
<div>PROCESS LIST CLOUD</div>
|
<h3>{{'PROCESS_LIST_CLOUD.TITLE' | translate}}</h3>
|
||||||
|
<adf-cloud-process-filters
|
||||||
|
[appName]="currentAppName"
|
||||||
|
[showIcons]="true"
|
||||||
|
(filterClick)="onFilterSelected($event)"
|
||||||
|
*ngIf="currentAppName">
|
||||||
|
</adf-cloud-process-filters>
|
||||||
|
|
||||||
<adf-cloud-app-list *ngIf="!currentAppName"
|
<adf-cloud-app-list *ngIf="!currentAppName"
|
||||||
(appClick)="onAppClick($event)"></adf-cloud-app-list>
|
(appClick)="onAppClick($event)"></adf-cloud-app-list>
|
||||||
<div *ngIf="currentAppName">
|
<div *ngIf="currentAppName">
|
||||||
@ -6,13 +13,13 @@
|
|||||||
<mat-expansion-panel>
|
<mat-expansion-panel>
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>
|
<mat-panel-title>
|
||||||
Process Example Filters
|
{{filterName | translate}}
|
||||||
</mat-panel-title>
|
</mat-panel-title>
|
||||||
<mat-panel-description>
|
<mat-panel-description>
|
||||||
Apply one of the filters to the process list
|
Customise your filter
|
||||||
</mat-panel-description>
|
</mat-panel-description>
|
||||||
</mat-expansion-panel-header>
|
</mat-expansion-panel-header>
|
||||||
<div class="app-process-cloud-spacing">
|
<div>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-select placeholder="Status" [(ngModel)]="status">
|
<mat-select placeholder="Status" [(ngModel)]="status">
|
||||||
<mat-option value="">
|
<mat-option value="">
|
||||||
@ -21,60 +28,32 @@
|
|||||||
<mat-option value="RUNNING">
|
<mat-option value="RUNNING">
|
||||||
RUNNING
|
RUNNING
|
||||||
</mat-option>
|
</mat-option>
|
||||||
<mat-option value="SUSPENDED">
|
<mat-option value="COMPLETED">
|
||||||
SUSPENDED
|
COMPLETED
|
||||||
</mat-option>
|
</mat-option>
|
||||||
<mat-option value="CANCELLED">
|
</mat-select>
|
||||||
CANCELLED
|
</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-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-process-cloud-spacing">
|
|
||||||
<mat-form-field class="example-full-width">
|
|
||||||
<input matInput placeholder="Filter by id" [(ngModel)]="filterId">
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
<mat-expansion-panel>
|
|
||||||
<mat-expansion-panel-header>
|
|
||||||
<mat-panel-title>
|
|
||||||
Sorting Panel
|
|
||||||
</mat-panel-title>
|
|
||||||
<mat-panel-description>
|
|
||||||
Choose how to sort your tasks
|
|
||||||
</mat-panel-description>
|
|
||||||
</mat-expansion-panel-header>
|
|
||||||
<div class="task-cloud-demo-select">
|
|
||||||
<mat-form-field>
|
|
||||||
<mat-select placeholder="Sort Field" [(ngModel)]="sortField">
|
|
||||||
<mat-option value="id">
|
|
||||||
ID
|
|
||||||
</mat-option>
|
|
||||||
<mat-option value="name">
|
|
||||||
NAME
|
|
||||||
</mat-option>
|
|
||||||
<mat-option value="status">
|
|
||||||
STATUS
|
|
||||||
</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
<div class="task-cloud-demo-select">
|
|
||||||
<mat-form-field>
|
|
||||||
<mat-select placeholder="Direction" [(ngModel)]="sortDirection">
|
|
||||||
<mat-option value="ASC">
|
|
||||||
ASC
|
|
||||||
</mat-option>
|
|
||||||
<mat-option value="DESC">
|
|
||||||
DESC
|
|
||||||
</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
<button mat-button (click)="onFilterButtonClick($event)">Apply Filter</button>
|
|
||||||
<button mat-button (click)="onClearFilters()">Clear Filter</button>
|
|
||||||
</mat-expansion-panel>
|
|
||||||
</mat-accordion>
|
</mat-accordion>
|
||||||
<adf-cloud-process-list
|
<adf-cloud-process-list
|
||||||
[applicationName]="currentAppName"
|
[applicationName]="currentAppName"
|
||||||
|
@ -5,3 +5,7 @@
|
|||||||
.app-process-cloud-spacing {
|
.app-process-cloud-spacing {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat-form-field {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
@ -15,30 +15,70 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, ViewChild } from '@angular/core';
|
import { Component, ViewChild, OnInit } from '@angular/core';
|
||||||
import { UserPreferencesService } from '@alfresco/adf-core';
|
import { UserPreferencesService } from '@alfresco/adf-core';
|
||||||
import { ProcessListCloudComponent } from '@alfresco/adf-process-services-cloud';
|
import { ProcessListCloudComponent } from '@alfresco/adf-process-services-cloud';
|
||||||
|
import { FormControl } from '@angular/forms';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-process-list-example',
|
selector: 'app-process-list-example',
|
||||||
templateUrl: './process-list-cloud-example.component.html',
|
templateUrl: './process-list-cloud-example.component.html',
|
||||||
styleUrls: ['./process-list-cloud-example.component.scss']
|
styleUrls: ['./process-list-cloud-example.component.scss']
|
||||||
})
|
})
|
||||||
export class ProcessListCloudExampleComponent {
|
export class ProcessListCloudExampleComponent implements OnInit {
|
||||||
|
|
||||||
@ViewChild('processCloud')
|
@ViewChild('processCloud')
|
||||||
processCloud: ProcessListCloudComponent;
|
processCloud: ProcessListCloudComponent;
|
||||||
|
|
||||||
|
sortFormControl: FormControl;
|
||||||
|
sortDirectionFormControl: FormControl;
|
||||||
|
|
||||||
currentAppName: string = '';
|
currentAppName: string = '';
|
||||||
|
filterName: string = '';
|
||||||
status: string = '';
|
status: string = '';
|
||||||
filterId: string = '';
|
filterId: string = '';
|
||||||
sortArray: any = [];
|
sort: string = '';
|
||||||
|
sortArray: any[];
|
||||||
sortField: string;
|
sortField: string;
|
||||||
sortDirection: string;
|
sortDirection: string;
|
||||||
|
|
||||||
|
columns = [
|
||||||
|
{key: 'id', label: 'ID'},
|
||||||
|
{key: 'name', label: 'NAME'},
|
||||||
|
{key: 'status', label: 'STATUS'},
|
||||||
|
{key: 'startDate', label: 'START DATE'}
|
||||||
|
];
|
||||||
|
|
||||||
constructor(private userPreference: UserPreferencesService) {
|
constructor(private userPreference: UserPreferencesService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
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
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
onAppClick(appClicked: any) {
|
onAppClick(appClicked: any) {
|
||||||
this.currentAppName = appClicked.name;
|
this.currentAppName = appClicked.name;
|
||||||
}
|
}
|
||||||
@ -51,16 +91,16 @@ export class ProcessListCloudExampleComponent {
|
|||||||
this.userPreference.paginationSize = event.maxItems;
|
this.userPreference.paginationSize = event.maxItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
onFilterButtonClick($event) {
|
onClearFilters() {
|
||||||
let newSortParam: any = {
|
|
||||||
orderBy: this.sortField,
|
|
||||||
direction: this.sortDirection };
|
|
||||||
this.sortArray.push(newSortParam);
|
|
||||||
this.processCloud.reload();
|
this.processCloud.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
onClearFilters() {
|
onFilterSelected(filter) {
|
||||||
this.sortArray = [];
|
this.status = filter.query.state || '';
|
||||||
this.processCloud.reload();
|
this.sort = filter.query.sort;
|
||||||
|
this.sortDirection = filter.query.order;
|
||||||
|
this.filterName = filter.name;
|
||||||
|
this.sortDirectionFormControl.setValue(this.sortDirection);
|
||||||
|
this.sortFormControl.setValue(this.sort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
---
|
||||||
|
Added: v3.0.0
|
||||||
|
Status: Active
|
||||||
|
Last reviewed: 2018-21-11
|
||||||
|
---
|
||||||
|
|
||||||
|
# Process Filter Cloud Component
|
||||||
|
|
||||||
|
Lists all available process filters and allows to select a filter.
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
- [Basic Usage](#basic-usage)
|
||||||
|
- [Class members](#class-members)
|
||||||
|
- [Properties](#properties)
|
||||||
|
- [Events](#events)
|
||||||
|
|
||||||
|
|
||||||
|
## Basic Usage
|
||||||
|
|
||||||
|
```html
|
||||||
|
<adf-cloud-process-filters
|
||||||
|
[appName]="currentAppName"
|
||||||
|
[showIcons]="true">
|
||||||
|
</adf-cloud-process-filters>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Class members
|
||||||
|
|
||||||
|
### Properties
|
||||||
|
|
||||||
|
| Name | Type | Default value | Description |
|
||||||
|
| ---- | ---- | ------------- | ----------- |
|
||||||
|
| appName | `string` | | (required) The application name |
|
||||||
|
| filterParam | `ProcessFilterParamModel` | | (optional) The filter to be selected by default |
|
||||||
|
| showIcons | `boolean` | false | (optional) The flag hides/shows icon against each filter |
|
||||||
|
|
||||||
|
### Events
|
||||||
|
|
||||||
|
| Name | Type | Description |
|
||||||
|
| ---- | ---- | ----------- |
|
||||||
|
| filterClick | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ProcessFilterRepresentationModel`](../../lib/process-services-cloud/src/lib/process-cloud/models/process-filter-cloud.model.ts)`>` | Emitted when a filter is selected/clicked. |
|
||||||
|
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when filters are loaded successfully. |
|
||||||
|
| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when any error occurs while loading the filters. |
|
||||||
|
|
||||||
|
### Details
|
||||||
|
|
||||||
|
The `filterParam` input can be used to select a filter as mentioned below.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<adf-cloud-process-filters
|
||||||
|
[filterParam]="{name:'Running Processes'}">
|
||||||
|
</adf-cloud-process-filters>
|
||||||
|
```
|
||||||
|
|
||||||
|
A filter can be selected by using any of the `ProcessFilterParamModel` property.
|
||||||
|
|
||||||
|
| Name | Type | Description |
|
||||||
|
| ---- | ---- | ----------- |
|
||||||
|
| id | string | The id of the filter |
|
||||||
|
| name | string | The name of the filter |
|
||||||
|
| key | string | The key of the filter |
|
||||||
|
| index | string | The zero-based position of the filter in the array |
|
@ -9,5 +9,10 @@
|
|||||||
"ADF_CLOUD_TASK_FILTERS": {
|
"ADF_CLOUD_TASK_FILTERS": {
|
||||||
"MY_TASKS": "My Tasks",
|
"MY_TASKS": "My Tasks",
|
||||||
"COMPLETED_TASKS": "Completed Tasks"
|
"COMPLETED_TASKS": "Completed Tasks"
|
||||||
|
},
|
||||||
|
"ADF_CLOUD_PROCESS_FILTERS": {
|
||||||
|
"ALL_PROCESSES": "All Processes",
|
||||||
|
"RUNNING_PROCESSES": "Running Processes",
|
||||||
|
"COMPLETED_PROCESSES": "Completed Processes"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"ADF_CLOUD_TASK_PROCESS_LIST": {
|
"ADF_CLOUD_PROCESS_LIST": {
|
||||||
"MESSAGES": {
|
"MESSAGES": {
|
||||||
"TITLE": "Nessun processo trovato",
|
"TITLE": "Nessun processo trovato",
|
||||||
"SUBTITLE":"Crea un nuovo processo",
|
"SUBTITLE":"Crea un nuovo processo",
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
/*!
|
||||||
|
* @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 ProcessQueryModel {
|
||||||
|
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 ProcessFilterRepresentationModel {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
key: string;
|
||||||
|
icon: string;
|
||||||
|
query: ProcessQueryModel;
|
||||||
|
|
||||||
|
constructor(obj?: any) {
|
||||||
|
if (obj) {
|
||||||
|
this.id = obj.id || Math.random().toString(36).substring(2, 9);
|
||||||
|
this.name = obj.name || null;
|
||||||
|
this.key = obj.key || null;
|
||||||
|
this.icon = obj.icon || null;
|
||||||
|
this.query = new ProcessQueryModel(obj.query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hasFilter() {
|
||||||
|
return !!this.query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ProcessFilterParamModel {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
key: string;
|
||||||
|
index: number;
|
||||||
|
constructor(obj?: any) {
|
||||||
|
if (obj) {
|
||||||
|
this.id = obj.id || null;
|
||||||
|
this.name = obj.name || null;
|
||||||
|
this.key = obj.key || null;
|
||||||
|
this.index = obj.index || null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { CommonModule } from '@angular/common';
|
||||||
|
import { ProcessFiltersCloudComponent } from './process-filters-cloud/process-filters-cloud.component';
|
||||||
|
import { MaterialModule } from '../material.module';
|
||||||
|
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
||||||
|
import { TranslateLoaderService, LogService, StorageService } from '@alfresco/adf-core';
|
||||||
|
import { ProcessFilterCloudService } from './services/process-filter-cloud.service';
|
||||||
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
HttpClientModule,
|
||||||
|
CommonModule,
|
||||||
|
TranslateModule.forRoot({
|
||||||
|
loader: {
|
||||||
|
provide: TranslateLoader,
|
||||||
|
useClass: TranslateLoaderService
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
MaterialModule
|
||||||
|
],
|
||||||
|
declarations: [ProcessFiltersCloudComponent],
|
||||||
|
|
||||||
|
exports: [ProcessFiltersCloudComponent],
|
||||||
|
providers: [ProcessFilterCloudService, LogService, StorageService]
|
||||||
|
})
|
||||||
|
export class ProcessCloudModule { }
|
@ -0,0 +1,17 @@
|
|||||||
|
<div class="menu-container">
|
||||||
|
<mat-list class="adf-menu-list" *ngIf="filters$ | async as filterList; else loading">
|
||||||
|
<mat-list-item (click)="selectFilterById(filter.id)" *ngFor="let filter of filterList"
|
||||||
|
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 | translate}}</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-process-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,375 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { ProcessFilterRepresentationModel, ProcessFilterParamModel } from '../models/process-filter-cloud.model';
|
||||||
|
import { ProcessFilterCloudService } from '../services/process-filter-cloud.service';
|
||||||
|
import { ProcessFiltersCloudComponent } from './process-filters-cloud.component';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
|
||||||
|
import { ProcessCloudModule } from '../process-cloud.module';
|
||||||
|
|
||||||
|
describe('ProcessFiltersCloudComponent', () => {
|
||||||
|
|
||||||
|
let processFilterService: ProcessFilterCloudService;
|
||||||
|
|
||||||
|
let fakeGlobalFilter = [
|
||||||
|
new ProcessFilterRepresentationModel({
|
||||||
|
name: 'FakeAllProcesses',
|
||||||
|
icon: 'adjust',
|
||||||
|
id: '10',
|
||||||
|
query: {state: ''}
|
||||||
|
}),
|
||||||
|
new ProcessFilterRepresentationModel({
|
||||||
|
name: 'FakeRunningProcesses',
|
||||||
|
icon: 'inbox',
|
||||||
|
id: '11',
|
||||||
|
query: {state: 'RUNNING'}
|
||||||
|
}),
|
||||||
|
new ProcessFilterRepresentationModel({
|
||||||
|
name: 'FakeCompletedProcesses',
|
||||||
|
key: 'completed-processes',
|
||||||
|
icon: 'done',
|
||||||
|
id: '12',
|
||||||
|
query: {state: 'COMPLETED'}
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
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: ProcessFiltersCloudComponent;
|
||||||
|
let fixture: ComponentFixture<ProcessFiltersCloudComponent>;
|
||||||
|
|
||||||
|
setupTestBed({
|
||||||
|
imports: [ProcessServiceCloudTestingModule, ProcessCloudModule],
|
||||||
|
providers: [ProcessFilterCloudService]
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ProcessFiltersCloudComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
|
||||||
|
processFilterService = TestBed.get(ProcessFilterCloudService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should attach specific icon for each filter if hasIcon is true', async(() => {
|
||||||
|
spyOn(processFilterService, 'getProcessFilters').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('inbox');
|
||||||
|
expect(filters[2].innerText).toContain('done');
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should not attach icons for each filter if hasIcon is false', (done) => {
|
||||||
|
spyOn(processFilterService, 'getProcessFilters').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(processFilterService, 'getProcessFilters').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('FakeAllProcesses');
|
||||||
|
expect(filters[1].nativeElement.innerText).toContain('FakeRunningProcesses');
|
||||||
|
expect(filters[2].nativeElement.innerText).toContain('FakeCompletedProcesses');
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should emit an error with a bad response', (done) => {
|
||||||
|
spyOn(processFilterService, 'getProcessFilters').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 emit success with the filters when filters are loaded', (done) => {
|
||||||
|
spyOn(processFilterService, 'getProcessFilters').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('FakeAllProcesses');
|
||||||
|
expect(component.filters[1].name).toEqual('FakeRunningProcesses');
|
||||||
|
expect(component.filters[2].name).toEqual('FakeCompletedProcesses');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select the first filter as default', async(() => {
|
||||||
|
spyOn(processFilterService, 'getProcessFilters').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('FakeAllProcesses');
|
||||||
|
});
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should be able to fetch and select the default filters if the input filter is not valid', (done) => {
|
||||||
|
spyOn(processFilterService, 'getProcessFilters').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 filter based on the input by name param', (done) => {
|
||||||
|
spyOn(processFilterService, 'getProcessFilters').and.returnValue(fakeGlobalFilterObservable);
|
||||||
|
|
||||||
|
component.filterParam = new ProcessFilterParamModel({ name: 'FakeRunningProcesses' });
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
|
||||||
|
component.filterClick.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.currentFilter).toBeDefined();
|
||||||
|
expect(component.currentFilter.name).toEqual('FakeRunningProcesses');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select the filter based on the input by key param', (done) => {
|
||||||
|
spyOn(processFilterService, 'getProcessFilters').and.returnValue(fakeGlobalFilterObservable);
|
||||||
|
|
||||||
|
component.filterParam = new ProcessFilterParamModel({ key: 'completed-processes' });
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
component.filterClick.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.currentFilter).toBeDefined();
|
||||||
|
expect(component.currentFilter.name).toEqual('FakeCompletedProcesses');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select the default filter if filter input does not exist', (done) => {
|
||||||
|
spyOn(processFilterService, 'getProcessFilters').and.returnValue(fakeGlobalFilterObservable);
|
||||||
|
|
||||||
|
component.filterParam = new ProcessFilterParamModel({ name: 'UnexistableFilter' });
|
||||||
|
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
component.filterClick.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.currentFilter).toBeDefined();
|
||||||
|
expect(component.currentFilter.name).toEqual('FakeAllProcesses');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select the filter based on the input by index param', (done) => {
|
||||||
|
spyOn(processFilterService, 'getProcessFilters').and.returnValue(fakeGlobalFilterObservable);
|
||||||
|
|
||||||
|
component.filterParam = new ProcessFilterParamModel({ index: 2 });
|
||||||
|
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
component.filterClick.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.currentFilter).toBeDefined();
|
||||||
|
expect(component.currentFilter.name).toEqual('FakeCompletedProcesses');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select the filter based on the input by id param', (done) => {
|
||||||
|
spyOn(processFilterService, 'getProcessFilters').and.returnValue(fakeGlobalFilterObservable);
|
||||||
|
|
||||||
|
component.filterParam = new ProcessFilterParamModel({ id: '12' });
|
||||||
|
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
component.filterClick.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.currentFilter).toBeDefined();
|
||||||
|
expect(component.currentFilter.name).toEqual('FakeCompletedProcesses');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit an event when a filter is selected', (done) => {
|
||||||
|
spyOn(processFilterService, 'getProcessFilters').and.returnValue(fakeGlobalFilterObservable);
|
||||||
|
|
||||||
|
component.filterParam = new ProcessFilterParamModel({ id: '10' });
|
||||||
|
|
||||||
|
const appName = 'my-app-1';
|
||||||
|
let change = new SimpleChange(null, appName, true);
|
||||||
|
component.ngOnChanges({ 'appName': change });
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
component.filterClick.subscribe((res) => {
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(component.currentFilter).toBeDefined();
|
||||||
|
expect(component.currentFilter.name).toEqual('FakeRunningProcesses');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
let filterButton = fixture.debugElement.nativeElement.querySelector('span[data-automation-id="FakeRunningProcesses_filter"]');
|
||||||
|
filterButton.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
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(<ProcessFilterParamModel> {id: filter.id});
|
||||||
|
expect(component.getCurrentFilter()).toBe(filter);
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,186 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { ProcessFilterCloudService } from '../services/process-filter-cloud.service';
|
||||||
|
import { ProcessFilterRepresentationModel, ProcessFilterParamModel } from '../models/process-filter-cloud.model';
|
||||||
|
import { TranslationService } from '@alfresco/adf-core';
|
||||||
|
@Component({
|
||||||
|
selector: 'adf-cloud-process-filters',
|
||||||
|
templateUrl: './process-filters-cloud.component.html',
|
||||||
|
styleUrls: ['process-filters-cloud.component.scss']
|
||||||
|
})
|
||||||
|
export class ProcessFiltersCloudComponent implements OnChanges {
|
||||||
|
|
||||||
|
/** (required) The application name */
|
||||||
|
@Input()
|
||||||
|
appName: string;
|
||||||
|
|
||||||
|
/** (optional) The filter to be selected by default */
|
||||||
|
@Input()
|
||||||
|
filterParam: ProcessFilterParamModel;
|
||||||
|
|
||||||
|
/** (optional) The flag hides/shows icon against each filter */
|
||||||
|
@Input()
|
||||||
|
showIcons: boolean = false;
|
||||||
|
|
||||||
|
/** Emitted when a filter is selected/clicked */
|
||||||
|
@Output()
|
||||||
|
filterClick: EventEmitter<ProcessFilterRepresentationModel> = new EventEmitter<ProcessFilterRepresentationModel>();
|
||||||
|
|
||||||
|
/** Emitted when filters are loaded successfully */
|
||||||
|
@Output()
|
||||||
|
success: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
/** Emitted when any error occurs while loading the filters */
|
||||||
|
@Output()
|
||||||
|
error: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
filters$: Observable<ProcessFilterRepresentationModel[]>;
|
||||||
|
|
||||||
|
currentFilter: ProcessFilterRepresentationModel;
|
||||||
|
|
||||||
|
filters: ProcessFilterRepresentationModel [] = [];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private processFilterCloudService: ProcessFilterCloudService,
|
||||||
|
private translate: TranslationService ) { }
|
||||||
|
|
||||||
|
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.selectFilterAndEmit(filter.currentValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the filter list based on appName
|
||||||
|
*/
|
||||||
|
getFilters(appName: string) {
|
||||||
|
this.filters$ = this.processFilterCloudService.getProcessFilters(appName);
|
||||||
|
|
||||||
|
this.filters$.subscribe(
|
||||||
|
(res: ProcessFilterRepresentationModel[]) => {
|
||||||
|
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 appName
|
||||||
|
*/
|
||||||
|
createFilters(appName?: string) {
|
||||||
|
this.filters$ = this.processFilterCloudService.createDefaultFilters(appName);
|
||||||
|
|
||||||
|
this.filters$.subscribe(
|
||||||
|
(resDefault: ProcessFilterRepresentationModel[]) => {
|
||||||
|
this.resetFilter();
|
||||||
|
this.filters = resDefault;
|
||||||
|
},
|
||||||
|
(errDefault: any) => {
|
||||||
|
this.error.emit(errDefault);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass the selected filter as next
|
||||||
|
*/
|
||||||
|
public selectFilter(filterParam: ProcessFilterParamModel) {
|
||||||
|
if (filterParam) {
|
||||||
|
this.currentFilter = this.filters.find((filter, index) => {
|
||||||
|
return filterParam.id === filter.id ||
|
||||||
|
(filterParam.name && this.checkFilterNamesEquality(filterParam.name, filter.name)) ||
|
||||||
|
(filterParam.key && (filterParam.key === filter.key)) ||
|
||||||
|
filterParam.index === index;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!this.currentFilter) {
|
||||||
|
this.selectDefaultProcessFilter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check equality of the filter names by translating the given name strings
|
||||||
|
*/
|
||||||
|
private checkFilterNamesEquality(name1: string, name2: string ): boolean {
|
||||||
|
const translatedName1 = this.translate.instant(name1);
|
||||||
|
const translatedName2 = this.translate.instant(name2);
|
||||||
|
|
||||||
|
return translatedName1.toLocaleLowerCase() === translatedName2.toLocaleLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select and emit the given filter
|
||||||
|
*/
|
||||||
|
public selectFilterAndEmit(newFilter: ProcessFilterParamModel) {
|
||||||
|
this.selectFilter(newFilter);
|
||||||
|
this.filterClick.emit(this.currentFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select filter with the id
|
||||||
|
*/
|
||||||
|
public selectFilterById(id: string) {
|
||||||
|
this.selectFilterAndEmit(<ProcessFilterParamModel> {id: id});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select as default process filter the first in the list
|
||||||
|
*/
|
||||||
|
public selectDefaultProcessFilter() {
|
||||||
|
if (!this.isFilterListEmpty()) {
|
||||||
|
this.currentFilter = this.filters[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current process
|
||||||
|
*/
|
||||||
|
getCurrentFilter(): ProcessFilterRepresentationModel {
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
private resetFilter() {
|
||||||
|
this.filters = [];
|
||||||
|
this.currentFilter = undefined;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/*!
|
||||||
|
* @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 './process-filters-cloud/process-filters-cloud.component';
|
||||||
|
export * from './models/process-filter-cloud.model';
|
||||||
|
export * from './process-cloud.module';
|
@ -0,0 +1,133 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { StorageService } from '@alfresco/adf-core';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { ProcessFilterRepresentationModel, ProcessQueryModel } from '../models/process-filter-cloud.model';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ProcessFilterCloudService {
|
||||||
|
|
||||||
|
constructor(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<ProcessFilterRepresentationModel[]> {
|
||||||
|
const allProcessesFilter = this.getAllProcessesFilter(appName);
|
||||||
|
this.addFilter(allProcessesFilter);
|
||||||
|
const runningProcessesFilter = this.getRunningProcessesFilter(appName);
|
||||||
|
this.addFilter(runningProcessesFilter);
|
||||||
|
const completedProcessesFilter = this.getCompletedProcessesFilter(appName);
|
||||||
|
this.addFilter(completedProcessesFilter);
|
||||||
|
|
||||||
|
return this.getProcessFilters(appName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all process instance filters for a process app.
|
||||||
|
* @param appName Name of the target app
|
||||||
|
* @returns Observable of process filter details
|
||||||
|
*/
|
||||||
|
getProcessFilters(appName: string): Observable<ProcessFilterRepresentationModel[]> {
|
||||||
|
let key = 'process-filters-' + appName;
|
||||||
|
const filters = JSON.parse(this.storage.getItem(key) || '[]');
|
||||||
|
return new Observable(function(observer) {
|
||||||
|
observer.next(filters);
|
||||||
|
observer.complete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new process instance filter
|
||||||
|
* @param filter The new filter to add
|
||||||
|
* @returns Details of process filter just added
|
||||||
|
*/
|
||||||
|
addFilter(filter: ProcessFilterRepresentationModel) {
|
||||||
|
const key = 'process-filters-' + filter.query.appName;
|
||||||
|
const storedFilters = JSON.parse(this.storage.getItem(key) || '[]');
|
||||||
|
|
||||||
|
storedFilters.push(filter);
|
||||||
|
this.storage.setItem(key, JSON.stringify(storedFilters));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a filter for "All" Process instances.
|
||||||
|
* @param appName Name of the target app
|
||||||
|
* @returns The newly created filter
|
||||||
|
*/
|
||||||
|
getAllProcessesFilter(appName: string): ProcessFilterRepresentationModel {
|
||||||
|
return new ProcessFilterRepresentationModel({
|
||||||
|
name: 'ADF_CLOUD_PROCESS_FILTERS.ALL_PROCESSES',
|
||||||
|
key: 'all-processes',
|
||||||
|
icon: 'adjust',
|
||||||
|
query: new ProcessQueryModel(
|
||||||
|
{
|
||||||
|
appName: appName,
|
||||||
|
sort: 'startDate',
|
||||||
|
order: 'DESC'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a filter for "Running" Process instances.
|
||||||
|
* @param appName Name of the target app
|
||||||
|
* @returns The newly created filter
|
||||||
|
*/
|
||||||
|
getRunningProcessesFilter(appName: string): ProcessFilterRepresentationModel {
|
||||||
|
return new ProcessFilterRepresentationModel({
|
||||||
|
name: 'ADF_CLOUD_PROCESS_FILTERS.RUNNING_PROCESSES',
|
||||||
|
icon: 'inbox',
|
||||||
|
key: 'running-processes',
|
||||||
|
query: new ProcessQueryModel(
|
||||||
|
{
|
||||||
|
appName: appName,
|
||||||
|
sort: 'startDate',
|
||||||
|
state: 'RUNNING',
|
||||||
|
order: 'DESC'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a filter for "Completed" Process instances.
|
||||||
|
* @param appName Name of the target app
|
||||||
|
* @returns The newly created filter
|
||||||
|
*/
|
||||||
|
getCompletedProcessesFilter(appName: string): ProcessFilterRepresentationModel {
|
||||||
|
return new ProcessFilterRepresentationModel({
|
||||||
|
name: 'ADF_CLOUD_PROCESS_FILTERS.COMPLETED_PROCESSES',
|
||||||
|
icon: 'done',
|
||||||
|
key: 'completed-processes',
|
||||||
|
query: new ProcessQueryModel(
|
||||||
|
{
|
||||||
|
appName: appName,
|
||||||
|
sort: 'startDate',
|
||||||
|
state: 'COMPLETED',
|
||||||
|
order: 'DESC'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -19,8 +19,8 @@
|
|||||||
<ng-template>
|
<ng-template>
|
||||||
<adf-empty-content *ngIf="!emptyCustomContent"
|
<adf-empty-content *ngIf="!emptyCustomContent"
|
||||||
icon="assessment"
|
icon="assessment"
|
||||||
[title]="'ADF_CLOUD_TASK_PROCESS_LIST.MESSAGES.TITLE' | translate"
|
[title]="'ADF_CLOUD_PROCESS_LIST.MESSAGES.TITLE' | translate"
|
||||||
[subtitle]="'ADF_CLOUD_TASK_PROCESS_LIST.MESSAGES.SUBTITLE'| translate">
|
[subtitle]="'ADF_CLOUD_PROCESS_LIST.MESSAGES.SUBTITLE'| translate">
|
||||||
</adf-empty-content>
|
</adf-empty-content>
|
||||||
<ng-content select="adf-empty-custom-content"></ng-content>
|
<ng-content select="adf-empty-custom-content"></ng-content>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
@ -1,16 +1,35 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { 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 { TaskListCloudModule } from './task-list-cloud/task-list-cloud.module';
|
||||||
import { TaskCloudModule } from './task-cloud/task-cloud.module';
|
import { TaskCloudModule } from './task-cloud/task-cloud.module';
|
||||||
import { ProcessListCloudModule } from './process-list-cloud/process-list-cloud.module';
|
import { ProcessListCloudModule } from './process-list-cloud/process-list-cloud.module';
|
||||||
|
import { ProcessCloudModule } from './process-cloud/process-cloud.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
AppListCloudModule,
|
AppListCloudModule,
|
||||||
TaskListCloudModule,
|
TaskListCloudModule,
|
||||||
TaskCloudModule,
|
TaskCloudModule,
|
||||||
ProcessListCloudModule
|
ProcessListCloudModule,
|
||||||
|
ProcessCloudModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
@ -23,6 +42,11 @@ import { ProcessListCloudModule } from './process-list-cloud/process-list-cloud.
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
declarations: [],
|
declarations: [],
|
||||||
exports: [AppListCloudModule, TaskListCloudModule, TaskCloudModule, ProcessListCloudModule]
|
exports: [
|
||||||
|
AppListCloudModule,
|
||||||
|
TaskListCloudModule,
|
||||||
|
TaskCloudModule,
|
||||||
|
ProcessListCloudModule,
|
||||||
|
ProcessCloudModule]
|
||||||
})
|
})
|
||||||
export class ProcessServicesCloudModule { }
|
export class ProcessServicesCloudModule { }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user