AAE-26215 standalone cloud tasks (#10537)

This commit is contained in:
Denys Vuika 2025-01-14 12:00:07 -05:00 committed by GitHub
parent 972566fb29
commit af3ca02347
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
128 changed files with 1419 additions and 1658 deletions

View File

@ -494,20 +494,6 @@ Status: Experimental | [Source](<>) |
| [Task Header Cloud Component](process-services-cloud/components/task-header-cloud.component.md) ![Experimental](docassets/images/ExperimentalIcon.png) | Shows all the information related to a task. | [Source](../lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.ts) | | [Task Header Cloud Component](process-services-cloud/components/task-header-cloud.component.md) ![Experimental](docassets/images/ExperimentalIcon.png) | Shows all the information related to a task. | [Source](../lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.ts) |
| [Task List Cloud component](process-services-cloud/components/task-list-cloud.component.md) ![Experimental](docassets/images/ExperimentalIcon.png) | Renders a list containing all the tasks matched by the parameters specified. | [Source](../lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts) | | [Task List Cloud component](process-services-cloud/components/task-list-cloud.component.md) ![Experimental](docassets/images/ExperimentalIcon.png) | Renders a list containing all the tasks matched by the parameters specified. | [Source](../lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts) |
### Directives
| Name | Description | Source link |
| ---- | ----------- | ----------- |
| [Claim Task Cloud Directive](process-services-cloud/directives/claim-task-cloud.directive.md) ![Experimental](docassets/images/ExperimentalIcon.png) | Claims a task | [Source](../lib/process-services-cloud/src/lib/task/directives/claim-task-cloud.directive.ts) |
| [Complete Task Directive](process-services-cloud/directives/complete-task.directive.md) ![Experimental](docassets/images/ExperimentalIcon.png) | Completes a task. | [Source](../lib/process-services-cloud/src/lib/task/directives/complete-task.directive.ts) |
| [Unclaim Task Cloud Directive](process-services-cloud/directives/unclaim-task-cloud.directive.md) ![Experimental](docassets/images/ExperimentalIcon.png) | Unclaims a task | [Source](../lib/process-services-cloud/src/lib/task/directives/unclaim-task-cloud.directive.ts) |
### Pipes
| Name | Description | Source link |
| ---- | ----------- | ----------- |
| [Group initial pipe](process-services-cloud/pipes/group-initial.pipe.md) | Extracts the initial character from a group name. | [Source](../lib/process-services-cloud/src/lib/group/pipe/group-initial.pipe.ts) |
### Services ### Services
| Name | Description | Source link | | Name | Description | Source link |

View File

@ -5,7 +5,7 @@ Status: Active
Last reviewed: 2019-07-13 Last reviewed: 2019-07-13
--- ---
# [Identity Group service](../../../lib/process-services-cloud/src/lib/group/services/identity-group.service.ts "Defined in identity-group.service.ts") # Identity Group service
Performs CRUD operations on identity groups. Performs CRUD operations on identity groups.
@ -13,11 +13,10 @@ Performs CRUD operations on identity groups.
### Methods ### Methods
- **search**(name: `string`, filters?: [`IdentityGroupFilterInterface`](../../../lib/process-services-cloud/src/lib/group/services/identity-group-filter.interface.ts)): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`IdentityGroupModel`](../../../lib/process-services-cloud/src/lib/group/models/identity-group.model.ts)`[]>`<br/> - **search**(name: `string`, filters?: `IdentityGroupFilterInterface`)): `Observable<IdentityGroupModel[]>`
- _name:_ `string` - - _name:_ `string` -
- _filters:_ [`IdentityGroupFilterInterface`](../../../lib/process-services-cloud/src/lib/group/services/identity-group-filter.interface.ts) - (Optional) - _filters:_ `IdentityGroupFilterInterface - (Optional)
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`IdentityGroupModel`](../../../lib/process-services-cloud/src/lib/group/models/identity-group.model.ts)`[]>` - - **Returns** `Observable<IdentityGroupModel[]>` -
## See also ## See also

View File

@ -5,7 +5,7 @@ Status: Active
Last reviewed: 2019-07-12 Last reviewed: 2019-07-12
--- ---
# [Identity user service](../../../lib/process-services-cloud/src/lib/people/services/identity-user.service.ts "Defined in identity-user.service.ts") # Identity User Service
Gets OAuth2 personal details and roles for users and performs CRUD operations on identity users. Gets OAuth2 personal details and roles for users and performs CRUD operations on identity users.
@ -13,14 +13,12 @@ Gets OAuth2 personal details and roles for users and performs CRUD operations on
### Methods ### Methods
- **getCurrentUserInfo**(): [`IdentityUserModel`](../../../lib/process-services-cloud/src/lib/people/models/identity-user.model.ts)<br/> - **getCurrentUserInfo**(): `IdentityUserModel` - Gets the name and other basic details of the current user.
Gets the name and other basic details of the current user. - **Returns** `IdentityUserMode` - The user's details
- **Returns** [`IdentityUserModel`](../../../lib/process-services-cloud/src/lib/people/models/identity-user.model.ts) - The user's details - **search**(name: `string`, filters?: `IdentityUserFilterInterface`)): `Observable<IdentityUserModel[]>` - Search users based on name input and filters.
- **search**(name: `string`, filters?: [`IdentityUserFilterInterface`](../../../lib/process-services-cloud/src/lib/people/services/identity-user-filter.interface.ts)): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`IdentityUserModel`](../../../lib/process-services-cloud/src/lib/people/models/identity-user.model.ts)`[]>`<br/>
Search users based on name input and filters.
- _name:_ `string` - Search query string - _name:_ `string` - Search query string
- _filters:_ [`IdentityUserFilterInterface`](../../../lib/process-services-cloud/src/lib/people/services/identity-user-filter.interface.ts) - (Optional) - _filters:_ `IdentityUserFilterInterface` - (Optional)
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`IdentityUserModel`](../../../lib/process-services-cloud/src/lib/people/models/identity-user.model.ts)`[]>` - List of users - **Returns** `Observable<IdentityUserModel[]>` - List of users
## See also ## See also

View File

@ -5,7 +5,7 @@ Status: Experimental
Last reviewed: 2023-04-03 Last reviewed: 2023-04-03
--- ---
# [Edit Task Filter Cloud component](../../../lib/process-services-cloud/src/lib/task/task-filters/components/edit-task-filters/edit-task-filter-cloud.component.ts "Defined in edit-task-filter-cloud.component.ts") # Edit Task Filter Cloud component
Edits task filter details. Edits task filter details.
@ -41,20 +41,20 @@ Edits task filter details.
### Properties ### Properties
| Name | Type | Default value | Description | | Name | Type | Default value | Description |
|--------------------|----------------------------------------------------------------------------------------------------------------------|---------------|--------------------------------------------| |--------------------|------------------------|---------------|--------------------------------------------|
| actions | `string[]` | | List of task filter actions. | | actions | `string[]` | | List of task filter actions. |
| appName | `string` | "" | (required) Name of the app. | | appName | `string` | "" | (required) Name of the app. |
| environmentList | [`Environment`](../../../lib/process-services-cloud/src/lib/common/interface/environment.interface.ts)`[]` | \[] | List of environments. | | environmentList | `Environment[]` | \[] | List of environments. |
| filterProperties | `string[]` | \[] | List of task filter properties to display. | | filterProperties | `string[]` | \[] | List of task filter properties to display. |
| id | `string` | | (required) ID of the task filter. | | id | `string` | | (required) ID of the task filter. |
| processInstanceId | `string` | | processInstanceId of the task filter. | | processInstanceId | `string` | | processInstanceId of the task filter. |
| role | `string` | "" | user role. | | role | `string` | "" | user role. |
| showFilterActions | `boolean` | true | Toggles the filter actions. | | showFilterActions | `boolean` | true | Toggles the filter actions. |
| showTaskFilterName | `boolean` | true | Toggles display of task filter name | | showTaskFilterName | `boolean` | true | Toggles display of task filter name |
| showTitle | `boolean` | true | Toggles the title. | | showTitle | `boolean` | true | Toggles the title. |
| sortProperties | `string[]` | \[] | List of sort properties to display. | | sortProperties | `string[]` | \[] | List of sort properties to display. |
| taskFilter | [`TaskFilterCloudModel`](../../../lib/process-services-cloud/src/lib/task/task-filters/models/filter-cloud.model.ts) | | Task Filter to use. | | taskFilter | `TaskFilterCloudModel` | | Task Filter to use. |
### Events ### Events
@ -86,14 +86,14 @@ given below:
|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **_appName_** | Name of the app | | **_appName_** | Name of the app |
| **_status_** | Execution state of the task. | | **_status_** | Execution state of the task. |
| **_assignee_** | [`User`](lib/core/src/lib/pipes/user-initial.pipe.ts) the task is assigned to | | **_assignee_** | `User` the task is assigned to |
| **_taskName_** | Name of the task | | **_taskName_** | Name of the task |
| **_taskId_** | ID of the task | | **_taskId_** | ID of the task |
| **_parentTaskId_** | ID of the task's parent task | | **_parentTaskId_** | ID of the task's parent task |
| **_priority_** | Task priority | | **_priority_** | Task priority |
| **_createdDate_** | Date the task was created | | **_createdDate_** | Date the task was created |
| **_standalone_** | Standalone status of the task | | **_standalone_** | Standalone status of the task |
| **_owner_** | [`User`](lib/core/src/lib/pipes/user-initial.pipe.ts) ID of the task's owner | | **_owner_** | `User` ID of the task's owner |
| **_processDefinitionId_** | Process definition ID | | **_processDefinitionId_** | Process definition ID |
| **_processInstanceId_** | Process instance ID | | **_processInstanceId_** | Process instance ID |
| **_lastModified_** | Date the task was last modified. If lastModified defined the component will show the range **_lastModifiedFrom_**, **_lastModifiedTo_** | | **_lastModified_** | Date the task was last modified. If lastModified defined the component will show the range **_lastModifiedFrom_**, **_lastModifiedTo_** |

View File

@ -5,7 +5,7 @@ Status: Experimental
Last reviewed: 2019-01-08 Last reviewed: 2019-01-08
--- ---
# [Task Filters Cloud component](../../../lib/process-services-cloud/src/lib/task/task-filters/components/task-filters-cloud.component.ts "Defined in task-filters-cloud.component.ts") # Task Filters Cloud component
Shows all available filters. Shows all available filters.
@ -39,13 +39,13 @@ Shows all available filters.
### Events ### Events
| Name | Type | Description | | Name | Type | Description |
|----------------------|---------------------------------------|-------------------------------------------------------------------------| |----------------------|--------------------------------------|-------------------------------------------------------------------------|
| error | `EventEmitter<any>` | Emitted when an error occurs during loading. | | error | `EventEmitter<any>` | Emitted when an error occurs during loading. |
| filterClicked | `EventEmitter<TaskFilterCloudModel>` | Emitted when a filter is being clicked from the UI. | | filterClicked | `EventEmitter<TaskFilterCloudModel>` | Emitted when a filter is being clicked from the UI. |
| filterCounterUpdated | `EventEmitter<TaskCloudEngineEvent>` | Emitted when filter counters are updated. | | filterCounterUpdated | `EventEmitter<TaskCloudEngineEvent>` | Emitted when filter counters are updated. |
| filterSelected | `EventEmitter`<TaskFilterCloudModel>` | Emitted when a filter is being selected based on the filterParam input. | | filterSelected | `EventEmitter<TaskFilterCloudModel>` | Emitted when a filter is being selected based on the filterParam input. |
| success | `EventEmitter<any>` | Emitted when the list is loaded. | | success | `EventEmitter<any>` | Emitted when the list is loaded. |
## Details ## Details
@ -80,9 +80,7 @@ If you want to disable notification bubbles as task filters change you can chang
```json ```json
{ {
...
"notifications": true "notifications": true
...
} }
``` ```

View File

@ -5,9 +5,9 @@ Status: Active
Last reviewed: 2019-04-17 Last reviewed: 2019-04-17
--- ---
# [Task form cloud component](../../../lib/process-services-cloud/src/lib/task/task-form/components/task-form-cloud.component.ts "Defined in task-form-cloud.component.ts") # Task Form Component
Shows a [`form`](../../../lib/process-services-cloud/src/lib/form/models/form-cloud.model.ts) for a task. Shows a form for a task.
Shows Cancel, Save, Complete, Claim and Release buttons. Cancel, Save and Complete buttons are always present. Claim and Release buttons are present according to user's permissions and task's condition (Claimed, Completed etc). Shows Cancel, Save, Complete, Claim and Release buttons. Cancel, Save and Complete buttons are always present. Claim and Release buttons are present according to user's permissions and task's condition (Claimed, Completed etc).
@ -33,34 +33,34 @@ Save and Complete buttons get disabled when at least one of the form's inputs ar
### Properties ### Properties
| Name | Type | Default value | Description | | Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- | |---------------------------|---------------------------------------|---------------|---------------------------------------------------|
| appName | `string` | "" | App id to fetch corresponding form and values. | | appName | `string` | "" | App id to fetch corresponding form and values. |
| readOnly | `boolean` | false | Toggle readonly state of the task. | | readOnly | `boolean` | false | Toggle readonly state of the task. |
| showCancelButton | `boolean` | true | Toggle rendering of the `Cancel` button. | | showCancelButton | `boolean` | true | Toggle rendering of the `Cancel` button. |
| showCompleteButton | `boolean` | true | Toggle rendering of the `Complete` button. | | showCompleteButton | `boolean` | true | Toggle rendering of the `Complete` button. |
| showRefreshButton | `boolean` | false | Toggle rendering of the `Refresh` button. | | showRefreshButton | `boolean` | false | Toggle rendering of the `Refresh` button. |
| showTitle | `boolean` | true | Toggle rendering of the form title. | | showTitle | `boolean` | true | Toggle rendering of the form title. |
| showValidationIcon | `boolean` | true | Toggle rendering of the `Validation` icon. | | showValidationIcon | `boolean` | true | Toggle rendering of the `Validation` icon. |
| taskId | `string` | | Task id to fetch corresponding form and values. | | taskId | `string` | | Task id to fetch corresponding form and values. |
| displayModeConfigurations | [`FormCloudDisplayModeConfiguration`](../../../lib/process-services-cloud/src/lib/services/form-fields.interfaces.ts)`[]` | | The available display configurations for the form | | displayModeConfigurations | `FormCloudDisplayModeConfiguration[]` | | The available display configurations for the form |
### Events ### Events
| Name | Type | Description | | Name | Type | Description |
| ---- | ---- | ----------- | |--------------------|---------------------------------------------------|--------------------------------------------------------------------------------------------------------|
| cancelClick | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string>` | Emitted when the cancel button is clicked. | | cancelClick | `EventEmitter<string>` | Emitted when the cancel button is clicked. |
| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when any error occurs. | | error | `EventEmitter<any>` | Emitted when any error occurs. |
| executeOutcome | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`FormOutcomeEvent`](../../../lib/core/src/lib/form/components/widgets/core/form-outcome-event.model.ts)`>` | Emitted when any outcome is executed. Default behaviour can be prevented via `event.preventDefault()`. | | executeOutcome | `EventEmitter<FormOutcomeEvent>` | Emitted when any outcome is executed. Default behaviour can be prevented via `event.preventDefault()`. |
| formCompleted | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`FormModel`](../../../lib/core/src/lib/form/components/widgets/core/form.model.ts)`>` | Emitted when the form is submitted with the `Complete` outcome. | | formCompleted | `EventEmitter<FormModel>` | Emitted when the form is submitted with the `Complete` outcome. |
| formContentClicked | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ContentLinkModel`](../../../lib/core/src/lib/form/components/widgets/core/content-link.model.ts)`>` | Emitted when form content is clicked. | | formContentClicked | `EventEmitter<ContentLinkModel>` | Emitted when form content is clicked. |
| formSaved | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`FormModel`](../../../lib/core/src/lib/form/components/widgets/core/form.model.ts)`>` | Emitted when the form is saved. | | formSaved | `EventEmitter<FormModel>` | Emitted when the form is saved. |
| onTaskLoaded | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>` | Emitted when a task is loaded\`. | | onTaskLoaded | `EventEmitter<TaskDetailsCloudModel>` | Emitted when a task is loaded. |
| taskClaimed | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string>` | Emitted when the task is claimed. | | taskClaimed | `EventEmitter<string>` | Emitted when the task is claimed. |
| taskCompleted | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string>` | Emitted when the task is completed. | | taskCompleted | `EventEmitter<string>` | Emitted when the task is completed. |
| taskUnclaimed | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string>` | Emitted when the task is unclaimed. | | taskUnclaimed | `EventEmitter<string>` | Emitted when the task is unclaimed. |
| displayModeOn | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`FormCloudDisplayModeConfiguration`](../../../lib/process-services-cloud/src/lib/services/form-fields.interfaces.ts)`>` | Emitted when a display mode configuration is turned on. | | displayModeOn | `EventEmitter<FormCloudDisplayModeConfiguration>` | Emitted when a display mode configuration is turned on. |
| displayModeOff | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`FormCloudDisplayModeConfiguration`](../../../lib/process-services-cloud/src/lib/services/form-fields.interfaces.ts)`>` | Emitted when a display mode configuration is turned off. | | displayModeOff | `EventEmitter<FormCloudDisplayModeConfiguration>` | Emitted when a display mode configuration is turned off. |
#### Enabling fullscreen display for the form of the task #### Enabling fullscreen display for the form of the task

View File

@ -5,7 +5,7 @@ Status: Experimental
Last reviewed: 2019-03-25 Last reviewed: 2019-03-25
--- ---
# [Task List Cloud component](../../../lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts "Defined in task-list-cloud.component.ts") # [Task List Cloud component](../../../lib/process-services-cloud/src/lib/task/task-list/components/task-list/task-list-cloud.component.ts "Defined in task-list-cloud.component.ts")
Renders a list containing all the tasks matched by the parameters specified. Renders a list containing all the tasks matched by the parameters specified.

View File

@ -1,32 +0,0 @@
---
Title: Claim Task Cloud Directive
Added: v3.9.0
Status: Experimental
Last reviewed: 2020-06-09
---
# [Claim task Cloud directive](../../../lib/process-services-cloud/src/lib/task/directives/claim-task-cloud.directive.ts "Defined in claim-task-cloud.directive.ts")
Claims a task
## Basic Usage
```html
<button adf-cloud-claim-task [appName]="appName" [taskId]="taskId" (success)="onTaskClaimed()">Claim</button>
```
## Class members
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| appName | `string` | "" | (Required) The name of the application. |
| taskId | `string` | | (Required) The id of the task. |
### Events
| Name | Type | Description |
| ---- | ---- | ----------- |
| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the task cannot be completed. |
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the task is completed. |

View File

@ -1,32 +0,0 @@
---
Title: Complete Task Directive
Added: v3.1.0
Status: Experimental
Last reviewed: 2019-03-19
---
# [Complete task directive](../../../lib/process-services-cloud/src/lib/task/directives/complete-task.directive.ts "Defined in complete-task.directive.ts")
Completes a task.
## Basic Usage
```html
<button adf-cloud-complete-task [appName]="appName" [taskId]="taskId" (success)="onTaskCompleted()">Complete</button>
```
## Class members
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| appName | `string` | "" | (Required) The name of the application. |
| taskId | `string` | | (Required) The id of the task. |
### Events
| Name | Type | Description |
| ---- | ---- | ----------- |
| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the task cannot be completed. |
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the task is completed. |

View File

@ -1,32 +0,0 @@
---
Title: Unclaim Task Cloud Directive
Added: v3.9.0
Status: Experimental
Last reviewed: 2020-06-09
---
# [Unclaim Task Cloud directive](../../../lib/process-services-cloud/src/lib/task/directives/unclaim-task-cloud.directive.ts "Defined in unclaim-task-cloud.directive.ts")
Unclaims a task
## Basic Usage
```html
<button adf-cloud-unclaim-task [appName]="appName" [taskId]="taskId" (success)="onTaskUnclaimed()">Unclaim</button>
```
## Class members
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| appName | `string` | "" | (Required) The name of the application. |
| taskId | `string` | "" | (Required) The id of the task. |
### Events
| Name | Type | Description |
| ---- | ---- | ----------- |
| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the task cannot be completed. |
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the task is completed. |

View File

@ -1,33 +0,0 @@
---
Title: Group initial pipe
Added: v3.0.0
Status: Active
Last reviewed: 2019-01-17
---
# [Group initial pipe](../../../lib/process-services-cloud/src/lib/group/pipe/group-initial.pipe.ts "Defined in group-initial.pipe.ts")
Extracts the initial character from a group name.
## Basic Usage
<!-- {% raw %} -->
```HTML
<div>
Group: {{ currentGroup | groupNameInitial }}
</div>
```
<!-- {% endraw %} -->
## Details
This pipe takes a [`IdentityGroupModel`](../../../lib/process-services-cloud/src/lib/group/models/identity-group.model.ts)
object as its parameter and extracts the initial character from the `name`
property. The initial is a handy way to identify the group in lists and
other situations where there is limited screen space available.
## See also
- [Group cloud component](../components/group-cloud.component.md)

View File

@ -26,7 +26,7 @@ class MyComponent {
### Methods ### Methods
- **completeTaskForm**(appName: `string`, taskId: `string`, processInstanceId: `string`, formId: `string`, formValues: [`FormValues`](../../../lib/core/src/lib/form/components/widgets/core/form-values.ts), outcome: `string`, version: `number`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>`<br/> - **completeTaskForm**(appName: `string`, taskId: `string`, processInstanceId: `string`, formId: `string`, formValues: [`FormValues`](../../../lib/core/src/lib/form/components/widgets/core/form-values.ts), outcome: `string`, version: `number`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>`<br/>
Completes a task form. Completes a task form.
- _appName:_ `string` - Name of the app - _appName:_ `string` - Name of the app
- _taskId:_ `string` - ID of the target task - _taskId:_ `string` - ID of the target task
@ -35,7 +35,7 @@ class MyComponent {
- _formValues:_ [`FormValues`](../../../lib/core/src/lib/form/components/widgets/core/form-values.ts) - [Form](../../../lib/process-services/src/lib/task-list/models/form.model.ts) values object - _formValues:_ [`FormValues`](../../../lib/core/src/lib/form/components/widgets/core/form-values.ts) - [Form](../../../lib/process-services/src/lib/task-list/models/form.model.ts) values object
- _outcome:_ `string` - [Form](../../../lib/process-services/src/lib/task-list/models/form.model.ts) outcome - _outcome:_ `string` - [Form](../../../lib/process-services/src/lib/task-list/models/form.model.ts) outcome
- _version:_ `number` - of the form - _version:_ `number` - of the form
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>` - Updated task details - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>` - Updated task details
- **createTemporaryRawRelatedContent**(file: `any`, nodeId: `string`, contentHost: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/> - **createTemporaryRawRelatedContent**(file: `any`, nodeId: `string`, contentHost: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/>
- _file:_ `any` - - _file:_ `any` -
@ -61,11 +61,11 @@ class MyComponent {
- _body:_ `any` - - _body:_ `any` -
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FormFieldOption`](../../../lib/core/src/lib/form/components/widgets/core/form-field-option.ts)`[]>` - - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FormFieldOption`](../../../lib/core/src/lib/form/components/widgets/core/form-field-option.ts)`[]>` -
- **getTask**(appName: `string`, taskId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>`<br/> - **getTask**(appName: `string`, taskId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>`<br/>
Gets details of a task Gets details of a task
- _appName:_ `string` - Name of the app - _appName:_ `string` - Name of the app
- _taskId:_ `string` - ID of the target task - _taskId:_ `string` - ID of the target task
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>` - Details of the task - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>` - Details of the task
- **getTaskForm**(appName: `string`, taskId: `string`, version?: `number`): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/> - **getTaskForm**(appName: `string`, taskId: `string`, version?: `number`): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/>
Gets the form definition of a task. Gets the form definition of a task.
- _appName:_ `string` - Name of the app - _appName:_ `string` - Name of the app
@ -83,14 +83,14 @@ class MyComponent {
- _data:_ [`TaskVariableCloud`](../../../lib/process-services-cloud/src/lib/form/models/task-variable-cloud.model.ts)`[]` - (Optional) Values for the form's fields - _data:_ [`TaskVariableCloud`](../../../lib/process-services-cloud/src/lib/form/models/task-variable-cloud.model.ts)`[]` - (Optional) Values for the form's fields
- _readOnly:_ `boolean` - Toggles whether or not the form should be read-only - _readOnly:_ `boolean` - Toggles whether or not the form should be read-only
- **Returns** [`FormModel`](../../../lib/core/src/lib/form/components/widgets/core/form.model.ts) - [Form](../../../lib/process-services/src/lib/task-list/models/form.model.ts) created from the JSON specification - **Returns** [`FormModel`](../../../lib/core/src/lib/form/components/widgets/core/form.model.ts) - [Form](../../../lib/process-services/src/lib/task-list/models/form.model.ts) created from the JSON specification
- **saveTaskForm**(appName: `string`, taskId: `string`, processInstanceId: `string`, formId: `string`, values: [`FormValues`](../../../lib/core/src/lib/form/components/widgets/core/form-values.ts)): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>`<br/> - **saveTaskForm**(appName: `string`, taskId: `string`, processInstanceId: `string`, formId: `string`, values: [`FormValues`](../../../lib/core/src/lib/form/components/widgets/core/form-values.ts)): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>`<br/>
Saves a task form. Saves a task form.
- _appName:_ `string` - Name of the app - _appName:_ `string` - Name of the app
- _taskId:_ `string` - ID of the target task - _taskId:_ `string` - ID of the target task
- _processInstanceId:_ `string` - ID of processInstance - _processInstanceId:_ `string` - ID of processInstance
- _formId:_ `string` - ID of the form to save - _formId:_ `string` - ID of the form to save
- _values:_ [`FormValues`](../../../lib/core/src/lib/form/components/widgets/core/form-values.ts) - [Form](../../../lib/process-services/src/lib/task-list/models/form.model.ts) values object - _values:_ [`FormValues`](../../../lib/core/src/lib/form/components/widgets/core/form-values.ts) - [Form](../../../lib/process-services/src/lib/task-list/models/form.model.ts) values object
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>` - Updated task details - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>` - Updated task details
## See also ## See also

View File

@ -13,40 +13,40 @@ Manages task cloud.
### Methods ### Methods
- **assign**(appName: `string`, taskId: `string`, assignee: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>`<br/> - **assign**(appName: `string`, taskId: `string`, assignee: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>`<br/>
Updates the task assignee. Updates the task assignee.
- _appName:_ `string` - Name of the app - _appName:_ `string` - Name of the app
- _taskId:_ `string` - ID of the task to update assignee - _taskId:_ `string` - ID of the task to update assignee
- _assignee:_ `string` - assignee to update current user task assignee - _assignee:_ `string` - assignee to update current user task assignee
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>` - Updated task details with new assignee - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>` - Updated task details with new assignee
- **canClaimTask**(taskDetails: [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)): `boolean`<br/> - **canClaimTask**(taskDetails: [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)): `boolean`<br/>
Validate if a task can be claimed. Validate if a task can be claimed.
- _taskDetails:_ [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts) - task details object - _taskDetails:_ [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts) - task details object
- **Returns** `boolean` - Boolean value if the task can be completed - **Returns** `boolean` - Boolean value if the task can be completed
- **canCompleteTask**(taskDetails: [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)): `boolean`<br/> - **canCompleteTask**(taskDetails: [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)): `boolean`<br/>
Validate if a task can be completed. Validate if a task can be completed.
- _taskDetails:_ [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts) - task details object - _taskDetails:_ [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts) - task details object
- **Returns** `boolean` - Boolean value if the task can be completed - **Returns** `boolean` - Boolean value if the task can be completed
- **canUnclaimTask**(taskDetails: [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)): `boolean`<br/> - **canUnclaimTask**(taskDetails: [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)): `boolean`<br/>
Validate if a task can be unclaimed. Validate if a task can be unclaimed.
- _taskDetails:_ [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts) - task details object - _taskDetails:_ [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts) - task details object
- **Returns** `boolean` - Boolean value if the task can be completed - **Returns** `boolean` - Boolean value if the task can be completed
- **claimTask**(appName: `string`, taskId: `string`, assignee: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>`<br/> - **claimTask**(appName: `string`, taskId: `string`, assignee: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>`<br/>
Claims a task for an assignee. Claims a task for an assignee.
- _appName:_ `string` - Name of the app - _appName:_ `string` - Name of the app
- _taskId:_ `string` - ID of the task to claim - _taskId:_ `string` - ID of the task to claim
- _assignee:_ `string` - User to assign the task to - _assignee:_ `string` - User to assign the task to
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>` - Details of the claimed task - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>` - Details of the claimed task
- **completeTask**(appName: `string`, taskId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>`<br/> - **completeTask**(appName: `string`, taskId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>`<br/>
Complete a task. Complete a task.
- _appName:_ `string` - Name of the app - _appName:_ `string` - Name of the app
- _taskId:_ `string` - ID of the task to complete - _taskId:_ `string` - ID of the task to complete
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>` - Details of the task that was completed - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>` - Details of the task that was completed
- **createNewTask**(startTaskRequest: [`StartTaskCloudRequestModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/start-task-cloud-request.model.ts), appName: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>`<br/> - **createNewTask**(startTaskRequest: [`StartTaskCloudRequestModel`](../../../lib/process-services-cloud/src/lib/task/models/start-task-cloud-request.model.ts), appName: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>`<br/>
Creates a new standalone task. Creates a new standalone task.
- _startTaskRequest:_ [`StartTaskCloudRequestModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/start-task-cloud-request.model.ts) - - _startTaskRequest:_ [`StartTaskCloudRequestModel`](../../../lib/process-services-cloud/src/lib/task/models/start-task-cloud-request.model.ts) -
- _appName:_ `string` - - _appName:_ `string` -
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>` - Details of the newly created task - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>` - Details of the newly created task
- **getBasePath**(appName: `string`): `string`<br/> - **getBasePath**(appName: `string`): `string`<br/>
- _appName:_ `string` - - _appName:_ `string` -
@ -71,33 +71,33 @@ Manages task cloud.
Gets the process definitions associated with an app. Gets the process definitions associated with an app.
- _appName:_ `string` - Name of the target app - _appName:_ `string` - Name of the target app
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessDefinitionCloud`](../../../lib/process-services-cloud/src/lib/models/process-definition-cloud.model.ts)`[]>` - Array of process definitions - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessDefinitionCloud`](../../../lib/process-services-cloud/src/lib/models/process-definition-cloud.model.ts)`[]>` - Array of process definitions
- **getTaskById**(appName: `string`, taskId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>`<br/> - **getTaskById**(appName: `string`, taskId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>`<br/>
Gets details of a task. Gets details of a task.
- _appName:_ `string` - Name of the app - _appName:_ `string` - Name of the app
- _taskId:_ `string` - ID of the task whose details you want - _taskId:_ `string` - ID of the task whose details you want
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>` - Task details - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>` - Task details
- **isAssigneePropertyClickable**(taskDetails: [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts), candidateUsers: [`CardViewArrayItem`](../../../lib/core/src/lib/card-view/models/card-view-arrayitem.model.ts)`[]`, candidateGroups: [`CardViewArrayItem`](../../../lib/core/src/lib/card-view/models/card-view-arrayitem.model.ts)`[]`): `boolean`<br/> - **isAssigneePropertyClickable**(taskDetails: [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts), candidateUsers: [`CardViewArrayItem`](../../../lib/core/src/lib/card-view/models/card-view-arrayitem.model.ts)`[]`, candidateGroups: [`CardViewArrayItem`](../../../lib/core/src/lib/card-view/models/card-view-arrayitem.model.ts)`[]`): `boolean`<br/>
- _taskDetails:_ [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts) - - _taskDetails:_ [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts) -
- _candidateUsers:_ [`CardViewArrayItem`](../../../lib/core/src/lib/card-view/models/card-view-arrayitem.model.ts)`[]` - - _candidateUsers:_ [`CardViewArrayItem`](../../../lib/core/src/lib/card-view/models/card-view-arrayitem.model.ts)`[]` -
- _candidateGroups:_ [`CardViewArrayItem`](../../../lib/core/src/lib/card-view/models/card-view-arrayitem.model.ts)`[]` - - _candidateGroups:_ [`CardViewArrayItem`](../../../lib/core/src/lib/card-view/models/card-view-arrayitem.model.ts)`[]` -
- **Returns** `boolean` - - **Returns** `boolean` -
- **isTaskEditable**(taskDetails: [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)): `boolean`<br/> - **isTaskEditable**(taskDetails: [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)): `boolean`<br/>
Validate if a task is editable. Validate if a task is editable.
- _taskDetails:_ [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts) - task details object - _taskDetails:_ [`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts) - task details object
- **Returns** `boolean` - Boolean value if the task is editable - **Returns** `boolean` - Boolean value if the task is editable
- **unclaimTask**(appName: `string`, taskId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>`<br/> - **unclaimTask**(appName: `string`, taskId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>`<br/>
Un-claims a task. Un-claims a task.
- _appName:_ `string` - Name of the app - _appName:_ `string` - Name of the app
- _taskId:_ `string` - ID of the task to unclaim - _taskId:_ `string` - ID of the task to unclaim
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>` - Details of the task that was unclaimed - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>` - Details of the task that was unclaimed
- **updateTask**(appName: `string`, taskId: `string`, payload: `any`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>`<br/> - **updateTask**(appName: `string`, taskId: `string`, payload: `any`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>`<br/>
Updates the details (name, description, due date) for a task. Updates the details (name, description, due date) for a task.
- _appName:_ `string` - Name of the app - _appName:_ `string` - Name of the app
- _taskId:_ `string` - ID of the task to update - _taskId:_ `string` - ID of the task to update
- _payload:_ `any` - Data to update the task - _payload:_ `any` - Data to update the task
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts)`>` - Updated task details - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsCloudModel`](../../../lib/process-services-cloud/src/lib/task/models/task-details-cloud.model.ts)`>` - Updated task details
## Details ## Details

View File

@ -15,15 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { NgModule } from '@angular/core';
import { AppDetailsCloudComponent } from './components/app-details-cloud/app-details-cloud.component'; import { AppDetailsCloudComponent } from './components/app-details-cloud/app-details-cloud.component';
import { AppListCloudComponent } from './components/app-list-cloud/app-list-cloud.component'; import { AppListCloudComponent } from './components/app-list-cloud/app-list-cloud.component';
export const APP_LIST_CLOUD_DIRECTIVES = [AppListCloudComponent, AppDetailsCloudComponent] as const; export const APP_LIST_CLOUD_DIRECTIVES = [AppListCloudComponent, AppDetailsCloudComponent] as const;
/** @deprecated use `...APP_LIST_CLOUD_DIRECTIVES` instead */
@NgModule({
imports: [...APP_LIST_CLOUD_DIRECTIVES],
exports: [...APP_LIST_CLOUD_DIRECTIVES]
})
export class AppListCloudModule {}

View File

@ -37,7 +37,7 @@ describe('DateRangeFilterComponent', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ProcessServiceCloudTestingModule] imports: [ProcessServiceCloudTestingModule, DateRangeFilterComponent]
}); });
fixture = TestBed.createComponent(DateRangeFilterComponent); fixture = TestBed.createComponent(DateRangeFilterComponent);
component = fixture.componentInstance; component = fixture.componentInstance;

View File

@ -18,7 +18,6 @@
import { applicationConfig, Meta, moduleMetadata, StoryFn } from '@storybook/angular'; import { applicationConfig, Meta, moduleMetadata, StoryFn } from '@storybook/angular';
import { ProcessServicesCloudStoryModule } from '../../testing/process-services-cloud-story.module'; import { ProcessServicesCloudStoryModule } from '../../testing/process-services-cloud-story.module';
import { mockFilterProperty } from '../mock/date-range-filter.mock'; import { mockFilterProperty } from '../mock/date-range-filter.mock';
import { ProcessCommonModule } from '../process-common.module';
import { DateRangeFilterComponent } from './date-range-filter.component'; import { DateRangeFilterComponent } from './date-range-filter.component';
import { importProvidersFrom } from '@angular/core'; import { importProvidersFrom } from '@angular/core';
@ -27,7 +26,7 @@ export default {
title: 'Process Services Cloud/Process Common/Date Range Filter', title: 'Process Services Cloud/Process Common/Date Range Filter',
decorators: [ decorators: [
moduleMetadata({ moduleMetadata({
imports: [ProcessCommonModule] imports: [DateRangeFilterComponent]
}), }),
applicationConfig({ applicationConfig({
providers: [importProvidersFrom(ProcessServicesCloudStoryModule)] providers: [importProvidersFrom(ProcessServicesCloudStoryModule)]

View File

@ -16,13 +16,17 @@
*/ */
import { Component, Input, EventEmitter, Output, OnInit } from '@angular/core'; import { Component, Input, EventEmitter, Output, OnInit } from '@angular/core';
import { MatSelectChange } from '@angular/material/select'; import { MatSelectChange, MatSelectModule } from '@angular/material/select';
import { ProcessFilterProperties, ProcessFilterOptions } from '../../process/process-filters/models/process-filter-cloud.model'; import { ProcessFilterProperties, ProcessFilterOptions } from '../../process/process-filters/models/process-filter-cloud.model';
import { FormGroup, FormControl } from '@angular/forms'; import { FormGroup, FormControl, ReactiveFormsModule } from '@angular/forms';
import { DateRangeFilter, DateCloudFilterType } from '../../models/date-cloud-filter.model'; import { DateRangeFilter, DateCloudFilterType } from '../../models/date-cloud-filter.model';
import { endOfDay, isValid, startOfDay } from 'date-fns'; import { endOfDay, isValid, startOfDay } from 'date-fns';
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core'; import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
import { ADF_DATE_FORMATS, AdfDateFnsAdapter } from '@alfresco/adf-core'; import { ADF_DATE_FORMATS, AdfDateFnsAdapter } from '@alfresco/adf-core';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatFormFieldModule } from '@angular/material/form-field';
interface DateRangeFormProps { interface DateRangeFormProps {
from: FormControl<Date>; from: FormControl<Date>;
@ -31,6 +35,8 @@ interface DateRangeFormProps {
@Component({ @Component({
selector: 'adf-cloud-date-range-filter', selector: 'adf-cloud-date-range-filter',
standalone: true,
imports: [CommonModule, TranslateModule, MatDatepickerModule, MatFormFieldModule, ReactiveFormsModule, MatSelectModule],
styleUrls: ['./date-range-filter.component.scss'], styleUrls: ['./date-range-filter.component.scss'],
templateUrl: './date-range-filter.component.html', templateUrl: './date-range-filter.component.html',
providers: [ providers: [

View File

@ -1,32 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { CoreModule } from '@alfresco/adf-core';
import { DateRangeFilterComponent } from './date-range-filter/date-range-filter.component';
import { MaterialModule } from '../material.module';
import { CommonModule } from '@angular/common';
import { DateRangeFilterService } from './date-range-filter/date-range-filter.service';
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
declarations: [DateRangeFilterComponent],
imports: [CommonModule, CoreModule, MaterialModule, ReactiveFormsModule],
exports: [DateRangeFilterComponent],
providers: [DateRangeFilterService]
})
export class ProcessCommonModule {}

View File

@ -52,7 +52,7 @@ import {
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { FormCloudService } from '../services/form-cloud.service'; import { FormCloudService } from '../services/form-cloud.service';
import { TaskVariableCloud } from '../models/task-variable-cloud.model'; import { TaskVariableCloud } from '../models/task-variable-cloud.model';
import { TaskDetailsCloudModel } from '../../task/start-task/models/task-details-cloud.model'; import { TaskDetailsCloudModel } from '../../task/models/task-details-cloud.model';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { v4 as uuidGeneration } from 'uuid'; import { v4 as uuidGeneration } from 'uuid';
import { FormCloudDisplayMode, FormCloudDisplayModeConfiguration } from '../../services/form-fields.interfaces'; import { FormCloudDisplayMode, FormCloudDisplayModeConfiguration } from '../../services/form-fields.interfaces';

View File

@ -24,14 +24,14 @@ import { IdentityGroupModel } from '../../../../group/models/identity-group.mode
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { GroupCloudModule } from '../../../../group/group-cloud.module'; import { GroupCloudComponent } from '../../../../group/components/group-cloud.component';
/* eslint-disable @angular-eslint/component-selector */ /* eslint-disable @angular-eslint/component-selector */
@Component({ @Component({
selector: 'group-cloud-widget', selector: 'group-cloud-widget',
standalone: true, standalone: true,
imports: [CommonModule, TranslateModule, ErrorWidgetComponent, GroupCloudModule], imports: [CommonModule, TranslateModule, ErrorWidgetComponent, GroupCloudComponent],
templateUrl: './group-cloud.widget.html', templateUrl: './group-cloud.widget.html',
host: { host: {
'(click)': 'event($event)', '(click)': 'event($event)',

View File

@ -25,14 +25,14 @@ import { IdentityUserService } from '../../../../people/services/identity-user.s
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { PeopleCloudModule } from '../../../../people/people-cloud.module'; import { PeopleCloudComponent } from '../../../../people/components/people-cloud.component';
/* eslint-disable @angular-eslint/component-selector */ /* eslint-disable @angular-eslint/component-selector */
@Component({ @Component({
selector: 'people-cloud-widget', selector: 'people-cloud-widget',
standalone: true, standalone: true,
imports: [CommonModule, TranslateModule, ErrorWidgetComponent, PeopleCloudModule], imports: [CommonModule, TranslateModule, ErrorWidgetComponent, PeopleCloudComponent],
templateUrl: './people-cloud.widget.html', templateUrl: './people-cloud.widget.html',
host: { host: {
'(click)': 'event($event)', '(click)': 'event($event)',

View File

@ -17,19 +17,26 @@
import { UploadApi } from '@alfresco/js-api'; import { UploadApi } from '@alfresco/js-api';
import { FormFieldOption, FormModel, FormValues } from '@alfresco/adf-core'; import { FormFieldOption, FormModel, FormValues } from '@alfresco/adf-core';
import { TaskDetailsCloudModel } from '../../task/start-task/models/task-details-cloud.model'; import { TaskDetailsCloudModel } from '../../task/models/task-details-cloud.model';
import { TaskVariableCloud } from '../models/task-variable-cloud.model'; import { TaskVariableCloud } from '../models/task-variable-cloud.model';
import { FormContent } from '../../services/form-fields.interfaces'; import { FormContent } from '../../services/form-fields.interfaces';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
export interface FormCloudServiceInterface { export interface FormCloudServiceInterface {
uploadApi: UploadApi; uploadApi: UploadApi;
getTaskForm(appName: string, taskId: string, version?: number): Observable<any>; getTaskForm(appName: string, taskId: string, version?: number): Observable<any>;
saveTaskForm(appName: string, taskId: string, processInstanceId: string, formId: string, values: FormValues): Observable<TaskDetailsCloudModel>; saveTaskForm(appName: string, taskId: string, processInstanceId: string, formId: string, values: FormValues): Observable<TaskDetailsCloudModel>;
createTemporaryRawRelatedContent(file: any, nodeId: string, contentHost: string): Observable<any>; createTemporaryRawRelatedContent(file: any, nodeId: string, contentHost: string): Observable<any>;
completeTaskForm(appName: string, taskId: string, processInstanceId: string, formId: string, formValues: FormValues, outcome: string, version: number): Observable<TaskDetailsCloudModel>; completeTaskForm(
appName: string,
taskId: string,
processInstanceId: string,
formId: string,
formValues: FormValues,
outcome: string,
version: number
): Observable<TaskDetailsCloudModel>;
getTask(appName: string, taskId: string): Observable<TaskDetailsCloudModel>; getTask(appName: string, taskId: string): Observable<TaskDetailsCloudModel>;
getTaskVariables(appName: string, taskId: string): Observable<TaskVariableCloud[]>; getTaskVariables(appName: string, taskId: string): Observable<TaskVariableCloud[]>;
getForm(appName: string, formKey: string, version?: number): Observable<FormContent>; getForm(appName: string, formKey: string, version?: number): Observable<FormContent>;

View File

@ -19,7 +19,7 @@ import { Injectable } from '@angular/core';
import { FormValues, FormModel, FormFieldOption } from '@alfresco/adf-core'; import { FormValues, FormModel, FormFieldOption } from '@alfresco/adf-core';
import { Observable, from, EMPTY } from 'rxjs'; import { Observable, from, EMPTY } from 'rxjs';
import { expand, map, reduce, switchMap } from 'rxjs/operators'; import { expand, map, reduce, switchMap } from 'rxjs/operators';
import { TaskDetailsCloudModel } from '../../task/start-task/models/task-details-cloud.model'; import { TaskDetailsCloudModel } from '../../task/models/task-details-cloud.model';
import { CompleteFormRepresentation, UploadApi } from '@alfresco/js-api'; import { CompleteFormRepresentation, UploadApi } from '@alfresco/js-api';
import { TaskVariableCloud } from '../models/task-variable-cloud.model'; import { TaskVariableCloud } from '../models/task-variable-cloud.model';
import { BaseCloudService } from '../../services/base-cloud.service'; import { BaseCloudService } from '../../services/base-cloud.service';
@ -31,16 +31,13 @@ import { AdfHttpClient } from '@alfresco/adf-core/api';
providedIn: 'root' providedIn: 'root'
}) })
export class FormCloudService extends BaseCloudService implements FormCloudServiceInterface { export class FormCloudService extends BaseCloudService implements FormCloudServiceInterface {
private _uploadApi: UploadApi; private _uploadApi: UploadApi;
get uploadApi(): UploadApi { get uploadApi(): UploadApi {
this._uploadApi = this._uploadApi ?? new UploadApi(this.apiService.getInstance()); this._uploadApi = this._uploadApi ?? new UploadApi(this.apiService.getInstance());
return this._uploadApi; return this._uploadApi;
} }
constructor( constructor(adfHttpClient: AdfHttpClient) {
adfHttpClient: AdfHttpClient
) {
super(adfHttpClient); super(adfHttpClient);
} }
@ -54,20 +51,22 @@ export class FormCloudService extends BaseCloudService implements FormCloudServi
*/ */
getTaskForm(appName: string, taskId: string, version?: number): Observable<any> { getTaskForm(appName: string, taskId: string, version?: number): Observable<any> {
return this.getTask(appName, taskId).pipe( return this.getTask(appName, taskId).pipe(
switchMap(task => this.getForm(appName, task.formKey, version).pipe( switchMap((task) =>
map((form: FormContent) => { this.getForm(appName, task.formKey, version).pipe(
const flattenForm = { map((form: FormContent) => {
...form.formRepresentation, const flattenForm = {
...form.formRepresentation.formDefinition, ...form.formRepresentation,
taskId: task.id, ...form.formRepresentation.formDefinition,
taskName: task.name, taskId: task.id,
processDefinitionId: task.processDefinitionId, taskName: task.name,
processInstanceId: task.processInstanceId processDefinitionId: task.processDefinitionId,
}; processInstanceId: task.processInstanceId
delete flattenForm.formDefinition; };
return flattenForm; delete flattenForm.formDefinition;
}) return flattenForm;
)) })
)
)
); );
} }
@ -89,26 +88,15 @@ export class FormCloudService extends BaseCloudService implements FormCloudServi
processInstanceId processInstanceId
}; };
return this.post(apiUrl, saveFormRepresentation).pipe( return this.post(apiUrl, saveFormRepresentation).pipe(map((res: any) => res.entry));
map((res: any) => res.entry)
);
} }
createTemporaryRawRelatedContent(file: any, nodeId: string, contentHost: string): Observable<any> { createTemporaryRawRelatedContent(file: any, nodeId: string, contentHost: string): Observable<any> {
const changedConfig = this.apiService.lastConfig; const changedConfig = this.apiService.lastConfig;
changedConfig.provider = 'ALL'; changedConfig.provider = 'ALL';
changedConfig.hostEcm = contentHost.replace('/alfresco', ''); changedConfig.hostEcm = contentHost.replace('/alfresco', '');
this.apiService.getInstance().setConfig(changedConfig); this.apiService.getInstance().setConfig(changedConfig);
return from(this.uploadApi.uploadFile( return from(this.uploadApi.uploadFile(file, '', nodeId, null, { overwrite: true })).pipe(map((res: any) => res.entry));
file,
'',
nodeId,
null,
{ overwrite: true }
)).pipe(
map((res: any) => res.entry)
);
} }
/** /**
@ -123,7 +111,15 @@ export class FormCloudService extends BaseCloudService implements FormCloudServi
* @param version of the form * @param version of the form
* @returns Updated task details * @returns Updated task details
*/ */
completeTaskForm(appName: string, taskId: string, processInstanceId: string, formId: string, formValues: FormValues, outcome: string, version: number): Observable<TaskDetailsCloudModel> { completeTaskForm(
appName: string,
taskId: string,
processInstanceId: string,
formId: string,
formValues: FormValues,
outcome: string,
version: number
): Observable<TaskDetailsCloudModel> {
const apiUrl = `${this.getBasePath(appName)}/form/v1/forms/${formId}/submit/versions/${version}`; const apiUrl = `${this.getBasePath(appName)}/form/v1/forms/${formId}/submit/versions/${version}`;
const completeFormRepresentation = { const completeFormRepresentation = {
values: formValues, values: formValues,
@ -135,9 +131,7 @@ export class FormCloudService extends BaseCloudService implements FormCloudServi
completeFormRepresentation.outcome = outcome; completeFormRepresentation.outcome = outcome;
} }
return this.post(apiUrl, completeFormRepresentation).pipe( return this.post(apiUrl, completeFormRepresentation).pipe(map((res: any) => res.entry));
map((res: any) => res.entry)
);
} }
/** /**
@ -150,9 +144,7 @@ export class FormCloudService extends BaseCloudService implements FormCloudServi
getTask(appName: string, taskId: string): Observable<TaskDetailsCloudModel> { getTask(appName: string, taskId: string): Observable<TaskDetailsCloudModel> {
const apiUrl = `${this.getBasePath(appName)}/query/v1/tasks/${taskId}`; const apiUrl = `${this.getBasePath(appName)}/query/v1/tasks/${taskId}`;
return this.get(apiUrl).pipe( return this.get(apiUrl).pipe(map((res: any) => res.entry));
map((res: any) => res.entry)
);
} }
/** /**
@ -170,10 +162,12 @@ export class FormCloudService extends BaseCloudService implements FormCloudServi
return this.get(apiUrl, { maxItems, skipCount }).pipe( return this.get(apiUrl, { maxItems, skipCount }).pipe(
expand((res: any) => { expand((res: any) => {
skipCount += maxItems; skipCount += maxItems;
return res.list.pagination.hasMoreItems ? this.get(apiUrl, { return res.list.pagination.hasMoreItems
maxItems, ? this.get(apiUrl, {
skipCount maxItems,
}) : EMPTY; skipCount
})
: EMPTY;
}), }),
map((res: any) => res.list.entries.map((variable) => new TaskVariableCloud(variable.entry))), map((res: any) => res.list.entries.map((variable) => new TaskVariableCloud(variable.entry))),
reduce((acc, res) => acc.concat(res), []) reduce((acc, res) => acc.concat(res), [])
@ -221,7 +215,7 @@ export class FormCloudService extends BaseCloudService implements FormCloudServi
delete flattenForm.formDefinition; delete flattenForm.formDefinition;
const formValues: FormValues = {}; const formValues: FormValues = {};
(data || []).forEach(variable => { (data || []).forEach((variable) => {
formValues[variable.name] = variable.value; formValues[variable.name] = variable.value;
}); });

View File

@ -43,7 +43,7 @@
class="adf-cloud-group-row" class="adf-cloud-group-row"
id="adf-group-{{i}}" id="adf-group-{{i}}"
data-automation-id="adf-cloud-group-row"> data-automation-id="adf-cloud-group-row">
<button class="adf-group-short-name" mat-fab>{{group | groupNameInitial }}</button> <button class="adf-group-short-name" mat-fab>{{getGroupNameInitials(group)}}</button>
<span>{{group.name}}</span> <span>{{group.name}}</span>
</div> </div>
</mat-option> </mat-option>

View File

@ -18,7 +18,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { of } from 'rxjs'; import { of } from 'rxjs';
import { GroupCloudModule } from '../group-cloud.module';
import { GroupCloudComponent } from './group-cloud.component'; import { GroupCloudComponent } from './group-cloud.component';
import { CoreTestingModule } from '@alfresco/adf-core'; import { CoreTestingModule } from '@alfresco/adf-core';
import { DebugElement, SimpleChange } from '@angular/core'; import { DebugElement, SimpleChange } from '@angular/core';
@ -72,7 +71,7 @@ describe('GroupCloudComponent', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [CoreTestingModule, GroupCloudModule] imports: [CoreTestingModule, GroupCloudComponent]
}); });
fixture = TestBed.createComponent(GroupCloudComponent); fixture = TestBed.createComponent(GroupCloudComponent);
component = fixture.componentInstance; component = fixture.componentInstance;

View File

@ -16,7 +16,6 @@
*/ */
import { applicationConfig, Meta, moduleMetadata, StoryFn } from '@storybook/angular'; import { applicationConfig, Meta, moduleMetadata, StoryFn } from '@storybook/angular';
import { GroupCloudModule } from '../group-cloud.module';
import { GroupCloudComponent } from './group-cloud.component'; import { GroupCloudComponent } from './group-cloud.component';
import { ProcessServicesCloudStoryModule } from '../../testing/process-services-cloud-story.module'; import { ProcessServicesCloudStoryModule } from '../../testing/process-services-cloud-story.module';
import { IdentityGroupService } from '../services/identity-group.service'; import { IdentityGroupService } from '../services/identity-group.service';
@ -28,13 +27,10 @@ export default {
title: 'Process Services Cloud/Group Cloud/Group Cloud', title: 'Process Services Cloud/Group Cloud/Group Cloud',
decorators: [ decorators: [
moduleMetadata({ moduleMetadata({
imports: [GroupCloudModule] imports: [GroupCloudComponent]
}), }),
applicationConfig({ applicationConfig({
providers: [ providers: [{ provide: IdentityGroupService, useClass: IdentityGroupServiceMock }, importProvidersFrom(ProcessServicesCloudStoryModule)]
{ provide: IdentityGroupService, useClass: IdentityGroupServiceMock },
importProvidersFrom(ProcessServicesCloudStoryModule)
]
}) })
], ],
argTypes: { argTypes: {
@ -102,7 +98,7 @@ export default {
description: 'FormControl to list of group.', description: 'FormControl to list of group.',
table: { table: {
type: { summary: 'FormControl' }, type: { summary: 'FormControl' },
defaultValue: { summary: 'new FormControl({ value: \'\', disabled: false })' }, defaultValue: { summary: "new FormControl({ value: '', disabled: false })" },
category: 'Form Controls' category: 'Form Controls'
} }
}, },
@ -111,7 +107,7 @@ export default {
description: 'FormControl to search the group.', description: 'FormControl to search the group.',
table: { table: {
type: { summary: 'FormControl' }, type: { summary: 'FormControl' },
defaultValue: { summary: 'new FormControl({ value: \'\', disabled: false })' }, defaultValue: { summary: "new FormControl({ value: '', disabled: false })" },
category: 'Form Controls' category: 'Form Controls'
} }
}, },

View File

@ -20,7 +20,6 @@ import {
DestroyRef, DestroyRef,
ElementRef, ElementRef,
EventEmitter, EventEmitter,
Inject,
inject, inject,
Input, Input,
OnChanges, OnChanges,
@ -30,18 +29,41 @@ import {
ViewChild, ViewChild,
ViewEncapsulation ViewEncapsulation
} from '@angular/core'; } from '@angular/core';
import { UntypedFormControl } from '@angular/forms'; import { ReactiveFormsModule, UntypedFormControl } from '@angular/forms';
import { animate, state, style, transition, trigger } from '@angular/animations'; import { animate, state, style, transition, trigger } from '@angular/animations';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, mergeMap, switchMap, tap } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, filter, mergeMap, switchMap, tap } from 'rxjs/operators';
import { ComponentSelectionMode } from '../../types'; import { ComponentSelectionMode } from '../../types';
import { IdentityGroupModel } from '../models/identity-group.model'; import { IdentityGroupModel } from '../models/identity-group.model';
import { IdentityGroupServiceInterface } from '../services/identity-group.service.interface';
import { IDENTITY_GROUP_SERVICE_TOKEN } from '../services/identity-group-service.token';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatIconModule } from '@angular/material/icon';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatSelectModule } from '@angular/material/select';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatButtonModule } from '@angular/material/button';
import { MatInputModule } from '@angular/material/input';
import { MatChipsModule } from '@angular/material/chips';
import { IdentityGroupService } from '../services/identity-group.service';
@Component({ @Component({
selector: 'adf-cloud-group', selector: 'adf-cloud-group',
standalone: true,
imports: [
CommonModule,
TranslateModule,
MatIconModule,
MatFormFieldModule,
MatProgressBarModule,
MatSelectModule,
MatAutocompleteModule,
MatButtonModule,
ReactiveFormsModule,
MatInputModule,
MatChipsModule
],
templateUrl: './group-cloud.component.html', templateUrl: './group-cloud.component.html',
styleUrls: ['./group-cloud.component.scss'], styleUrls: ['./group-cloud.component.scss'],
animations: [ animations: [
@ -140,10 +162,7 @@ export class GroupCloudComponent implements OnInit, OnChanges {
private readonly destroyRef = inject(DestroyRef); private readonly destroyRef = inject(DestroyRef);
constructor( constructor(private identityGroupService: IdentityGroupService) {}
@Inject(IDENTITY_GROUP_SERVICE_TOKEN)
private identityGroupService: IdentityGroupServiceInterface
) {}
ngOnInit(): void { ngOnInit(): void {
this.initSearch(); this.initSearch();
@ -470,4 +489,13 @@ export class GroupCloudComponent implements OnInit, OnChanges {
getValidationMinLength(): string { getValidationMinLength(): string {
return this.searchGroupsControl.errors.minlength.requiredLength; return this.searchGroupsControl.errors.minlength.requiredLength;
} }
getGroupNameInitials(group: IdentityGroupModel): string {
let result = '';
if (group) {
const groupName = group.name;
result = (groupName ? groupName[0] : '').toUpperCase();
}
return result;
}
} }

View File

@ -16,21 +16,11 @@
*/ */
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { CoreModule } from '@alfresco/adf-core';
import { MaterialModule } from '../material.module';
import { GroupCloudComponent } from './components/group-cloud.component'; import { GroupCloudComponent } from './components/group-cloud.component';
import { InitialGroupNamePipe } from './pipe/group-initial.pipe';
import { IDENTITY_GROUP_SERVICE_TOKEN } from './services/identity-group-service.token';
import { IdentityGroupService } from './services/identity-group.service';
import { MatProgressBarModule } from '@angular/material/progress-bar';
/** @deprecated use GroupCloudComponent instead */
@NgModule({ @NgModule({
imports: [CommonModule, MaterialModule, FormsModule, ReactiveFormsModule, CoreModule, MatProgressBarModule], imports: [GroupCloudComponent],
declarations: [GroupCloudComponent, InitialGroupNamePipe], exports: [GroupCloudComponent]
providers: [{ provide: IDENTITY_GROUP_SERVICE_TOKEN, useExisting: IdentityGroupService }],
exports: [GroupCloudComponent, InitialGroupNamePipe]
}) })
export class GroupCloudModule {} export class GroupCloudModule {}

View File

@ -18,30 +18,20 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, EMPTY, of } from 'rxjs'; import { Observable, EMPTY, of } from 'rxjs';
import { IdentityGroupModel } from '../models/identity-group.model'; import { IdentityGroupModel } from '../models/identity-group.model';
import { IdentityGroupFilterInterface } from '../services/identity-group-filter.interface'; import { IdentityGroupService } from '@alfresco/adf-process-services-cloud';
import { IdentityGroupServiceInterface } from '../services/identity-group.service.interface';
export const mockVegetableAubergine: IdentityGroupModel = { id: 'aubergine', name: 'Vegetable Aubergine'}; export const mockVegetableAubergine: IdentityGroupModel = { id: 'aubergine', name: 'Vegetable Aubergine' };
export const mockMeatChicken: IdentityGroupModel = { id: 'chicken', name: 'Meat Chicken'}; export const mockMeatChicken: IdentityGroupModel = { id: 'chicken', name: 'Meat Chicken' };
export const mockFoodGroups = [ mockVegetableAubergine, mockMeatChicken ]; export const mockFoodGroups = [mockVegetableAubergine, mockMeatChicken];
export const mockSearchGroupEmptyFilters: IdentityGroupFilterInterface = { @Injectable()
roles: [], export class IdentityGroupServiceMock extends IdentityGroupService {
withinApplication: '' search(name: string): Observable<IdentityGroupModel[]> {
};
@Injectable({
providedIn: 'root'
})
export class IdentityGroupServiceMock implements IdentityGroupServiceInterface {
search(name: string, _filters?: IdentityGroupFilterInterface): Observable<IdentityGroupModel[]> {
if (name.trim() === '') { if (name.trim() === '') {
return EMPTY; return EMPTY;
} }
return of(mockFoodGroups.filter(group => return of(mockFoodGroups.filter((group) => group.name.toUpperCase().includes(name.toUpperCase())));
group.name.toUpperCase().includes(name.toUpperCase())
));
} }
} }

View File

@ -1,39 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { HttpErrorResponse } from '@angular/common/http';
import { IdentityGroupFilterInterface } from '../services/identity-group-filter.interface';
export const mockSearchGroupByRoles: IdentityGroupFilterInterface = {
roles: ['fake-role-1', 'fake-role-2'],
withinApplication: ''
};
export const mockSearchGroupByRolesAndApp: IdentityGroupFilterInterface = {
roles: ['fake-role-1', 'fake-role-2'],
withinApplication: 'fake-app-name'
};
export const mockSearchGroupByApp: IdentityGroupFilterInterface = {
roles: [],
withinApplication: 'fake-app-name'
};
export const mockHttpErrorResponse = new HttpErrorResponse({
error: 'Mock Error',
status: 404, statusText: 'Not Found'
});

View File

@ -1,41 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { IdentityGroupModel } from '../models/identity-group.model';
import { InitialGroupNamePipe } from './group-initial.pipe';
describe('InitialGroupNamePipe', () => {
let pipe: InitialGroupNamePipe;
let fakeGroup: IdentityGroupModel;
beforeEach(() => {
pipe = new InitialGroupNamePipe();
fakeGroup = {name: 'mock'};
});
it('should return with the group initial', () => {
fakeGroup.name = 'FAKE-GROUP-NAME';
const result = pipe.transform(fakeGroup);
expect(result).toBe('F');
});
it('should return an empty string when group is null', () => {
const result = pipe.transform(null);
expect(result).toBe('');
});
});

View File

@ -1,38 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { Pipe, PipeTransform } from '@angular/core';
import { IdentityGroupModel } from '../models/identity-group.model';
@Pipe({
name: 'groupNameInitial'
})
export class InitialGroupNamePipe implements PipeTransform {
transform(group: IdentityGroupModel): string {
let result = '';
if (group) {
result = this.getInitialGroupName(group.name).toUpperCase();
}
return result;
}
getInitialGroupName(groupName: string) {
groupName = (groupName ? groupName[0] : '');
return groupName;
}
}

View File

@ -16,8 +16,6 @@
*/ */
export * from './components/group-cloud.component'; export * from './components/group-cloud.component';
export * from './pipe/group-initial.pipe';
export * from './models/identity-group.model'; export * from './models/identity-group.model';
export * from './group-cloud.module'; export * from './group-cloud.module';
export * from './services/identity-group.service'; export * from './services/identity-group.service';
export * from './services/identity-group-service.token';

View File

@ -1,21 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 interface IdentityGroupFilterInterface {
roles?: string[];
withinApplication?: string;
}

View File

@ -1,21 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { InjectionToken } from '@angular/core';
import { IdentityGroupServiceInterface } from './identity-group.service.interface';
export const IDENTITY_GROUP_SERVICE_TOKEN = new InjectionToken<IdentityGroupServiceInterface>('IdentityGroup');

View File

@ -1,24 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { Observable } from 'rxjs';
import { IdentityGroupModel } from '../models/identity-group.model';
import { IdentityGroupFilterInterface } from './identity-group-filter.interface';
export interface IdentityGroupServiceInterface {
search(name: string, filters?: IdentityGroupFilterInterface): Observable<IdentityGroupModel[]>;
}

View File

@ -18,15 +18,16 @@
import { TestBed } from '@angular/core/testing'; import { TestBed } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { IdentityGroupService } from './identity-group.service'; import { IdentityGroupService } from './identity-group.service';
import {
mockHttpErrorResponse,
mockSearchGroupByApp,
mockSearchGroupByRoles,
mockSearchGroupByRolesAndApp
} from '../mock/identity-group.service.mock';
import { mockFoodGroups } from '../mock/group-cloud.mock'; import { mockFoodGroups } from '../mock/group-cloud.mock';
import { AdfHttpClient } from '@alfresco/adf-core/api'; import { AdfHttpClient } from '@alfresco/adf-core/api';
import { HttpClientTestingModule } from '@angular/common/http/testing'; import { HttpClientTestingModule } from '@angular/common/http/testing';
import { HttpErrorResponse } from '@angular/common/http';
const mockHttpErrorResponse = new HttpErrorResponse({
error: 'Mock Error',
status: 404,
statusText: 'Not Found'
});
describe('IdentityGroupService', () => { describe('IdentityGroupService', () => {
let service: IdentityGroupService; let service: IdentityGroupService;
@ -81,86 +82,111 @@ describe('IdentityGroupService', () => {
requestSpy.and.returnValue(Promise.resolve(mockFoodGroups)); requestSpy.and.returnValue(Promise.resolve(mockFoodGroups));
const searchSpy = spyOn(service, 'search').and.callThrough(); const searchSpy = spyOn(service, 'search').and.callThrough();
service.search('fake', mockSearchGroupByRoles).subscribe((res) => { service
expect(res).toBeDefined(); .search('fake', {
expect(searchSpy).toHaveBeenCalled(); roles: ['fake-role-1', 'fake-role-2'],
expect(service.queryParams).toEqual({ withinApplication: ''
search: 'fake', })
role: 'fake-role-1,fake-role-2' .subscribe((res) => {
expect(res).toBeDefined();
expect(searchSpy).toHaveBeenCalled();
expect(service.queryParams).toEqual({
search: 'fake',
role: 'fake-role-1,fake-role-2'
});
done();
}); });
done();
});
}); });
it('should not fetch groups by roles if error occurred', (done) => { it('should not fetch groups by roles if error occurred', (done) => {
requestSpy.and.returnValue(Promise.reject(mockHttpErrorResponse)); requestSpy.and.returnValue(Promise.reject(mockHttpErrorResponse));
const searchSpy = spyOn(service, 'search').and.callThrough(); const searchSpy = spyOn(service, 'search').and.callThrough();
service.search('fake', mockSearchGroupByRoles).subscribe( service
() => { .search('fake', {
fail('expected an error, not groups'); roles: ['fake-role-1', 'fake-role-2'],
}, withinApplication: ''
(error) => { })
expect(searchSpy).toHaveBeenCalled(); .subscribe(
expect(service.queryParams).toEqual({ () => {
search: 'fake', fail('expected an error, not groups');
role: 'fake-role-1,fake-role-2' },
}); (error) => {
expect(error.status).toEqual(404); expect(searchSpy).toHaveBeenCalled();
expect(error.statusText).toEqual('Not Found'); expect(service.queryParams).toEqual({
expect(error.error).toEqual('Mock Error'); search: 'fake',
done(); role: 'fake-role-1,fake-role-2'
} });
); expect(error.status).toEqual(404);
expect(error.statusText).toEqual('Not Found');
expect(error.error).toEqual('Mock Error');
done();
}
);
}); });
it('should fetch groups within app', (done) => { it('should fetch groups within app', (done) => {
requestSpy.and.returnValue(Promise.resolve(mockFoodGroups)); requestSpy.and.returnValue(Promise.resolve(mockFoodGroups));
service.search('fake', mockSearchGroupByApp).subscribe((res) => { service
expect(res).toBeDefined(); .search('fake', {
expect(service.queryParams).toEqual({ roles: [],
search: 'fake', withinApplication: 'fake-app-name'
application: 'fake-app-name' })
.subscribe((res) => {
expect(res).toBeDefined();
expect(service.queryParams).toEqual({
search: 'fake',
application: 'fake-app-name'
});
done();
}); });
done();
});
}); });
it('should fetch groups within app with roles', (done) => { it('should fetch groups within app with roles', (done) => {
requestSpy.and.returnValue(Promise.resolve(mockFoodGroups)); requestSpy.and.returnValue(Promise.resolve(mockFoodGroups));
service.search('fake', mockSearchGroupByRolesAndApp).subscribe((res) => { service
expect(res).toBeDefined(); .search('fake', {
expect(service.queryParams).toEqual({ roles: ['fake-role-1', 'fake-role-2'],
search: 'fake', withinApplication: 'fake-app-name'
application: 'fake-app-name', })
role: 'fake-role-1,fake-role-2' .subscribe((res) => {
expect(res).toBeDefined();
expect(service.queryParams).toEqual({
search: 'fake',
application: 'fake-app-name',
role: 'fake-role-1,fake-role-2'
});
done();
}); });
done();
});
}); });
it('should not fetch groups within app if error occurred', (done) => { it('should not fetch groups within app if error occurred', (done) => {
requestSpy.and.returnValue(Promise.reject(mockHttpErrorResponse)); requestSpy.and.returnValue(Promise.reject(mockHttpErrorResponse));
const searchSpy = spyOn(service, 'search').and.callThrough(); const searchSpy = spyOn(service, 'search').and.callThrough();
service.search('fake', mockSearchGroupByApp).subscribe( service
() => { .search('fake', {
fail('expected an error, not groups'); roles: [],
}, withinApplication: 'fake-app-name'
(error) => { })
expect(searchSpy).toHaveBeenCalled(); .subscribe(
expect(service.queryParams).toEqual({ () => {
search: 'fake', fail('expected an error, not groups');
application: 'fake-app-name' },
}); (error) => {
expect(error.status).toEqual(404); expect(searchSpy).toHaveBeenCalled();
expect(error.statusText).toEqual('Not Found'); expect(service.queryParams).toEqual({
expect(error.error).toEqual('Mock Error'); search: 'fake',
done(); application: 'fake-app-name'
} });
); expect(error.status).toEqual(404);
expect(error.statusText).toEqual('Not Found');
expect(error.error).toEqual('Mock Error');
done();
}
);
}); });
}); });
}); });

View File

@ -18,21 +18,20 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { AppConfigService, OAuth2Service } from '@alfresco/adf-core'; import { AppConfigService, OAuth2Service } from '@alfresco/adf-core';
import { EMPTY, Observable } from 'rxjs'; import { EMPTY, Observable } from 'rxjs';
import { IdentityGroupServiceInterface } from './identity-group.service.interface';
import { IdentityGroupFilterInterface } from './identity-group-filter.interface';
import { IdentityGroupModel } from '../models/identity-group.model'; import { IdentityGroupModel } from '../models/identity-group.model';
const IDENTITY_MICRO_SERVICE_INGRESS = 'identity-adapter-service'; const IDENTITY_MICRO_SERVICE_INGRESS = 'identity-adapter-service';
export interface IdentityGroupFilterInterface {
roles?: string[];
withinApplication?: string;
}
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class IdentityGroupService implements IdentityGroupServiceInterface { export class IdentityGroupService {
queryParams: { search: string; application?: string; roles?: string[] };
queryParams: { search: string; application?: string; roles?: string [] }; constructor(private oAuth2Service: OAuth2Service, private appConfigService: AppConfigService) {}
constructor(
private oAuth2Service: OAuth2Service,
private appConfigService: AppConfigService
) {}
public search(name: string, filters?: IdentityGroupFilterInterface): Observable<IdentityGroupModel[]> { public search(name: string, filters?: IdentityGroupFilterInterface): Observable<IdentityGroupModel[]> {
if (name.trim() === '') { if (name.trim() === '') {
@ -52,13 +51,13 @@ export class IdentityGroupService implements IdentityGroupServiceInterface {
return this.invokeIdentityGroupApi(); return this.invokeIdentityGroupApi();
} }
private searchGroupsWithGlobalRoles(name: string, roles: string []): Observable<IdentityGroupModel[]> { private searchGroupsWithGlobalRoles(name: string, roles: string[]): Observable<IdentityGroupModel[]> {
this.buildQueryParam(name, roles); this.buildQueryParam(name, roles);
return this.invokeIdentityGroupApi(); return this.invokeIdentityGroupApi();
} }
private searchGroupsWithinApp(name: string, applicationName: string, roles?: string []): Observable<IdentityGroupModel[]> { private searchGroupsWithinApp(name: string, applicationName: string, roles?: string[]): Observable<IdentityGroupModel[]> {
this.buildQueryParam(name, roles, applicationName); this.buildQueryParam(name, roles, applicationName);
return this.invokeIdentityGroupApi(); return this.invokeIdentityGroupApi();
@ -69,13 +68,13 @@ export class IdentityGroupService implements IdentityGroupServiceInterface {
return this.oAuth2Service.get({ url, queryParams: this.queryParams }); return this.oAuth2Service.get({ url, queryParams: this.queryParams });
} }
private buildQueryParam(name: string, roles?: string [], applicationName?: string) { private buildQueryParam(name: string, roles?: string[], applicationName?: string) {
this.queryParams = { search: name }; this.queryParams = { search: name };
this.addOptionalValueToQueryParam('application', applicationName); this.addOptionalValueToQueryParam('application', applicationName);
this.addOptionalCommaValueToQueryParam('role', roles); this.addOptionalCommaValueToQueryParam('role', roles);
} }
private addOptionalCommaValueToQueryParam(key: string, values: string []) { private addOptionalCommaValueToQueryParam(key: string, values: string[]) {
if (values?.length > 0) { if (values?.length > 0) {
const valuesNotEmpty = this.filterOutEmptyValue(values); const valuesNotEmpty = this.filterOutEmptyValue(values);
if (valuesNotEmpty?.length > 0) { if (valuesNotEmpty?.length > 0) {
@ -90,8 +89,8 @@ export class IdentityGroupService implements IdentityGroupServiceInterface {
} }
} }
private filterOutEmptyValue(roles: string []): string [] { private filterOutEmptyValue(roles: string[]): string[] {
return roles.filter( role => role.trim() ? true : false); return roles.filter((role) => (role.trim() ? true : false));
} }
private get identityHost(): string { private get identityHost(): string {

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { TaskDetailsCloudModel } from '../task/start-task/models/task-details-cloud.model'; import { TaskDetailsCloudModel } from '../task/models/task-details-cloud.model';
export interface TaskCloudEngineEvent { export interface TaskCloudEngineEvent {
eventType: string; eventType: string;

View File

@ -25,7 +25,6 @@
</mat-icon> </mat-icon>
</mat-chip-row> </mat-chip-row>
<input matInput <input matInput
#chipInput
[disabled]="isReadonly()" [disabled]="isReadonly()"
[formControl]="searchUserCtrl" [formControl]="searchUserCtrl"
[matAutocomplete]="auto" [matAutocomplete]="auto"
@ -63,9 +62,8 @@
</ng-template> </ng-template>
</mat-autocomplete> </mat-autocomplete>
</mat-form-field> </mat-form-field>
<mat-progress-bar
*ngIf="validationLoading" <mat-progress-bar *ngIf="validationLoading" mode="indeterminate" />
mode="indeterminate" />
<div class="adf-error-container" *ngIf="showErrors"> <div class="adf-error-container" *ngIf="showErrors">
<mat-error *ngIf="hasPreselectError() && !isValidationLoading()" [@transitionMessages]="subscriptAnimationState" class="adf-error"> <mat-error *ngIf="hasPreselectError() && !isValidationLoading()" [@transitionMessages]="subscriptAnimationState" class="adf-error">

View File

@ -19,25 +19,23 @@ import { PeopleCloudComponent } from './people-cloud.component';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CoreTestingModule } from '@alfresco/adf-core'; import { CoreTestingModule } from '@alfresco/adf-core';
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module'; import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
import { PeopleCloudModule } from '../people-cloud.module';
import { DebugElement, SimpleChange } from '@angular/core'; import { DebugElement, SimpleChange } from '@angular/core';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { of } from 'rxjs'; import { of } from 'rxjs';
import { IdentityUserServiceInterface } from '../services/identity-user.service.interface';
import { IDENTITY_USER_SERVICE_TOKEN } from '../services/identity-user-service.token';
import { mockFoodUsers, mockKielbasaSausage, mockShepherdsPie, mockYorkshirePudding, mockPreselectedFoodUsers } from '../mock/people-cloud.mock'; import { mockFoodUsers, mockKielbasaSausage, mockShepherdsPie, mockYorkshirePudding, mockPreselectedFoodUsers } from '../mock/people-cloud.mock';
import { HarnessLoader } from '@angular/cdk/testing'; import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatChipHarness } from '@angular/material/chips/testing'; import { MatChipHarness } from '@angular/material/chips/testing';
import { MatInputHarness } from '@angular/material/input/testing'; import { MatInputHarness } from '@angular/material/input/testing';
import { MatFormFieldHarness } from '@angular/material/form-field/testing'; import { MatFormFieldHarness } from '@angular/material/form-field/testing';
import { IdentityUserService } from '@alfresco/adf-process-services-cloud';
describe('PeopleCloudComponent', () => { describe('PeopleCloudComponent', () => {
let loader: HarnessLoader; let loader: HarnessLoader;
let component: PeopleCloudComponent; let component: PeopleCloudComponent;
let fixture: ComponentFixture<PeopleCloudComponent>; let fixture: ComponentFixture<PeopleCloudComponent>;
let element: HTMLElement; let element: HTMLElement;
let identityUserService: IdentityUserServiceInterface; let identityUserService: IdentityUserService;
let searchSpy: jasmine.Spy; let searchSpy: jasmine.Spy;
/** /**
@ -83,13 +81,13 @@ describe('PeopleCloudComponent', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [CoreTestingModule, ProcessServiceCloudTestingModule, PeopleCloudModule] imports: [CoreTestingModule, ProcessServiceCloudTestingModule, PeopleCloudComponent]
}); });
fixture = TestBed.createComponent(PeopleCloudComponent); fixture = TestBed.createComponent(PeopleCloudComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
element = fixture.nativeElement; element = fixture.nativeElement;
identityUserService = TestBed.inject(IDENTITY_USER_SERVICE_TOKEN); identityUserService = fixture.debugElement.injector.get(IdentityUserService);
loader = TestbedHarnessEnvironment.loader(fixture); loader = TestbedHarnessEnvironment.loader(fixture);
}); });

View File

@ -17,7 +17,6 @@
import { applicationConfig, Meta, moduleMetadata, StoryFn } from '@storybook/angular'; import { applicationConfig, Meta, moduleMetadata, StoryFn } from '@storybook/angular';
import { PeopleCloudComponent } from './people-cloud.component'; import { PeopleCloudComponent } from './people-cloud.component';
import { PeopleCloudModule } from '../people-cloud.module';
import { ProcessServicesCloudStoryModule } from '../../testing/process-services-cloud-story.module'; import { ProcessServicesCloudStoryModule } from '../../testing/process-services-cloud-story.module';
import { IdentityUserService } from '../services/identity-user.service'; import { IdentityUserService } from '../services/identity-user.service';
import { IdentityUserServiceMock, mockFoodUsers, mockKielbasaSausage, mockShepherdsPie, mockYorkshirePudding } from '../mock/people-cloud.mock'; import { IdentityUserServiceMock, mockFoodUsers, mockKielbasaSausage, mockShepherdsPie, mockYorkshirePudding } from '../mock/people-cloud.mock';
@ -28,13 +27,10 @@ export default {
title: 'Process Services Cloud/People Cloud/People Cloud', title: 'Process Services Cloud/People Cloud/People Cloud',
decorators: [ decorators: [
moduleMetadata({ moduleMetadata({
imports: [PeopleCloudModule] imports: [PeopleCloudComponent]
}), }),
applicationConfig({ applicationConfig({
providers: [ providers: [{ provide: IdentityUserService, useClass: IdentityUserServiceMock }, importProvidersFrom(ProcessServicesCloudStoryModule)]
{ provide: IdentityUserService, useClass: IdentityUserServiceMock },
importProvidersFrom(ProcessServicesCloudStoryModule)
]
}) })
], ],
argTypes: { argTypes: {
@ -119,7 +115,7 @@ export default {
description: 'FormControl to list of users.', description: 'FormControl to list of users.',
table: { table: {
type: { summary: 'FormControl' }, type: { summary: 'FormControl' },
defaultValue: { summary: 'new FormControl({ value: \'\', disabled: false })' }, defaultValue: { summary: "new FormControl({ value: '', disabled: false })" },
category: 'Form Controls' category: 'Form Controls'
} }
}, },
@ -128,7 +124,7 @@ export default {
description: 'FormControl to search the user.', description: 'FormControl to search the user.',
table: { table: {
type: { summary: 'FormControl' }, type: { summary: 'FormControl' },
defaultValue: { summary: 'new FormControl({ value: \'\', disabled: false })' }, defaultValue: { summary: "new FormControl({ value: '', disabled: false })" },
category: 'Form Controls' category: 'Form Controls'
} }
}, },
@ -173,7 +169,7 @@ export default {
} }
} as Meta<PeopleCloudComponent>; } as Meta<PeopleCloudComponent>;
const template: StoryFn<PeopleCloudComponent> = args => ({ const template: StoryFn<PeopleCloudComponent> = (args) => ({
props: args props: args
}); });

View File

@ -15,14 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import { UntypedFormControl } from '@angular/forms'; import { ReactiveFormsModule, UntypedFormControl } from '@angular/forms';
import { import {
AfterViewInit, AfterViewInit,
Component, Component,
DestroyRef, DestroyRef,
ElementRef, ElementRef,
EventEmitter, EventEmitter,
Inject,
inject, inject,
Input, Input,
OnChanges, OnChanges,
@ -34,17 +33,40 @@ import {
} from '@angular/core'; } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, mergeMap, switchMap, tap } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, filter, mergeMap, switchMap, tap } from 'rxjs/operators';
import { FullNamePipe } from '@alfresco/adf-core'; import { FullNamePipe, InitialUsernamePipe } from '@alfresco/adf-core';
import { animate, state, style, transition, trigger } from '@angular/animations'; import { animate, state, style, transition, trigger } from '@angular/animations';
import { ComponentSelectionMode } from '../../types'; import { ComponentSelectionMode } from '../../types';
import { IdentityUserModel } from '../models/identity-user.model'; import { IdentityUserModel } from '../models/identity-user.model';
import { IdentityUserServiceInterface } from '../services/identity-user.service.interface'; import { MatFormFieldAppearance, MatFormFieldModule, SubscriptSizing } from '@angular/material/form-field';
import { IDENTITY_USER_SERVICE_TOKEN } from '../services/identity-user-service.token';
import { MatFormFieldAppearance, SubscriptSizing } from '@angular/material/form-field';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatIconModule } from '@angular/material/icon';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatSelectModule } from '@angular/material/select';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatChipsModule } from '@angular/material/chips';
import { MatInputModule } from '@angular/material/input';
import { IdentityUserService } from '../services/identity-user.service';
@Component({ @Component({
selector: 'adf-cloud-people', selector: 'adf-cloud-people',
standalone: true,
imports: [
CommonModule,
TranslateModule,
MatIconModule,
MatFormFieldModule,
MatProgressBarModule,
MatSelectModule,
InitialUsernamePipe,
FullNamePipe,
MatAutocompleteModule,
ReactiveFormsModule,
MatChipsModule,
MatInputModule
],
providers: [FullNamePipe],
templateUrl: './people-cloud.component.html', templateUrl: './people-cloud.component.html',
styleUrls: ['./people-cloud.component.scss'], styleUrls: ['./people-cloud.component.scss'],
animations: [ animations: [
@ -53,7 +75,6 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
transition('void => enter', [style({ opacity: 0, transform: 'translateY(-100%)' }), animate('300ms cubic-bezier(0.55, 0, 0.55, 0.2)')]) transition('void => enter', [style({ opacity: 0, transform: 'translateY(-100%)' }), animate('300ms cubic-bezier(0.55, 0, 0.55, 0.2)')])
]) ])
], ],
providers: [FullNamePipe],
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class PeopleCloudComponent implements OnInit, OnChanges, AfterViewInit { export class PeopleCloudComponent implements OnInit, OnChanges, AfterViewInit {
@ -196,10 +217,7 @@ export class PeopleCloudComponent implements OnInit, OnChanges, AfterViewInit {
private readonly destroyRef = inject(DestroyRef); private readonly destroyRef = inject(DestroyRef);
constructor( constructor(private identityUserService: IdentityUserService) {}
@Inject(IDENTITY_USER_SERVICE_TOKEN)
private identityUserService: IdentityUserServiceInterface
) {}
ngOnInit(): void { ngOnInit(): void {
this.initSearch(); this.initSearch();

View File

@ -1,72 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { HttpErrorResponse } from '@angular/common/http';
import { IdentityUserFilterInterface } from '../services/identity-user-filter.interface';
export const mockSearchUserEmptyFilters: IdentityUserFilterInterface = {
roles: [],
groups: [],
withinApplication: ''
};
export const mockSearchUserByGroups: IdentityUserFilterInterface = {
roles: [],
groups: ['fake-group-1', 'fake-group-2'],
withinApplication: ''
};
export const mockSearchUserByGroupsAndRoles: IdentityUserFilterInterface = {
roles: ['fake-role-1', 'fake-role-2'],
groups: ['fake-group-1', 'fake-group-2'],
withinApplication: ''
};
export const mockSearchUserByGroupsAndRolesAndApp: IdentityUserFilterInterface = {
roles: ['fake-role-1', 'fake-role-2'],
groups: ['fake-group-1', 'fake-group-2'],
withinApplication: 'fake-app-name'
};
export const mockSearchUserByRoles: IdentityUserFilterInterface = {
roles: ['fake-role-1', 'fake-role-2'],
groups: [],
withinApplication: ''
};
export const mockSearchUserByRolesAndApp: IdentityUserFilterInterface = {
roles: ['fake-role-1', 'fake-role-2'],
groups: [],
withinApplication: 'fake-app-name'
};
export const mockSearchUserByApp: IdentityUserFilterInterface = {
roles: [],
groups: [],
withinApplication: 'fake-app-name'
};
export const mockSearchUserByAppAndGroups: IdentityUserFilterInterface = {
roles: [],
groups: ['fake-group-1', 'fake-group-2'],
withinApplication: 'fake-app-name'
};
export const mockHttpErrorResponse = new HttpErrorResponse({
error: 'Mock Error',
status: 404, statusText: 'Not Found'
});

View File

@ -1,22 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 const mockToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ' +
'zdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiZmFtaWx5X25hbWUiOiJEb2UiLCJnaXZ' +
'lbl9uYW1lIjoiSm9obiIsImFkbWluIjp0cnVlLCJlbWFpbCI6ImpvaG5Eb2VAZ21haWwuY29tIiwicHJ' +
'lZmVycmVkX3VzZXJuYW1lIjoiam9obkRvZTEiLCJqdGkiOiI2MmQ3YjA4NS1hNTJjLTRjZmEtYjA2Zi1' +
'hODFhN2IwNjRjZDIiLCJpYXQiOjE1NDM0MTA0NzcsImV4cCI6MTU0MzQxNTIxM30.pSP86kmX3keuU5E3ndaOUq2TzKdJRsuMnBdFz3Y-UEU';

View File

@ -18,12 +18,29 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, EMPTY, of } from 'rxjs'; import { Observable, EMPTY, of } from 'rxjs';
import { IdentityUserModel } from '../models/identity-user.model'; import { IdentityUserModel } from '../models/identity-user.model';
import { IdentityUserFilterInterface } from '../services/identity-user-filter.interface'; import { IdentityUserService } from '@alfresco/adf-process-services-cloud';
import { IdentityUserServiceInterface } from '../services/identity-user.service.interface';
export const mockYorkshirePudding: IdentityUserModel = { id: 'yorkshire', username: 'Yorkshire Pudding', firstName: 'Yorkshire', lastName: 'Pudding', email: 'pudding@food.com' }; export const mockYorkshirePudding: IdentityUserModel = {
export const mockShepherdsPie: IdentityUserModel = { id: 'shepherds', username: 'Shepherds Pie', firstName: 'Shepherds', lastName: 'Pie', email: 'shepherds@food.com'}; id: 'yorkshire',
export const mockKielbasaSausage: IdentityUserModel = { id: 'kielbasa', username: 'Kielbasa Sausage', firstName: 'Kielbasa', lastName: 'Sausage', email: 'sausage@food.com' }; username: 'Yorkshire Pudding',
firstName: 'Yorkshire',
lastName: 'Pudding',
email: 'pudding@food.com'
};
export const mockShepherdsPie: IdentityUserModel = {
id: 'shepherds',
username: 'Shepherds Pie',
firstName: 'Shepherds',
lastName: 'Pie',
email: 'shepherds@food.com'
};
export const mockKielbasaSausage: IdentityUserModel = {
id: 'kielbasa',
username: 'Kielbasa Sausage',
firstName: 'Kielbasa',
lastName: 'Sausage',
email: 'sausage@food.com'
};
export const mockFoodUsers: IdentityUserModel[] = [mockYorkshirePudding, mockShepherdsPie, mockKielbasaSausage]; export const mockFoodUsers: IdentityUserModel[] = [mockYorkshirePudding, mockShepherdsPie, mockKielbasaSausage];
@ -32,24 +49,19 @@ export const mockPreselectedFoodUsers = [
{ ...mockKielbasaSausage, readonly: false } { ...mockKielbasaSausage, readonly: false }
]; ];
@Injectable({ @Injectable()
providedIn: 'root' export class IdentityUserServiceMock extends IdentityUserService {
})
export class IdentityUserServiceMock implements IdentityUserServiceInterface {
queryParams: { search: string; application?: string; roles?: string[]; groups?: string[] }; queryParams: { search: string; application?: string; roles?: string[]; groups?: string[] };
getCurrentUserInfo(): IdentityUserModel { getCurrentUserInfo(): IdentityUserModel {
return mockKielbasaSausage; return mockKielbasaSausage;
} }
search(name: string, _filters?: IdentityUserFilterInterface): Observable<IdentityUserModel[]> { search(name: string): Observable<IdentityUserModel[]> {
if (name.trim() === '') { if (name.trim() === '') {
return EMPTY; return EMPTY;
} }
return of(mockFoodUsers.filter(group => return of(mockFoodUsers.filter((group) => group.username.toUpperCase().includes(name.toUpperCase())));
group.username.toUpperCase().includes(name.toUpperCase())
));
} }
} }

View File

@ -17,18 +17,10 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { PeopleCloudComponent } from './components/people-cloud.component'; import { PeopleCloudComponent } from './components/people-cloud.component';
import { CommonModule } from '@angular/common';
import { MaterialModule } from '../material.module';
import { CoreModule, FullNamePipe, InitialUsernamePipe } from '@alfresco/adf-core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { IdentityUserService } from './services/identity-user.service';
import { IDENTITY_USER_SERVICE_TOKEN } from './services/identity-user-service.token';
import { MatProgressBarModule } from '@angular/material/progress-bar';
/** @deprecated use PeopleCloudComponent instead */
@NgModule({ @NgModule({
imports: [CommonModule, MaterialModule, FormsModule, ReactiveFormsModule, CoreModule, FullNamePipe, InitialUsernamePipe, MatProgressBarModule], imports: [PeopleCloudComponent],
declarations: [PeopleCloudComponent], exports: [PeopleCloudComponent]
exports: [PeopleCloudComponent],
providers: [{ provide: IDENTITY_USER_SERVICE_TOKEN, useExisting: IdentityUserService }]
}) })
export class PeopleCloudModule {} export class PeopleCloudModule {}

View File

@ -19,4 +19,3 @@ export * from './components/people-cloud.component';
export * from './people-cloud.module'; export * from './people-cloud.module';
export * from './models/identity-user.model'; export * from './models/identity-user.model';
export * from './services/identity-user.service'; export * from './services/identity-user.service';
export * from './services/identity-user-service.token';

View File

@ -1,22 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 interface IdentityUserFilterInterface {
roles?: string[];
withinApplication?: string;
groups?: string[];
}

View File

@ -1,21 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { InjectionToken } from '@angular/core';
import { IdentityUserServiceInterface } from './identity-user.service.interface';
export const IDENTITY_USER_SERVICE_TOKEN = new InjectionToken<IdentityUserServiceInterface>('identity-user-service-token');

View File

@ -1,25 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { Observable } from 'rxjs';
import { IdentityUserModel } from '../models/identity-user.model';
import { IdentityUserFilterInterface } from './identity-user-filter.interface';
export interface IdentityUserServiceInterface {
getCurrentUserInfo(): IdentityUserModel;
search(name: string, filters?: IdentityUserFilterInterface): Observable<IdentityUserModel[]>;
}

View File

@ -18,18 +18,15 @@
import { TestBed } from '@angular/core/testing'; import { TestBed } from '@angular/core/testing';
import { IdentityUserService } from './identity-user.service'; import { IdentityUserService } from './identity-user.service';
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module'; import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
import {
mockSearchUserByApp,
mockSearchUserByAppAndGroups,
mockSearchUserByGroups,
mockSearchUserByGroupsAndRoles,
mockSearchUserByGroupsAndRolesAndApp,
mockSearchUserByRoles,
mockSearchUserByRolesAndApp
} from '../mock/identity-user.service.mock';
import { mockFoodUsers } from '../mock/people-cloud.mock'; import { mockFoodUsers } from '../mock/people-cloud.mock';
import { AdfHttpClient } from '@alfresco/adf-core/api'; import { AdfHttpClient } from '@alfresco/adf-core/api';
import { mockHttpErrorResponse } from '../../group/mock/identity-group.service.mock'; import { HttpErrorResponse } from '@angular/common/http';
const mockHttpErrorResponse = new HttpErrorResponse({
error: 'Mock Error',
status: 404,
statusText: 'Not Found'
});
describe('IdentityUserService', () => { describe('IdentityUserService', () => {
let service: IdentityUserService; let service: IdentityUserService;
@ -83,154 +80,214 @@ describe('IdentityUserService', () => {
requestSpy.and.returnValue(Promise.resolve(mockFoodUsers)); requestSpy.and.returnValue(Promise.resolve(mockFoodUsers));
const searchSpy = spyOn(service, 'search').and.callThrough(); const searchSpy = spyOn(service, 'search').and.callThrough();
service.search('fake', mockSearchUserByRoles).subscribe((res) => { service
expect(res).toBeDefined(); .search('fake', {
expect(searchSpy).toHaveBeenCalled(); roles: ['fake-role-1', 'fake-role-2'],
expect(service.queryParams).toEqual({ groups: [],
search: 'fake', withinApplication: ''
role: 'fake-role-1,fake-role-2' })
.subscribe((res) => {
expect(res).toBeDefined();
expect(searchSpy).toHaveBeenCalled();
expect(service.queryParams).toEqual({
search: 'fake',
role: 'fake-role-1,fake-role-2'
});
done();
}); });
done();
});
}); });
it('should not fetch users by roles if error occurred', (done) => { it('should not fetch users by roles if error occurred', (done) => {
requestSpy.and.returnValue(Promise.reject(mockHttpErrorResponse)); requestSpy.and.returnValue(Promise.reject(mockHttpErrorResponse));
service.search('fake', mockSearchUserByRoles).subscribe( service
() => { .search('fake', {
fail('expected an error, not users'); roles: ['fake-role-1', 'fake-role-2'],
}, groups: [],
(error) => { withinApplication: ''
expect(error.status).toEqual(404); })
expect(error.statusText).toEqual('Not Found'); .subscribe(
expect(error.error).toEqual('Mock Error'); () => {
done(); fail('expected an error, not users');
} },
); (error) => {
expect(error.status).toEqual(404);
expect(error.statusText).toEqual('Not Found');
expect(error.error).toEqual('Mock Error');
done();
}
);
}); });
it('should fetch users by groups', (done) => { it('should fetch users by groups', (done) => {
requestSpy.and.returnValue(Promise.resolve(mockFoodUsers)); requestSpy.and.returnValue(Promise.resolve(mockFoodUsers));
const searchSpy = spyOn(service, 'search').and.callThrough(); const searchSpy = spyOn(service, 'search').and.callThrough();
service.search('fake', mockSearchUserByGroups).subscribe((res) => { service
expect(res).toBeDefined(); .search('fake', {
expect(searchSpy).toHaveBeenCalled(); roles: [],
expect(service.queryParams).toEqual({ groups: ['fake-group-1', 'fake-group-2'],
search: 'fake', withinApplication: ''
group: 'fake-group-1,fake-group-2' })
.subscribe((res) => {
expect(res).toBeDefined();
expect(searchSpy).toHaveBeenCalled();
expect(service.queryParams).toEqual({
search: 'fake',
group: 'fake-group-1,fake-group-2'
});
done();
}); });
done();
});
}); });
it('should fetch users by roles with groups', (done) => { it('should fetch users by roles with groups', (done) => {
requestSpy.and.returnValue(Promise.resolve(mockFoodUsers)); requestSpy.and.returnValue(Promise.resolve(mockFoodUsers));
const searchSpy = spyOn(service, 'search').and.callThrough(); const searchSpy = spyOn(service, 'search').and.callThrough();
service.search('fake', mockSearchUserByGroupsAndRoles).subscribe((res) => { service
expect(res).toBeDefined(); .search('fake', {
expect(searchSpy).toHaveBeenCalled(); roles: ['fake-role-1', 'fake-role-2'],
expect(service.queryParams).toEqual({ groups: ['fake-group-1', 'fake-group-2'],
search: 'fake', withinApplication: ''
role: 'fake-role-1,fake-role-2', })
group: 'fake-group-1,fake-group-2' .subscribe((res) => {
expect(res).toBeDefined();
expect(searchSpy).toHaveBeenCalled();
expect(service.queryParams).toEqual({
search: 'fake',
role: 'fake-role-1,fake-role-2',
group: 'fake-group-1,fake-group-2'
});
done();
}); });
done();
});
}); });
it('should fetch users by roles with groups and appName', (done) => { it('should fetch users by roles with groups and appName', (done) => {
requestSpy.and.returnValue(Promise.resolve(mockFoodUsers)); requestSpy.and.returnValue(Promise.resolve(mockFoodUsers));
const searchSpy = spyOn(service, 'search').and.callThrough(); const searchSpy = spyOn(service, 'search').and.callThrough();
service.search('fake', mockSearchUserByGroupsAndRolesAndApp).subscribe((res) => { service
expect(res).toBeDefined(); .search('fake', {
expect(searchSpy).toHaveBeenCalled(); roles: ['fake-role-1', 'fake-role-2'],
expect(service.queryParams).toEqual({ groups: ['fake-group-1', 'fake-group-2'],
search: 'fake', withinApplication: 'fake-app-name'
role: 'fake-role-1,fake-role-2', })
application: 'fake-app-name', .subscribe((res) => {
group: 'fake-group-1,fake-group-2' expect(res).toBeDefined();
expect(searchSpy).toHaveBeenCalled();
expect(service.queryParams).toEqual({
search: 'fake',
role: 'fake-role-1,fake-role-2',
application: 'fake-app-name',
group: 'fake-group-1,fake-group-2'
});
done();
}); });
done();
});
}); });
it('should not fetch users by groups if error occurred', (done) => { it('should not fetch users by groups if error occurred', (done) => {
requestSpy.and.returnValue(Promise.reject(mockHttpErrorResponse)); requestSpy.and.returnValue(Promise.reject(mockHttpErrorResponse));
service.search('fake', mockSearchUserByGroups).subscribe( service
() => { .search('fake', {
fail('expected an error, not users'); roles: [],
}, groups: ['fake-group-1', 'fake-group-2'],
(error) => { withinApplication: ''
expect(error.status).toEqual(404); })
expect(error.statusText).toEqual('Not Found'); .subscribe(
expect(error.error).toEqual('Mock Error'); () => {
done(); fail('expected an error, not users');
} },
); (error) => {
expect(error.status).toEqual(404);
expect(error.statusText).toEqual('Not Found');
expect(error.error).toEqual('Mock Error');
done();
}
);
}); });
it('should fetch users within app', (done) => { it('should fetch users within app', (done) => {
requestSpy.and.returnValue(Promise.resolve(mockFoodUsers)); requestSpy.and.returnValue(Promise.resolve(mockFoodUsers));
service.search('fake', mockSearchUserByApp).subscribe((res) => { service
expect(res).toBeDefined(); .search('fake', {
expect(service.queryParams).toEqual({ roles: [],
search: 'fake', groups: [],
application: 'fake-app-name' withinApplication: 'fake-app-name'
})
.subscribe((res) => {
expect(res).toBeDefined();
expect(service.queryParams).toEqual({
search: 'fake',
application: 'fake-app-name'
});
done();
}); });
done();
});
}); });
it('should fetch users within app with roles', (done) => { it('should fetch users within app with roles', (done) => {
requestSpy.and.returnValue(Promise.resolve(mockFoodUsers)); requestSpy.and.returnValue(Promise.resolve(mockFoodUsers));
service.search('fake', mockSearchUserByRolesAndApp).subscribe((res) => { service
expect(res).toBeDefined(); .search('fake', {
expect(service.queryParams).toEqual({ roles: ['fake-role-1', 'fake-role-2'],
search: 'fake', groups: [],
application: 'fake-app-name', withinApplication: 'fake-app-name'
role: 'fake-role-1,fake-role-2' })
.subscribe((res) => {
expect(res).toBeDefined();
expect(service.queryParams).toEqual({
search: 'fake',
application: 'fake-app-name',
role: 'fake-role-1,fake-role-2'
});
done();
}); });
done();
});
}); });
it('should fetch users within app with groups', (done) => { it('should fetch users within app with groups', (done) => {
requestSpy.and.returnValue(Promise.resolve(mockFoodUsers)); requestSpy.and.returnValue(Promise.resolve(mockFoodUsers));
const searchSpy = spyOn(service, 'search').and.callThrough(); const searchSpy = spyOn(service, 'search').and.callThrough();
service.search('fake', mockSearchUserByAppAndGroups).subscribe((res) => { service
expect(res).toBeDefined(); .search('fake', {
expect(searchSpy).toHaveBeenCalled(); roles: [],
expect(service.queryParams).toEqual({ groups: ['fake-group-1', 'fake-group-2'],
search: 'fake', withinApplication: 'fake-app-name'
application: 'fake-app-name', })
group: 'fake-group-1,fake-group-2' .subscribe((res) => {
expect(res).toBeDefined();
expect(searchSpy).toHaveBeenCalled();
expect(service.queryParams).toEqual({
search: 'fake',
application: 'fake-app-name',
group: 'fake-group-1,fake-group-2'
});
done();
}); });
done();
});
}); });
it('should not fetch users within app if error occurred', (done) => { it('should not fetch users within app if error occurred', (done) => {
requestSpy.and.returnValue(Promise.reject(mockHttpErrorResponse)); requestSpy.and.returnValue(Promise.reject(mockHttpErrorResponse));
service.search('fake', mockSearchUserByApp).subscribe( service
() => { .search('fake', {
fail('expected an error, not users'); roles: [],
}, groups: [],
(error) => { withinApplication: 'fake-app-name'
expect(error.status).toEqual(404); })
expect(error.statusText).toEqual('Not Found'); .subscribe(
expect(error.error).toEqual('Mock Error'); () => {
done(); fail('expected an error, not users');
} },
); (error) => {
expect(error.status).toEqual(404);
expect(error.statusText).toEqual('Not Found');
expect(error.error).toEqual('Mock Error');
done();
}
);
}); });
}); });
}); });

View File

@ -18,16 +18,20 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { AppConfigService, JwtHelperService, OAuth2Service } from '@alfresco/adf-core'; import { AppConfigService, JwtHelperService, OAuth2Service } from '@alfresco/adf-core';
import { EMPTY, Observable } from 'rxjs'; import { EMPTY, Observable } from 'rxjs';
import { IdentityUserServiceInterface } from './identity-user.service.interface';
import { IdentityUserModel } from '../models/identity-user.model'; import { IdentityUserModel } from '../models/identity-user.model';
import { IdentityUserFilterInterface } from './identity-user-filter.interface';
const IDENTITY_MICRO_SERVICE_INGRESS = 'identity-adapter-service'; const IDENTITY_MICRO_SERVICE_INGRESS = 'identity-adapter-service';
export interface IdentityUserFilterInterface {
roles?: string[];
withinApplication?: string;
groups?: string[];
}
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class IdentityUserService implements IdentityUserServiceInterface { export class IdentityUserService {
queryParams: { search: string; application?: string; roles?: string[]; groups?: string[] }; queryParams: { search: string; application?: string; roles?: string[]; groups?: string[] };
constructor(private jwtHelperService: JwtHelperService, private oAuth2Service: OAuth2Service, private appConfigService: AppConfigService) {} constructor(private jwtHelperService: JwtHelperService, private oAuth2Service: OAuth2Service, private appConfigService: AppConfigService) {}

View File

@ -20,9 +20,8 @@ import { CoreModule, FormRenderingService, provideTranslations } from '@alfresco
import { APP_LIST_CLOUD_DIRECTIVES } from './app/app-list-cloud.module'; import { APP_LIST_CLOUD_DIRECTIVES } from './app/app-list-cloud.module';
import { TaskCloudModule } from './task/task-cloud.module'; import { TaskCloudModule } from './task/task-cloud.module';
import { ProcessCloudModule } from './process/process-cloud.module'; import { ProcessCloudModule } from './process/process-cloud.module';
import { GroupCloudModule } from './group/group-cloud.module';
import { FORM_CLOUD_DIRECTIVES } from './form/form-cloud.module'; import { FORM_CLOUD_DIRECTIVES } from './form/form-cloud.module';
import { TaskFormModule } from './task/task-form/task-form.module'; import { TASK_FORM_CLOUD_DIRECTIVES } from './task/task-form/task-form.module';
import { import {
LocalPreferenceCloudService, LocalPreferenceCloudService,
PreferenceCloudServiceInterface, PreferenceCloudServiceInterface,
@ -31,10 +30,11 @@ import {
PROCESS_LISTS_PREFERENCES_SERVICE_TOKEN, PROCESS_LISTS_PREFERENCES_SERVICE_TOKEN,
TASK_LIST_PREFERENCES_SERVICE_TOKEN TASK_LIST_PREFERENCES_SERVICE_TOKEN
} from './services/public-api'; } from './services/public-api';
import { PeopleCloudModule } from './people/people-cloud.module';
import { CloudFormRenderingService } from './form/components/cloud-form-rendering.service'; import { CloudFormRenderingService } from './form/components/cloud-form-rendering.service';
import { ApolloModule } from 'apollo-angular'; import { ApolloModule } from 'apollo-angular';
import { RichTextEditorComponent } from './rich-text-editor'; import { RichTextEditorComponent } from './rich-text-editor';
import { GroupCloudComponent } from './group/components/group-cloud.component';
import { PeopleCloudComponent } from './people/components/people-cloud.component';
@NgModule({ @NgModule({
imports: [ imports: [
@ -42,10 +42,10 @@ import { RichTextEditorComponent } from './rich-text-editor';
...APP_LIST_CLOUD_DIRECTIVES, ...APP_LIST_CLOUD_DIRECTIVES,
ProcessCloudModule, ProcessCloudModule,
TaskCloudModule, TaskCloudModule,
GroupCloudModule, GroupCloudComponent,
PeopleCloudModule, PeopleCloudComponent,
...FORM_CLOUD_DIRECTIVES, ...FORM_CLOUD_DIRECTIVES,
TaskFormModule, ...TASK_FORM_CLOUD_DIRECTIVES,
ApolloModule, ApolloModule,
RichTextEditorComponent RichTextEditorComponent
], ],
@ -54,10 +54,10 @@ import { RichTextEditorComponent } from './rich-text-editor';
...APP_LIST_CLOUD_DIRECTIVES, ...APP_LIST_CLOUD_DIRECTIVES,
ProcessCloudModule, ProcessCloudModule,
TaskCloudModule, TaskCloudModule,
GroupCloudModule, GroupCloudComponent,
...FORM_CLOUD_DIRECTIVES, ...FORM_CLOUD_DIRECTIVES,
TaskFormModule, ...TASK_FORM_CLOUD_DIRECTIVES,
PeopleCloudModule, PeopleCloudComponent,
RichTextEditorComponent RichTextEditorComponent
] ]
}) })

View File

@ -23,12 +23,10 @@ import { ApplicationVersionModel } from '../../models/application-version.model'
import { processInstancePlaceholdersCloudMock, processInstanceDetailsCloudMock } from './process-instance-details-cloud.mock'; import { processInstancePlaceholdersCloudMock, processInstanceDetailsCloudMock } from './process-instance-details-cloud.mock';
import { fakeProcessDefinitions } from '../start-process/mock/start-process.component.mock'; import { fakeProcessDefinitions } from '../start-process/mock/start-process.component.mock';
import { mockAppVersions } from '../process-filters/mock/process-filters-cloud.mock'; import { mockAppVersions } from '../process-filters/mock/process-filters-cloud.mock';
import { ProcessCloudInterface } from '../services/process-cloud.interface'; import { ProcessCloudService } from '@alfresco/adf-process-services-cloud';
@Injectable({ @Injectable()
providedIn: 'root' export class ProcessCloudServiceMock extends ProcessCloudService {
})
export class ProcessCloudServiceMock implements ProcessCloudInterface {
dataChangesDetected = new Subject<ProcessInstanceCloud>(); dataChangesDetected = new Subject<ProcessInstanceCloud>();
getProcessInstanceById(appName: string, processInstanceId: string): Observable<ProcessInstanceCloud> { getProcessInstanceById(appName: string, processInstanceId: string): Observable<ProcessInstanceCloud> {

View File

@ -47,7 +47,6 @@ import { DateCloudFilterType } from '../../../models/date-cloud-filter.model';
import { ProcessDefinitionCloud } from '../../../models/process-definition-cloud.model'; import { ProcessDefinitionCloud } from '../../../models/process-definition-cloud.model';
import { PeopleCloudComponent } from '../../../people/components/people-cloud.component'; import { PeopleCloudComponent } from '../../../people/components/people-cloud.component';
import { IdentityUserServiceMock } from '../../../people/mock/people-cloud.mock'; import { IdentityUserServiceMock } from '../../../people/mock/people-cloud.mock';
import { IDENTITY_USER_SERVICE_TOKEN } from '../../../people/services/identity-user-service.token';
import { PROCESS_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service'; import { PROCESS_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service';
import { LocalPreferenceCloudService } from '../../../services/local-preference-cloud.service'; import { LocalPreferenceCloudService } from '../../../services/local-preference-cloud.service';
import { NotificationCloudService } from '../../../services/notification-cloud.service'; import { NotificationCloudService } from '../../../services/notification-cloud.service';
@ -62,6 +61,7 @@ import {
PROCESS_FILTER_ACTION_SAVE_DEFAULT PROCESS_FILTER_ACTION_SAVE_DEFAULT
} from './edit-process-filter-cloud.component'; } from './edit-process-filter-cloud.component';
import { ProcessFilterDialogCloudComponent } from './process-filter-dialog-cloud.component'; import { ProcessFilterDialogCloudComponent } from './process-filter-dialog-cloud.component';
import { IdentityUserService } from '@alfresco/adf-process-services-cloud';
describe('EditProcessFilterCloudComponent', () => { describe('EditProcessFilterCloudComponent', () => {
let loader: HarnessLoader; let loader: HarnessLoader;
@ -114,7 +114,9 @@ describe('EditProcessFilterCloudComponent', () => {
MatInputModule, MatInputModule,
ReactiveFormsModule, ReactiveFormsModule,
MatChipsModule, MatChipsModule,
MatProgressBarModule MatProgressBarModule,
PeopleCloudComponent,
DateRangeFilterComponent
], ],
providers: [ providers: [
{ provide: PROCESS_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }, { provide: PROCESS_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService },
@ -122,9 +124,8 @@ describe('EditProcessFilterCloudComponent', () => {
{ provide: DateAdapter, useClass: DateFnsAdapter }, { provide: DateAdapter, useClass: DateFnsAdapter },
{ provide: NotificationCloudService, useValue: { makeGQLQuery: () => of([]) } }, { provide: NotificationCloudService, useValue: { makeGQLQuery: () => of([]) } },
{ provide: MAT_DATE_FORMATS, useValue: ADF_DATE_FORMATS }, { provide: MAT_DATE_FORMATS, useValue: ADF_DATE_FORMATS },
{ provide: IDENTITY_USER_SERVICE_TOKEN, useExisting: IdentityUserServiceMock } { provide: IdentityUserService, useClass: IdentityUserServiceMock }
], ]
declarations: [PeopleCloudComponent, DateRangeFilterComponent]
}); });
fixture = TestBed.createComponent(EditProcessFilterCloudComponent); fixture = TestBed.createComponent(EditProcessFilterCloudComponent);
component = fixture.componentInstance; component = fixture.componentInstance;

View File

@ -25,8 +25,8 @@ import { HttpClientModule } from '@angular/common/http';
import { EditProcessFilterCloudComponent } from './components/edit-process-filter-cloud.component'; import { EditProcessFilterCloudComponent } from './components/edit-process-filter-cloud.component';
import { ProcessFilterDialogCloudComponent } from './components/process-filter-dialog-cloud.component'; import { ProcessFilterDialogCloudComponent } from './components/process-filter-dialog-cloud.component';
import { APP_LIST_CLOUD_DIRECTIVES } from './../../app/app-list-cloud.module'; import { APP_LIST_CLOUD_DIRECTIVES } from './../../app/app-list-cloud.module';
import { ProcessCommonModule } from '../../common/process-common.module'; import { PeopleCloudComponent } from '../../people/components/people-cloud.component';
import { PeopleCloudModule } from '../../people/people-cloud.module'; import { DateRangeFilterComponent } from '../../common/date-range-filter/date-range-filter.component';
@NgModule({ @NgModule({
imports: [ imports: [
@ -37,8 +37,8 @@ import { PeopleCloudModule } from '../../people/people-cloud.module';
MaterialModule, MaterialModule,
...APP_LIST_CLOUD_DIRECTIVES, ...APP_LIST_CLOUD_DIRECTIVES,
CoreModule, CoreModule,
ProcessCommonModule, DateRangeFilterComponent,
PeopleCloudModule PeopleCloudComponent
], ],
declarations: [ProcessFiltersCloudComponent, EditProcessFilterCloudComponent, ProcessFilterDialogCloudComponent], declarations: [ProcessFiltersCloudComponent, EditProcessFilterCloudComponent, ProcessFilterDialogCloudComponent],
exports: [ProcessFiltersCloudComponent, EditProcessFilterCloudComponent, ProcessFilterDialogCloudComponent] exports: [ProcessFiltersCloudComponent, EditProcessFilterCloudComponent, ProcessFilterDialogCloudComponent]

View File

@ -1,31 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { Observable, Subject } from 'rxjs';
import { ProcessInstanceCloud } from '../start-process/models/process-instance-cloud.model';
import { ProcessDefinitionCloud } from '../../models/process-definition-cloud.model';
import { ApplicationVersionModel } from '../../models/application-version.model';
export interface ProcessCloudInterface {
dataChangesDetected: Subject<ProcessInstanceCloud>;
getProcessInstanceById(appName: string, processInstanceId: string): Observable<ProcessInstanceCloud>;
getProcessDefinitions(appName: string): Observable<ProcessDefinitionCloud[]>;
getApplicationVersions(appName: string): Observable<ApplicationVersionModel[]>;
cancelProcess(appName: string, processInstanceId: string): Observable<ProcessInstanceCloud>;
}

View File

@ -22,12 +22,11 @@ import { ProcessInstanceCloud } from '../start-process/models/process-instance-c
import { BaseCloudService } from '../../services/base-cloud.service'; import { BaseCloudService } from '../../services/base-cloud.service';
import { ProcessDefinitionCloud } from '../../models/process-definition-cloud.model'; import { ProcessDefinitionCloud } from '../../models/process-definition-cloud.model';
import { ApplicationVersionModel, ApplicationVersionResponseModel } from '../../models/application-version.model'; import { ApplicationVersionModel, ApplicationVersionResponseModel } from '../../models/application-version.model';
import { ProcessCloudInterface } from './process-cloud.interface';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class ProcessCloudService extends BaseCloudService implements ProcessCloudInterface { export class ProcessCloudService extends BaseCloudService {
dataChangesDetected = new Subject<ProcessInstanceCloud>(); dataChangesDetected = new Subject<ProcessInstanceCloud>();
/** /**

View File

@ -1,22 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 './claim-task-cloud.directive';
export * from './unclaim-task-cloud.directive';
export * from './complete-task.directive';
export * from './task-directive.module';

View File

@ -1,30 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { CompleteTaskDirective } from './complete-task.directive';
import { ClaimTaskCloudDirective } from './claim-task-cloud.directive';
import { UnClaimTaskCloudDirective } from './unclaim-task-cloud.directive';
export const TASK_DIRECTIVES = [CompleteTaskDirective, ClaimTaskCloudDirective, UnClaimTaskCloudDirective] as const;
/** @deprecated */
@NgModule({
imports: [...TASK_DIRECTIVES],
exports: [...TASK_DIRECTIVES]
})
export class TaskDirectiveModule {}

View File

@ -16,23 +16,23 @@
*/ */
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { AppConfigService, CardViewArrayItem } from '@alfresco/adf-core'; import { CardViewArrayItem } from '@alfresco/adf-core';
import { from, Observable, of, Subject, throwError } from 'rxjs'; import { from, Observable, of, Subject, throwError } from 'rxjs';
import { DEFAULT_TASK_PRIORITIES, TaskPriorityOption } from '../models/task.model'; import { DEFAULT_TASK_PRIORITIES, TaskPriorityOption } from '../models/task.model';
import { TaskDetailsCloudModel, TASK_ASSIGNED_STATE, TASK_CREATED_STATE } from '../start-task/models/task-details-cloud.model'; import { TaskDetailsCloudModel, TASK_ASSIGNED_STATE, TASK_CREATED_STATE } from '../models/task-details-cloud.model';
import { taskDetailsContainer } from '../task-header/mocks/task-details-cloud.mock'; import { taskDetailsContainer } from '../task-header/mocks/task-details-cloud.mock';
import { ProcessDefinitionCloud } from '../../models/process-definition-cloud.model'; import { ProcessDefinitionCloud } from '../../models/process-definition-cloud.model';
import { StartTaskCloudRequestModel } from '../start-task/models/start-task-cloud-request.model'; import { TaskCloudService } from '@alfresco/adf-process-services-cloud';
import { TaskCloudServiceInterface } from '../services/task-cloud.service.interface'; import { AdfHttpClient } from '@alfresco/adf-core/api';
@Injectable({ @Injectable()
providedIn: 'root' export class TaskCloudServiceMock extends TaskCloudService {
})
export class TaskCloudServiceMock implements TaskCloudServiceInterface {
currentUserMock = 'AssignedTaskUser'; currentUserMock = 'AssignedTaskUser';
dataChangesDetected$ = new Subject(); dataChangesDetected$ = new Subject();
constructor(private appConfigService: AppConfigService) {} constructor(adfHttpClient: AdfHttpClient) {
super(adfHttpClient);
}
getTaskById(_appName: string, taskId: string): Observable<TaskDetailsCloudModel> { getTaskById(_appName: string, taskId: string): Observable<TaskDetailsCloudModel> {
return of(taskDetailsContainer[taskId]); return of(taskDetailsContainer[taskId]);
@ -80,7 +80,7 @@ export class TaskCloudServiceMock implements TaskCloudServiceInterface {
return isClickable; return isClickable;
} }
updateTask(_appName: string, taskId: string, _payload: any): Observable<TaskDetailsCloudModel> { updateTask(_appName: string, taskId: string): Observable<TaskDetailsCloudModel> {
return of(taskDetailsContainer[taskId]); return of(taskDetailsContainer[taskId]);
} }
@ -92,12 +92,8 @@ export class TaskCloudServiceMock implements TaskCloudServiceInterface {
return taskDetails && taskDetails.status === TASK_CREATED_STATE; return taskDetails && taskDetails.status === TASK_CREATED_STATE;
} }
private isAssignedToMe(assignee: string): boolean { protected isAssignedToMe(assignee: string): boolean {
if (assignee === this.currentUserMock) { return assignee === this.currentUserMock;
return true;
}
return false;
} }
completeTask(appName: string, taskId: string): Observable<TaskDetailsCloudModel> { completeTask(appName: string, taskId: string): Observable<TaskDetailsCloudModel> {
@ -106,7 +102,7 @@ export class TaskCloudServiceMock implements TaskCloudServiceInterface {
return from([]); return from([]);
} else { } else {
return throwError('AppName/TaskId not configured'); return throwError(() => new Error('AppName/TaskId not configured'));
} }
} }
@ -115,13 +111,13 @@ export class TaskCloudServiceMock implements TaskCloudServiceInterface {
return taskDetails && taskDetails.status === TASK_ASSIGNED_STATE && taskDetails.assignee === currentUser; return taskDetails && taskDetails.status === TASK_ASSIGNED_STATE && taskDetails.assignee === currentUser;
} }
claimTask(appName: string, taskId: string, _assignee: string): Observable<TaskDetailsCloudModel> { claimTask(appName: string, taskId: string): Observable<TaskDetailsCloudModel> {
if ((appName || appName === '') && taskId) { if ((appName || appName === '') && taskId) {
window.alert('Claim task mock'); window.alert('Claim task mock');
return from([]); return from([]);
} else { } else {
return throwError('AppName/TaskId not configured'); return throwError(() => new Error('AppName/TaskId not configured'));
} }
} }
@ -131,11 +127,11 @@ export class TaskCloudServiceMock implements TaskCloudServiceInterface {
return from([]); return from([]);
} else { } else {
return throwError('AppName/TaskId not configured'); return throwError(() => new Error('AppName/TaskId not configured'));
} }
} }
createNewTask(_startTaskRequest: StartTaskCloudRequestModel, _appName: string): Observable<TaskDetailsCloudModel> { createNewTask(): Observable<TaskDetailsCloudModel> {
window.alert('Create new task mock'); window.alert('Create new task mock');
return from([]); return from([]);
@ -147,17 +143,17 @@ export class TaskCloudServiceMock implements TaskCloudServiceInterface {
return from([]); return from([]);
} else { } else {
return throwError('AppName not configured'); return throwError(() => new Error('AppName not configured'));
} }
} }
assign(appName: string, taskId: string, _assignee: string): Observable<TaskDetailsCloudModel> { assign(appName: string, taskId: string): Observable<TaskDetailsCloudModel> {
if (appName && taskId) { if (appName && taskId) {
window.alert('Assign mock'); window.alert('Assign mock');
return from([]); return from([]);
} else { } else {
return throwError('AppName/TaskId not configured'); return throwError(() => new Error('AppName/TaskId not configured'));
} }
} }
} }

View File

@ -1,18 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 './task.model';

View File

@ -16,7 +16,6 @@
*/ */
export class StartTaskCloudRequestModel { export class StartTaskCloudRequestModel {
name: string; name: string;
description: string; description: string;
assignee: string; assignee: string;

View File

@ -51,12 +51,7 @@ export interface StartTaskCloudResponseModel {
entry: TaskDetailsCloudModel; entry: TaskDetailsCloudModel;
} }
export type TaskStatus = export type TaskStatus = 'COMPLETED' | 'CREATED' | 'ASSIGNED' | 'SUSPENDED' | 'CANCELLED';
'COMPLETED' |
'CREATED' |
'ASSIGNED' |
'SUSPENDED' |
'CANCELLED';
export const TASK_COMPLETED_STATE: TaskStatus = 'COMPLETED'; export const TASK_COMPLETED_STATE: TaskStatus = 'COMPLETED';
export const TASK_CREATED_STATE: TaskStatus = 'CREATED'; export const TASK_CREATED_STATE: TaskStatus = 'CREATED';
@ -64,11 +59,7 @@ export const TASK_ASSIGNED_STATE: TaskStatus = 'ASSIGNED';
export const TASK_SUSPENDED_STATE: TaskStatus = 'SUSPENDED'; export const TASK_SUSPENDED_STATE: TaskStatus = 'SUSPENDED';
export const TASK_CANCELLED_STATE: TaskStatus = 'CANCELLED'; export const TASK_CANCELLED_STATE: TaskStatus = 'CANCELLED';
export type TaskPermissions = export type TaskPermissions = 'VIEW' | 'CLAIM' | 'RELEASE' | 'UPDATE';
'VIEW' |
'CLAIM' |
'RELEASE' |
'UPDATE';
export const TASK_CLAIM_PERMISSION: TaskPermissions = 'CLAIM'; export const TASK_CLAIM_PERMISSION: TaskPermissions = 'CLAIM';
export const TASK_RELEASE_PERMISSION: TaskPermissions = 'RELEASE'; export const TASK_RELEASE_PERMISSION: TaskPermissions = 'RELEASE';

View File

@ -17,12 +17,10 @@
export * from './task-list/public-api'; export * from './task-list/public-api';
export * from './task-filters/public-api'; export * from './task-filters/public-api';
export * from './start-task/public-api'; export * from './models/task-details-cloud.model';
export * from './models/task.model';
export * from './models/start-task-cloud-request.model';
export * from './task-header/public-api'; export * from './task-header/public-api';
export * from './task-form/public-api'; export * from './task-form/public-api';
export * from './directives/public-api';
export * from './models/public-api';
export * from './services/task-cloud.service'; export * from './services/task-cloud.service';
export * from './task-cloud.module'; export * from './task-cloud.module';

View File

@ -1,45 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { CardViewArrayItem } from '@alfresco/adf-core';
import { Observable, Subject } from 'rxjs';
import { ProcessDefinitionCloud } from '../../models/process-definition-cloud.model';
import { TaskPriorityOption } from '../models/task.model';
import { StartTaskCloudRequestModel } from '../start-task/models/start-task-cloud-request.model';
import { TaskDetailsCloudModel } from '../start-task/models/task-details-cloud.model';
export interface TaskCloudServiceInterface {
dataChangesDetected$: Subject<unknown>;
priorities: TaskPriorityOption[];
completeTask(appName: string, taskId: string): Observable<TaskDetailsCloudModel>;
canCompleteTask(taskDetails: TaskDetailsCloudModel): boolean;
isTaskEditable(taskDetails: TaskDetailsCloudModel): boolean;
isAssigneePropertyClickable(taskDetails: TaskDetailsCloudModel, candidateUsers: CardViewArrayItem[], candidateGroups: CardViewArrayItem[]): boolean;
canClaimTask(taskDetails: TaskDetailsCloudModel): boolean;
canUnclaimTask(taskDetails: TaskDetailsCloudModel): boolean;
claimTask(appName: string, taskId: string, assignee: string): Observable<TaskDetailsCloudModel>;
unclaimTask(appName: string, taskId: string): Observable<TaskDetailsCloudModel>;
getTaskById(appName: string, taskId: string): Observable<TaskDetailsCloudModel>;
createNewTask(startTaskRequest: StartTaskCloudRequestModel, appName: string): Observable<TaskDetailsCloudModel>;
updateTask(appName: string, taskId: string, payload: any): Observable<TaskDetailsCloudModel>;
getCandidateUsers(appName: string, taskId: string): Observable<string[]>;
getCandidateGroups(appName: string, taskId: string): Observable<string[]>;
getProcessDefinitions(appName: string): Observable<ProcessDefinitionCloud[]>;
assign(appName: string, taskId: string, assignee: string): Observable<TaskDetailsCloudModel>;
getPriorityLabel(priority: number): string;
}

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Injectable } from '@angular/core'; import { inject, Injectable } from '@angular/core';
import { CardViewArrayItem, TranslationService } from '@alfresco/adf-core'; import { CardViewArrayItem, TranslationService } from '@alfresco/adf-core';
import { throwError, Observable, of, Subject } from 'rxjs'; import { throwError, Observable, of, Subject } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
@ -26,22 +26,24 @@ import {
TASK_CLAIM_PERMISSION, TASK_CLAIM_PERMISSION,
TASK_CREATED_STATE, TASK_CREATED_STATE,
TASK_RELEASE_PERMISSION TASK_RELEASE_PERMISSION
} from '../start-task/models/task-details-cloud.model'; } from '../models/task-details-cloud.model';
import { BaseCloudService } from '../../services/base-cloud.service'; import { BaseCloudService } from '../../services/base-cloud.service';
import { StartTaskCloudRequestModel } from '../start-task/models/start-task-cloud-request.model'; import { StartTaskCloudRequestModel } from '../models/start-task-cloud-request.model';
import { ProcessDefinitionCloud } from '../../models/process-definition-cloud.model'; import { ProcessDefinitionCloud } from '../../models/process-definition-cloud.model';
import { DEFAULT_TASK_PRIORITIES, TaskPriorityOption } from '../models/task.model'; import { DEFAULT_TASK_PRIORITIES, TaskPriorityOption } from '../models/task.model';
import { TaskCloudServiceInterface } from './task-cloud.service.interface';
import { IdentityUserService } from '../../people/services/identity-user.service'; import { IdentityUserService } from '../../people/services/identity-user.service';
import { AdfHttpClient } from '@alfresco/adf-core/api'; import { AdfHttpClient } from '@alfresco/adf-core/api';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class TaskCloudService extends BaseCloudService implements TaskCloudServiceInterface { export class TaskCloudService extends BaseCloudService {
private translateService = inject(TranslationService);
private identityUserService = inject(IdentityUserService);
dataChangesDetected$ = new Subject(); dataChangesDetected$ = new Subject();
constructor(private translateService: TranslationService, private identityUserService: IdentityUserService, adfHttpClient: AdfHttpClient) { constructor(adfHttpClient: AdfHttpClient) {
super(adfHttpClient); super(adfHttpClient);
} }
@ -293,7 +295,7 @@ export class TaskCloudService extends BaseCloudService implements TaskCloudServi
return this.appConfigService.get('adf-cloud-priority-values') || DEFAULT_TASK_PRIORITIES; return this.appConfigService.get('adf-cloud-priority-values') || DEFAULT_TASK_PRIORITIES;
} }
private isAssignedToMe(assignee: string): boolean { protected isAssignedToMe(assignee: string): boolean {
const currentUser = this.identityUserService.getCurrentUserInfo().username; const currentUser = this.identityUserService.getCurrentUserInfo().username;
return assignee === currentUser; return assignee === currentUser;
} }

View File

@ -1,18 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 './models/task-details-cloud.model';

View File

@ -17,13 +17,12 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { TaskListCloudModule } from './task-list/task-list-cloud.module'; import { TaskListCloudModule } from './task-list/task-list-cloud.module';
import { TaskFiltersCloudModule } from './task-filters/task-filters-cloud.module'; import { TASK_FILTERS_CLOUD_DIRECTIVES } from './task-filters/task-filters-cloud.module';
import { TASK_DIRECTIVES } from './directives/task-directive.module'; import { TASK_FORM_CLOUD_DIRECTIVES } from './task-form/task-form.module';
import { TaskFormModule } from './task-form/task-form.module';
import { TaskHeaderCloudComponent } from './task-header/components/task-header-cloud.component'; import { TaskHeaderCloudComponent } from './task-header/components/task-header-cloud.component';
@NgModule({ @NgModule({
imports: [TaskListCloudModule, TaskFiltersCloudModule, TaskHeaderCloudComponent, ...TASK_DIRECTIVES, TaskFormModule], imports: [TaskListCloudModule, ...TASK_FILTERS_CLOUD_DIRECTIVES, TaskHeaderCloudComponent, ...TASK_FORM_CLOUD_DIRECTIVES],
exports: [TaskListCloudModule, TaskFiltersCloudModule, TaskHeaderCloudComponent, ...TASK_DIRECTIVES, TaskFormModule] exports: [TaskListCloudModule, ...TASK_FILTERS_CLOUD_DIRECTIVES, TaskHeaderCloudComponent, ...TASK_FORM_CLOUD_DIRECTIVES]
}) })
export class TaskCloudModule {} export class TaskCloudModule {}

View File

@ -0,0 +1,117 @@
<mat-accordion [hideToggle]="isLoading" class="adf-edit-task-filter">
<mat-expansion-panel (afterExpand)="onExpand()" (closed)="onClose()">
<mat-expansion-panel-header *ngIf="taskFilter" id="adf-edit-task-filter-expansion-header" class="adf-edit-task-filter-header">
<ng-container *ngIf="!isLoading; else loadingTemplate">
<mat-panel-title *ngIf="showTaskFilterName" id="adf-edit-task-filter-title-id" class="adf-edit-task-filter-header__title"
>{{taskFilter.name | translate}}</mat-panel-title>
<mat-panel-description class="adf-edit-task-filter-header__description" id="adf-edit-task-filter-sub-title-id">
<span *ngIf="showTitle">{{ 'ADF_CLOUD_EDIT_TASK_FILTER.TITLE' | translate}}</span>
<div *ngIf="showFilterActions" class="adf-cloud-edit-task-filter-actions">
<ng-container *ngIf="toggleFilterActions">
<button *ngFor="let filterAction of taskFilterActions"
mat-icon-button
[title]="filterAction.tooltip | translate"
[attr.data-automation-id]="'adf-filter-action-' + filterAction.actionType"
[disabled]="isDisabledAction(filterAction)"
(click)="executeFilterActions(filterAction)">
<adf-icon [value]="filterAction.icon" />
</button>
</ng-container>
</div>
</mat-panel-description>
</ng-container>
<ng-template #loadingTemplate>
<div class="adf-cloud-edit-task-filter-loading-margin">
<mat-progress-spinner mode="indeterminate" [diameter]="30" />
</div>
</ng-template>
</mat-expansion-panel-header>
<ng-container *ngIf="!isLoading;">
<form *ngIf="editTaskFilterForm" [formGroup]="editTaskFilterForm" class="adf-edit-task-filter-content">
<div class="adf-edit-task-filter-form">
<ng-container *ngFor="let taskFilterProperty of taskFilterProperties">
<mat-form-field [floatLabel]="'auto'"
*ngIf="taskFilterProperty.type === 'select'"
[attr.data-automation-id]="taskFilterProperty.key">
<mat-label class="adf-edit-task-filter-content__select-label">{{taskFilterProperty.label | translate}}</mat-label>
<mat-select
[formControlName]="taskFilterProperty.key"
[attr.data-automation-id]="'adf-cloud-edit-task-property-' + taskFilterProperty.key"
(selectionChange)="onStatusChange($event)">
<mat-option *ngFor="let propertyOption of taskFilterProperty.options"
[value]="propertyOption.value"
[attr.data-automation-id]="'adf-cloud-edit-task-property-options-' + taskFilterProperty.key">
{{ propertyOption.label | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field [floatLabel]="'auto'"
*ngIf="taskFilterProperty.type === 'text'"
[attr.data-automation-id]="taskFilterProperty.key">
<mat-label class="adf-edit-task-filter-content__text-label">{{taskFilterProperty.label | translate}}</mat-label>
<input matInput
[formControlName]="taskFilterProperty.key"
type="text"
[attr.data-automation-id]="'adf-cloud-edit-task-property-' + taskFilterProperty.key" />
</mat-form-field>
<mat-form-field [floatLabel]="'auto'"
*ngIf="taskFilterProperty.type === 'date'"
[attr.data-automation-id]="taskFilterProperty.key">
<mat-label>{{taskFilterProperty.label | translate}}</mat-label>
<input matInput
(keyup)="onDateChanged($any($event).target.value, taskFilterProperty)"
(dateChange)="onDateChanged($event.value, taskFilterProperty)"
[matDatepicker]="dateController"
[placeholder]="taskFilterProperty.label | translate"
[attr.data-automation-id]="'adf-cloud-edit-task-property-' + taskFilterProperty.key">
<mat-datepicker-toggle matSuffix
[for]="dateController"
[attr.data-automation-id]="'adf-cloud-edit-task-property-date-toggle-' + taskFilterProperty.key" />
<mat-datepicker #dateController
[attr.data-automation-id]="'adf-cloud-edit-task-property-date-picker-' + taskFilterProperty.key" />
<div class="adf-edit-task-filter-date-error-container">
<div *ngIf="hasError(taskFilterProperty)">
<div class="adf-error-text">{{'ADF_TASK_LIST.START_TASK.FORM.ERROR.DATE'|translate}}</div>
<mat-icon class="adf-error-icon">warning</mat-icon>
</div>
</div>
</mat-form-field>
<div class="adf-edit-task-filter-checkbox"
*ngIf="taskFilterProperty.type === 'checkbox'">
<mat-checkbox color="primary"
[formControlName]="taskFilterProperty.key"
[attr.data-automation-id]="taskFilterProperty.key"
>{{taskFilterProperty.label | translate}}</mat-checkbox>
</div>
<adf-cloud-date-range-filter
*ngIf="taskFilterProperty.type === 'date-range'"
[processFilterProperty]="taskFilterProperty"
[options]="taskFilterProperty.dateFilterOptions"
(dateTypeChange)="onDateTypeChange($event, taskFilterProperty)"
(dateChanged)="onDateRangeFilterChanged($event, taskFilterProperty)" />
<adf-cloud-people
class="{{ 'adf-edit-task-filter-' + taskFilterProperty.key }}"
*ngIf="taskFilterProperty.type === 'people'"
[preSelectUsers]="taskFilterProperty.value"
[title]="taskFilterProperty.label"
[validate]="true"
[appName]="appName"
[mode]="taskFilterProperty.selectionMode"
(changedUsers)="onChangedUser($event, taskFilterProperty)" />
<adf-cloud-task-assignment-filter
*ngIf="taskFilterProperty.type === 'assignment'"
[taskFilterProperty]="taskFilterProperty"
[status]="selectedStatus"
[appName]="appName"
(assignedUsersChange)="onAssignedUsersChange($event)"
(assignedGroupsChange)="onAssignedGroupsChange($event)"
(assignmentTypeChange)="onAssignmentTypeChange($event)" />
</ng-container>
</div>
</form>
</ng-container>
</mat-expansion-panel>
</mat-accordion>

View File

@ -19,21 +19,20 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SimpleChange } from '@angular/core'; import { SimpleChange } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { of, Subject } from 'rxjs'; import { of, Subject } from 'rxjs';
import { TASK_FILTERS_SERVICE_TOKEN } from '../../../../services/cloud-token.service'; import { TASK_FILTERS_SERVICE_TOKEN } from '../../../../../services/cloud-token.service';
import { LocalPreferenceCloudService } from '../../../../services/local-preference-cloud.service'; import { LocalPreferenceCloudService } from '../../../../../services/local-preference-cloud.service';
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module'; import { ProcessServiceCloudTestingModule } from '../../../../../testing/process-service-cloud.testing.module';
import { AppsProcessCloudService } from '../../../../app/services/apps-process-cloud.service'; import { AppsProcessCloudService } from '../../../../../app/services/apps-process-cloud.service';
import { fakeApplicationInstance, fakeApplicationInstanceWithEnvironment } from '../../../../app/mock/app-model.mock'; import { fakeApplicationInstance, fakeApplicationInstanceWithEnvironment } from '../../../../../app/mock/app-model.mock';
import { TaskFiltersCloudModule } from '../../task-filters-cloud.module'; import { ServiceTaskFilterCloudService } from '../../../services/service-task-filter-cloud.service';
import { ServiceTaskFilterCloudService } from '../../services/service-task-filter-cloud.service'; import { TaskCloudService } from '../../../../services/task-cloud.service';
import { TaskCloudService } from '../../../services/task-cloud.service'; import { fakeServiceFilter } from '../../../mock/task-filters-cloud.mock';
import { fakeServiceFilter } from '../../mock/task-filters-cloud.mock';
import { EditServiceTaskFilterCloudComponent } from './edit-service-task-filter-cloud.component'; import { EditServiceTaskFilterCloudComponent } from './edit-service-task-filter-cloud.component';
import { MatIconTestingModule } from '@angular/material/icon/testing'; import { MatIconTestingModule } from '@angular/material/icon/testing';
import { ProcessDefinitionCloud } from '../../../../models/process-definition-cloud.model'; import { ProcessDefinitionCloud } from '../../../../../models/process-definition-cloud.model';
import { TaskFilterDialogCloudComponent } from '../task-filter-dialog/task-filter-dialog-cloud.component'; import { TaskFilterDialogCloudComponent } from '../../task-filter-dialog/task-filter-dialog-cloud.component';
import { fakeEnvironmentList } from '../../../../common/mock/environment.mock'; import { fakeEnvironmentList } from '../../../../../common/mock/environment.mock';
import { mockApplicationTaskFilterProperties } from '../../mock/edit-task-filter-cloud.mock'; import { mockApplicationTaskFilterProperties } from '../../../mock/edit-task-filter-cloud.mock';
import { HarnessLoader } from '@angular/cdk/testing'; import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatExpansionPanelHarness } from '@angular/material/expansion/testing'; import { MatExpansionPanelHarness } from '@angular/material/expansion/testing';
@ -54,7 +53,7 @@ describe('EditServiceTaskFilterCloudComponent', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ProcessServiceCloudTestingModule, TaskFiltersCloudModule, MatIconTestingModule], imports: [ProcessServiceCloudTestingModule, MatIconTestingModule, EditServiceTaskFilterCloudComponent],
providers: [MatDialog, { provide: TASK_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }] providers: [MatDialog, { provide: TASK_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }]
}); });
fixture = TestBed.createComponent(EditServiceTaskFilterCloudComponent); fixture = TestBed.createComponent(EditServiceTaskFilterCloudComponent);

View File

@ -17,15 +17,50 @@
import { Component, inject, ViewEncapsulation } from '@angular/core'; import { Component, inject, ViewEncapsulation } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { ServiceTaskFilterCloudModel, TaskFilterAction, TaskFilterProperties } from '../../models/filter-cloud.model'; import { ServiceTaskFilterCloudModel, TaskFilterAction, TaskFilterProperties } from '../../../models/filter-cloud.model';
import { ServiceTaskFilterCloudService } from '../../services/service-task-filter-cloud.service'; import { ServiceTaskFilterCloudService } from '../../../services/service-task-filter-cloud.service';
import { BaseEditTaskFilterCloudComponent, DropdownOption } from './base-edit-task-filter-cloud.component'; import { BaseEditTaskFilterCloudComponent, DropdownOption } from '../base-edit-task-filter-cloud.component';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatButtonModule } from '@angular/material/button';
import { IconComponent } from '@alfresco/adf-core';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { ReactiveFormsModule } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { MatInputModule } from '@angular/material/input';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatIconModule } from '@angular/material/icon';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { DateRangeFilterComponent } from '../../../../../common/date-range-filter/date-range-filter.component';
import { PeopleCloudComponent } from '../../../../../people/components/people-cloud.component';
import { TaskAssignmentFilterCloudComponent } from '../../task-assignment-filter/task-assignment-filter.component';
@Component({ @Component({
selector: 'adf-cloud-edit-service-task-filter', selector: 'adf-cloud-edit-service-task-filter',
templateUrl: './base-edit-task-filter-cloud.component.html', standalone: true,
styleUrls: ['./base-edit-task-filter-cloud.component.scss'], imports: [
CommonModule,
TranslateModule,
MatExpansionModule,
MatButtonModule,
IconComponent,
MatProgressSpinnerModule,
ReactiveFormsModule,
MatFormFieldModule,
MatSelectModule,
MatInputModule,
MatDatepickerModule,
MatIconModule,
MatCheckboxModule,
DateRangeFilterComponent,
PeopleCloudComponent,
TaskAssignmentFilterCloudComponent
],
templateUrl: './edit-service-task-filter-cloud.component.html',
styleUrls: ['./edit-service-task-filter-cloud.component.scss'],
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class EditServiceTaskFilterCloudComponent extends BaseEditTaskFilterCloudComponent<ServiceTaskFilterCloudModel> { export class EditServiceTaskFilterCloudComponent extends BaseEditTaskFilterCloudComponent<ServiceTaskFilterCloudModel> {
@ -62,9 +97,7 @@ export class EditServiceTaskFilterCloudComponent extends BaseEditTaskFilterCloud
} }
protected addFilter(filterToAdd: ServiceTaskFilterCloudModel): Observable<any> { protected addFilter(filterToAdd: ServiceTaskFilterCloudModel): Observable<any> {
return this.serviceTaskFilterCloudService return this.serviceTaskFilterCloudService.addFilter(filterToAdd).pipe(takeUntilDestroyed(this.destroyRef));
.addFilter(filterToAdd)
.pipe(takeUntilDestroyed(this.destroyRef));
} }
isDisabledForDefaultFilters(action: TaskFilterAction): boolean { isDisabledForDefaultFilters(action: TaskFilterAction): boolean {

View File

@ -0,0 +1,97 @@
@import 'styles/flex';
.adf-edit-task-filter-checkbox {
font-size: var(--theme-subheading-2-font-size);
padding-top: 10px;
text-align: center;
flex: 1 23%;
}
.adf-edit-task-filter-date-error-container {
position: absolute;
height: 20px;
margin-top: 12px;
width: 100%;
& > div {
display: flex;
flex-flow: row;
justify-content: flex-start;
}
.adf-error-text {
padding-right: 8px;
height: 16px;
font-size: 10px;
line-height: 1.33;
color: var(--theme-warn-color);
width: auto;
}
.adf-error-icon {
font-size: 16px;
color: var(--theme-warn-color);
}
}
.adf-edit-task-filter-dateRange mat-grid-list {
width: 450px;
}
.adf {
&-cloud-edit-task-filter-loading-margin {
margin-left: calc((100% - 100px) / 2);
margin-right: calc((100% - 100px) / 2);
}
&-edit-task-filter-form {
flex-flow: row wrap;
display: flex;
place-content: center flex-start;
align-items: center;
:not(:last-child) {
margin-right: 10px;
}
mat-form-field,
adf-cloud-people,
adf-cloud-task-assignment-filter {
flex: 1 1 23%;
}
@include layout-bp(lt-sm) {
flex-flow: column;
:not(:last-child) {
margin-bottom: 10px;
margin-right: 0;
}
}
}
&-edit-task-filter {
&-header {
height: var(--adf-edit-task-and-service-filter-header-height);
&__title {
color: var(--adf-edit-task-and-service-filter-header-title-color);
}
&__description {
color: var(--adf-edit-task-and-service-filter-header-description-color);
place-content: center space-between;
}
}
&-content {
&__text-label {
color: var(--adf-edit-task-and-service-filter-content-text-label-color);
}
&__select-label {
color: var(--adf-edit-task-and-service-filter-content-select-label-color);
}
}
}
}

View File

@ -20,20 +20,18 @@ import { By } from '@angular/platform-browser';
import { AlfrescoApiService } from '@alfresco/adf-content-services'; import { AlfrescoApiService } from '@alfresco/adf-content-services';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { of, Subject } from 'rxjs'; import { of, Subject } from 'rxjs';
import { TASK_FILTERS_SERVICE_TOKEN } from '../../../../services/cloud-token.service'; import { TASK_FILTERS_SERVICE_TOKEN } from '../../../../../services/cloud-token.service';
import { LocalPreferenceCloudService } from '../../../../services/local-preference-cloud.service'; import { LocalPreferenceCloudService } from '../../../../../services/local-preference-cloud.service';
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module'; import { ProcessServiceCloudTestingModule } from '../../../../../testing/process-service-cloud.testing.module';
import { AppsProcessCloudService } from '../../../../app/services/apps-process-cloud.service'; import { AppsProcessCloudService } from '../../../../../app/services/apps-process-cloud.service';
import { fakeApplicationInstance } from '../../../../app/mock/app-model.mock'; import { fakeApplicationInstance } from '../../../../../app/mock/app-model.mock';
import { TaskFiltersCloudModule } from '../../task-filters-cloud.module';
import { EditTaskFilterCloudComponent } from './edit-task-filter-cloud.component'; import { EditTaskFilterCloudComponent } from './edit-task-filter-cloud.component';
import { TaskFilterCloudService } from '../../services/task-filter-cloud.service'; import { TaskFilterCloudService } from '../../../services/task-filter-cloud.service';
import { TaskCloudService } from '../../../services/task-cloud.service'; import { TaskCloudService } from '../../../../services/task-cloud.service';
import { fakeFilter } from '../../mock/task-filters-cloud.mock'; import { fakeFilter } from '../../../mock/task-filters-cloud.mock';
import { DateCloudFilterType } from '../../../../models/date-cloud-filter.model'; import { DateCloudFilterType } from '../../../../../models/date-cloud-filter.model';
import { AssignmentType, TaskFilterCloudModel, TaskStatusFilter } from '../../models/filter-cloud.model'; import { AssignmentType, TaskFilterCloudModel, TaskStatusFilter } from '../../../models/filter-cloud.model';
import { PeopleCloudModule } from '../../../../people/people-cloud.module'; import { ProcessDefinitionCloud } from '../../../../../models/process-definition-cloud.model';
import { ProcessDefinitionCloud } from '../../../../models/process-definition-cloud.model';
import { MatIconTestingModule } from '@angular/material/icon/testing'; import { MatIconTestingModule } from '@angular/material/icon/testing';
import { import {
mockAlfrescoApi, mockAlfrescoApi,
@ -46,17 +44,18 @@ import {
mockTaskFilterIdChange, mockTaskFilterIdChange,
mockTaskFilterResponse, mockTaskFilterResponse,
mockTaskFilterResponseWithProcessInstanceIdNull mockTaskFilterResponseWithProcessInstanceIdNull
} from '../../mock/edit-task-filter-cloud.mock'; } from '../../../mock/edit-task-filter-cloud.mock';
import { mockFoodUsers } from '../../../../people/mock/people-cloud.mock'; import { mockFoodUsers } from '../../../../../people/mock/people-cloud.mock';
import { mockFoodGroups } from '../../../../group/mock/group-cloud.mock'; import { mockFoodGroups } from '../../../../../group/mock/group-cloud.mock';
import { SimpleChanges } from '@angular/core'; import { SimpleChanges } from '@angular/core';
import { TaskFilterDialogCloudComponent } from '../task-filter-dialog/task-filter-dialog-cloud.component'; import { TaskFilterDialogCloudComponent } from '../../task-filter-dialog/task-filter-dialog-cloud.component';
import { set } from 'date-fns'; import { set } from 'date-fns';
import { HarnessLoader } from '@angular/cdk/testing'; import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatSelectHarness } from '@angular/material/select/testing'; import { MatSelectHarness } from '@angular/material/select/testing';
import { MatExpansionPanelHarness } from '@angular/material/expansion/testing'; import { MatExpansionPanelHarness } from '@angular/material/expansion/testing';
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing'; import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
import { PeopleCloudComponent } from '@alfresco/adf-process-services-cloud';
describe('EditTaskFilterCloudComponent', () => { describe('EditTaskFilterCloudComponent', () => {
let loader: HarnessLoader; let loader: HarnessLoader;
@ -74,7 +73,7 @@ describe('EditTaskFilterCloudComponent', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ProcessServiceCloudTestingModule, TaskFiltersCloudModule, PeopleCloudModule, MatIconTestingModule], imports: [ProcessServiceCloudTestingModule, PeopleCloudComponent, MatIconTestingModule, EditTaskFilterCloudComponent],
providers: [MatDialog, { provide: TASK_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }] providers: [MatDialog, { provide: TASK_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }]
}); });
fixture = TestBed.createComponent(EditTaskFilterCloudComponent); fixture = TestBed.createComponent(EditTaskFilterCloudComponent);

View File

@ -18,22 +18,52 @@
import { Component, inject, ViewEncapsulation } from '@angular/core'; import { Component, inject, ViewEncapsulation } from '@angular/core';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { import { TaskFilterAction, TaskFilterCloudModel, TaskFilterProperties, TaskStatusFilter } from '../../../models/filter-cloud.model';
TaskFilterAction, import { TaskFilterCloudService } from '../../../services/task-filter-cloud.service';
TaskFilterCloudModel, import { DateCloudFilterType } from '../../../../../models/date-cloud-filter.model';
TaskFilterProperties, import { BaseEditTaskFilterCloudComponent, DropdownOption } from '../base-edit-task-filter-cloud.component';
TaskStatusFilter
} from '../../models/filter-cloud.model';
import { TaskFilterCloudService } from '../../services/task-filter-cloud.service';
import { DateCloudFilterType } from '../../../../models/date-cloud-filter.model';
import { BaseEditTaskFilterCloudComponent, DropdownOption } from './base-edit-task-filter-cloud.component';
import { set } from 'date-fns'; import { set } from 'date-fns';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatButtonModule } from '@angular/material/button';
import { IconComponent } from '@alfresco/adf-core';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatFormFieldModule } from '@angular/material/form-field';
import { ReactiveFormsModule } from '@angular/forms';
import { MatSelectModule } from '@angular/material/select';
import { MatInputModule } from '@angular/material/input';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatIconModule } from '@angular/material/icon';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { DateRangeFilterComponent } from '../../../../../common/date-range-filter/date-range-filter.component';
import { PeopleCloudComponent } from '../../../../../people/components/people-cloud.component';
import { TaskAssignmentFilterCloudComponent } from '../../task-assignment-filter/task-assignment-filter.component';
@Component({ @Component({
selector: 'adf-cloud-edit-task-filter', selector: 'adf-cloud-edit-task-filter',
templateUrl: './base-edit-task-filter-cloud.component.html', standalone: true,
styleUrls: ['./base-edit-task-filter-cloud.component.scss'], imports: [
CommonModule,
TranslateModule,
MatExpansionModule,
MatButtonModule,
IconComponent,
MatProgressSpinnerModule,
MatFormFieldModule,
ReactiveFormsModule,
MatSelectModule,
MatInputModule,
MatDatepickerModule,
MatIconModule,
MatCheckboxModule,
DateRangeFilterComponent,
PeopleCloudComponent,
TaskAssignmentFilterCloudComponent
],
templateUrl: './edit-task-filter-cloud.component.html',
styleUrls: ['./edit-task-filter-cloud.component.scss'],
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class EditTaskFilterCloudComponent extends BaseEditTaskFilterCloudComponent<TaskFilterCloudModel> { export class EditTaskFilterCloudComponent extends BaseEditTaskFilterCloudComponent<TaskFilterCloudModel> {
@ -51,21 +81,14 @@ export class EditTaskFilterCloudComponent extends BaseEditTaskFilterCloudCompone
} }
protected getTaskFilterById(appName: string, id: string) { protected getTaskFilterById(appName: string, id: string) {
return this.taskFilterCloudService return this.taskFilterCloudService.getTaskFilterById(appName, id).pipe(map((response) => new TaskFilterCloudModel(response)));
.getTaskFilterById(appName, id)
.pipe(
map(response => new TaskFilterCloudModel(response))
);
} }
createAndFilterProperties() { createAndFilterProperties() {
const result = super.createAndFilterProperties(); const result = super.createAndFilterProperties();
if (this.hasLastModifiedProperty()) { if (this.hasLastModifiedProperty()) {
return [ return [...result, ...this.createLastModifiedProperty()];
...result,
...this.createLastModifiedProperty()
];
} }
return result; return result;
@ -81,14 +104,11 @@ export class EditTaskFilterCloudComponent extends BaseEditTaskFilterCloudCompone
private setLastModifiedToFilter(formValues: TaskFilterCloudModel) { private setLastModifiedToFilter(formValues: TaskFilterCloudModel) {
if (formValues.lastModifiedTo && Date.parse(formValues.lastModifiedTo.toString())) { if (formValues.lastModifiedTo && Date.parse(formValues.lastModifiedTo.toString())) {
const lastModifiedToFilterValue = set( const lastModifiedToFilterValue = set(new Date(formValues.lastModifiedTo), {
new Date(formValues.lastModifiedTo), hours: 23,
{ minutes: 59,
hours: 23, seconds: 59
minutes: 59, });
seconds: 59
}
);
formValues.lastModifiedTo = lastModifiedToFilterValue.toISOString(); formValues.lastModifiedTo = lastModifiedToFilterValue.toISOString();
} }
} }
@ -102,9 +122,7 @@ export class EditTaskFilterCloudComponent extends BaseEditTaskFilterCloudCompone
} }
protected addFilter(filterToAdd: TaskFilterCloudModel): Observable<any> { protected addFilter(filterToAdd: TaskFilterCloudModel): Observable<any> {
return this.taskFilterCloudService return this.taskFilterCloudService.addFilter(filterToAdd).pipe(takeUntilDestroyed(this.destroyRef));
.addFilter(filterToAdd)
.pipe(takeUntilDestroyed(this.destroyRef));
} }
isDisabledForDefaultFilters(action: TaskFilterAction): boolean { isDisabledForDefaultFilters(action: TaskFilterAction): boolean {
@ -250,7 +268,7 @@ export class EditTaskFilterCloudComponent extends BaseEditTaskFilterCloudCompone
label: 'ADF_CLOUD_EDIT_TASK_FILTER.LABEL.DUE_DATE', label: 'ADF_CLOUD_EDIT_TASK_FILTER.LABEL.DUE_DATE',
type: 'date-range', type: 'date-range',
key: 'dueDateRange', key: 'dueDateRange',
attributes: { dateType: 'dueDateType', from: '_dueDateFrom', to: '_dueDateTo'}, attributes: { dateType: 'dueDateType', from: '_dueDateFrom', to: '_dueDateTo' },
value: { value: {
dueDateType: this.taskFilter.dueDateType || null, dueDateType: this.taskFilter.dueDateType || null,
_dueDateFrom: this.taskFilter.dueDateFrom || null, _dueDateFrom: this.taskFilter.dueDateFrom || null,
@ -268,7 +286,7 @@ export class EditTaskFilterCloudComponent extends BaseEditTaskFilterCloudCompone
label: 'ADF_CLOUD_EDIT_TASK_FILTER.LABEL.COMPLETED_DATE', label: 'ADF_CLOUD_EDIT_TASK_FILTER.LABEL.COMPLETED_DATE',
type: 'date-range', type: 'date-range',
key: 'completedDateRange', key: 'completedDateRange',
attributes: { dateType: 'completedDateType', from: '_completedFrom', to: '_completedTo'}, attributes: { dateType: 'completedDateType', from: '_completedFrom', to: '_completedTo' },
value: { value: {
completedDateType: this.taskFilter.completedDateType || null, completedDateType: this.taskFilter.completedDateType || null,
_completedFrom: this.taskFilter.completedFrom || null, _completedFrom: this.taskFilter.completedFrom || null,
@ -279,7 +297,7 @@ export class EditTaskFilterCloudComponent extends BaseEditTaskFilterCloudCompone
label: 'ADF_CLOUD_EDIT_TASK_FILTER.LABEL.CREATED_DATE', label: 'ADF_CLOUD_EDIT_TASK_FILTER.LABEL.CREATED_DATE',
type: 'date-range', type: 'date-range',
key: 'createdDateRange', key: 'createdDateRange',
attributes: { dateType: 'createdDateType', from: '_createdFrom', to: '_createdTo'}, attributes: { dateType: 'createdDateType', from: '_createdFrom', to: '_createdTo' },
value: { value: {
createdDateType: this.taskFilter.createdDateType || null, createdDateType: this.taskFilter.createdDateType || null,
_createdFrom: this.taskFilter.createdFrom || null, _createdFrom: this.taskFilter.createdFrom || null,
@ -297,7 +315,7 @@ export class EditTaskFilterCloudComponent extends BaseEditTaskFilterCloudCompone
label: 'ADF_CLOUD_EDIT_TASK_FILTER.LABEL.ASSIGNMENT', label: 'ADF_CLOUD_EDIT_TASK_FILTER.LABEL.ASSIGNMENT',
type: 'assignment', type: 'assignment',
key: 'assignment', key: 'assignment',
attributes: { assignedUsers: 'assignedUsers', candidateGroups: 'candidateGroups'}, attributes: { assignedUsers: 'assignedUsers', candidateGroups: 'candidateGroups' },
value: { value: {
assignedUsers: this.taskFilter.assignedUsers || [], assignedUsers: this.taskFilter.assignedUsers || [],
candidateGroups: this.taskFilter.candidateGroups || [] candidateGroups: this.taskFilter.candidateGroups || []

View File

@ -18,13 +18,12 @@
import { SimpleChange } from '@angular/core'; import { SimpleChange } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { of, throwError } from 'rxjs'; import { of, throwError } from 'rxjs';
import { TASK_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service'; import { TASK_FILTERS_SERVICE_TOKEN } from '../../../../services/cloud-token.service';
import { LocalPreferenceCloudService } from '../../../services/local-preference-cloud.service'; import { LocalPreferenceCloudService } from '../../../../services/local-preference-cloud.service';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module'; import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
import { TaskFiltersCloudModule } from '../task-filters-cloud.module'; import { fakeGlobalServiceFilters } from '../../mock/task-filters-cloud.mock';
import { fakeGlobalServiceFilters } from '../mock/task-filters-cloud.mock'; import { ServiceTaskFilterCloudService } from '../../services/service-task-filter-cloud.service';
import { ServiceTaskFilterCloudService } from '../services/service-task-filter-cloud.service';
import { ServiceTaskFiltersCloudComponent } from './service-task-filters-cloud.component'; import { ServiceTaskFiltersCloudComponent } from './service-task-filters-cloud.component';
describe('ServiceTaskFiltersCloudComponent', () => { describe('ServiceTaskFiltersCloudComponent', () => {
@ -36,7 +35,7 @@ describe('ServiceTaskFiltersCloudComponent', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ProcessServiceCloudTestingModule, TaskFiltersCloudModule], imports: [ProcessServiceCloudTestingModule, ServiceTaskFiltersCloudComponent],
providers: [{ provide: TASK_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }] providers: [{ provide: TASK_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }]
}); });
fixture = TestBed.createComponent(ServiceTaskFiltersCloudComponent); fixture = TestBed.createComponent(ServiceTaskFiltersCloudComponent);

View File

@ -15,27 +15,24 @@
* limitations under the License. * limitations under the License.
*/ */
import { import { Component, EventEmitter, inject, OnChanges, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
Component,
EventEmitter,
inject,
OnChanges,
OnInit,
Output,
SimpleChanges,
ViewEncapsulation
} from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { FilterParamsModel, ServiceTaskFilterCloudModel } from '../models/filter-cloud.model'; import { FilterParamsModel, ServiceTaskFilterCloudModel } from '../../models/filter-cloud.model';
import { BaseTaskFiltersCloudComponent } from './base-task-filters-cloud.component'; import { BaseTaskFiltersCloudComponent } from '../base-task-filters-cloud.component';
import { ServiceTaskFilterCloudService } from '../services/service-task-filter-cloud.service'; import { ServiceTaskFilterCloudService } from '../../services/service-task-filter-cloud.service';
import { TranslationService } from '@alfresco/adf-core'; import { IconComponent, TranslationService } from '@alfresco/adf-core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatListModule } from '@angular/material/list';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
@Component({ @Component({
selector: 'adf-cloud-service-task-filters', selector: 'adf-cloud-service-task-filters',
templateUrl: './base-task-filters-cloud.component.html', standalone: true,
styleUrls: ['./base-task-filters-cloud.component.scss'], imports: [CommonModule, TranslateModule, MatListModule, IconComponent, MatProgressSpinnerModule],
templateUrl: './service-task-filters-cloud.component.html',
styleUrls: ['./service-task-filters-cloud.component.scss'],
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class ServiceTaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent implements OnInit, OnChanges { export class ServiceTaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent implements OnInit, OnChanges {

View File

@ -21,7 +21,6 @@
<adf-cloud-group *ngIf="isCandidateGroupsType()" <adf-cloud-group *ngIf="isCandidateGroupsType()"
class="adf-group-cloud-filter" class="adf-group-cloud-filter"
data-automation-id="adf-group-cloud-candidate-groups-filter" data-automation-id="adf-group-cloud-candidate-groups-filter"
[mode]="'multiple'"
[appName]="appName" [appName]="appName"
[preSelectGroups]="candidateGroups" [preSelectGroups]="candidateGroups"
[mode]="taskFilterProperty.selectionMode" [mode]="taskFilterProperty.selectionMode"

View File

@ -17,8 +17,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TaskAssignmentFilterCloudComponent } from './task-assignment-filter.component'; import { TaskAssignmentFilterCloudComponent } from './task-assignment-filter.component';
import { GroupCloudModule } from '../../../../group/group-cloud.module';
import { TaskFiltersCloudModule } from '../../task-filters-cloud.module';
import { AssignmentType, TaskStatusFilter } from '../../models/filter-cloud.model'; import { AssignmentType, TaskStatusFilter } from '../../models/filter-cloud.model';
import { IdentityUserService } from '../../../../people/services/identity-user.service'; import { IdentityUserService } from '../../../../people/services/identity-user.service';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
@ -30,6 +28,7 @@ import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatSelectHarness } from '@angular/material/select/testing'; import { MatSelectHarness } from '@angular/material/select/testing';
import { MatFormFieldHarness } from '@angular/material/form-field/testing'; import { MatFormFieldHarness } from '@angular/material/form-field/testing';
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module'; import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
import { GroupCloudComponent } from '@alfresco/adf-process-services-cloud';
describe('TaskAssignmentFilterComponent', () => { describe('TaskAssignmentFilterComponent', () => {
let component: TaskAssignmentFilterCloudComponent; let component: TaskAssignmentFilterCloudComponent;
@ -58,7 +57,7 @@ describe('TaskAssignmentFilterComponent', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ProcessServiceCloudTestingModule, GroupCloudModule, TaskFiltersCloudModule] imports: [ProcessServiceCloudTestingModule, GroupCloudComponent, TaskAssignmentFilterCloudComponent]
}); });
}); });

View File

@ -16,21 +16,26 @@
*/ */
import { Component, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges } from '@angular/core'; import { Component, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { MatSelectChange } from '@angular/material/select'; import { MatSelectChange, MatSelectModule } from '@angular/material/select';
import { AssignmentType, TaskFilterProperties, TaskStatusFilter } from '../../models/filter-cloud.model'; import { AssignmentType, TaskFilterProperties, TaskStatusFilter } from '../../models/filter-cloud.model';
import { IdentityUserModel } from '../../../../people/models/identity-user.model'; import { IdentityUserModel } from '../../../../people/models/identity-user.model';
import { IdentityUserService } from '../../../../people/services/identity-user.service'; import { IdentityUserService } from '../../../../people/services/identity-user.service';
import { IdentityGroupModel } from '../../../../group/models/identity-group.model'; import { IdentityGroupModel } from '../../../../group/models/identity-group.model';
import { DropdownOption } from '../edit-task-filters/base-edit-task-filter-cloud.component'; import { DropdownOption } from '../edit-task-filters/base-edit-task-filter-cloud.component';
import { FormControl } from '@angular/forms'; import { FormControl, FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { GroupCloudComponent } from '../../../../group/components/group-cloud.component';
import { PeopleCloudComponent } from '../../../../people/components/people-cloud.component';
@Component({ @Component({
selector: 'adf-cloud-task-assignment-filter', selector: 'adf-cloud-task-assignment-filter',
standalone: true,
imports: [CommonModule, GroupCloudComponent, TranslateModule, MatSelectModule, FormsModule, PeopleCloudComponent],
templateUrl: './task-assignment-filter.component.html', templateUrl: './task-assignment-filter.component.html',
styleUrls: ['./task-assignment-filter.component.scss'] styleUrls: ['./task-assignment-filter.component.scss']
}) })
export class TaskAssignmentFilterCloudComponent implements OnInit, OnChanges { export class TaskAssignmentFilterCloudComponent implements OnInit, OnChanges {
@Input() appName: string; @Input() appName: string;
@Input() taskFilterProperty: TaskFilterProperties; @Input() taskFilterProperty: TaskFilterProperties;

View File

@ -18,7 +18,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { TaskFilterDialogCloudComponent } from './task-filter-dialog-cloud.component'; import { TaskFilterDialogCloudComponent } from './task-filter-dialog-cloud.component';
import { TaskFiltersCloudModule } from '../../task-filters-cloud.module';
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module'; import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
describe('TaskFilterDialogCloudComponent', () => { describe('TaskFilterDialogCloudComponent', () => {
@ -36,7 +35,7 @@ describe('TaskFilterDialogCloudComponent', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ProcessServiceCloudTestingModule, TaskFiltersCloudModule], imports: [ProcessServiceCloudTestingModule, TaskFilterDialogCloudComponent],
providers: [ providers: [
{ provide: MatDialogRef, useValue: mockDialogRef }, { provide: MatDialogRef, useValue: mockDialogRef },
{ provide: MAT_DIALOG_DATA, useValue: mockDialogData } { provide: MAT_DIALOG_DATA, useValue: mockDialogData }

View File

@ -16,17 +16,23 @@
*/ */
import { Component, Inject, OnInit, ViewEncapsulation } from '@angular/core'; import { Component, Inject, OnInit, ViewEncapsulation } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { AbstractControl, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { AbstractControl, ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatInputModule } from '@angular/material/input';
import { MatCardModule } from '@angular/material/card';
import { MatButtonModule } from '@angular/material/button';
@Component({ @Component({
selector: 'adf-cloud-task-filter-dialog', selector: 'adf-cloud-task-filter-dialog',
templateUrl: './task-filter-dialog-cloud.component.html', standalone: true,
styleUrls: ['./task-filter-dialog-cloud.component.scss'], imports: [CommonModule, TranslateModule, MatInputModule, ReactiveFormsModule, MatDialogModule, MatCardModule, MatButtonModule],
encapsulation: ViewEncapsulation.None templateUrl: './task-filter-dialog-cloud.component.html',
styleUrls: ['./task-filter-dialog-cloud.component.scss'],
encapsulation: ViewEncapsulation.None
}) })
export class TaskFilterDialogCloudComponent implements OnInit { export class TaskFilterDialogCloudComponent implements OnInit {
// eslint-disable-next-line @typescript-eslint/naming-convention // eslint-disable-next-line @typescript-eslint/naming-convention
public static ACTION_SAVE = 'SAVE'; public static ACTION_SAVE = 'SAVE';
defaultIcon = 'inbox'; defaultIcon = 'inbox';
@ -36,8 +42,8 @@ export class TaskFilterDialogCloudComponent implements OnInit {
constructor( constructor(
private fb: UntypedFormBuilder, private fb: UntypedFormBuilder,
public dialogRef: MatDialogRef<TaskFilterDialogCloudComponent>, public dialogRef: MatDialogRef<TaskFilterDialogCloudComponent>,
@Inject(MAT_DIALOG_DATA) public data) { @Inject(MAT_DIALOG_DATA) public data
} ) {}
ngOnInit() { ngOnInit() {
this.filterForm = this.fb.group({ this.filterForm = this.fb.group({

View File

@ -0,0 +1,35 @@
<mat-action-list class="adf-task-filters" *ngIf="filters$ | async as filterList; else loading">
<button
*ngFor="let filter of filterList"
mat-list-item
(click)="onFilterClick(filter)"
[attr.aria-label]="filter.name | translate"
[id]="filter.id"
[attr.data-automation-id]="filter.key + '_filter'"
[class.adf-active]="currentFilter === filter">
<div class="adf-task-filters__entry">
<div class="adf-task-filters__entry-label">
<adf-icon data-automation-id="adf-filter-icon"
*ngIf="showIcons"
[value]="filter.icon"
/>
<span data-automation-id="adf-filter-label">
{{ filter.name | translate }}
</span>
</div>
<span *ngIf="counters[filter.key]"
[attr.data-automation-id]="filter.key + '_filter-counter'"
class="adf-task-filters__entry-counter"
[class.adf-active]="wasFilterUpdated(filter.key)">
{{ counters[filter.key] }}
</span>
</div>
</button>
</mat-action-list>
<ng-template #loading>
<ng-container>
<div class="adf-app-list-spinner">
<mat-spinner />
</div>
</ng-container>
</ng-template>

View File

@ -0,0 +1,39 @@
.adf-task-filters {
margin-right: calc(-1 * var(--adf-theme-spacing));
&__entry {
font-size: var(--theme-body-1-font-size);
color: var(--adf-theme-foreground-text-color-054);
display: flex;
justify-content: space-between;
align-items: center;
flex: 1;
height: 100%;
&:hover {
color: var(--theme-primary-color);
}
}
&__entry-label {
display: flex;
flex: 1;
align-items: center;
gap: var(--adf-theme-spacing);
}
&__entry-counter {
padding: 0 5px;
border-radius: 15px;
&.adf-active {
background-color: var(--theme-accent-color);
color: var(--theme-accent-color-default-contrast);
font-size: smaller;
}
}
.adf-active .adf-task-filters__entry-label {
color: var(--theme-primary-color);
}
}

View File

@ -20,18 +20,17 @@ import { SimpleChange } from '@angular/core';
import { ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing'; import { ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { first, of, throwError } from 'rxjs'; import { first, of, throwError } from 'rxjs';
import { TASK_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service'; import { TASK_FILTERS_SERVICE_TOKEN } from '../../../../services/cloud-token.service';
import { LocalPreferenceCloudService } from '../../../services/local-preference-cloud.service'; import { LocalPreferenceCloudService } from '../../../../services/local-preference-cloud.service';
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module'; import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
import { defaultTaskFiltersMock, fakeGlobalFilter, taskNotifications } from '../mock/task-filters-cloud.mock'; import { defaultTaskFiltersMock, fakeGlobalFilter, taskNotifications } from '../../mock/task-filters-cloud.mock';
import { TaskFilterCloudService } from '../services/task-filter-cloud.service'; import { TaskFilterCloudService } from '../../services/task-filter-cloud.service';
import { TaskFiltersCloudModule } from '../task-filters-cloud.module';
import { TaskFiltersCloudComponent } from './task-filters-cloud.component'; import { TaskFiltersCloudComponent } from './task-filters-cloud.component';
import { TaskListCloudService } from '../../task-list/services/task-list-cloud.service'; import { TaskListCloudService } from '../../../task-list/services/task-list-cloud.service';
import { HarnessLoader } from '@angular/cdk/testing'; import { HarnessLoader } from '@angular/cdk/testing';
import { MatActionListItemHarness } from '@angular/material/list/testing'; import { MatActionListItemHarness } from '@angular/material/list/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { TaskFilterCloudAdapter } from '../../../models/filter-cloud-model'; import { TaskFilterCloudAdapter } from '../../../../models/filter-cloud-model';
describe('TaskFiltersCloudComponent', () => { describe('TaskFiltersCloudComponent', () => {
let loader: HarnessLoader; let loader: HarnessLoader;
@ -47,7 +46,7 @@ describe('TaskFiltersCloudComponent', () => {
const configureTestingModule = (searchApiMethod: 'GET' | 'POST') => { const configureTestingModule = (searchApiMethod: 'GET' | 'POST') => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ProcessServiceCloudTestingModule, TaskFiltersCloudModule], imports: [ProcessServiceCloudTestingModule, TaskFiltersCloudComponent],
providers: [{ provide: TASK_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }] providers: [{ provide: TASK_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }]
}); });
taskFilterService = TestBed.inject(TaskFilterCloudService); taskFilterService = TestBed.inject(TaskFilterCloudService);

View File

@ -15,33 +15,29 @@
* limitations under the License. * limitations under the License.
*/ */
import { import { Component, EventEmitter, inject, Input, OnChanges, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
Component,
EventEmitter,
inject,
Input,
OnChanges,
OnInit,
Output,
SimpleChanges,
ViewEncapsulation
} from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { TaskFilterCloudService } from '../services/task-filter-cloud.service'; import { TaskFilterCloudService } from '../../services/task-filter-cloud.service';
import { FilterParamsModel, TaskFilterCloudModel } from '../models/filter-cloud.model'; import { FilterParamsModel, TaskFilterCloudModel } from '../../models/filter-cloud.model';
import { AppConfigService, TranslationService } from '@alfresco/adf-core'; import { AppConfigService, IconComponent, TranslationService } from '@alfresco/adf-core';
import { debounceTime, tap } from 'rxjs/operators'; import { debounceTime, tap } from 'rxjs/operators';
import { BaseTaskFiltersCloudComponent } from './base-task-filters-cloud.component'; import { BaseTaskFiltersCloudComponent } from '../base-task-filters-cloud.component';
import { TaskDetailsCloudModel } from '../../start-task/models/task-details-cloud.model'; import { TaskDetailsCloudModel } from '../../../models/task-details-cloud.model';
import { TaskCloudEngineEvent } from '../../../models/engine-event-cloud.model'; import { TaskCloudEngineEvent } from '../../../../models/engine-event-cloud.model';
import { TaskListCloudService } from '../../task-list/services/task-list-cloud.service'; import { TaskListCloudService } from '../../../task-list/services/task-list-cloud.service';
import { TaskFilterCloudAdapter } from '../../../models/filter-cloud-model'; import { TaskFilterCloudAdapter } from '../../../../models/filter-cloud-model';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { TranslateModule } from '@ngx-translate/core';
import { CommonModule } from '@angular/common';
import { MatListModule } from '@angular/material/list';
@Component({ @Component({
selector: 'adf-cloud-task-filters', selector: 'adf-cloud-task-filters',
templateUrl: './base-task-filters-cloud.component.html', standalone: true,
styleUrls: ['./base-task-filters-cloud.component.scss'], imports: [CommonModule, MatProgressSpinnerModule, TranslateModule, IconComponent, MatListModule],
templateUrl: './task-filters-cloud.component.html',
styleUrls: ['./task-filters-cloud.component.scss'],
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent implements OnInit, OnChanges { export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent implements OnInit, OnChanges {
@ -101,8 +97,8 @@ export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent imp
getFilters(appName: string): void { getFilters(appName: string): void {
this.filters$ = this.taskFilterCloudService.getTaskListFilters(appName); this.filters$ = this.taskFilterCloudService.getTaskListFilters(appName);
this.filters$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe( this.filters$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
(res) => { next: (res) => {
this.resetFilter(); this.resetFilter();
this.filters = res || []; this.filters = res || [];
this.initFilterCounters(); this.initFilterCounters();
@ -110,10 +106,10 @@ export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent imp
this.updateFilterCounters(); this.updateFilterCounters();
this.success.emit(res); this.success.emit(res);
}, },
(err: any) => { error: (err) => {
this.error.emit(err); this.error.emit(err);
} }
); });
} }
/** /**
@ -164,8 +160,8 @@ export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent imp
this.taskFilterCloudService this.taskFilterCloudService
.getTaskNotificationSubscription(this.appName) .getTaskNotificationSubscription(this.appName)
.pipe(debounceTime(1000)) .pipe(debounceTime(1000))
.subscribe((result: TaskCloudEngineEvent[]) => { .subscribe((result) => {
result.map((taskEvent: TaskCloudEngineEvent) => { result.forEach((taskEvent) => {
this.checkFilterCounter(taskEvent.entity); this.checkFilterCounter(taskEvent.entity);
}); });
@ -176,7 +172,7 @@ export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent imp
} }
checkFilterCounter(filterNotification: TaskDetailsCloudModel) { checkFilterCounter(filterNotification: TaskDetailsCloudModel) {
this.filters.map((filter) => { this.filters.forEach((filter) => {
if (this.isFilterPresent(filter, filterNotification)) { if (this.isFilterPresent(filter, filterNotification)) {
this.addToUpdatedCounters(filter.key); this.addToUpdatedCounters(filter.key);
} }
@ -238,6 +234,7 @@ export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent imp
} }
/** /**
* @deprecated unused method
* Select as default task filter the first in the list * Select as default task filter the first in the list
*/ */
public selectDefaultTaskFilter() { public selectDefaultTaskFilter() {

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { TaskDetailsCloudModel } from '../../../task/start-task/models/task-details-cloud.model'; import { TaskDetailsCloudModel } from '../../models/task-details-cloud.model';
import { assignedTaskDetailsCloudMock } from '../../task-header/mocks/task-details-cloud.mock'; import { assignedTaskDetailsCloudMock } from '../../task-header/mocks/task-details-cloud.mock';
import { TaskFilterCloudModel, ServiceTaskFilterCloudModel, AssignmentType, TaskStatusFilter } from '../models/filter-cloud.model'; import { TaskFilterCloudModel, ServiceTaskFilterCloudModel, AssignmentType, TaskStatusFilter } from '../models/filter-cloud.model';

View File

@ -15,14 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
export * from './components/task-filters-cloud.component'; export * from './components/edit-task-filters/edit-task-filter/edit-task-filter-cloud.component';
export * from './components/service-task-filters-cloud.component'; export * from './components/edit-task-filters/edit-service-task-filter/edit-service-task-filter-cloud.component';
export * from './components/edit-task-filters/edit-task-filter-cloud.component'; export * from './components/service-task-filters/service-task-filters-cloud.component';
export * from './components/edit-task-filters/edit-service-task-filter-cloud.component'; export * from './components/task-assignment-filter/task-assignment-filter.component';
export * from './components/task-filter-dialog/task-filter-dialog-cloud.component';
export * from './components/task-filters/task-filters-cloud.component';
export * from './models/filter-cloud.model'; export * from './models/filter-cloud.model';
export * from './services/task-filter-cloud.service'; export * from './services/task-filter-cloud.service';
export * from './services/service-task-filter-cloud.service'; export * from './services/service-task-filter-cloud.service';
export * from './task-filters-cloud.module'; export * from './task-filters-cloud.module';

View File

@ -16,45 +16,25 @@
*/ */
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { TaskFiltersCloudComponent } from './components/task-filters/task-filters-cloud.component';
import { CommonModule } from '@angular/common'; import { EditServiceTaskFilterCloudComponent } from './components/edit-task-filters/edit-service-task-filter/edit-service-task-filter-cloud.component';
import { TaskFiltersCloudComponent } from './components/task-filters-cloud.component'; import { EditTaskFilterCloudComponent } from './components/edit-task-filters/edit-task-filter/edit-task-filter-cloud.component';
import { MaterialModule } from '../../material.module';
import { CoreModule } from '@alfresco/adf-core';
import { HttpClientModule } from '@angular/common/http';
import { ProcessCommonModule } from '../../common/process-common.module';
import { PeopleCloudModule } from '../../people/people-cloud.module';
import { EditServiceTaskFilterCloudComponent } from './components/edit-task-filters/edit-service-task-filter-cloud.component';
import { EditTaskFilterCloudComponent } from './components/edit-task-filters/edit-task-filter-cloud.component';
import { TaskFilterDialogCloudComponent } from './components/task-filter-dialog/task-filter-dialog-cloud.component'; import { TaskFilterDialogCloudComponent } from './components/task-filter-dialog/task-filter-dialog-cloud.component';
import { ServiceTaskFiltersCloudComponent } from './components/service-task-filters-cloud.component'; import { ServiceTaskFiltersCloudComponent } from './components/service-task-filters/service-task-filters-cloud.component';
import { TaskAssignmentFilterCloudComponent } from './components/task-assignment-filter/task-assignment-filter.component'; import { TaskAssignmentFilterCloudComponent } from './components/task-assignment-filter/task-assignment-filter.component';
import { GroupCloudModule } from '../../group/group-cloud.module';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { APP_LIST_CLOUD_DIRECTIVES } from '../../app/app-list-cloud.module';
export const TASK_FILTERS_CLOUD_DIRECTIVES = [
TaskFilterDialogCloudComponent,
TaskFiltersCloudComponent,
ServiceTaskFiltersCloudComponent,
EditTaskFilterCloudComponent,
TaskAssignmentFilterCloudComponent,
EditServiceTaskFilterCloudComponent
] as const;
/** @deprecated use ...TASK_FILTERS_CLOUD_DIRECTIVES instead */
@NgModule({ @NgModule({
imports: [ imports: [...TASK_FILTERS_CLOUD_DIRECTIVES],
FormsModule, exports: [...TASK_FILTERS_CLOUD_DIRECTIVES]
ReactiveFormsModule,
HttpClientModule,
CommonModule,
MaterialModule,
...APP_LIST_CLOUD_DIRECTIVES,
CoreModule,
GroupCloudModule,
ProcessCommonModule,
PeopleCloudModule,
MatProgressSpinnerModule
],
declarations: [
TaskFiltersCloudComponent,
ServiceTaskFiltersCloudComponent,
EditTaskFilterCloudComponent,
EditServiceTaskFilterCloudComponent,
TaskFilterDialogCloudComponent,
TaskAssignmentFilterCloudComponent
],
exports: [TaskFiltersCloudComponent, ServiceTaskFiltersCloudComponent, EditTaskFilterCloudComponent, EditServiceTaskFilterCloudComponent]
}) })
export class TaskFiltersCloudModule {} export class TaskFiltersCloudModule {}

View File

@ -31,7 +31,7 @@ import {
TASK_RELEASE_PERMISSION, TASK_RELEASE_PERMISSION,
TASK_VIEW_PERMISSION, TASK_VIEW_PERMISSION,
TaskDetailsCloudModel TaskDetailsCloudModel
} from '../../../start-task/models/task-details-cloud.model'; } from '../../../models/task-details-cloud.model';
import { UserTaskCloudButtonsComponent } from '../user-task-cloud-buttons/user-task-cloud-buttons.component'; import { UserTaskCloudButtonsComponent } from '../user-task-cloud-buttons/user-task-cloud-buttons.component';
import { TaskFormCloudComponent } from './task-form-cloud.component'; import { TaskFormCloudComponent } from './task-form-cloud.component';

View File

@ -23,7 +23,7 @@ import { DateCloudWidgetComponent } from '../../../../form/components/widgets/da
import { DropdownCloudWidgetComponent } from '../../../../form/components/widgets/dropdown/dropdown-cloud.widget'; import { DropdownCloudWidgetComponent } from '../../../../form/components/widgets/dropdown/dropdown-cloud.widget';
import { FormCloudDisplayModeConfiguration } from '../../../../services/form-fields.interfaces'; import { FormCloudDisplayModeConfiguration } from '../../../../services/form-fields.interfaces';
import { TaskCloudService } from '../../../services/task-cloud.service'; import { TaskCloudService } from '../../../services/task-cloud.service';
import { TaskDetailsCloudModel } from '../../../start-task/models/task-details-cloud.model'; import { TaskDetailsCloudModel } from '../../../models/task-details-cloud.model';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { UserTaskCloudButtonsComponent } from '../user-task-cloud-buttons/user-task-cloud-buttons.component'; import { UserTaskCloudButtonsComponent } from '../user-task-cloud-buttons/user-task-cloud-buttons.component';
import { FormCustomOutcomesComponent } from '../../../../form/components/form-cloud-custom-outcomes.component'; import { FormCustomOutcomesComponent } from '../../../../form/components/form-cloud-custom-outcomes.component';

View File

@ -17,16 +17,18 @@
import { Component, ContentChildren, ViewChild } from '@angular/core'; import { Component, ContentChildren, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TaskCloudService } from '../services/task-cloud.service'; import { TaskCloudService } from '../../../../services/task-cloud.service';
import { of, throwError } from 'rxjs'; import { of, throwError } from 'rxjs';
import { ClaimTaskCloudDirective } from './claim-task-cloud.directive'; import { ClaimTaskCloudDirective } from './claim-task-cloud.directive';
import { taskClaimCloudMock } from '../task-header/mocks/fake-claim-task.mock'; import { taskClaimCloudMock } from '../../../../task-header/mocks/fake-claim-task.mock';
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module'; import { ProcessServiceCloudTestingModule } from '../../../../../testing/process-service-cloud.testing.module';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
describe('ClaimTaskCloudDirective', () => { describe('ClaimTaskCloudDirective', () => {
@Component({ @Component({
selector: 'adf-cloud-claim-test-component', selector: 'adf-cloud-claim-test-component',
standalone: true,
imports: [ClaimTaskCloudDirective],
template: '<button adf-cloud-claim-task [taskId]="taskMock" [appName]="appNameMock" (error)="onError($event)"></button>' template: '<button adf-cloud-claim-task [taskId]="taskMock" [appName]="appNameMock" (error)="onError($event)"></button>'
}) })
class TestComponent { class TestComponent {
@ -46,8 +48,8 @@ describe('ClaimTaskCloudDirective', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ProcessServiceCloudTestingModule], imports: [ProcessServiceCloudTestingModule, TestComponent],
declarations: [TestComponent] declarations: []
}); });
taskCloudService = TestBed.inject(TaskCloudService); taskCloudService = TestBed.inject(TaskCloudService);
fixture = TestBed.createComponent(TestComponent); fixture = TestBed.createComponent(TestComponent);
@ -95,6 +97,8 @@ describe('ClaimTaskCloudDirective', () => {
describe('Claim Task Directive validation errors', () => { describe('Claim Task Directive validation errors', () => {
@Component({ @Component({
selector: 'adf-cloud-claim-no-fields-validation-component', selector: 'adf-cloud-claim-no-fields-validation-component',
standalone: true,
imports: [ClaimTaskCloudDirective],
template: '<button adf-cloud-claim-task></button>' template: '<button adf-cloud-claim-task></button>'
}) })
class ClaimTestMissingInputDirectiveComponent { class ClaimTestMissingInputDirectiveComponent {
@ -108,6 +112,8 @@ describe('Claim Task Directive validation errors', () => {
@Component({ @Component({
selector: 'adf-cloud-claim-no-taskid-validation-component', selector: 'adf-cloud-claim-no-taskid-validation-component',
standalone: true,
imports: [ClaimTaskCloudDirective],
template: '<button adf-cloud-claim-task [appName]="appName"></button>' template: '<button adf-cloud-claim-task [appName]="appName"></button>'
}) })
class ClaimTestMissingTaskIdDirectiveComponent { class ClaimTestMissingTaskIdDirectiveComponent {
@ -119,6 +125,8 @@ describe('Claim Task Directive validation errors', () => {
@Component({ @Component({
selector: 'adf-cloud-claim-undefined-appname-component', selector: 'adf-cloud-claim-undefined-appname-component',
standalone: true,
imports: [ClaimTaskCloudDirective],
template: '<button adf-cloud-claim-task [taskId]="taskMock" [appName]="appNameUndefined"></button>' template: '<button adf-cloud-claim-task [taskId]="taskMock" [appName]="appNameUndefined"></button>'
}) })
class ClaimTestInvalidAppNameUndefinedDirectiveComponent { class ClaimTestInvalidAppNameUndefinedDirectiveComponent {
@ -131,6 +139,8 @@ describe('Claim Task Directive validation errors', () => {
@Component({ @Component({
selector: 'adf-cloud-claim-null-appname-component', selector: 'adf-cloud-claim-null-appname-component',
standalone: true,
imports: [ClaimTaskCloudDirective],
template: '<button adf-cloud-claim-task [taskId]="taskMock" [appName]="appNameNull"></button>' template: '<button adf-cloud-claim-task [taskId]="taskMock" [appName]="appNameNull"></button>'
}) })
class ClaimTestInvalidAppNameNullDirectiveComponent { class ClaimTestInvalidAppNameNullDirectiveComponent {
@ -145,8 +155,8 @@ describe('Claim Task Directive validation errors', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ProcessServiceCloudTestingModule], imports: [
declarations: [ ProcessServiceCloudTestingModule,
ClaimTestMissingTaskIdDirectiveComponent, ClaimTestMissingTaskIdDirectiveComponent,
ClaimTestInvalidAppNameUndefinedDirectiveComponent, ClaimTestInvalidAppNameUndefinedDirectiveComponent,
ClaimTestInvalidAppNameNullDirectiveComponent, ClaimTestInvalidAppNameNullDirectiveComponent,

View File

@ -16,8 +16,8 @@
*/ */
import { Directive, Input, HostListener, Output, EventEmitter, OnInit, ElementRef, Renderer2 } from '@angular/core'; import { Directive, Input, HostListener, Output, EventEmitter, OnInit, ElementRef, Renderer2 } from '@angular/core';
import { IdentityUserService } from '../../people/services/identity-user.service'; import { IdentityUserService } from '../../../../../people/services/identity-user.service';
import { TaskCloudService } from '../services/task-cloud.service'; import { TaskCloudService } from '../../../../services/task-cloud.service';
@Directive({ @Directive({
// eslint-disable-next-line @angular-eslint/directive-selector // eslint-disable-next-line @angular-eslint/directive-selector

View File

@ -17,11 +17,11 @@
import { Component, ContentChildren, ViewChild } from '@angular/core'; import { Component, ContentChildren, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TaskCloudService } from '../services/task-cloud.service'; import { TaskCloudService } from '../../../../services/task-cloud.service';
import { of, throwError } from 'rxjs'; import { of, throwError } from 'rxjs';
import { UnClaimTaskCloudDirective } from './unclaim-task-cloud.directive'; import { UnClaimTaskCloudDirective } from './unclaim-task-cloud.directive';
import { taskClaimCloudMock } from '../task-header/mocks/fake-claim-task.mock'; import { taskClaimCloudMock } from '../../../../task-header/mocks/fake-claim-task.mock';
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module'; import { ProcessServiceCloudTestingModule } from '../../../../../testing/process-service-cloud.testing.module';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
describe('UnClaimTaskCloudDirective', () => { describe('UnClaimTaskCloudDirective', () => {

View File

@ -16,7 +16,7 @@
*/ */
import { Directive, Input, HostListener, Output, EventEmitter, OnInit, ElementRef, Renderer2 } from '@angular/core'; import { Directive, Input, HostListener, Output, EventEmitter, OnInit, ElementRef, Renderer2 } from '@angular/core';
import { TaskCloudService } from '../services/task-cloud.service'; import { TaskCloudService } from '../../../../services/task-cloud.service';
@Directive({ @Directive({
// eslint-disable-next-line @angular-eslint/directive-selector // eslint-disable-next-line @angular-eslint/directive-selector

Some files were not shown because too many files have changed in this diff Show More