mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
[AAE-10773] Make Form core process agonostic (#8032)
* move form list in a component * move things in the right place * move last pice in the right place * move things in the right place * move people and group in the right place * move radio and typehead form service start remove responsibilities * remove model service and editor service from formService * move dropdwon in process-service finish remove service from form service * fix some wrong import * move activiti * fix double quote imports * move dynamic table * fix shell * move unit test * [ci:force] fix lint issues * fix build and some unit test * fix process spec type spy problems [ci:foce] * fix * fix broken tests * fix lint issues * fix cloud dropdown test * cleanup process-service-cloud tests * fix people process * improve e2e test Co-authored-by: Kasia Biernat <kasia.biernat@hyland.com>
This commit is contained in:
parent
eb27d38eba
commit
a535af667b
@ -15,26 +15,19 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Observable, of, Subject } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AlfrescoApiService,
|
TaskFormService
|
||||||
EcmModelService,
|
} from '@alfresco/adf-process-services';
|
||||||
LogService,
|
import { AlfrescoApiService, LogService } from '@alfresco/adf-core';
|
||||||
FormService,
|
|
||||||
FormOutcomeEvent
|
|
||||||
} from '@alfresco/adf-core';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class FakeFormService extends FormService {
|
export class FakeTaskFormService extends TaskFormService {
|
||||||
executeOutcome = new Subject<FormOutcomeEvent>();
|
|
||||||
|
|
||||||
constructor(
|
constructor(apiService: AlfrescoApiService, logService: LogService) {
|
||||||
ecmModelService: EcmModelService,
|
super(apiService, logService);
|
||||||
apiService: AlfrescoApiService,
|
|
||||||
protected logService: LogService
|
|
||||||
) {
|
|
||||||
super(ecmModelService, apiService, logService);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public getRestFieldValues(
|
public getRestFieldValues(
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
import { Component, ViewChild, OnDestroy, OnInit } from '@angular/core';
|
import { Component, ViewChild, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { FormModel, FormService, LogService, FormOutcomeEvent } from '@alfresco/adf-core';
|
import { FormModel, FormService, LogService, FormOutcomeEvent } from '@alfresco/adf-core';
|
||||||
import { FormComponent } from '@alfresco/adf-process-services';
|
import { FormComponent, EditorService } from '@alfresco/adf-process-services';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ export class FormListComponent implements OnInit, OnDestroy {
|
|||||||
showValidationIcon = false;
|
showValidationIcon = false;
|
||||||
private onDestroy$ = new Subject<boolean>();
|
private onDestroy$ = new Subject<boolean>();
|
||||||
|
|
||||||
constructor(private formService: FormService, private logService: LogService) {
|
constructor(private formService: FormService, private editorService: EditorService, private logService: LogService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -63,7 +63,7 @@ export class FormListComponent implements OnInit, OnDestroy {
|
|||||||
onRowDblClick(event: CustomEvent<any>) {
|
onRowDblClick(event: CustomEvent<any>) {
|
||||||
const rowForm = event.detail.value.obj;
|
const rowForm = event.detail.value.obj;
|
||||||
|
|
||||||
this.formService.getFormDefinitionById(rowForm.id).subscribe((formModel) => {
|
this.editorService.getFormDefinitionById(rowForm.id).subscribe((formModel) => {
|
||||||
const form = this.formService.parseForm(formModel.formDefinition);
|
const form = this.formService.parseForm(formModel.formDefinition);
|
||||||
this.form = form;
|
this.form = form;
|
||||||
});
|
});
|
||||||
|
@ -22,8 +22,11 @@ import {
|
|||||||
FormOutcomeEvent,
|
FormOutcomeEvent,
|
||||||
CoreAutomationService
|
CoreAutomationService
|
||||||
} from '@alfresco/adf-core';
|
} from '@alfresco/adf-core';
|
||||||
|
import {
|
||||||
|
TaskFormService
|
||||||
|
} from '@alfresco/adf-process-services';
|
||||||
import { InMemoryFormService } from '../../services/in-memory-form.service';
|
import { InMemoryFormService } from '../../services/in-memory-form.service';
|
||||||
import { FakeFormService } from './fake-form.service';
|
import { FakeTaskFormService } from './fake-tak-form.service';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
@ -31,7 +34,7 @@ import { takeUntil } from 'rxjs/operators';
|
|||||||
selector: 'app-form-loading',
|
selector: 'app-form-loading',
|
||||||
templateUrl: './form-loading.component.html',
|
templateUrl: './form-loading.component.html',
|
||||||
styleUrls: ['./form-loading.component.scss'],
|
styleUrls: ['./form-loading.component.scss'],
|
||||||
providers: [{ provide: FormService, useClass: FakeFormService }]
|
providers: [{ provide: FakeTaskFormService, useClass: TaskFormService }]
|
||||||
})
|
})
|
||||||
export class FormLoadingComponent implements OnInit, OnDestroy {
|
export class FormLoadingComponent implements OnInit, OnDestroy {
|
||||||
form: FormModel;
|
form: FormModel;
|
||||||
|
@ -35,8 +35,7 @@ import {
|
|||||||
ScriptFilesApi
|
ScriptFilesApi
|
||||||
} from '@alfresco/js-api';
|
} from '@alfresco/js-api';
|
||||||
import {
|
import {
|
||||||
FORM_FIELD_VALIDATORS, FormRenderingService, FormService,
|
FORM_FIELD_VALIDATORS, FormRenderingService, FormService, AppConfigService, PaginationComponent, UserPreferenceValues,
|
||||||
DynamicTableRow, ValidateDynamicTableRowEvent, AppConfigService, PaginationComponent, UserPreferenceValues,
|
|
||||||
AlfrescoApiService, UserPreferencesService, LogService, DataCellEvent, NotificationService
|
AlfrescoApiService, UserPreferencesService, LogService, DataCellEvent, NotificationService
|
||||||
} from '@alfresco/adf-core';
|
} from '@alfresco/adf-core';
|
||||||
|
|
||||||
@ -54,10 +53,12 @@ import {
|
|||||||
TaskFiltersComponent,
|
TaskFiltersComponent,
|
||||||
TaskListComponent,
|
TaskListComponent,
|
||||||
ProcessFormRenderingService,
|
ProcessFormRenderingService,
|
||||||
APP_LIST_LAYOUT_LIST
|
APP_LIST_LAYOUT_LIST,
|
||||||
|
ValidateDynamicTableRowEvent,
|
||||||
|
DynamicTableRow
|
||||||
} from '@alfresco/adf-process-services';
|
} from '@alfresco/adf-process-services';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { /*CustomEditorComponent*/ CustomStencil01 } from './custom-editor/custom-editor.component';
|
import { CustomStencil01 } from './custom-editor/custom-editor.component';
|
||||||
import { DemoFieldValidator } from './demo-field-validator';
|
import { DemoFieldValidator } from './demo-field-validator';
|
||||||
import { PreviewService } from '../../services/preview.service';
|
import { PreviewService } from '../../services/preview.service';
|
||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { AppConfigService, AlfrescoApiService, EcmModelService, LogService,
|
import { AppConfigService, LogService,
|
||||||
FormFieldOption, FormService, FormValues, FormModel,
|
FormFieldOption, FormService, FormValues, FormModel,
|
||||||
FormOutcomeModel, FormOutcomeEvent } from '@alfresco/adf-core';
|
FormOutcomeModel, FormOutcomeEvent } from '@alfresco/adf-core';
|
||||||
import { Observable, Subject } from 'rxjs';
|
import { Observable, Subject } from 'rxjs';
|
||||||
@ -43,10 +43,8 @@ export class InMemoryFormService extends FormService {
|
|||||||
executeOutcome = new Subject<FormOutcomeEvent>();
|
executeOutcome = new Subject<FormOutcomeEvent>();
|
||||||
|
|
||||||
constructor(appConfig: AppConfigService,
|
constructor(appConfig: AppConfigService,
|
||||||
ecmModelService: EcmModelService,
|
|
||||||
apiService: AlfrescoApiService,
|
|
||||||
protected logService: LogService) {
|
protected logService: LogService) {
|
||||||
super(ecmModelService, apiService, logService);
|
super();
|
||||||
this.data = appConfig.get<ProcessServiceData>('activiti');
|
this.data = appConfig.get<ProcessServiceData>('activiti');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,16 +45,16 @@ Forms defined in APS have the following default mappings for the form fields:
|
|||||||
| Number | integer | [`NumberWidgetComponent`](lib/core/src/lib/form/components/widgets/number/number.widget.ts) |
|
| Number | integer | [`NumberWidgetComponent`](lib/core/src/lib/form/components/widgets/number/number.widget.ts) |
|
||||||
| Checkbox | boolean | [`CheckboxWidgetComponent`](lib/core/src/lib/form/components/widgets/checkbox/checkbox.widget.ts) |
|
| Checkbox | boolean | [`CheckboxWidgetComponent`](lib/core/src/lib/form/components/widgets/checkbox/checkbox.widget.ts) |
|
||||||
| Date | date | [`DateWidgetComponent`](lib/core/src/lib/form/components/widgets/date/date.widget.ts) |
|
| Date | date | [`DateWidgetComponent`](lib/core/src/lib/form/components/widgets/date/date.widget.ts) |
|
||||||
| Dropdown | dropdown | [`DropdownWidgetComponent`](lib/core/src/lib/form/components/widgets/dropdown/dropdown.widget.ts) |
|
| Dropdown | dropdown | [`DropdownWidgetComponent`](lib/process-services/src/lib/form/widgets/dropdown/dropdown.widget.ts) |
|
||||||
| Typeahead | typeahead | [`TypeaheadWidgetComponent`](lib/core/src/lib/form/components/widgets/typeahead/typeahead.widget.ts) |
|
| Typeahead | typeahead | [`TypeaheadWidgetComponent`](lib/process-services/src/lib/form/widgets/typeahead/typeahead.widget.ts) |
|
||||||
| Amount | amount | [`AmountWidgetComponent`](lib/core/src/lib/form/components/widgets/amount/amount.widget.ts) |
|
| Amount | amount | [`AmountWidgetComponent`](lib/core/src/lib/form/components/widgets/amount/amount.widget.ts) |
|
||||||
| Radio buttons | radio-buttons | [`RadioButtonsWidgetComponent`](lib/core/src/lib/form/components/widgets/radio-buttons/radio-buttons.widget.ts) |
|
| Radio buttons | radio-buttons | [`RadioButtonsWidgetComponent`](lib/process-services/src/lib/form/widgets/radio-buttons/radio-buttons.widget.ts) |
|
||||||
| People | people | [`PeopleWidgetComponent`](lib/core/src/lib/form/components/widgets/people/people.widget.ts) |
|
| People | people | [`PeopleWidgetComponent`](lib/process-services/src/lib/form/widgets/people/people.widget.ts) |
|
||||||
| Group of people | functional-group | [`FunctionalGroupWidgetComponent`](lib/core/src/lib/form/components/widgets/functional-group/functional-group.widget.ts) |
|
| Group of people | functional-group | [`FunctionalGroupWidgetComponent`](lib/process-services/src/lib/form/widgets/functional-group/functional-group.widget.ts) |
|
||||||
| Dynamic table | dynamic-table | [`DynamicTableWidgetComponent`](lib/core/src/lib/form/components/widgets/dynamic-table/dynamic-table.widget.ts) |
|
| Dynamic table | dynamic-table | [`DynamicTableWidgetComponent`](lib/process-services/src/lib/form/widgets/dynamic-table/dynamic-table.widget.ts) |
|
||||||
| Hyperlink | hyperlink | [`HyperlinkWidgetComponent`](lib/core/src/lib/form/components/widgets/hyperlink/hyperlink.widget.ts) |
|
| Hyperlink | hyperlink | [`HyperlinkWidgetComponent`](lib/core/src/lib/form/components/widgets/hyperlink/hyperlink.widget.ts) |
|
||||||
| Header | group | [`ContainerWidgetComponent`](lib/core/src/lib/form/components/widgets/container/container.widget.ts) |
|
| Header | group | [`ContainerWidgetComponent`](lib/core/src/lib/form/components/widgets/container/container.widget.ts) |
|
||||||
| Attach File | upload | AttachWidgetComponent or [`UploadWidgetComponent`](lib/core/src/lib/form/components/widgets/upload/upload.widget.ts) (based on metadata) |
|
| Attach File | upload | AttachWidgetComponent or [`UploadWidgetComponent`](lib/process-services/src/lib/form/widgets/upload/upload.widget.ts) (based on metadata) |
|
||||||
| Display value | readonly | [`TextWidgetComponent`](lib/core/src/lib/form/components/widgets/text/text.widget.ts) |
|
| Display value | readonly | [`TextWidgetComponent`](lib/core/src/lib/form/components/widgets/text/text.widget.ts) |
|
||||||
| Display text | readonly-text | [`DisplayTextWidgetComponent`](lib/core/src/lib/form/components/widgets/display-text/display-text.widget.ts) |
|
| Display text | readonly-text | [`DisplayTextWidgetComponent`](lib/core/src/lib/form/components/widgets/display-text/display-text.widget.ts) |
|
||||||
| Display Rich text | display-rich-text | [`DisplayRichTextWidgetComponent`](lib/core/src/lib/form/components/widgets/display-rich-text/display-rich-text.widget.ts) |
|
| Display Rich text | display-rich-text | [`DisplayRichTextWidgetComponent`](lib/core/src/lib/form/components/widgets/display-rich-text/display-rich-text.widget.ts) |
|
||||||
|
@ -5,7 +5,7 @@ Status: Active
|
|||||||
Last reviewed: 2018-11-20
|
Last reviewed: 2018-11-20
|
||||||
---
|
---
|
||||||
|
|
||||||
# [Form List Component](lib/core/src/lib/form/components/form-list.component.ts "Defined in form-list.component.ts")
|
# [Form List Component](lib/process-services/src/lib/form/form-list/form-list.component.ts "Defined in form-list.component.ts")
|
||||||
|
|
||||||
Shows forms as a list.
|
Shows forms as a list.
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ Added: v2.0.0
|
|||||||
Status: Active
|
Status: Active
|
||||||
---
|
---
|
||||||
|
|
||||||
# [APS Alfresco Content Service](lib/core/src/lib/form/services/activiti-alfresco.service.ts "Defined in activiti-alfresco.service.ts")
|
# [APS Alfresco Content Service](lib/process-services/src/lib/form/services/activiti-alfresco.service.ts "Defined in activiti-alfresco.service.ts")
|
||||||
|
|
||||||
Gets Alfresco Repository folder content based on a Repository account configured in Alfresco Process Services (APS).
|
Gets Alfresco Repository folder content based on a Repository account configured in Alfresco Process Services (APS).
|
||||||
|
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
---
|
|
||||||
Title: Node Service
|
|
||||||
Added: v2.0.0
|
|
||||||
Status: Active
|
|
||||||
Last reviewed: 2018-11-20
|
|
||||||
---
|
|
||||||
|
|
||||||
# [Node Service](lib/core/src/lib/form/services/node.service.ts "Defined in node.service.ts") **Deprecated**
|
|
||||||
|
|
||||||
use [Nodes Api service](./nodes-api.service.md) instead of this.
|
|
||||||
|
|
||||||
Gets Alfresco Repository node metadata and creates nodes with metadata.
|
|
||||||
|
|
||||||
## Class members
|
|
||||||
|
|
||||||
### Methods
|
|
||||||
|
|
||||||
- **createNode**(name: `string`, nodeType: `string`, properties: `any`, path: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodeEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/NodeEntry.md)`>`<br/>
|
|
||||||
(**Deprecated:** in 3.8.0, use `createNodeInsideRoot` method from NodesApiService instead. Create a new Node from form metadata)
|
|
||||||
- _name:_ `string` - Node name
|
|
||||||
- _nodeType:_ `string` - Node type
|
|
||||||
- _properties:_ `any` - Node body properties
|
|
||||||
- _path:_ `string` - Path to the node
|
|
||||||
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodeEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/NodeEntry.md)`>` - The created node
|
|
||||||
- **createNodeMetadata**(nodeType: `string`, nameSpace: `any`, data: `any`, path: `string`, name?: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodeEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/NodeEntry.md)`>`<br/>
|
|
||||||
(**Deprecated:** in 3.8.0, use NodesApiService instead. Create a new Node from form metadata.)
|
|
||||||
- _nodeType:_ `string` - Node type
|
|
||||||
- _nameSpace:_ `any` - Namespace for properties
|
|
||||||
- _data:_ `any` - [Property](../../../lib/content-services/src/lib/content-metadata/interfaces/property.interface.ts) data to store in the node under namespace
|
|
||||||
- _path:_ `string` - Path to the node
|
|
||||||
- _name:_ `string` - (Optional) Node name
|
|
||||||
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodeEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/NodeEntry.md)`>` - The created node
|
|
||||||
- **getNodeMetadata**(nodeId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodeMetadata`](../../../lib/core/models/node-metadata.model.ts)`>`<br/>
|
|
||||||
(**Deprecated:** in 3.8.0, use NodesApiService instead. Get the metadata and the nodeType for a nodeId cleaned by the prefix.)
|
|
||||||
- _nodeId:_ `string` - ID of the target node
|
|
||||||
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodeMetadata`](../../../lib/core/models/node-metadata.model.ts)`>` - Node metadata
|
|
||||||
|
|
||||||
## Details
|
|
||||||
|
|
||||||
Note that this service cannot be used to create nodes with content.
|
|
||||||
|
|
||||||
The `path` parameter to `createNode` and `createNodeMetadata` specifies an intermediate
|
|
||||||
path of folders to create between the root and the target node.
|
|
||||||
|
|
||||||
### Importing
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { NodeService } from '@alfresco/adf-core';
|
|
||||||
|
|
||||||
export class SomePageComponent implements OnInit {
|
|
||||||
|
|
||||||
constructor(private nodeService: NodeService) {
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## See also
|
|
||||||
|
|
||||||
- [Nodes api service](nodes-api.service.md)
|
|
||||||
- [Deleted nodes api service](deleted-nodes-api.service.md)
|
|
@ -4,7 +4,7 @@ Added: v2.0.0
|
|||||||
Status: Active
|
Status: Active
|
||||||
---
|
---
|
||||||
|
|
||||||
# [Process Content Service](lib/core/src/lib/form/services/process-content.service.ts "Defined in process-content.service.ts")
|
# [Process Content Service](lib/process-services/src/lib/form/services/process-content.service.ts "Defined in process-content.service.ts")
|
||||||
|
|
||||||
Manipulates content related to a Process Instance or Task Instance in APS.
|
Manipulates content related to a Process Instance or Task Instance in APS.
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ Added: v2.0.0
|
|||||||
Status: Active
|
Status: Active
|
||||||
---
|
---
|
||||||
|
|
||||||
# [APS Content Component](lib/core/src/lib/form/components/widgets/content/content.widget.ts "Defined in content.widget.ts")
|
# [APS Content Component](lib/process-services/src/lib/form/widgets/document/content.widget.ts "Defined in content.widget.ts")
|
||||||
|
|
||||||
Shows the content preview.
|
Shows the content preview.
|
||||||
|
|
||||||
|
@ -759,7 +759,7 @@ Release Notes - Apps Development Framework - Version 2.0.
|
|||||||
- \[[ADF-1879](https://issues.alfresco.com/jira/browse/ADF-1879)] - ADF Process Services is not working properly
|
- \[[ADF-1879](https://issues.alfresco.com/jira/browse/ADF-1879)] - ADF Process Services is not working properly
|
||||||
- \[[ADF-1885](https://issues.alfresco.com/jira/browse/ADF-1885)] - Once accessed process services components appear throughout app
|
- \[[ADF-1885](https://issues.alfresco.com/jira/browse/ADF-1885)] - Once accessed process services components appear throughout app
|
||||||
- \[[ADF-1890](https://issues.alfresco.com/jira/browse/ADF-1890)] - Viewer - Content projection for sidebar only works if sidebarPosition is left
|
- \[[ADF-1890](https://issues.alfresco.com/jira/browse/ADF-1890)] - Viewer - Content projection for sidebar only works if sidebarPosition is left
|
||||||
- \[[ADF-1891](https://issues.alfresco.com/jira/browse/ADF-1891)] - [`ActivitiContentService`](lib/core/src/lib/form/services/activiti-alfresco.service.ts) is not exported
|
- \[[ADF-1891](https://issues.alfresco.com/jira/browse/ADF-1891)] - [`ActivitiContentService`](lib/process-services/src/lib/form/services/activiti-alfresco.service.ts) is not exported
|
||||||
- \[[ADF-1898](https://issues.alfresco.com/jira/browse/ADF-1898)] - [`ProcessService`](../process-services/services/process.service.md).createOrUpdateProcessInstanceVariables has incorrect method signature
|
- \[[ADF-1898](https://issues.alfresco.com/jira/browse/ADF-1898)] - [`ProcessService`](../process-services/services/process.service.md).createOrUpdateProcessInstanceVariables has incorrect method signature
|
||||||
- \[[ADF-1900](https://issues.alfresco.com/jira/browse/ADF-1900)] - [`ProcessService`](../process-services/services/process.service.md).getProcessInstanceVariables has incorrect method signature
|
- \[[ADF-1900](https://issues.alfresco.com/jira/browse/ADF-1900)] - [`ProcessService`](../process-services/services/process.service.md).getProcessInstanceVariables has incorrect method signature
|
||||||
- \[[ADF-1901](https://issues.alfresco.com/jira/browse/ADF-1901)] - [`ProcessService`](../process-services/services/process.service.md).createDefaultFilters has incorrect method signature
|
- \[[ADF-1901](https://issues.alfresco.com/jira/browse/ADF-1901)] - [`ProcessService`](../process-services/services/process.service.md).createDefaultFilters has incorrect method signature
|
||||||
|
@ -353,7 +353,7 @@ Release Notes - Apps Development Framework - Version 2.2.
|
|||||||
- \[[ADF-2242](https://issues.alfresco.com/jira/browse/ADF-2242)] - Search on custom sources is not working.
|
- \[[ADF-2242](https://issues.alfresco.com/jira/browse/ADF-2242)] - Search on custom sources is not working.
|
||||||
- \[[ADF-2243](https://issues.alfresco.com/jira/browse/ADF-2243)] - Translation is missing for the 'Extended Search'.
|
- \[[ADF-2243](https://issues.alfresco.com/jira/browse/ADF-2243)] - Translation is missing for the 'Extended Search'.
|
||||||
- \[[ADF-2246](https://issues.alfresco.com/jira/browse/ADF-2246)] - [Destination Picker] The selection from the dropdown is ignored after 'Clear' action
|
- \[[ADF-2246](https://issues.alfresco.com/jira/browse/ADF-2246)] - [Destination Picker] The selection from the dropdown is ignored after 'Clear' action
|
||||||
- \[[ADF-2251](https://issues.alfresco.com/jira/browse/ADF-2251)] - [`ContentWidgetModule`](../../lib/process-services/src/lib/content-widget/content-widget.module.ts) is not exposed from ADF
|
- \[[ADF-2251](https://issues.alfresco.com/jira/browse/ADF-2251)] - [`ContentWidgetModule`](lib/process-services/src/lib/form/widgets/content-widget/content-widget.module.ts) is not exposed from ADF
|
||||||
- \[[ADF-2254](https://issues.alfresco.com/jira/browse/ADF-2254)] - Viewer does not update top menu on "fileNodeId" changes
|
- \[[ADF-2254](https://issues.alfresco.com/jira/browse/ADF-2254)] - Viewer does not update top menu on "fileNodeId" changes
|
||||||
- \[[ADF-2255](https://issues.alfresco.com/jira/browse/ADF-2255)] - SelectBox field does not render the data in ADF form
|
- \[[ADF-2255](https://issues.alfresco.com/jira/browse/ADF-2255)] - SelectBox field does not render the data in ADF form
|
||||||
- \[[ADF-2260](https://issues.alfresco.com/jira/browse/ADF-2260)] - Action menu translation is missing when right clicking on a file/folder
|
- \[[ADF-2260](https://issues.alfresco.com/jira/browse/ADF-2260)] - Action menu translation is missing when right clicking on a file/folder
|
||||||
|
@ -432,7 +432,7 @@ These changes are noted with an arrow "->".
|
|||||||
- `adf-grid-list`
|
- `adf-grid-list`
|
||||||
- `adf-grid-list-item`
|
- `adf-grid-list-item`
|
||||||
|
|
||||||
#### [../../lib/core/form/components/widgets/dynamic-table/dynamic-table.widget.scss](lib/core/src/lib/form/components/widgets/dynamic-table/dynamic-table.widget.scss)
|
#### [../../lib/core/form/components/widgets/dynamic-table/dynamic-table.widget.scss](lib/process-services/src/lib/form/widgets/dynamic-table/dynamic-table.widget.scss)
|
||||||
|
|
||||||
- `adf-is-selected`
|
- `adf-is-selected`
|
||||||
- `adf-no-select`
|
- `adf-no-select`
|
||||||
|
@ -83,21 +83,21 @@ formRenderingService.setComponentTypeResolver('text', customResolver, true);
|
|||||||
| Number | integer | [`NumberWidgetComponent`](lib/core/src/lib/form/components/widgets/number/number.widget.ts) |
|
| Number | integer | [`NumberWidgetComponent`](lib/core/src/lib/form/components/widgets/number/number.widget.ts) |
|
||||||
| Multi-line text | multi-line-text | [`MultilineTextWidgetComponentComponent`](lib/core/src/lib/form/components/widgets/multiline-text/multiline-text.widget.ts) |
|
| Multi-line text | multi-line-text | [`MultilineTextWidgetComponentComponent`](lib/core/src/lib/form/components/widgets/multiline-text/multiline-text.widget.ts) |
|
||||||
| Checkbox | boolean | [`CheckboxWidgetComponent`](lib/core/src/lib/form/components/widgets/checkbox/checkbox.widget.ts) |
|
| Checkbox | boolean | [`CheckboxWidgetComponent`](lib/core/src/lib/form/components/widgets/checkbox/checkbox.widget.ts) |
|
||||||
| Dropdown | dropdown | [`DropdownWidgetComponent`](lib/core/src/lib/form/components/widgets/dropdown/dropdown.widget.ts) |
|
| Dropdown | dropdown | [`DropdownWidgetComponent`](lib/process-services/src/lib/form/widgets/dropdown/dropdown.widget.ts) |
|
||||||
| Date | date | [`DateWidgetComponent`](lib/core/src/lib/form/components/widgets/date/date.widget.ts) |
|
| Date | date | [`DateWidgetComponent`](lib/core/src/lib/form/components/widgets/date/date.widget.ts) |
|
||||||
| Amount | amount | [`AmountWidgetComponent`](lib/core/src/lib/form/components/widgets/amount/amount.widget.ts) |
|
| Amount | amount | [`AmountWidgetComponent`](lib/core/src/lib/form/components/widgets/amount/amount.widget.ts) |
|
||||||
| Radio buttons | radio-buttons | [`RadioButtonsWidgetComponent`](lib/core/src/lib/form/components/widgets/radio-buttons/radio-buttons.widget.ts) |
|
| Radio buttons | radio-buttons | [`RadioButtonsWidgetComponent`](lib/process-services/src/lib/form/widgets/radio-buttons/radio-buttons.widget.ts) |
|
||||||
| Hyperlink | hyperlink | [`HyperlinkWidgetComponent`](lib/core/src/lib/form/components/widgets/hyperlink/hyperlink.widget.ts) |
|
| Hyperlink | hyperlink | [`HyperlinkWidgetComponent`](lib/core/src/lib/form/components/widgets/hyperlink/hyperlink.widget.ts) |
|
||||||
| Display value | readonly | DisplayValueWidgetComponent |
|
| Display value | readonly | DisplayValueWidgetComponent |
|
||||||
| Display Rich text | display-rich-text | [`DisplayRichTextWidgetComponent`](lib/core/src/lib/form/components/widgets/display-rich-text/display-rich-text.widget.ts) |
|
| Display Rich text | display-rich-text | [`DisplayRichTextWidgetComponent`](lib/core/src/lib/form/components/widgets/display-rich-text/display-rich-text.widget.ts) |
|
||||||
| Display text | readonly-text | [`DisplayTextWidgetComponentComponent`](lib/core/src/lib/form/components/widgets/display-text/display-text.widget.ts) |
|
| Display text | readonly-text | [`DisplayTextWidgetComponentComponent`](lib/core/src/lib/form/components/widgets/display-text/display-text.widget.ts) |
|
||||||
| Typeahead | typeahead | [`TypeaheadWidgetComponent`](lib/core/src/lib/form/components/widgets/typeahead/typeahead.widget.ts) |
|
| Typeahead | typeahead | [`TypeaheadWidgetComponent`](lib/process-services/src/lib/form/widgets/typeahead/typeahead.widget.ts) |
|
||||||
| People | people | [`PeopleWidgetComponent`](lib/core/src/lib/form/components/widgets/people/people.widget.ts) |
|
| People | people | [`PeopleWidgetComponent`](lib/process-services/src/lib/form/widgets/people/people.widget.ts) |
|
||||||
| Group of people | functional-group | [`FunctionalGroupWidgetComponent`](lib/core/src/lib/form/components/widgets/functional-group/functional-group.widget.ts) |
|
| Group of people | functional-group | [`FunctionalGroupWidgetComponent`](lib/process-services/src/lib/form/widgets/functional-group/functional-group.widget.ts) |
|
||||||
| Dynamic table | dynamic-table | [`DynamicTableWidgetComponent`](lib/core/src/lib/form/components/widgets/dynamic-table/dynamic-table.widget.ts) |
|
| Dynamic table | dynamic-table | [`DynamicTableWidgetComponent`](lib/process-services/src/lib/form/widgets/dynamic-table/dynamic-table.widget.ts) |
|
||||||
| N/A | container | [`ContainerWidgetComponent`](lib/core/src/lib/form/components/widgets/container/container.widget.ts) (layout component) |
|
| N/A | container | [`ContainerWidgetComponent`](lib/core/src/lib/form/components/widgets/container/container.widget.ts) (layout component) |
|
||||||
| Header | group | [`ContainerWidgetComponent`](lib/core/src/lib/form/components/widgets/container/container.widget.ts) |
|
| Header | group | [`ContainerWidgetComponent`](lib/core/src/lib/form/components/widgets/container/container.widget.ts) |
|
||||||
| Attach | upload | AttachWidgetComponent or [`UploadWidgetComponent`](lib/core/src/lib/form/components/widgets/upload/upload.widget.ts) (based on metadata) |
|
| Attach | upload | AttachWidgetComponent or [`UploadWidgetComponent`](lib/process-services/src/lib/form/widgets/upload/upload.widget.ts) (based on metadata) |
|
||||||
| N/A | N/A | [`UnknownWidgetComponent`](lib/core/src/lib/form/components/widgets/unknown/unknown.widget.ts) |
|
| N/A | N/A | [`UnknownWidgetComponent`](lib/core/src/lib/form/components/widgets/unknown/unknown.widget.ts) |
|
||||||
|
|
||||||
## Form Extensibility for APS/AAE
|
## Form Extensibility for APS/AAE
|
||||||
|
@ -27,13 +27,10 @@ import { TabModel } from './tab.model';
|
|||||||
import { fakeMetadataForm, fakeViewerForm } from '../../mock/form.mock';
|
import { fakeMetadataForm, fakeViewerForm } from '../../mock/form.mock';
|
||||||
import { Node } from '@alfresco/js-api';
|
import { Node } from '@alfresco/js-api';
|
||||||
import { UploadWidgetContentLinkModel } from './upload-widget-content-link.model';
|
import { UploadWidgetContentLinkModel } from './upload-widget-content-link.model';
|
||||||
import { AlfrescoApiService } from '../../../../services';
|
|
||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
import { CoreTestingModule, setupTestBed } from '../../../../testing';
|
import { CoreTestingModule, setupTestBed } from '../../../../testing';
|
||||||
|
|
||||||
describe('FormModel', () => {
|
describe('FormModel', () => {
|
||||||
let formService: FormService;
|
let formService: FormService;
|
||||||
let alfrescoApiService: AlfrescoApiService;
|
|
||||||
|
|
||||||
setupTestBed({
|
setupTestBed({
|
||||||
imports: [
|
imports: [
|
||||||
@ -42,9 +39,7 @@ describe('FormModel', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
alfrescoApiService = TestBed.inject(AlfrescoApiService);
|
formService = new FormService();
|
||||||
|
|
||||||
formService = new FormService(null, alfrescoApiService, null);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should store original json', () => {
|
it('should store original json', () => {
|
||||||
|
@ -21,30 +21,14 @@ import { AmountWidgetComponent } from './amount/amount.widget';
|
|||||||
import { CheckboxWidgetComponent } from './checkbox/checkbox.widget';
|
import { CheckboxWidgetComponent } from './checkbox/checkbox.widget';
|
||||||
import { DateWidgetComponent } from './date/date.widget';
|
import { DateWidgetComponent } from './date/date.widget';
|
||||||
import { DisplayTextWidgetComponent } from './display-text/display-text.widget';
|
import { DisplayTextWidgetComponent } from './display-text/display-text.widget';
|
||||||
import { DocumentWidgetComponent } from './document/document.widget';
|
|
||||||
import { DropdownWidgetComponent } from './dropdown/dropdown.widget';
|
|
||||||
import { DynamicTableWidgetComponent } from './dynamic-table/dynamic-table.widget';
|
|
||||||
import { BooleanEditorComponent } from './dynamic-table/editors/boolean/boolean.editor';
|
|
||||||
import { DateEditorComponent } from './dynamic-table/editors/date/date.editor';
|
|
||||||
import { DateTimeEditorComponent } from './dynamic-table/editors/datetime/datetime.editor';
|
|
||||||
import { DropdownEditorComponent } from './dynamic-table/editors/dropdown/dropdown.editor';
|
|
||||||
import { RowEditorComponent } from './dynamic-table/editors/row.editor';
|
|
||||||
import { TextEditorComponent } from './dynamic-table/editors/text/text.editor';
|
|
||||||
import { AmountEditorComponent } from './dynamic-table/editors/amount/amount.editor';
|
|
||||||
import { ErrorWidgetComponent } from './error/error.component';
|
import { ErrorWidgetComponent } from './error/error.component';
|
||||||
import { FunctionalGroupWidgetComponent } from './functional-group/functional-group.widget';
|
|
||||||
import { HyperlinkWidgetComponent } from './hyperlink/hyperlink.widget';
|
import { HyperlinkWidgetComponent } from './hyperlink/hyperlink.widget';
|
||||||
import { MultilineTextWidgetComponentComponent } from './multiline-text/multiline-text.widget';
|
import { MultilineTextWidgetComponentComponent } from './multiline-text/multiline-text.widget';
|
||||||
import { NumberWidgetComponent } from './number/number.widget';
|
import { NumberWidgetComponent } from './number/number.widget';
|
||||||
import { PeopleWidgetComponent } from './people/people.widget';
|
|
||||||
import { RadioButtonsWidgetComponent } from './radio-buttons/radio-buttons.widget';
|
|
||||||
import { InputMaskDirective } from './text/text-mask.component';
|
import { InputMaskDirective } from './text/text-mask.component';
|
||||||
import { TextWidgetComponent } from './text/text.widget';
|
import { TextWidgetComponent } from './text/text.widget';
|
||||||
import { TypeaheadWidgetComponent } from './typeahead/typeahead.widget';
|
|
||||||
import { UploadWidgetComponent } from './upload/upload.widget';
|
|
||||||
import { DateTimeWidgetComponent } from './date-time/date-time.widget';
|
import { DateTimeWidgetComponent } from './date-time/date-time.widget';
|
||||||
import { JsonWidgetComponent } from './json/json.widget';
|
import { JsonWidgetComponent } from './json/json.widget';
|
||||||
import { UploadFolderWidgetComponent } from './upload-folder/upload-folder.widget';
|
|
||||||
import { FileViewerWidgetComponent } from './file-viewer/file-viewer.widget';
|
import { FileViewerWidgetComponent } from './file-viewer/file-viewer.widget';
|
||||||
import { DisplayRichTextWidgetComponent } from './display-rich-text/display-rich-text.widget';
|
import { DisplayRichTextWidgetComponent } from './display-rich-text/display-rich-text.widget';
|
||||||
|
|
||||||
@ -52,41 +36,21 @@ import { DisplayRichTextWidgetComponent } from './display-rich-text/display-rich
|
|||||||
export * from './widget.component';
|
export * from './widget.component';
|
||||||
export * from './core';
|
export * from './core';
|
||||||
|
|
||||||
|
|
||||||
// primitives
|
// primitives
|
||||||
export * from './unknown/unknown.widget';
|
export * from './unknown/unknown.widget';
|
||||||
export * from './text/text.widget';
|
export * from './text/text.widget';
|
||||||
export * from './number/number.widget';
|
export * from './number/number.widget';
|
||||||
export * from './checkbox/checkbox.widget';
|
export * from './checkbox/checkbox.widget';
|
||||||
export * from './multiline-text/multiline-text.widget';
|
export * from './multiline-text/multiline-text.widget';
|
||||||
export * from './dropdown/dropdown.widget';
|
|
||||||
export * from './hyperlink/hyperlink.widget';
|
export * from './hyperlink/hyperlink.widget';
|
||||||
export * from './radio-buttons/radio-buttons.widget';
|
|
||||||
export * from './display-text/display-text.widget';
|
export * from './display-text/display-text.widget';
|
||||||
export * from './upload/upload.widget';
|
|
||||||
export * from './typeahead/typeahead.widget';
|
|
||||||
export * from './functional-group/functional-group.widget';
|
|
||||||
export * from './people/people.widget';
|
|
||||||
export * from './date/date.widget';
|
export * from './date/date.widget';
|
||||||
export * from './amount/amount.widget';
|
export * from './amount/amount.widget';
|
||||||
export * from './dynamic-table/dynamic-table.widget';
|
|
||||||
export * from './error/error.component';
|
export * from './error/error.component';
|
||||||
export * from './document/document.widget';
|
|
||||||
export * from './date-time/date-time.widget';
|
export * from './date-time/date-time.widget';
|
||||||
export * from './json/json.widget';
|
export * from './json/json.widget';
|
||||||
export * from './upload-folder/upload-folder.widget';
|
|
||||||
export * from './file-viewer/file-viewer.widget';
|
export * from './file-viewer/file-viewer.widget';
|
||||||
export * from './display-rich-text/display-rich-text.widget';
|
export * from './display-rich-text/display-rich-text.widget';
|
||||||
|
|
||||||
// editors (dynamic table)
|
|
||||||
export * from './dynamic-table/dynamic-table.widget.model';
|
|
||||||
export * from './dynamic-table/editors/row.editor';
|
|
||||||
export * from './dynamic-table/editors/date/date.editor';
|
|
||||||
export * from './dynamic-table/editors/dropdown/dropdown.editor';
|
|
||||||
export * from './dynamic-table/editors/boolean/boolean.editor';
|
|
||||||
export * from './dynamic-table/editors/text/text.editor';
|
|
||||||
export * from './dynamic-table/editors/datetime/datetime.editor';
|
|
||||||
export * from './dynamic-table/editors/amount/amount.editor';
|
|
||||||
export * from './text/text-mask.component';
|
export * from './text/text-mask.component';
|
||||||
|
|
||||||
export const WIDGET_DIRECTIVES: any[] = [
|
export const WIDGET_DIRECTIVES: any[] = [
|
||||||
@ -95,29 +59,13 @@ export const WIDGET_DIRECTIVES: any[] = [
|
|||||||
NumberWidgetComponent,
|
NumberWidgetComponent,
|
||||||
CheckboxWidgetComponent,
|
CheckboxWidgetComponent,
|
||||||
MultilineTextWidgetComponentComponent,
|
MultilineTextWidgetComponentComponent,
|
||||||
DropdownWidgetComponent,
|
|
||||||
HyperlinkWidgetComponent,
|
HyperlinkWidgetComponent,
|
||||||
RadioButtonsWidgetComponent,
|
|
||||||
DisplayTextWidgetComponent,
|
DisplayTextWidgetComponent,
|
||||||
UploadWidgetComponent,
|
|
||||||
TypeaheadWidgetComponent,
|
|
||||||
FunctionalGroupWidgetComponent,
|
|
||||||
PeopleWidgetComponent,
|
|
||||||
DateWidgetComponent,
|
DateWidgetComponent,
|
||||||
AmountWidgetComponent,
|
AmountWidgetComponent,
|
||||||
DynamicTableWidgetComponent,
|
|
||||||
DateEditorComponent,
|
|
||||||
DropdownEditorComponent,
|
|
||||||
BooleanEditorComponent,
|
|
||||||
TextEditorComponent,
|
|
||||||
RowEditorComponent,
|
|
||||||
ErrorWidgetComponent,
|
ErrorWidgetComponent,
|
||||||
DocumentWidgetComponent,
|
|
||||||
DateTimeWidgetComponent,
|
DateTimeWidgetComponent,
|
||||||
DateTimeEditorComponent,
|
|
||||||
JsonWidgetComponent,
|
JsonWidgetComponent,
|
||||||
AmountEditorComponent,
|
|
||||||
UploadFolderWidgetComponent,
|
|
||||||
FileViewerWidgetComponent,
|
FileViewerWidgetComponent,
|
||||||
DisplayRichTextWidgetComponent
|
DisplayRichTextWidgetComponent
|
||||||
];
|
];
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
<div class="adf-upload-folder-widget {{field.className}}"
|
|
||||||
[class.adf-invalid]="!field.isValid"
|
|
||||||
[class.adf-readonly]="field.readOnly">
|
|
||||||
<label class="adf-label" [attr.for]="field.id">{{field.name | translate }}<span class="adf-asterisk" *ngIf="isRequired()">*</span></label>
|
|
||||||
<div class="adf-upload-widget-container">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,8 +0,0 @@
|
|||||||
.adf {
|
|
||||||
&-upload-folder-widget {
|
|
||||||
width: 100%;
|
|
||||||
word-break: break-all;
|
|
||||||
padding: 0.4375em 0;
|
|
||||||
border-top: 0.8438em solid transparent;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
/*!
|
|
||||||
* @license
|
|
||||||
* Copyright 2019 Alfresco Software, Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
import { setupTestBed } from '../../../../testing/setup-test-bed';
|
|
||||||
import { CoreTestingModule } from '../../../../testing';
|
|
||||||
import { UploadFolderWidgetComponent } from './upload-folder.widget';
|
|
||||||
import { FormFieldModel } from '../core/form-field.model';
|
|
||||||
import { FormModel } from '../core/form.model';
|
|
||||||
import { FormFieldTypes } from '../core/form-field-types';
|
|
||||||
|
|
||||||
describe('UploadFolderWidgetComponent', () => {
|
|
||||||
|
|
||||||
let widget: UploadFolderWidgetComponent;
|
|
||||||
let fixture: ComponentFixture<UploadFolderWidgetComponent>;
|
|
||||||
let element: HTMLElement;
|
|
||||||
|
|
||||||
setupTestBed({
|
|
||||||
imports: [
|
|
||||||
CoreTestingModule
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(UploadFolderWidgetComponent);
|
|
||||||
widget = fixture.componentInstance;
|
|
||||||
element = fixture.nativeElement;
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when is required', () => {
|
|
||||||
|
|
||||||
it('should be able to display label with asterisk', async () => {
|
|
||||||
widget.field = new FormFieldModel( new FormModel({ taskId: '<id>' }), {
|
|
||||||
type: FormFieldTypes.UPLOAD,
|
|
||||||
required: true
|
|
||||||
});
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
await fixture.whenStable();
|
|
||||||
|
|
||||||
const asterisk: HTMLElement = element.querySelector('.adf-asterisk');
|
|
||||||
|
|
||||||
expect(asterisk).toBeTruthy();
|
|
||||||
expect(asterisk.textContent).toEqual('*');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,165 +0,0 @@
|
|||||||
/*!
|
|
||||||
* @license
|
|
||||||
* Copyright 2019 Alfresco Software, Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* eslint-disable @angular-eslint/component-selector */
|
|
||||||
|
|
||||||
import { LogService } from '../../../../services/log.service';
|
|
||||||
import { ThumbnailService } from '../../../../services/thumbnail.service';
|
|
||||||
import { Component, ElementRef, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
|
||||||
import { Observable, from } from 'rxjs';
|
|
||||||
import { FormService } from '../../../services/form.service';
|
|
||||||
import { ProcessContentService } from '../../../services/process-content.service';
|
|
||||||
import { ContentLinkModel } from '../core/content-link.model';
|
|
||||||
import { WidgetComponent } from '../widget.component';
|
|
||||||
import { mergeMap, map } from 'rxjs/operators';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'upload-folder-widget',
|
|
||||||
templateUrl: './upload-folder.widget.html',
|
|
||||||
styleUrls: ['./upload-folder.widget.scss'],
|
|
||||||
host: {
|
|
||||||
'(click)': 'event($event)',
|
|
||||||
'(blur)': 'event($event)',
|
|
||||||
'(change)': 'event($event)',
|
|
||||||
'(focus)': 'event($event)',
|
|
||||||
'(focusin)': 'event($event)',
|
|
||||||
'(focusout)': 'event($event)',
|
|
||||||
'(input)': 'event($event)',
|
|
||||||
'(invalid)': 'event($event)',
|
|
||||||
'(select)': 'event($event)'
|
|
||||||
},
|
|
||||||
encapsulation: ViewEncapsulation.None
|
|
||||||
})
|
|
||||||
export class UploadFolderWidgetComponent extends WidgetComponent implements OnInit {
|
|
||||||
|
|
||||||
hasFile: boolean;
|
|
||||||
displayText: string;
|
|
||||||
multipleOption: string = '';
|
|
||||||
mimeTypeIcon: string;
|
|
||||||
|
|
||||||
@ViewChild('uploadFiles')
|
|
||||||
fileInput: ElementRef;
|
|
||||||
|
|
||||||
constructor(public formService: FormService,
|
|
||||||
private logService: LogService,
|
|
||||||
private thumbnailService: ThumbnailService,
|
|
||||||
public processContentService: ProcessContentService) {
|
|
||||||
super(formService);
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
if (this.field &&
|
|
||||||
this.field.value &&
|
|
||||||
this.field.value.length > 0) {
|
|
||||||
this.hasFile = true;
|
|
||||||
}
|
|
||||||
this.getMultipleFileParam();
|
|
||||||
}
|
|
||||||
|
|
||||||
removeFile(file: any) {
|
|
||||||
if (this.field) {
|
|
||||||
this.removeElementFromList(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onFileChanged(event: any) {
|
|
||||||
const files = event.target.files;
|
|
||||||
let filesSaved = [];
|
|
||||||
|
|
||||||
if (this.field.json.value) {
|
|
||||||
filesSaved = [...this.field.json.value];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (files && files.length > 0) {
|
|
||||||
from(files)
|
|
||||||
.pipe(mergeMap((file) => this.uploadRawContent(file)))
|
|
||||||
.subscribe(
|
|
||||||
(res) => {
|
|
||||||
filesSaved.push(res);
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
this.logService.error('Error uploading file. See console output for more details.');
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
this.field.value = filesSaved;
|
|
||||||
this.field.json.value = filesSaved;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.hasFile = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private uploadRawContent(file): Observable<any> {
|
|
||||||
return this.processContentService.createTemporaryRawRelatedContent(file).pipe(
|
|
||||||
map((response: any) => {
|
|
||||||
this.logService.info(response);
|
|
||||||
return response;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private getMultipleFileParam() {
|
|
||||||
if (this.field &&
|
|
||||||
this.field.params &&
|
|
||||||
this.field.params.multiple) {
|
|
||||||
this.multipleOption = this.field.params.multiple ? 'multiple' : '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private removeElementFromList(file) {
|
|
||||||
const index = this.field.value.indexOf(file);
|
|
||||||
|
|
||||||
if (index !== -1) {
|
|
||||||
this.field.value.splice(index, 1);
|
|
||||||
this.field.json.value = this.field.value;
|
|
||||||
this.field.updateForm();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.hasFile = this.field.value.length > 0;
|
|
||||||
|
|
||||||
this.resetFormValueWithNoFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
private resetFormValueWithNoFiles() {
|
|
||||||
if (this.field.value.length === 0) {
|
|
||||||
this.field.value = [];
|
|
||||||
this.field.json.value = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getIcon(mimeType) {
|
|
||||||
return this.thumbnailService.getMimeTypeIcon(mimeType);
|
|
||||||
}
|
|
||||||
|
|
||||||
fileClicked(contentLinkModel: any): void {
|
|
||||||
const file = new ContentLinkModel(contentLinkModel);
|
|
||||||
let fetch = this.processContentService.getContentPreview(file.id);
|
|
||||||
if (file.isTypeImage() || file.isTypePdf()) {
|
|
||||||
fetch = this.processContentService.getFileRawContent(file.id);
|
|
||||||
}
|
|
||||||
fetch.subscribe(
|
|
||||||
(blob: Blob) => {
|
|
||||||
file.contentBlob = blob;
|
|
||||||
this.formService.formContentClicked.next(file);
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
this.logService.error('Unable to send event for file ' + file.name);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,5 +20,4 @@ export * from './form-error.event';
|
|||||||
export * from './form-field.event';
|
export * from './form-field.event';
|
||||||
export * from './validate-form-field.event';
|
export * from './validate-form-field.event';
|
||||||
export * from './validate-form.event';
|
export * from './validate-form.event';
|
||||||
export * from './validate-dynamic-table-row.event';
|
|
||||||
export * from './form-rules.event';
|
export * from './form-rules.event';
|
||||||
|
@ -31,8 +31,6 @@ import { MASK_DIRECTIVE, WIDGET_DIRECTIVES } from './components/widgets';
|
|||||||
import { StartFormCustomButtonDirective } from './components/form-custom-button.directive';
|
import { StartFormCustomButtonDirective } from './components/form-custom-button.directive';
|
||||||
|
|
||||||
import { FormFieldComponent } from './components/form-field/form-field.component';
|
import { FormFieldComponent } from './components/form-field/form-field.component';
|
||||||
import { FormListComponent } from './components/form-list.component';
|
|
||||||
import { ContentWidgetComponent } from './components/widgets/content/content.widget';
|
|
||||||
import { WidgetComponent } from './components/widgets/widget.component';
|
import { WidgetComponent } from './components/widgets/widget.component';
|
||||||
import { MatDatetimepickerModule, MatNativeDatetimeModule } from '@mat-datetimepicker/core';
|
import { MatDatetimepickerModule, MatNativeDatetimeModule } from '@mat-datetimepicker/core';
|
||||||
import { FormRendererComponent } from './components/form-renderer.component';
|
import { FormRendererComponent } from './components/form-renderer.component';
|
||||||
@ -61,9 +59,7 @@ import { InplaceFormInputComponent } from './components/inplace-form-input/inpla
|
|||||||
ViewerModule
|
ViewerModule
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
ContentWidgetComponent,
|
|
||||||
FormFieldComponent,
|
FormFieldComponent,
|
||||||
FormListComponent,
|
|
||||||
FormRendererComponent,
|
FormRendererComponent,
|
||||||
StartFormCustomButtonDirective,
|
StartFormCustomButtonDirective,
|
||||||
...WIDGET_DIRECTIVES,
|
...WIDGET_DIRECTIVES,
|
||||||
@ -72,9 +68,7 @@ import { InplaceFormInputComponent } from './components/inplace-form-input/inpla
|
|||||||
InplaceFormInputComponent
|
InplaceFormInputComponent
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
ContentWidgetComponent,
|
|
||||||
FormFieldComponent,
|
FormFieldComponent,
|
||||||
FormListComponent,
|
|
||||||
FormRendererComponent,
|
FormRendererComponent,
|
||||||
StartFormCustomButtonDirective,
|
StartFormCustomButtonDirective,
|
||||||
...WIDGET_DIRECTIVES,
|
...WIDGET_DIRECTIVES,
|
||||||
|
@ -17,21 +17,14 @@
|
|||||||
|
|
||||||
export * from './components/form-field/form-field.component';
|
export * from './components/form-field/form-field.component';
|
||||||
export * from './components/form-base.component';
|
export * from './components/form-base.component';
|
||||||
export * from './components/form-list.component';
|
|
||||||
export * from './components/inplace-form-input/inplace-form-input.component';
|
export * from './components/inplace-form-input/inplace-form-input.component';
|
||||||
export * from './components/widgets/content/content.widget';
|
|
||||||
export * from './components/form-custom-button.directive';
|
export * from './components/form-custom-button.directive';
|
||||||
export * from './components/form-renderer.component';
|
export * from './components/form-renderer.component';
|
||||||
export * from './components/widgets';
|
export * from './components/widgets';
|
||||||
export * from './components/widgets/dynamic-table/dynamic-table-row.model';
|
|
||||||
|
|
||||||
export * from './services/activiti-alfresco.service';
|
|
||||||
export * from './services/ecm-model.service';
|
|
||||||
export * from './services/form-rendering.service';
|
export * from './services/form-rendering.service';
|
||||||
export * from './services/form.service';
|
export * from './services/form.service';
|
||||||
export * from './services/form-validation-service.interface';
|
export * from './services/form-validation-service.interface';
|
||||||
export * from './services/node.service';
|
|
||||||
export * from './services/process-content.service';
|
|
||||||
export * from './services/widget-visibility.service';
|
export * from './services/widget-visibility.service';
|
||||||
|
|
||||||
export * from './events';
|
export * from './events';
|
||||||
@ -39,3 +32,5 @@ export * from './events';
|
|||||||
export * from './form-base.module';
|
export * from './form-base.module';
|
||||||
|
|
||||||
export * from './models/form-rules.model';
|
export * from './models/form-rules.model';
|
||||||
|
export * from './models/form-definition.model';
|
||||||
|
export * from './models/task-process-variable.model';
|
||||||
|
@ -17,10 +17,8 @@
|
|||||||
|
|
||||||
import { DynamicComponentResolver } from '../../../../index';
|
import { DynamicComponentResolver } from '../../../../index';
|
||||||
import {
|
import {
|
||||||
FormFieldModel,
|
|
||||||
FormFieldTypes,
|
FormFieldTypes,
|
||||||
UnknownWidgetComponent,
|
UnknownWidgetComponent,
|
||||||
UploadWidgetComponent,
|
|
||||||
TextWidgetComponent,
|
TextWidgetComponent,
|
||||||
JsonWidgetComponent,
|
JsonWidgetComponent,
|
||||||
DisplayRichTextWidgetComponent
|
DisplayRichTextWidgetComponent
|
||||||
@ -35,23 +33,6 @@ describe('FormRenderingService', () => {
|
|||||||
service = new FormRenderingService();
|
service = new FormRenderingService();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should resolve Upload field as Upload widget', () => {
|
|
||||||
const field = new FormFieldModel(null, {
|
|
||||||
type: FormFieldTypes.UPLOAD,
|
|
||||||
params: {
|
|
||||||
link: null
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const type = service.resolveComponentType(field);
|
|
||||||
expect(type).toBe(UploadWidgetComponent);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should resolve Upload widget for Upload field', () => {
|
|
||||||
const resolver = service.getComponentTypeResolver(FormFieldTypes.UPLOAD);
|
|
||||||
const type = resolver(null);
|
|
||||||
expect(type).toBe(UploadWidgetComponent);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should resolve Unknown widget for unknown field type', () => {
|
it('should resolve Unknown widget for unknown field type', () => {
|
||||||
const resolver = service.getComponentTypeResolver('missing-type');
|
const resolver = service.getComponentTypeResolver('missing-type');
|
||||||
const type = resolver(null);
|
const type = resolver(null);
|
||||||
@ -70,12 +51,6 @@ describe('FormRenderingService', () => {
|
|||||||
expect(type).toBe(UnknownWidgetComponent);
|
expect(type).toBe(UnknownWidgetComponent);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fallback to custom resolver when field type missing', () => {
|
|
||||||
const resolver = service.getComponentTypeResolver(null, UploadWidgetComponent);
|
|
||||||
const type = resolver(null);
|
|
||||||
expect(type).toBe(UploadWidgetComponent);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require field type to set resolver for type', () => {
|
it('should require field type to set resolver for type', () => {
|
||||||
expect(
|
expect(
|
||||||
() => service.setComponentTypeResolver(
|
() => service.setComponentTypeResolver(
|
||||||
@ -120,10 +95,6 @@ describe('FormRenderingService', () => {
|
|||||||
expect(service.resolveComponentType(null)).toBe(UnknownWidgetComponent);
|
expect(service.resolveComponentType(null)).toBe(UnknownWidgetComponent);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return custom value when resolving with no field', () => {
|
|
||||||
expect(service.resolveComponentType(null, UploadWidgetComponent)).toBe(UploadWidgetComponent);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should resolve Display Text Widget for JSON field type', () => {
|
it('should resolve Display Text Widget for JSON field type', () => {
|
||||||
const resolver = service.getComponentTypeResolver('json');
|
const resolver = service.getComponentTypeResolver('json');
|
||||||
const type = resolver(null);
|
const type = resolver(null);
|
||||||
|
@ -32,20 +32,12 @@ export class FormRenderingService extends DynamicComponentMapper {
|
|||||||
integer: DynamicComponentResolver.fromType(widgets.NumberWidgetComponent),
|
integer: DynamicComponentResolver.fromType(widgets.NumberWidgetComponent),
|
||||||
'multi-line-text': DynamicComponentResolver.fromType(widgets.MultilineTextWidgetComponentComponent),
|
'multi-line-text': DynamicComponentResolver.fromType(widgets.MultilineTextWidgetComponentComponent),
|
||||||
boolean: DynamicComponentResolver.fromType(widgets.CheckboxWidgetComponent),
|
boolean: DynamicComponentResolver.fromType(widgets.CheckboxWidgetComponent),
|
||||||
dropdown: DynamicComponentResolver.fromType(widgets.DropdownWidgetComponent),
|
|
||||||
date: DynamicComponentResolver.fromType(widgets.DateWidgetComponent),
|
date: DynamicComponentResolver.fromType(widgets.DateWidgetComponent),
|
||||||
amount: DynamicComponentResolver.fromType(widgets.AmountWidgetComponent),
|
amount: DynamicComponentResolver.fromType(widgets.AmountWidgetComponent),
|
||||||
'radio-buttons': DynamicComponentResolver.fromType(widgets.RadioButtonsWidgetComponent),
|
|
||||||
hyperlink: DynamicComponentResolver.fromType(widgets.HyperlinkWidgetComponent),
|
hyperlink: DynamicComponentResolver.fromType(widgets.HyperlinkWidgetComponent),
|
||||||
'readonly-text': DynamicComponentResolver.fromType(widgets.DisplayTextWidgetComponent),
|
'readonly-text': DynamicComponentResolver.fromType(widgets.DisplayTextWidgetComponent),
|
||||||
json: DynamicComponentResolver.fromType(widgets.JsonWidgetComponent),
|
json: DynamicComponentResolver.fromType(widgets.JsonWidgetComponent),
|
||||||
readonly: DynamicComponentResolver.fromType(widgets.TextWidgetComponent),
|
readonly: DynamicComponentResolver.fromType(widgets.TextWidgetComponent),
|
||||||
typeahead: DynamicComponentResolver.fromType(widgets.TypeaheadWidgetComponent),
|
|
||||||
people: DynamicComponentResolver.fromType(widgets.PeopleWidgetComponent),
|
|
||||||
'functional-group': DynamicComponentResolver.fromType(widgets.FunctionalGroupWidgetComponent),
|
|
||||||
'dynamic-table': DynamicComponentResolver.fromType(widgets.DynamicTableWidgetComponent),
|
|
||||||
document: DynamicComponentResolver.fromType(widgets.DocumentWidgetComponent),
|
|
||||||
upload: DynamicComponentResolver.fromType(widgets.UploadWidgetComponent),
|
|
||||||
datetime: DynamicComponentResolver.fromType(widgets.DateTimeWidgetComponent),
|
datetime: DynamicComponentResolver.fromType(widgets.DateTimeWidgetComponent),
|
||||||
'file-viewer': DynamicComponentResolver.fromType(widgets.FileViewerWidgetComponent),
|
'file-viewer': DynamicComponentResolver.fromType(widgets.FileViewerWidgetComponent),
|
||||||
'display-rich-text': DynamicComponentResolver.fromType(widgets.DisplayRichTextWidgetComponent)
|
'display-rich-text': DynamicComponentResolver.fromType(widgets.DisplayRichTextWidgetComponent)
|
||||||
|
@ -15,40 +15,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { fakeAsync, TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { formModelTabs } from '../../mock';
|
import { formModelTabs } from '../../mock';
|
||||||
import { FormService } from './form.service';
|
import { FormService } from './form.service';
|
||||||
import { setupTestBed } from '../../testing/setup-test-bed';
|
import { setupTestBed } from '../../testing/setup-test-bed';
|
||||||
import { CoreTestingModule } from '../../testing/core.testing.module';
|
import { CoreTestingModule } from '../../testing/core.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
declare let jasmine: any;
|
|
||||||
|
|
||||||
const fakeGroupResponse = {
|
|
||||||
size: 2,
|
|
||||||
total: 2,
|
|
||||||
start: 0,
|
|
||||||
data: [{
|
|
||||||
id: '2004',
|
|
||||||
name: 'PEOPLE_GROUP',
|
|
||||||
externalId: null,
|
|
||||||
status: 'active',
|
|
||||||
groups: null
|
|
||||||
}, { id: 2005, name: 'PEOPLE_GROUP_2', externalId: null, status: 'active', groups: null }]
|
|
||||||
};
|
|
||||||
|
|
||||||
const fakePeopleResponse = {
|
|
||||||
size: 3,
|
|
||||||
total: 3,
|
|
||||||
start: 0,
|
|
||||||
data: [{ id: 2002, firstName: 'Peo', lastName: 'Ple', email: 'people' }, {
|
|
||||||
id: 2003,
|
|
||||||
firstName: 'Peo02',
|
|
||||||
lastName: 'Ple02',
|
|
||||||
email: 'people02'
|
|
||||||
}, { id: 2004, firstName: 'Peo03', lastName: 'Ple03', email: 'people03' }]
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('Form service', () => {
|
describe('Form service', () => {
|
||||||
|
|
||||||
let service: FormService;
|
let service: FormService;
|
||||||
@ -62,289 +35,12 @@ describe('Form service', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
service = TestBed.inject(FormService);
|
service = TestBed.inject(FormService);
|
||||||
jasmine.Ajax.install();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jasmine.Ajax.uninstall();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Content tests', () => {
|
describe('parseForm', () => {
|
||||||
|
|
||||||
const responseBody = {
|
|
||||||
data: [
|
|
||||||
{ id: '1' },
|
|
||||||
{ id: '2' }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
const values = {
|
|
||||||
field1: 'one',
|
|
||||||
field2: 'two'
|
|
||||||
};
|
|
||||||
|
|
||||||
const simpleResponseBody = { id: 1, modelType: 'test' };
|
|
||||||
|
|
||||||
it('should fetch and parse process definitions', (done) => {
|
|
||||||
service.getProcessDefinitions().subscribe(() => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/process-definitions')).toBeTruthy();
|
|
||||||
expect([{ id: '1' }, { id: '2' }]).toEqual(JSON.parse(jasmine.Ajax.requests.mostRecent().response).data);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify(responseBody)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fetch and parse tasks', (done) => {
|
|
||||||
service.getTasks().subscribe(() => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/tasks/query')).toBeTruthy();
|
|
||||||
expect([{ id: '1' }, { id: '2' }]).toEqual(JSON.parse(jasmine.Ajax.requests.mostRecent().response).data);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify(responseBody)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fetch and parse the task by id', (done) => {
|
|
||||||
service.getTask('1').subscribe((result) => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/tasks/1')).toBeTruthy();
|
|
||||||
expect(result.id).toEqual('1');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify({ id: '1' })
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should save task form', (done) => {
|
|
||||||
service.saveTaskForm('1', values).subscribe(() => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/task-forms/1/save-form')).toBeTruthy();
|
|
||||||
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).values.field1).toEqual(values.field1);
|
|
||||||
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).values.field2).toEqual(values.field2);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify(responseBody)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should complete task form', (done) => {
|
|
||||||
service.completeTaskForm('1', values).subscribe(() => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/task-forms/1')).toBeTruthy();
|
|
||||||
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).values.field1).toEqual(values.field1);
|
|
||||||
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).values.field2).toEqual(values.field2);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify(responseBody)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should complete task form with a specific outcome', (done) => {
|
|
||||||
service.completeTaskForm('1', values, 'custom').subscribe(() => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/task-forms/1')).toBeTruthy();
|
|
||||||
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).values.field2).toEqual(values.field2);
|
|
||||||
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).outcome).toEqual('custom');
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify(responseBody)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get task form by id', (done) => {
|
|
||||||
service.getTaskForm('1').subscribe((result) => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/task-forms/1')).toBeTruthy();
|
|
||||||
expect(result.id).toEqual(1);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify({ id: 1 })
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get form definition by id', (done) => {
|
|
||||||
service.getFormDefinitionById(1).subscribe((result) => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/form-models/1')).toBeTruthy();
|
|
||||||
expect(result.id).toEqual(1);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify({ id: 1 })
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get form definition id by name', (done) => {
|
|
||||||
const formName = 'form1';
|
|
||||||
const formId = 1;
|
|
||||||
const response = {
|
|
||||||
data: [
|
|
||||||
{ id: formId }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
service.getFormDefinitionByName(formName).subscribe((result) => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith(`models?filter=myReusableForms&filterText=${formName}&modelType=2`)).toBeTruthy();
|
|
||||||
expect(result).toEqual(formId);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify(response)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle error with generic message', () => {
|
|
||||||
service.handleError(null).subscribe(() => {
|
|
||||||
}, (error) => {
|
|
||||||
expect(error).toBe(FormService.UNKNOWN_ERROR_MESSAGE);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle error with error message', () => {
|
|
||||||
const message = '<error>';
|
|
||||||
|
|
||||||
service.handleError({ message }).subscribe(() => {
|
|
||||||
}, (error) => {
|
|
||||||
expect(error).toBe(message);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle error with detailed message', () => {
|
|
||||||
service.handleError({
|
|
||||||
status: '400',
|
|
||||||
statusText: 'Bad request'
|
|
||||||
}).subscribe(
|
|
||||||
() => {
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
expect(error).toBe('400 - Bad request');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle error with generic message', () => {
|
|
||||||
service.handleError({}).subscribe(() => {
|
|
||||||
}, (error) => {
|
|
||||||
expect(error).toBe(FormService.GENERIC_ERROR_MESSAGE);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get all the forms with modelType=2', (done) => {
|
|
||||||
service.getForms().subscribe((result) => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('models?modelType=2')).toBeTruthy();
|
|
||||||
expect(result.length).toEqual(2);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify({
|
|
||||||
data: [
|
|
||||||
{ name: 'FakeName-1', lastUpdatedByFullName: 'FakeUser-1', lastUpdated: '2017-01-02' },
|
|
||||||
{ name: 'FakeName-2', lastUpdatedByFullName: 'FakeUser-2', lastUpdated: '2017-01-03' }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should search for Form with modelType=2', (done) => {
|
|
||||||
const response = { data: [{ id: 1, name: 'findMe' }, { id: 2, name: 'testForm' }] };
|
|
||||||
|
|
||||||
service.searchFrom('findMe').subscribe((result) => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('models?modelType=2')).toBeTruthy();
|
|
||||||
expect(result.name).toEqual('findMe');
|
|
||||||
expect(result.id).toEqual(1);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify(response)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create a Form with modelType=2', (done) => {
|
|
||||||
service.createForm('testName').subscribe(() => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/models')).toBeTruthy();
|
|
||||||
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).modelType).toEqual(2);
|
|
||||||
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).name).toEqual('testName');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify(simpleResponseBody)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return list of people', (done) => {
|
|
||||||
spyOn(service, 'getUserProfileImageApi').and.returnValue('/app/rest/users/2002/picture');
|
|
||||||
const fakeFilter: string = 'whatever';
|
|
||||||
|
|
||||||
service.getWorkflowUsers(fakeFilter).subscribe((result) => {
|
|
||||||
expect(result).toBeDefined();
|
|
||||||
expect(result.length).toBe(3);
|
|
||||||
expect(result[0].id).toBe(2002);
|
|
||||||
expect(result[0].firstName).toBe('Peo');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify(fakePeopleResponse)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return list of groups', (done) => {
|
|
||||||
const fakeFilter: string = 'whatever';
|
|
||||||
|
|
||||||
service.getWorkflowGroups(fakeFilter).subscribe((result) => {
|
|
||||||
expect(result).toBeDefined();
|
|
||||||
expect(result.length).toBe(2);
|
|
||||||
expect(result[0].id).toBe('2004');
|
|
||||||
expect(result[0].name).toBe('PEOPLE_GROUP');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify(fakeGroupResponse)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse a Form Definition with tabs', () => {
|
it('should parse a Form Definition with tabs', () => {
|
||||||
expect(formModelTabs.formRepresentation.formDefinition).toBeDefined();
|
expect(formModelTabs.formRepresentation.formDefinition).toBeDefined();
|
||||||
@ -352,60 +48,5 @@ describe('Form service', () => {
|
|||||||
expect(formParsed).toBeDefined();
|
expect(formParsed).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a Form form a Node', fakeAsync(() => {
|
|
||||||
const nameForm = 'testNode';
|
|
||||||
const formId = 100;
|
|
||||||
|
|
||||||
const stubCreateForm = () => {
|
|
||||||
jasmine.Ajax.stubRequest(
|
|
||||||
'http://localhost:9876/bpm/activiti-app/api/enterprise/models'
|
|
||||||
).andReturn({
|
|
||||||
status: 200,
|
|
||||||
statusText: 'HTTP/1.1 200 OK',
|
|
||||||
contentType: 'text/xml;charset=UTF-8',
|
|
||||||
responseText: { id: formId, name: 'test', lastUpdatedByFullName: 'uset', lastUpdated: '12-12-2016' }
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const stubGetEcmModel = () => {
|
|
||||||
jasmine.Ajax.stubRequest(
|
|
||||||
'http://localhost:9876/ecm/alfresco/api/-default-/private/alfresco/versions/1/cmm/activitiFormsModel/types'
|
|
||||||
).andReturn({
|
|
||||||
status: 200,
|
|
||||||
statusText: 'HTTP/1.1 200 OK',
|
|
||||||
contentType: 'text/xml;charset=UTF-8',
|
|
||||||
responseText: {
|
|
||||||
list: {
|
|
||||||
entries: [{
|
|
||||||
entry: {
|
|
||||||
prefixedName: nameForm,
|
|
||||||
title: nameForm,
|
|
||||||
properties: [{ name: 'name' }, { name: 'email' }]
|
|
||||||
}
|
|
||||||
}, { entry: { prefixedName: 'notme', title: 'notme' } }]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const stubAddFieldsToAForm = () => {
|
|
||||||
jasmine.Ajax.stubRequest(
|
|
||||||
'http://localhost:9876/bpm/activiti-app/api/enterprise/editor/form-models/' + formId
|
|
||||||
).andReturn({
|
|
||||||
status: 200,
|
|
||||||
statusText: 'HTTP/1.1 200 OK',
|
|
||||||
contentType: 'text/xml;charset=UTF-8',
|
|
||||||
responseText: { id: formId, name: 'test', lastUpdatedByFullName: 'user', lastUpdated: '12-12-2016' }
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
stubCreateForm();
|
|
||||||
stubGetEcmModel();
|
|
||||||
stubAddFieldsToAForm();
|
|
||||||
|
|
||||||
service.createFormFromANode(nameForm).subscribe((result) => {
|
|
||||||
expect(result.id).toEqual(formId);
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -15,29 +15,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AlfrescoApiService } from '../../services/alfresco-api.service';
|
|
||||||
import { LogService } from '../../services/log.service';
|
|
||||||
import { UserProcessModel } from '../../models';
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Observable, Subject, from, of, throwError } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { FormDefinitionModel } from '../models/form-definition.model';
|
|
||||||
import { ContentLinkModel } from '../components/widgets/core/content-link.model';
|
import { ContentLinkModel } from '../components/widgets/core/content-link.model';
|
||||||
import { GroupModel } from '../components/widgets/core/group.model';
|
|
||||||
import { EcmModelService } from './ecm-model.service';
|
|
||||||
import { map, catchError, switchMap, combineAll, defaultIfEmpty } from 'rxjs/operators';
|
|
||||||
import {
|
|
||||||
CompleteFormRepresentation,
|
|
||||||
ModelsApi,
|
|
||||||
ProcessInstanceVariablesApi,
|
|
||||||
SaveFormRepresentation,
|
|
||||||
TasksApi,
|
|
||||||
TaskFormsApi,
|
|
||||||
ProcessInstancesApi,
|
|
||||||
FormModelsApi,
|
|
||||||
ProcessDefinitionsApi,
|
|
||||||
UsersApi,
|
|
||||||
ActivitiGroupsApi
|
|
||||||
} from '@alfresco/js-api';
|
|
||||||
import { FormOutcomeEvent } from '../components/widgets/core/form-outcome-event.model';
|
import { FormOutcomeEvent } from '../components/widgets/core/form-outcome-event.model';
|
||||||
import { FormValues } from '../components/widgets/core/form-values';
|
import { FormValues } from '../components/widgets/core/form-values';
|
||||||
import { FormModel } from '../components/widgets/core/form.model';
|
import { FormModel } from '../components/widgets/core/form.model';
|
||||||
@ -47,7 +27,6 @@ import { FormFieldEvent } from '../events/form-field.event';
|
|||||||
import { FormErrorEvent } from '../events/form-error.event';
|
import { FormErrorEvent } from '../events/form-error.event';
|
||||||
import { ValidateFormEvent } from '../events/validate-form.event';
|
import { ValidateFormEvent } from '../events/validate-form.event';
|
||||||
import { ValidateFormFieldEvent } from '../events/validate-form-field.event';
|
import { ValidateFormFieldEvent } from '../events/validate-form-field.event';
|
||||||
import { ValidateDynamicTableRowEvent } from '../events/validate-dynamic-table-row.event';
|
|
||||||
import { FormValidationService } from './form-validation-service.interface';
|
import { FormValidationService } from './form-validation-service.interface';
|
||||||
import { FormRulesEvent } from '../events/form-rules.event';
|
import { FormRulesEvent } from '../events/form-rules.event';
|
||||||
|
|
||||||
@ -56,63 +35,6 @@ import { FormRulesEvent } from '../events/form-rules.event';
|
|||||||
})
|
})
|
||||||
export class FormService implements FormValidationService {
|
export class FormService implements FormValidationService {
|
||||||
|
|
||||||
static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error';
|
|
||||||
static GENERIC_ERROR_MESSAGE: string = 'Server error';
|
|
||||||
|
|
||||||
_taskFormsApi: TaskFormsApi;
|
|
||||||
get taskFormsApi(): TaskFormsApi {
|
|
||||||
this._taskFormsApi = this._taskFormsApi ?? new TaskFormsApi(this.apiService.getInstance());
|
|
||||||
return this._taskFormsApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
_taskApi: TasksApi;
|
|
||||||
get taskApi(): TasksApi {
|
|
||||||
this._taskApi = this._taskApi ?? new TasksApi(this.apiService.getInstance());
|
|
||||||
return this._taskApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
_modelsApi: ModelsApi;
|
|
||||||
get modelsApi(): ModelsApi {
|
|
||||||
this._modelsApi = this._modelsApi ?? new ModelsApi(this.apiService.getInstance());
|
|
||||||
return this._modelsApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
_editorApi: FormModelsApi;
|
|
||||||
get editorApi(): FormModelsApi {
|
|
||||||
this._editorApi = this._editorApi ?? new FormModelsApi(this.apiService.getInstance());
|
|
||||||
return this._editorApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
_processDefinitionsApi: ProcessDefinitionsApi;
|
|
||||||
get processDefinitionsApi(): ProcessDefinitionsApi {
|
|
||||||
this._processDefinitionsApi = this._processDefinitionsApi ?? new ProcessDefinitionsApi(this.apiService.getInstance());
|
|
||||||
return this._processDefinitionsApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
_processInstanceVariablesApi: ProcessInstanceVariablesApi;
|
|
||||||
get processInstanceVariablesApi(): ProcessInstanceVariablesApi {
|
|
||||||
this._processInstanceVariablesApi = this._processInstanceVariablesApi ?? new ProcessInstanceVariablesApi(this.apiService.getInstance());
|
|
||||||
return this._processInstanceVariablesApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
_processInstancesApi: ProcessInstancesApi;
|
|
||||||
get processInstancesApi(): ProcessInstancesApi {
|
|
||||||
this._processInstancesApi = this._processInstancesApi ?? new ProcessInstancesApi(this.apiService.getInstance());
|
|
||||||
return this._processInstancesApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
_groupsApi: ActivitiGroupsApi;
|
|
||||||
get groupsApi(): ActivitiGroupsApi {
|
|
||||||
this._groupsApi = this._groupsApi ?? new ActivitiGroupsApi(this.apiService.getInstance());
|
|
||||||
return this._groupsApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
_usersApi: UsersApi;
|
|
||||||
get usersApi(): UsersApi {
|
|
||||||
this._usersApi = this._usersApi ?? new UsersApi(this.apiService.getInstance());
|
|
||||||
return this._usersApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
formLoaded = new Subject<FormEvent>();
|
formLoaded = new Subject<FormEvent>();
|
||||||
formDataRefreshed = new Subject<FormEvent>();
|
formDataRefreshed = new Subject<FormEvent>();
|
||||||
formFieldValueChanged = new Subject<FormFieldEvent>();
|
formFieldValueChanged = new Subject<FormFieldEvent>();
|
||||||
@ -125,7 +47,7 @@ export class FormService implements FormValidationService {
|
|||||||
|
|
||||||
validateForm = new Subject<ValidateFormEvent>();
|
validateForm = new Subject<ValidateFormEvent>();
|
||||||
validateFormField = new Subject<ValidateFormFieldEvent>();
|
validateFormField = new Subject<ValidateFormFieldEvent>();
|
||||||
validateDynamicTableRow = new Subject<ValidateDynamicTableRowEvent>();
|
validateDynamicTableRow = new Subject<FormFieldEvent>();
|
||||||
|
|
||||||
executeOutcome = new Subject<FormOutcomeEvent>();
|
executeOutcome = new Subject<FormOutcomeEvent>();
|
||||||
|
|
||||||
@ -133,9 +55,7 @@ export class FormService implements FormValidationService {
|
|||||||
|
|
||||||
formRulesEvent = new Subject<FormRulesEvent>();
|
formRulesEvent = new Subject<FormRulesEvent>();
|
||||||
|
|
||||||
constructor(private ecmModelService: EcmModelService,
|
constructor() {
|
||||||
private apiService: AlfrescoApiService,
|
|
||||||
protected logService: LogService) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,449 +83,4 @@ export class FormService implements FormValidationService {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Form with a field for each metadata property.
|
|
||||||
*
|
|
||||||
* @param formName Name of the new form
|
|
||||||
* @returns The new form
|
|
||||||
*/
|
|
||||||
createFormFromANode(formName: string): Observable<any> {
|
|
||||||
return new Observable((observer) => {
|
|
||||||
this.createForm(formName).subscribe(
|
|
||||||
(form) => {
|
|
||||||
this.ecmModelService.searchEcmType(formName, EcmModelService.MODEL_NAME).subscribe(
|
|
||||||
(customType) => {
|
|
||||||
const formDefinitionModel = new FormDefinitionModel(form.id, form.name, form.lastUpdatedByFullName, form.lastUpdated, customType.entry.properties);
|
|
||||||
from(
|
|
||||||
this.editorApi.saveForm(form.id, formDefinitionModel)
|
|
||||||
).subscribe((formData) => {
|
|
||||||
observer.next(formData);
|
|
||||||
observer.complete();
|
|
||||||
}, (err) => this.handleError(err));
|
|
||||||
},
|
|
||||||
(err) => this.handleError(err));
|
|
||||||
},
|
|
||||||
(err) => this.handleError(err));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a Form.
|
|
||||||
*
|
|
||||||
* @param formName Name of the new form
|
|
||||||
* @returns The new form
|
|
||||||
*/
|
|
||||||
createForm(formName: string): Observable<any> {
|
|
||||||
const dataModel = {
|
|
||||||
name: formName,
|
|
||||||
description: '',
|
|
||||||
modelType: 2,
|
|
||||||
stencilSet: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
return from(
|
|
||||||
this.modelsApi.createModel(dataModel)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves a form.
|
|
||||||
*
|
|
||||||
* @param formId ID of the form to save
|
|
||||||
* @param formModel Model data for the form
|
|
||||||
* @returns Data for the saved form
|
|
||||||
*/
|
|
||||||
saveForm(formId: number, formModel: FormDefinitionModel): Observable<any> {
|
|
||||||
return from(
|
|
||||||
this.editorApi.saveForm(formId, formModel)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Searches for a form by name.
|
|
||||||
*
|
|
||||||
* @param name The form name to search for
|
|
||||||
* @returns Form model(s) matching the search name
|
|
||||||
*/
|
|
||||||
searchFrom(name: string): Observable<any> {
|
|
||||||
const opts = {
|
|
||||||
modelType: 2
|
|
||||||
};
|
|
||||||
|
|
||||||
return from(
|
|
||||||
this.modelsApi.getModels(opts)
|
|
||||||
)
|
|
||||||
.pipe(
|
|
||||||
map((forms: any) => forms.data.find((formData) => formData.name === name)),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all the forms.
|
|
||||||
*
|
|
||||||
* @returns List of form models
|
|
||||||
*/
|
|
||||||
getForms(): Observable<any> {
|
|
||||||
const opts = {
|
|
||||||
modelType: 2
|
|
||||||
};
|
|
||||||
|
|
||||||
return from(this.modelsApi.getModels(opts))
|
|
||||||
.pipe(
|
|
||||||
map(this.toJsonArray),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets process definitions.
|
|
||||||
*
|
|
||||||
* @returns List of process definitions
|
|
||||||
*/
|
|
||||||
getProcessDefinitions(): Observable<any> {
|
|
||||||
return from(this.processDefinitionsApi.getProcessDefinitions({}))
|
|
||||||
.pipe(
|
|
||||||
map(this.toJsonArray),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets instance variables for a process.
|
|
||||||
*
|
|
||||||
* @param processInstanceId ID of the target process
|
|
||||||
* @returns List of instance variable information
|
|
||||||
*/
|
|
||||||
getProcessVariablesById(processInstanceId: string): Observable<any[]> {
|
|
||||||
return from(this.processInstanceVariablesApi.getProcessInstanceVariables(processInstanceId))
|
|
||||||
.pipe(
|
|
||||||
map(this.toJson),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all the tasks.
|
|
||||||
*
|
|
||||||
* @returns List of tasks
|
|
||||||
*/
|
|
||||||
getTasks(): Observable<any> {
|
|
||||||
return from(this.taskApi.listTasks({}))
|
|
||||||
.pipe(
|
|
||||||
map(this.toJsonArray),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a task.
|
|
||||||
*
|
|
||||||
* @param taskId Task Id
|
|
||||||
* @returns Task info
|
|
||||||
*/
|
|
||||||
getTask(taskId: string): Observable<any> {
|
|
||||||
return from(this.taskApi.getTask(taskId))
|
|
||||||
.pipe(
|
|
||||||
map(this.toJson),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves a task form.
|
|
||||||
*
|
|
||||||
* @param taskId Task Id
|
|
||||||
* @param formValues Form Values
|
|
||||||
* @returns Null response when the operation is complete
|
|
||||||
*/
|
|
||||||
saveTaskForm(taskId: string, formValues: FormValues): Observable<any> {
|
|
||||||
const saveFormRepresentation = { values: formValues } as SaveFormRepresentation;
|
|
||||||
|
|
||||||
return from(this.taskFormsApi.saveTaskForm(taskId, saveFormRepresentation))
|
|
||||||
.pipe(
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Completes a Task Form.
|
|
||||||
*
|
|
||||||
* @param taskId Task Id
|
|
||||||
* @param formValues Form Values
|
|
||||||
* @param outcome Form Outcome
|
|
||||||
* @returns Null response when the operation is complete
|
|
||||||
*/
|
|
||||||
completeTaskForm(taskId: string, formValues: FormValues, outcome?: string): Observable<any> {
|
|
||||||
const completeFormRepresentation = { values: formValues } as CompleteFormRepresentation;
|
|
||||||
if (outcome) {
|
|
||||||
completeFormRepresentation.outcome = outcome;
|
|
||||||
}
|
|
||||||
|
|
||||||
return from(this.taskFormsApi.completeTaskForm(taskId, completeFormRepresentation))
|
|
||||||
.pipe(
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a form related to a task.
|
|
||||||
*
|
|
||||||
* @param taskId ID of the target task
|
|
||||||
* @returns Form definition
|
|
||||||
*/
|
|
||||||
getTaskForm(taskId: string): Observable<any> {
|
|
||||||
return from(this.taskFormsApi.getTaskForm(taskId))
|
|
||||||
.pipe(
|
|
||||||
map(this.toJson),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a form definition.
|
|
||||||
*
|
|
||||||
* @param formId ID of the target form
|
|
||||||
* @returns Form definition
|
|
||||||
*/
|
|
||||||
getFormDefinitionById(formId: number): Observable<any> {
|
|
||||||
return from(this.editorApi.getForm(formId))
|
|
||||||
.pipe(
|
|
||||||
map(this.toJson),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the form definition with a given name.
|
|
||||||
*
|
|
||||||
* @param name The form name
|
|
||||||
* @returns Form definition
|
|
||||||
*/
|
|
||||||
getFormDefinitionByName(name: string): Observable<any> {
|
|
||||||
const opts = {
|
|
||||||
filter: 'myReusableForms',
|
|
||||||
filterText: name,
|
|
||||||
modelType: 2
|
|
||||||
};
|
|
||||||
|
|
||||||
return from(this.modelsApi.getModels(opts))
|
|
||||||
.pipe(
|
|
||||||
map(this.getFormId),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the start form instance for a given process.
|
|
||||||
*
|
|
||||||
* @param processId Process definition ID
|
|
||||||
* @returns Form definition
|
|
||||||
*/
|
|
||||||
getStartFormInstance(processId: string): Observable<any> {
|
|
||||||
return from(this.processInstancesApi.getProcessInstanceStartForm(processId))
|
|
||||||
.pipe(
|
|
||||||
map(this.toJson),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a process instance.
|
|
||||||
*
|
|
||||||
* @param processId ID of the process to get
|
|
||||||
* @returns Process instance
|
|
||||||
*/
|
|
||||||
getProcessInstance(processId: string): Observable<any> {
|
|
||||||
return from(this.processInstancesApi.getProcessInstance(processId))
|
|
||||||
.pipe(
|
|
||||||
map(this.toJson),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the start form definition for a given process.
|
|
||||||
*
|
|
||||||
* @param processId Process definition ID
|
|
||||||
* @returns Form definition
|
|
||||||
*/
|
|
||||||
getStartFormDefinition(processId: string): Observable<any> {
|
|
||||||
return from(this.processDefinitionsApi.getProcessDefinitionStartForm(processId))
|
|
||||||
.pipe(
|
|
||||||
map(this.toJson),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets values of fields populated by a REST backend.
|
|
||||||
*
|
|
||||||
* @param taskId Task identifier
|
|
||||||
* @param field Field identifier
|
|
||||||
* @returns Field values
|
|
||||||
*/
|
|
||||||
getRestFieldValues(taskId: string, field: string): Observable<any> {
|
|
||||||
return from(this.taskFormsApi.getRestFieldValues(taskId, field))
|
|
||||||
.pipe(
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets values of fields populated by a REST backend using a process ID.
|
|
||||||
*
|
|
||||||
* @param processDefinitionId Process identifier
|
|
||||||
* @param field Field identifier
|
|
||||||
* @returns Field values
|
|
||||||
*/
|
|
||||||
getRestFieldValuesByProcessId(processDefinitionId: string, field: string): Observable<any> {
|
|
||||||
return from(this.processDefinitionsApi.getRestFieldValues(processDefinitionId, field))
|
|
||||||
.pipe(
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets column values of fields populated by a REST backend using a process ID.
|
|
||||||
*
|
|
||||||
* @param processDefinitionId Process identifier
|
|
||||||
* @param field Field identifier
|
|
||||||
* @param column Column identifier
|
|
||||||
* @returns Field values
|
|
||||||
*/
|
|
||||||
getRestFieldValuesColumnByProcessId(processDefinitionId: string, field: string, column?: string): Observable<any> {
|
|
||||||
return from(this.processDefinitionsApi.getRestTableFieldValues(processDefinitionId, field, column))
|
|
||||||
.pipe(
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets column values of fields populated by a REST backend.
|
|
||||||
*
|
|
||||||
* @param taskId Task identifier
|
|
||||||
* @param field Field identifier
|
|
||||||
* @param column Column identifier
|
|
||||||
* @returns Field values
|
|
||||||
*/
|
|
||||||
getRestFieldValuesColumn(taskId: string, field: string, column?: string): Observable<any> {
|
|
||||||
return from(this.taskFormsApi.getRestFieldColumnValues(taskId, field, column))
|
|
||||||
.pipe(
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a URL for the profile picture of a user.
|
|
||||||
*
|
|
||||||
* @param userId ID of the target user
|
|
||||||
* @returns URL string
|
|
||||||
*/
|
|
||||||
getUserProfileImageApi(userId: string): string {
|
|
||||||
return this.usersApi.getUserProfilePictureUrl(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a list of workflow users.
|
|
||||||
*
|
|
||||||
* @param filter Filter to select specific users
|
|
||||||
* @param groupId Group ID for the search
|
|
||||||
* @returns Array of users
|
|
||||||
*/
|
|
||||||
getWorkflowUsers(filter: string, groupId?: string): Observable<UserProcessModel[]> {
|
|
||||||
const option: any = { filter };
|
|
||||||
if (groupId) {
|
|
||||||
option.groupId = groupId;
|
|
||||||
}
|
|
||||||
return from(this.usersApi.getUsers(option))
|
|
||||||
.pipe(
|
|
||||||
switchMap(response => response.data as UserProcessModel[] || []),
|
|
||||||
map((user) => {
|
|
||||||
user.userImage = this.getUserProfileImageApi(user.id.toString());
|
|
||||||
return of(user);
|
|
||||||
}),
|
|
||||||
combineAll(),
|
|
||||||
defaultIfEmpty([]),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a list of groups in a workflow.
|
|
||||||
*
|
|
||||||
* @param filter Filter to select specific groups
|
|
||||||
* @param groupId Group ID for the search
|
|
||||||
* @returns Array of groups
|
|
||||||
*/
|
|
||||||
getWorkflowGroups(filter: string, groupId?: string): Observable<GroupModel[]> {
|
|
||||||
const option: any = { filter };
|
|
||||||
if (groupId) {
|
|
||||||
option.groupId = groupId;
|
|
||||||
}
|
|
||||||
return from(this.groupsApi.getGroups(option))
|
|
||||||
.pipe(
|
|
||||||
map((response: any) => response.data || []),
|
|
||||||
catchError((err) => this.handleError(err))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the ID of a form.
|
|
||||||
*
|
|
||||||
* @param form Object representing a form
|
|
||||||
* @returns ID string
|
|
||||||
*/
|
|
||||||
getFormId(form: any): string {
|
|
||||||
let result = null;
|
|
||||||
|
|
||||||
if (form && form.data && form.data.length > 0) {
|
|
||||||
result = form.data[0].id;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a JSON representation of form data.
|
|
||||||
*
|
|
||||||
* @param res Object representing form data
|
|
||||||
* @returns JSON data
|
|
||||||
*/
|
|
||||||
toJson(res: any) {
|
|
||||||
if (res) {
|
|
||||||
return res || {};
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a JSON array representation of form data.
|
|
||||||
*
|
|
||||||
* @param res Object representing form data
|
|
||||||
* @returns JSON data
|
|
||||||
*/
|
|
||||||
toJsonArray(res: any) {
|
|
||||||
if (res) {
|
|
||||||
return res.data || [];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reports an error message.
|
|
||||||
*
|
|
||||||
* @param error Data object with optional `message` and `status` fields for the error
|
|
||||||
* @returns Error message
|
|
||||||
*/
|
|
||||||
handleError(error: any): Observable<any> {
|
|
||||||
let errMsg = FormService.UNKNOWN_ERROR_MESSAGE;
|
|
||||||
if (error) {
|
|
||||||
errMsg = (error.message) ? error.message :
|
|
||||||
error.status ? `${error.status} - ${error.statusText}` : FormService.GENERIC_ERROR_MESSAGE;
|
|
||||||
}
|
|
||||||
this.logService.error(errMsg);
|
|
||||||
return throwError(errMsg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,171 +0,0 @@
|
|||||||
/*!
|
|
||||||
* @license
|
|
||||||
* Copyright 2019 Alfresco Software, Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
import { NodeMetadata } from '../../models/node-metadata.model';
|
|
||||||
import { EcmModelService } from './ecm-model.service';
|
|
||||||
import { NodeService } from './node.service';
|
|
||||||
import { setupTestBed } from '../../testing/setup-test-bed';
|
|
||||||
import { CoreTestingModule } from '../../testing/core.testing.module';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
declare let jasmine: any;
|
|
||||||
|
|
||||||
describe('NodeService', () => {
|
|
||||||
|
|
||||||
let service: NodeService;
|
|
||||||
|
|
||||||
setupTestBed({
|
|
||||||
imports: [
|
|
||||||
TranslateModule.forRoot(),
|
|
||||||
CoreTestingModule
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
service = TestBed.inject(NodeService);
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
jasmine.Ajax.install();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
jasmine.Ajax.uninstall();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should fetch and node metadata', (done) => {
|
|
||||||
const responseBody = {
|
|
||||||
entry: {
|
|
||||||
id: '111-222-33-44-1123',
|
|
||||||
nodeType: 'typeTest',
|
|
||||||
properties: {
|
|
||||||
test: 'test',
|
|
||||||
testdata: 'testdata'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
service.getNodeMetadata('-nodeid-').subscribe((result) => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('nodes/-nodeid-')).toBeTruthy();
|
|
||||||
const node = new NodeMetadata({
|
|
||||||
test: 'test',
|
|
||||||
testdata: 'testdata'
|
|
||||||
}, 'typeTest');
|
|
||||||
expect(result).toEqual(node);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify(responseBody)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should clean the metadata from :', (done) => {
|
|
||||||
const responseBody = {
|
|
||||||
entry: {
|
|
||||||
id: '111-222-33-44-1123',
|
|
||||||
nodeType: 'typeTest',
|
|
||||||
properties: {
|
|
||||||
'metadata:test': 'test',
|
|
||||||
'metadata:testdata': 'testdata'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
service.getNodeMetadata('-nodeid-').subscribe((result) => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('nodes/-nodeid-')).toBeTruthy();
|
|
||||||
const node = new NodeMetadata({
|
|
||||||
test: 'test',
|
|
||||||
testdata: 'testdata'
|
|
||||||
}, 'typeTest');
|
|
||||||
expect(result).toEqual(node);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify(responseBody)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should create a node with metadata', (done) => {
|
|
||||||
const data = {
|
|
||||||
test: 'test',
|
|
||||||
testdata: 'testdata'
|
|
||||||
};
|
|
||||||
|
|
||||||
const responseBody = {
|
|
||||||
id: 'a74d91fb-ea8a-4812-ad98-ad878366b5be',
|
|
||||||
isFile: false,
|
|
||||||
isFolder: true
|
|
||||||
};
|
|
||||||
|
|
||||||
service.createNodeMetadata('typeTest', EcmModelService.MODEL_NAMESPACE, data, '/Sites/swsdp/documentLibrary', 'testNode').subscribe(() => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('-root-/children')).toBeTruthy();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify(responseBody)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should add activitiForms suffix to the metadata properties', (done) => {
|
|
||||||
const data = {
|
|
||||||
test: 'test',
|
|
||||||
testdata: 'testdata'
|
|
||||||
};
|
|
||||||
|
|
||||||
service.createNodeMetadata('typeTest', EcmModelService.MODEL_NAMESPACE, data, '/Sites/swsdp/documentLibrary').subscribe(() => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('-root-/children')).toBeTruthy();
|
|
||||||
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).properties[EcmModelService.MODEL_NAMESPACE + ':test']).toBeDefined();
|
|
||||||
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).properties[EcmModelService.MODEL_NAMESPACE + ':testdata']).toBeDefined();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify({})
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should assign an UUID to the name when name not passed', (done) => {
|
|
||||||
const data = {
|
|
||||||
test: 'test',
|
|
||||||
testdata: 'testdata'
|
|
||||||
};
|
|
||||||
|
|
||||||
service.createNodeMetadata('typeTest', EcmModelService.MODEL_NAMESPACE, data, '/Sites/swsdp/documentLibrary').subscribe(() => {
|
|
||||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('-root-/children')).toBeTruthy();
|
|
||||||
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).name).toBeDefined();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'application/json',
|
|
||||||
responseText: JSON.stringify({})
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,70 +0,0 @@
|
|||||||
/*!
|
|
||||||
* @license
|
|
||||||
* Copyright 2019 Alfresco Software, Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { NodeEntry } from '@alfresco/js-api';
|
|
||||||
import { NodeMetadata } from '../../models/node-metadata.model';
|
|
||||||
import { NodesApiService } from '../../services/nodes-api.service';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
/**
|
|
||||||
* @deprecated in 3.8.0, use NodesApiService instead.
|
|
||||||
*/
|
|
||||||
export class NodeService {
|
|
||||||
|
|
||||||
constructor(private nodesApiService: NodesApiService) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated in 3.8.0, use NodesApiService instead.
|
|
||||||
* Get the metadata and the nodeType for a nodeId cleaned by the prefix.
|
|
||||||
* @param nodeId ID of the target node
|
|
||||||
* @returns Node metadata
|
|
||||||
*/
|
|
||||||
public getNodeMetadata(nodeId: string): Observable<NodeMetadata> {
|
|
||||||
return this.nodesApiService.getNodeMetadata(nodeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated in 3.8.0, use NodesApiService instead.
|
|
||||||
* Create a new Node from form metadata.
|
|
||||||
* @param path Path to the node
|
|
||||||
* @param nodeType Node type
|
|
||||||
* @param name Node name
|
|
||||||
* @param nameSpace Namespace for properties
|
|
||||||
* @param data Property data to store in the node under namespace
|
|
||||||
* @returns The created node
|
|
||||||
*/
|
|
||||||
public createNodeMetadata(nodeType: string, nameSpace: any, data: any, path: string, name?: string): Observable<NodeEntry> {
|
|
||||||
return this.nodesApiService.createNodeMetadata(nodeType, nameSpace, data, path, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated in 3.8.0, use `createNodeInsideRoot` method from NodesApiService instead.
|
|
||||||
* Create a new Node from form metadata
|
|
||||||
* @param name Node name
|
|
||||||
* @param nodeType Node type
|
|
||||||
* @param properties Node body properties
|
|
||||||
* @param path Path to the node
|
|
||||||
* @returns The created node
|
|
||||||
*/
|
|
||||||
public createNode(name: string, nodeType: string, properties: any, path: string): Observable<NodeEntry> {
|
|
||||||
return this.nodesApiService.createNodeInsideRoot(name, nodeType, properties, path);
|
|
||||||
}
|
|
||||||
}
|
|
@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { fakeAsync, TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import {
|
import {
|
||||||
ContainerModel,
|
ContainerModel,
|
||||||
FormFieldModel,
|
FormFieldModel,
|
||||||
@ -24,12 +24,11 @@ import {
|
|||||||
TabModel,
|
TabModel,
|
||||||
FormOutcomeModel
|
FormOutcomeModel
|
||||||
} from '../components/widgets/core';
|
} from '../components/widgets/core';
|
||||||
import { TaskProcessVariableModel } from '../models/task-process-variable.model';
|
|
||||||
import { WidgetVisibilityModel, WidgetTypeEnum } from '../models/widget-visibility.model';
|
import { WidgetVisibilityModel, WidgetTypeEnum } from '../models/widget-visibility.model';
|
||||||
import { WidgetVisibilityService } from './widget-visibility.service';
|
import { WidgetVisibilityService } from './widget-visibility.service';
|
||||||
import { setupTestBed } from '../../testing/setup-test-bed';
|
import { setupTestBed } from '../../testing/setup-test-bed';
|
||||||
import {
|
import {
|
||||||
fakeFormJson, fakeTaskProcessVariableModels,
|
fakeFormJson,
|
||||||
formTest, formValues, complexVisibilityJsonVisible,
|
formTest, formValues, complexVisibilityJsonVisible,
|
||||||
nextConditionForm, complexVisibilityJsonNotVisible,
|
nextConditionForm, complexVisibilityJsonNotVisible,
|
||||||
headerVisibilityCond
|
headerVisibilityCond
|
||||||
@ -156,160 +155,6 @@ describe('WidgetVisibilityCloudService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should retrieve the process variables', () => {
|
|
||||||
const fakeFormWithField = new FormModel(fakeFormJson);
|
|
||||||
let visibilityObjTest: WidgetVisibilityModel;
|
|
||||||
const chainedVisibilityObj = new WidgetVisibilityModel({});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
visibilityObjTest = new WidgetVisibilityModel({});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return the process variables for task', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
(res) => {
|
|
||||||
expect(res).toBeDefined();
|
|
||||||
expect(res.length).toEqual(3);
|
|
||||||
expect(res[0].id).toEqual('TEST_VAR_1');
|
|
||||||
expect(res[0].type).toEqual('string');
|
|
||||||
expect(res[0].value).toEqual('test_value_1');
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: fakeTaskProcessVariableModels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be able to retrieve the value of a process variable', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
(res: TaskProcessVariableModel[]) => {
|
|
||||||
expect(res).toBeDefined();
|
|
||||||
const varValue = service.getVariableValue(formTest, 'TEST_VAR_1', res);
|
|
||||||
expect(varValue).not.toBeUndefined();
|
|
||||||
expect(varValue).toBe('test_value_1');
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: fakeTaskProcessVariableModels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return undefined if the variable does not exist', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
(res: TaskProcessVariableModel[]) => {
|
|
||||||
const varValue = service.getVariableValue(formTest, 'TEST_MYSTERY_VAR', res);
|
|
||||||
expect(varValue).toBeUndefined();
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: fakeTaskProcessVariableModels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should retrieve the value for the right field when it is a process variable', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
() => {
|
|
||||||
visibilityObjTest.rightValue = 'test_value_2';
|
|
||||||
spyOn(service, 'isFormFieldValid').and.returnValue(true);
|
|
||||||
const rightValue = service.getRightValue(formTest, visibilityObjTest);
|
|
||||||
|
|
||||||
expect(rightValue).not.toBeNull();
|
|
||||||
expect(rightValue).toBe('test_value_2');
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: fakeTaskProcessVariableModels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should retrieve the value for the left field when it is a process variable', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
() => {
|
|
||||||
visibilityObjTest.leftValue = 'TEST_VAR_2';
|
|
||||||
visibilityObjTest.leftType = WidgetTypeEnum.field;
|
|
||||||
const leftValue = service.getLeftValue(formTest, visibilityObjTest);
|
|
||||||
|
|
||||||
expect(leftValue).not.toBeNull();
|
|
||||||
expect(leftValue).toBe('test_value_2');
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: fakeTaskProcessVariableModels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should evaluate the visibility for the field between form value and process var', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
() => {
|
|
||||||
visibilityObjTest.leftType = 'LEFT_FORM_FIELD_ID';
|
|
||||||
visibilityObjTest.operator = '!=';
|
|
||||||
visibilityObjTest.rightValue = 'TEST_VAR_2';
|
|
||||||
const isVisible = service.isFieldVisible(fakeFormWithField, visibilityObjTest);
|
|
||||||
|
|
||||||
expect(isVisible).toBeTruthy();
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: fakeTaskProcessVariableModels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should evaluate visibility with multiple conditions', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
() => {
|
|
||||||
visibilityObjTest.leftType = 'field';
|
|
||||||
visibilityObjTest.leftValue = 'TEST_VAR_2';
|
|
||||||
visibilityObjTest.operator = '!=';
|
|
||||||
visibilityObjTest.rightValue = 'TEST_VAR_2';
|
|
||||||
visibilityObjTest.nextConditionOperator = 'and';
|
|
||||||
chainedVisibilityObj.leftType = 'field';
|
|
||||||
chainedVisibilityObj.leftValue = 'TEST_VAR_2';
|
|
||||||
chainedVisibilityObj.operator = '!empty';
|
|
||||||
visibilityObjTest.nextCondition = chainedVisibilityObj;
|
|
||||||
|
|
||||||
const isVisible = service.isFieldVisible(fakeFormWithField, visibilityObjTest);
|
|
||||||
|
|
||||||
expect(isVisible).toBeTruthy();
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: fakeTaskProcessVariableModels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should catch error on 403 response', fakeAsync(() => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(() => {
|
|
||||||
}, (errorMessage) => {
|
|
||||||
expect(errorMessage).toEqual('Error while performing a call - Server error');
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 403
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('should return the value of the field', () => {
|
describe('should return the value of the field', () => {
|
||||||
let visibilityObjTest: WidgetVisibilityModel;
|
let visibilityObjTest: WidgetVisibilityModel;
|
||||||
let fakeFormWithField = new FormModel(fakeFormJson);
|
let fakeFormWithField = new FormModel(fakeFormJson);
|
||||||
@ -644,143 +489,6 @@ describe('WidgetVisibilityCloudService', () => {
|
|||||||
expect(fakeFormWithField.outcomes[outcomeIndex].isVisible).toBeFalsy();
|
expect(fakeFormWithField.outcomes[outcomeIndex].isVisible).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use the form value to evaluate the visibility condition if the form value is defined', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
(res: TaskProcessVariableModel[]) => {
|
|
||||||
expect(res).toBeDefined();
|
|
||||||
const varValue = service.getVariableValue(formTest, 'FIELD_FORM_EMPTY', res);
|
|
||||||
expect(varValue).not.toBeUndefined();
|
|
||||||
expect(varValue).toBe('PROCESS_RIGHT_FORM_FIELD_VALUE');
|
|
||||||
|
|
||||||
visibilityObjTest.leftType = WidgetTypeEnum.field;
|
|
||||||
visibilityObjTest.leftValue = 'FIELD_FORM_EMPTY';
|
|
||||||
visibilityObjTest.operator = '==';
|
|
||||||
visibilityObjTest.rightValue = 'RIGHT_FORM_FIELD_VALUE';
|
|
||||||
|
|
||||||
const myForm = new FormModel({
|
|
||||||
id: '9999',
|
|
||||||
name: 'FORM_PROCESS_VARIABLE_VISIBILITY',
|
|
||||||
processDefinitionId: 'PROCESS_TEST:9:9999',
|
|
||||||
processDefinitionName: 'PROCESS_TEST',
|
|
||||||
processDefinitionKey: 'PROCESS_TEST',
|
|
||||||
taskId: '999',
|
|
||||||
taskName: 'TEST',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldType: 'ContainerRepresentation',
|
|
||||||
id: '000000000000000000',
|
|
||||||
name: 'Label',
|
|
||||||
type: 'container',
|
|
||||||
value: null,
|
|
||||||
numberOfColumns: 2,
|
|
||||||
fields: {
|
|
||||||
1: [
|
|
||||||
{
|
|
||||||
fieldType: 'FormFieldRepresentation',
|
|
||||||
id: 'FIELD_FORM_EMPTY',
|
|
||||||
name: 'FIELD_FORM_EMPTY',
|
|
||||||
type: 'text',
|
|
||||||
value: 'RIGHT_FORM_FIELD_VALUE',
|
|
||||||
visibilityCondition: null,
|
|
||||||
isVisible: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldType: 'FormFieldRepresentation',
|
|
||||||
id: 'FIELD_FORM_WITH_CONDITION',
|
|
||||||
name: 'FIELD_FORM_WITH_CONDITION',
|
|
||||||
type: 'text',
|
|
||||||
value: 'field_form_with_condition_value',
|
|
||||||
visibilityCondition: visibilityObjTest,
|
|
||||||
isVisible: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
service.refreshVisibility(myForm);
|
|
||||||
|
|
||||||
const fieldWithVisibilityAttached = myForm.getFieldById('FIELD_FORM_WITH_CONDITION');
|
|
||||||
expect(fieldWithVisibilityAttached.isVisible).toBeTruthy();
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: [{ id: 'FIELD_FORM_EMPTY', type: 'string', value: 'PROCESS_RIGHT_FORM_FIELD_VALUE' }]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use the process value to evaluate the True visibility condition if the form value is empty', (done) => {
|
|
||||||
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
(res: TaskProcessVariableModel[]) => {
|
|
||||||
expect(res).toBeDefined();
|
|
||||||
|
|
||||||
visibilityObjTest.leftType = WidgetTypeEnum.field;
|
|
||||||
visibilityObjTest.leftValue = 'FIELD_FORM_EMPTY';
|
|
||||||
visibilityObjTest.operator = '==';
|
|
||||||
visibilityObjTest.rightType = WidgetTypeEnum.value;
|
|
||||||
visibilityObjTest.rightValue = 'PROCESS_RIGHT_FORM_FIELD_VALUE';
|
|
||||||
|
|
||||||
const myForm = new FormModel({
|
|
||||||
id: '9999',
|
|
||||||
name: 'FORM_PROCESS_VARIABLE_VISIBILITY',
|
|
||||||
processDefinitionId: 'PROCESS_TEST:9:9999',
|
|
||||||
processDefinitionName: 'PROCESS_TEST',
|
|
||||||
processDefinitionKey: 'PROCESS_TEST',
|
|
||||||
taskId: '999',
|
|
||||||
taskName: 'TEST',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldType: 'ContainerRepresentation',
|
|
||||||
id: '000000000000000000',
|
|
||||||
name: 'Label',
|
|
||||||
type: 'container',
|
|
||||||
value: null,
|
|
||||||
numberOfColumns: 2,
|
|
||||||
fields: {
|
|
||||||
1: [
|
|
||||||
{
|
|
||||||
fieldType: 'FormFieldRepresentation',
|
|
||||||
id: 'FIELD_FORM_EMPTY',
|
|
||||||
name: 'FIELD_FORM_EMPTY',
|
|
||||||
type: 'text',
|
|
||||||
value: '',
|
|
||||||
visibilityCondition: null,
|
|
||||||
isVisible: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldType: 'FormFieldRepresentation',
|
|
||||||
id: 'FIELD_FORM_WITH_CONDITION',
|
|
||||||
name: 'FIELD_FORM_WITH_CONDITION',
|
|
||||||
type: 'text',
|
|
||||||
value: 'field_form_with_condition_value',
|
|
||||||
visibilityCondition: visibilityObjTest,
|
|
||||||
isVisible: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
service.refreshVisibility(myForm);
|
|
||||||
|
|
||||||
const fieldWithVisibilityAttached = myForm.getFieldById('FIELD_FORM_WITH_CONDITION');
|
|
||||||
expect(fieldWithVisibilityAttached.isVisible).toBeTruthy();
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: [{ id: 'FIELD_FORM_EMPTY', type: 'string', value: 'PROCESS_RIGHT_FORM_FIELD_VALUE' }]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use the process variables when they are passed to check the visibility', () => {
|
it('should use the process variables when they are passed to check the visibility', () => {
|
||||||
|
|
||||||
visibilityObjTest.leftType = WidgetTypeEnum.field;
|
visibilityObjTest.leftType = WidgetTypeEnum.field;
|
||||||
@ -837,72 +545,6 @@ describe('WidgetVisibilityCloudService', () => {
|
|||||||
expect(fieldWithVisibilityAttached.isVisible).toBeTruthy();
|
expect(fieldWithVisibilityAttached.isVisible).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use the process value to evaluate the False visibility condition if the form value is empty', (done) => {
|
|
||||||
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
(res: TaskProcessVariableModel[]) => {
|
|
||||||
expect(res).toBeDefined();
|
|
||||||
|
|
||||||
visibilityObjTest.leftType = 'FIELD_FORM_EMPTY';
|
|
||||||
visibilityObjTest.operator = '==';
|
|
||||||
visibilityObjTest.rightValue = 'RIGHT_FORM_FIELD_VALUE';
|
|
||||||
|
|
||||||
const myForm = new FormModel({
|
|
||||||
id: '9999',
|
|
||||||
name: 'FORM_PROCESS_VARIABLE_VISIBILITY',
|
|
||||||
processDefinitionId: 'PROCESS_TEST:9:9999',
|
|
||||||
processDefinitionName: 'PROCESS_TEST',
|
|
||||||
processDefinitionKey: 'PROCESS_TEST',
|
|
||||||
taskId: '999',
|
|
||||||
taskName: 'TEST',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldType: 'ContainerRepresentation',
|
|
||||||
id: '000000000000000000',
|
|
||||||
name: 'Label',
|
|
||||||
type: 'container',
|
|
||||||
value: null,
|
|
||||||
numberOfColumns: 2,
|
|
||||||
fields: {
|
|
||||||
1: [
|
|
||||||
{
|
|
||||||
fieldType: 'FormFieldRepresentation',
|
|
||||||
id: 'FIELD_FORM_EMPTY',
|
|
||||||
name: 'FIELD_FORM_EMPTY',
|
|
||||||
type: 'text',
|
|
||||||
value: '',
|
|
||||||
visibilityCondition: null,
|
|
||||||
isVisible: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldType: 'FormFieldRepresentation',
|
|
||||||
id: 'FIELD_FORM_WITH_CONDITION',
|
|
||||||
name: 'FIELD_FORM_WITH_CONDITION',
|
|
||||||
type: 'text',
|
|
||||||
value: 'field_form_with_condition_value',
|
|
||||||
visibilityCondition: visibilityObjTest,
|
|
||||||
isVisible: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
service.refreshVisibility(myForm);
|
|
||||||
|
|
||||||
const fieldWithVisibilityAttached = myForm.getFieldById('FIELD_FORM_WITH_CONDITION');
|
|
||||||
expect(fieldWithVisibilityAttached.isVisible).toBeFalsy();
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: [{ id: 'FIELD_FORM_EMPTY', type: 'string', value: 'PROCESS_RIGHT_FORM_FIELD_VALUE' }]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should refresh the visibility for single tab', () => {
|
it('should refresh the visibility for single tab', () => {
|
||||||
visibilityObjTest.leftType = WidgetTypeEnum.field;
|
visibilityObjTest.leftType = WidgetTypeEnum.field;
|
||||||
visibilityObjTest.leftValue = 'FIELD_TEST';
|
visibilityObjTest.leftValue = 'FIELD_TEST';
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { fakeAsync, TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import {
|
import {
|
||||||
ContainerModel,
|
ContainerModel,
|
||||||
FormFieldModel,
|
FormFieldModel,
|
||||||
@ -23,12 +23,10 @@ import {
|
|||||||
FormModel,
|
FormModel,
|
||||||
TabModel
|
TabModel
|
||||||
} from '../components/widgets/core';
|
} from '../components/widgets/core';
|
||||||
import { TaskProcessVariableModel } from '../models/task-process-variable.model';
|
|
||||||
import { WidgetVisibilityModel } from '../models/widget-visibility.model';
|
import { WidgetVisibilityModel } from '../models/widget-visibility.model';
|
||||||
import { WidgetVisibilityService } from './widget-visibility.service';
|
import { WidgetVisibilityService } from './widget-visibility.service';
|
||||||
import { setupTestBed } from '../../testing/setup-test-bed';
|
import { setupTestBed } from '../../testing/setup-test-bed';
|
||||||
import {
|
import {
|
||||||
fakeTaskProcessVariableModels,
|
|
||||||
fakeFormJson, formTest,
|
fakeFormJson, formTest,
|
||||||
formValues, complexVisibilityJsonVisible,
|
formValues, complexVisibilityJsonVisible,
|
||||||
complexVisibilityJsonNotVisible, tabVisibilityJsonMock,
|
complexVisibilityJsonNotVisible, tabVisibilityJsonMock,
|
||||||
@ -39,8 +37,6 @@ import {
|
|||||||
import { CoreTestingModule } from '../../testing/core.testing.module';
|
import { CoreTestingModule } from '../../testing/core.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
declare let jasmine: any;
|
|
||||||
|
|
||||||
describe('WidgetVisibilityService', () => {
|
describe('WidgetVisibilityService', () => {
|
||||||
|
|
||||||
let service: WidgetVisibilityService;
|
let service: WidgetVisibilityService;
|
||||||
@ -56,11 +52,6 @@ describe('WidgetVisibilityService', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
service = TestBed.inject(WidgetVisibilityService);
|
service = TestBed.inject(WidgetVisibilityService);
|
||||||
jasmine.Ajax.install();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
jasmine.Ajax.uninstall();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should be able to evaluate next condition operations', () => {
|
describe('should be able to evaluate next condition operations', () => {
|
||||||
@ -161,158 +152,6 @@ describe('WidgetVisibilityService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should retrieve the process variables', () => {
|
|
||||||
let fakeFormWithField: FormModel;
|
|
||||||
let visibilityObjTest: WidgetVisibilityModel;
|
|
||||||
const chainedVisibilityObj = new WidgetVisibilityModel({});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fakeFormWithField = new FormModel(fakeFormJson);
|
|
||||||
visibilityObjTest = new WidgetVisibilityModel({});
|
|
||||||
fakeFormWithField = new FormModel(fakeFormJson);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return the process variables for task', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
(res) => {
|
|
||||||
expect(res).toBeDefined();
|
|
||||||
expect(res.length).toEqual(3);
|
|
||||||
expect(res[0].id).toEqual('TEST_VAR_1');
|
|
||||||
expect(res[0].type).toEqual('string');
|
|
||||||
expect(res[0].value).toEqual('test_value_1');
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: fakeTaskProcessVariableModels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be able to retrieve the value of a process variable', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
(res: TaskProcessVariableModel[]) => {
|
|
||||||
expect(res).toBeDefined();
|
|
||||||
const varValue = service.getVariableValue(formTest, 'TEST_VAR_1', res);
|
|
||||||
expect(varValue).not.toBeUndefined();
|
|
||||||
expect(varValue).toBe('test_value_1');
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: fakeTaskProcessVariableModels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return undefined if the variable does not exist', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
(res: TaskProcessVariableModel[]) => {
|
|
||||||
const varValue = service.getVariableValue(formTest, 'TEST_MYSTERY_VAR', res);
|
|
||||||
expect(varValue).toBeUndefined();
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: fakeTaskProcessVariableModels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should retrieve the value for the right field when it is a process variable', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
() => {
|
|
||||||
visibilityObjTest.rightRestResponseId = 'TEST_VAR_2';
|
|
||||||
const rightValue = service.getRightValue(formTest, visibilityObjTest);
|
|
||||||
|
|
||||||
expect(rightValue).not.toBeNull();
|
|
||||||
expect(rightValue).toBe('test_value_2');
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: fakeTaskProcessVariableModels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should retrieve the value for the left field when it is a process variable', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
() => {
|
|
||||||
visibilityObjTest.leftRestResponseId = 'TEST_VAR_2';
|
|
||||||
const leftValue = service.getLeftValue(formTest, visibilityObjTest);
|
|
||||||
|
|
||||||
expect(leftValue).not.toBeNull();
|
|
||||||
expect(leftValue).toBe('test_value_2');
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: fakeTaskProcessVariableModels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should evaluate the visibility for the field between form value and process var', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
() => {
|
|
||||||
visibilityObjTest.leftFormFieldId = 'LEFT_FORM_FIELD_ID';
|
|
||||||
visibilityObjTest.operator = '!=';
|
|
||||||
visibilityObjTest.rightRestResponseId = 'TEST_VAR_2';
|
|
||||||
const isVisible = service.isFieldVisible(fakeFormWithField, new WidgetVisibilityModel(visibilityObjTest));
|
|
||||||
|
|
||||||
expect(isVisible).toBeTruthy();
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: fakeTaskProcessVariableModels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should evaluate visibility with multiple conditions', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
() => {
|
|
||||||
visibilityObjTest.leftFormFieldId = 'LEFT_FORM_FIELD_ID';
|
|
||||||
visibilityObjTest.operator = '!=';
|
|
||||||
visibilityObjTest.rightRestResponseId = 'TEST_VAR_2';
|
|
||||||
visibilityObjTest.nextConditionOperator = 'and';
|
|
||||||
chainedVisibilityObj.leftRestResponseId = 'TEST_VAR_2';
|
|
||||||
chainedVisibilityObj.operator = '!empty';
|
|
||||||
visibilityObjTest.nextCondition = chainedVisibilityObj;
|
|
||||||
|
|
||||||
const isVisible = service.isFieldVisible(fakeFormWithField, visibilityObjTest);
|
|
||||||
|
|
||||||
expect(isVisible).toBeTruthy();
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: fakeTaskProcessVariableModels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should catch error on 403 response', fakeAsync(() => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(() => {
|
|
||||||
}, (errorMessage) => {
|
|
||||||
expect(errorMessage).toEqual('Error while performing a call - Server error');
|
|
||||||
});
|
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 403
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('should return the value of the field', () => {
|
describe('should return the value of the field', () => {
|
||||||
let visibilityObjTest: WidgetVisibilityModel;
|
let visibilityObjTest: WidgetVisibilityModel;
|
||||||
let fakeFormWithField: FormModel;
|
let fakeFormWithField: FormModel;
|
||||||
@ -650,206 +489,6 @@ describe('WidgetVisibilityService', () => {
|
|||||||
expect(fakeFormWithField.tabs[0].isVisible).toBeFalsy();
|
expect(fakeFormWithField.tabs[0].isVisible).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use the form value to evaluate the visibility condition if the form value is defined', (done) => {
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
(res: TaskProcessVariableModel[]) => {
|
|
||||||
expect(res).toBeDefined();
|
|
||||||
const varValue = service.getVariableValue(formTest, 'FIELD_FORM_EMPTY', res);
|
|
||||||
expect(varValue).not.toBeUndefined();
|
|
||||||
expect(varValue).toBe('PROCESS_RIGHT_FORM_FIELD_VALUE');
|
|
||||||
|
|
||||||
visibilityObjTest.leftFormFieldId = 'FIELD_FORM_EMPTY';
|
|
||||||
visibilityObjTest.operator = '==';
|
|
||||||
visibilityObjTest.rightValue = 'RIGHT_FORM_FIELD_VALUE';
|
|
||||||
|
|
||||||
const myForm = new FormModel({
|
|
||||||
id: '9999',
|
|
||||||
name: 'FORM_PROCESS_VARIABLE_VISIBILITY',
|
|
||||||
processDefinitionId: 'PROCESS_TEST:9:9999',
|
|
||||||
processDefinitionName: 'PROCESS_TEST',
|
|
||||||
processDefinitionKey: 'PROCESS_TEST',
|
|
||||||
taskId: '999',
|
|
||||||
taskName: 'TEST',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldType: 'ContainerRepresentation',
|
|
||||||
id: '000000000000000000',
|
|
||||||
name: 'Label',
|
|
||||||
type: 'container',
|
|
||||||
value: null,
|
|
||||||
numberOfColumns: 2,
|
|
||||||
fields: {
|
|
||||||
1: [
|
|
||||||
{
|
|
||||||
fieldType: 'FormFieldRepresentation',
|
|
||||||
id: 'FIELD_FORM_EMPTY',
|
|
||||||
name: 'FIELD_FORM_EMPTY',
|
|
||||||
type: 'text',
|
|
||||||
value: 'RIGHT_FORM_FIELD_VALUE',
|
|
||||||
visibilityCondition: null,
|
|
||||||
isVisible: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldType: 'FormFieldRepresentation',
|
|
||||||
id: 'FIELD_FORM_WITH_CONDITION',
|
|
||||||
name: 'FIELD_FORM_WITH_CONDITION',
|
|
||||||
type: 'text',
|
|
||||||
value: 'field_form_with_condition_value',
|
|
||||||
visibilityCondition: visibilityObjTest,
|
|
||||||
isVisible: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
service.refreshVisibility(myForm);
|
|
||||||
|
|
||||||
const fieldWithVisibilityAttached = myForm.getFieldById('FIELD_FORM_WITH_CONDITION');
|
|
||||||
expect(fieldWithVisibilityAttached.isVisible).toBeTruthy();
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: [{ id: 'FIELD_FORM_EMPTY', type: 'string', value: 'PROCESS_RIGHT_FORM_FIELD_VALUE' }]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use the process value to evaluate the True visibility condition if the form value is empty', (done) => {
|
|
||||||
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
(res: TaskProcessVariableModel[]) => {
|
|
||||||
expect(res).toBeDefined();
|
|
||||||
|
|
||||||
visibilityObjTest.leftFormFieldId = 'FIELD_FORM_EMPTY';
|
|
||||||
visibilityObjTest.operator = '==';
|
|
||||||
visibilityObjTest.rightValue = 'PROCESS_RIGHT_FORM_FIELD_VALUE';
|
|
||||||
|
|
||||||
const myForm = new FormModel({
|
|
||||||
id: '9999',
|
|
||||||
name: 'FORM_PROCESS_VARIABLE_VISIBILITY',
|
|
||||||
processDefinitionId: 'PROCESS_TEST:9:9999',
|
|
||||||
processDefinitionName: 'PROCESS_TEST',
|
|
||||||
processDefinitionKey: 'PROCESS_TEST',
|
|
||||||
taskId: '999',
|
|
||||||
taskName: 'TEST',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldType: 'ContainerRepresentation',
|
|
||||||
id: '000000000000000000',
|
|
||||||
name: 'Label',
|
|
||||||
type: 'container',
|
|
||||||
value: null,
|
|
||||||
numberOfColumns: 2,
|
|
||||||
fields: {
|
|
||||||
1: [
|
|
||||||
{
|
|
||||||
fieldType: 'FormFieldRepresentation',
|
|
||||||
id: 'FIELD_FORM_EMPTY',
|
|
||||||
name: 'FIELD_FORM_EMPTY',
|
|
||||||
type: 'text',
|
|
||||||
value: '',
|
|
||||||
visibilityCondition: null,
|
|
||||||
isVisible: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldType: 'FormFieldRepresentation',
|
|
||||||
id: 'FIELD_FORM_WITH_CONDITION',
|
|
||||||
name: 'FIELD_FORM_WITH_CONDITION',
|
|
||||||
type: 'text',
|
|
||||||
value: 'field_form_with_condition_value',
|
|
||||||
visibilityCondition: visibilityObjTest,
|
|
||||||
isVisible: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
service.refreshVisibility(myForm);
|
|
||||||
|
|
||||||
const fieldWithVisibilityAttached = myForm.getFieldById('FIELD_FORM_WITH_CONDITION');
|
|
||||||
expect(fieldWithVisibilityAttached.isVisible).toBeTruthy();
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: [{ id: 'FIELD_FORM_EMPTY', type: 'string', value: 'PROCESS_RIGHT_FORM_FIELD_VALUE' }]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use the process value to evaluate the False visibility condition if the form value is empty', (done) => {
|
|
||||||
|
|
||||||
service.getTaskProcessVariable('9999').subscribe(
|
|
||||||
(res: TaskProcessVariableModel[]) => {
|
|
||||||
expect(res).toBeDefined();
|
|
||||||
|
|
||||||
visibilityObjTest.leftFormFieldId = 'FIELD_FORM_EMPTY';
|
|
||||||
visibilityObjTest.operator = '==';
|
|
||||||
visibilityObjTest.rightValue = 'RIGHT_FORM_FIELD_VALUE';
|
|
||||||
|
|
||||||
const myForm = new FormModel({
|
|
||||||
id: '9999',
|
|
||||||
name: 'FORM_PROCESS_VARIABLE_VISIBILITY',
|
|
||||||
processDefinitionId: 'PROCESS_TEST:9:9999',
|
|
||||||
processDefinitionName: 'PROCESS_TEST',
|
|
||||||
processDefinitionKey: 'PROCESS_TEST',
|
|
||||||
taskId: '999',
|
|
||||||
taskName: 'TEST',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldType: 'ContainerRepresentation',
|
|
||||||
id: '000000000000000000',
|
|
||||||
name: 'Label',
|
|
||||||
type: 'container',
|
|
||||||
value: null,
|
|
||||||
numberOfColumns: 2,
|
|
||||||
fields: {
|
|
||||||
1: [
|
|
||||||
{
|
|
||||||
fieldType: 'FormFieldRepresentation',
|
|
||||||
id: 'FIELD_FORM_EMPTY',
|
|
||||||
name: 'FIELD_FORM_EMPTY',
|
|
||||||
type: 'text',
|
|
||||||
value: '',
|
|
||||||
visibilityCondition: null,
|
|
||||||
isVisible: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldType: 'FormFieldRepresentation',
|
|
||||||
id: 'FIELD_FORM_WITH_CONDITION',
|
|
||||||
name: 'FIELD_FORM_WITH_CONDITION',
|
|
||||||
type: 'text',
|
|
||||||
value: 'field_form_with_condition_value',
|
|
||||||
visibilityCondition: visibilityObjTest,
|
|
||||||
isVisible: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
service.refreshVisibility(myForm);
|
|
||||||
|
|
||||||
const fieldWithVisibilityAttached = myForm.getFieldById('FIELD_FORM_WITH_CONDITION');
|
|
||||||
expect(fieldWithVisibilityAttached.isVisible).toBeFalsy();
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
|
||||||
status: 200,
|
|
||||||
contentType: 'json',
|
|
||||||
responseText: [{ id: 'FIELD_FORM_EMPTY', type: 'string', value: 'PROCESS_RIGHT_FORM_FIELD_VALUE' }]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should refresh the visibility for single tab', () => {
|
it('should refresh the visibility for single tab', () => {
|
||||||
visibilityObjTest.leftFormFieldId = 'FIELD_TEST';
|
visibilityObjTest.leftFormFieldId = 'FIELD_TEST';
|
||||||
visibilityObjTest.operator = '!=';
|
visibilityObjTest.operator = '!=';
|
||||||
|
@ -15,11 +15,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AlfrescoApiService } from '../../services/alfresco-api.service';
|
|
||||||
import { LogService } from '../../services/log.service';
|
import { LogService } from '../../services/log.service';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { Observable, from, throwError } from 'rxjs';
|
|
||||||
import {
|
import {
|
||||||
FormFieldModel,
|
FormFieldModel,
|
||||||
FormModel,
|
FormModel,
|
||||||
@ -29,25 +27,16 @@ import {
|
|||||||
} from '../components/widgets/core';
|
} from '../components/widgets/core';
|
||||||
import { TaskProcessVariableModel } from '../models/task-process-variable.model';
|
import { TaskProcessVariableModel } from '../models/task-process-variable.model';
|
||||||
import { WidgetVisibilityModel, WidgetTypeEnum } from '../models/widget-visibility.model';
|
import { WidgetVisibilityModel, WidgetTypeEnum } from '../models/widget-visibility.model';
|
||||||
import { map, catchError } from 'rxjs/operators';
|
|
||||||
import { TaskFormsApi } from '@alfresco/js-api';
|
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class WidgetVisibilityService {
|
export class WidgetVisibilityService {
|
||||||
|
|
||||||
_taskFormsApi: TaskFormsApi;
|
|
||||||
get taskFormsApi(): TaskFormsApi {
|
|
||||||
this._taskFormsApi = this._taskFormsApi ?? new TaskFormsApi(this.apiService.getInstance());
|
|
||||||
return this._taskFormsApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
private processVarList: TaskProcessVariableModel[];
|
private processVarList: TaskProcessVariableModel[];
|
||||||
private form: FormModel;
|
private form: FormModel;
|
||||||
|
|
||||||
constructor(private apiService: AlfrescoApiService,
|
constructor(private logService: LogService) {
|
||||||
private logService: LogService) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public refreshVisibility(form: FormModel, processVarList?: TaskProcessVariableModel[]) {
|
public refreshVisibility(form: FormModel, processVarList?: TaskProcessVariableModel[]) {
|
||||||
@ -68,15 +57,15 @@ export class WidgetVisibilityService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshEntityVisibility(element: FormFieldModel | TabModel) {
|
public refreshEntityVisibility(element: FormFieldModel | TabModel) {
|
||||||
element.isVisible = this.isParentTabVisible(this.form, element) && this.evaluateVisibility(element.form, element.visibilityCondition);
|
element.isVisible = this.isParentTabVisible(this.form, element) && this.evaluateVisibility(element.form, element.visibilityCondition);
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshOutcomeVisibility(element: FormOutcomeModel) {
|
private refreshOutcomeVisibility(element: FormOutcomeModel) {
|
||||||
element.isVisible = this.evaluateVisibility(element.form, element.visibilityCondition);
|
element.isVisible = this.evaluateVisibility(element.form, element.visibilityCondition);
|
||||||
}
|
}
|
||||||
|
|
||||||
evaluateVisibility(form: FormModel, visibilityObj: WidgetVisibilityModel): boolean {
|
public evaluateVisibility(form: FormModel, visibilityObj: WidgetVisibilityModel): boolean {
|
||||||
const isLeftFieldPresent = visibilityObj && (visibilityObj.leftType || visibilityObj.leftValue);
|
const isLeftFieldPresent = visibilityObj && (visibilityObj.leftType || visibilityObj.leftValue);
|
||||||
if (!isLeftFieldPresent || isLeftFieldPresent === 'null') {
|
if (!isLeftFieldPresent || isLeftFieldPresent === 'null') {
|
||||||
return true;
|
return true;
|
||||||
@ -85,12 +74,12 @@ export class WidgetVisibilityService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isFieldVisible(form: FormModel, visibilityObj: WidgetVisibilityModel, accumulator: any[] = [], result: boolean = false): boolean {
|
public isFieldVisible(form: FormModel, visibilityObj: WidgetVisibilityModel, accumulator: any[] = [], result: boolean = false): boolean {
|
||||||
const leftValue = this.getLeftValue(form, visibilityObj);
|
const leftValue = this.getLeftValue(form, visibilityObj);
|
||||||
const rightValue = this.getRightValue(form, visibilityObj);
|
const rightValue = this.getRightValue(form, visibilityObj);
|
||||||
const actualResult = this.evaluateCondition(leftValue, rightValue, visibilityObj.operator);
|
const actualResult = this.evaluateCondition(leftValue, rightValue, visibilityObj.operator);
|
||||||
|
|
||||||
accumulator.push({ value: actualResult, operator: visibilityObj.nextConditionOperator });
|
accumulator.push({value: actualResult, operator: visibilityObj.nextConditionOperator});
|
||||||
|
|
||||||
if (this.isValidCondition(visibilityObj.nextCondition)) {
|
if (this.isValidCondition(visibilityObj.nextCondition)) {
|
||||||
result = this.isFieldVisible(form, visibilityObj.nextCondition, accumulator);
|
result = this.isFieldVisible(form, visibilityObj.nextCondition, accumulator);
|
||||||
@ -124,7 +113,7 @@ export class WidgetVisibilityService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getLeftValue(form: FormModel, visibilityObj: WidgetVisibilityModel): string {
|
public getLeftValue(form: FormModel, visibilityObj: WidgetVisibilityModel): string {
|
||||||
let leftValue = '';
|
let leftValue = '';
|
||||||
if (visibilityObj.leftType && visibilityObj.leftType === WidgetTypeEnum.variable) {
|
if (visibilityObj.leftType && visibilityObj.leftType === WidgetTypeEnum.variable) {
|
||||||
leftValue = this.getVariableValue(form, visibilityObj.leftValue, this.processVarList);
|
leftValue = this.getVariableValue(form, visibilityObj.leftValue, this.processVarList);
|
||||||
@ -138,7 +127,7 @@ export class WidgetVisibilityService {
|
|||||||
return leftValue;
|
return leftValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRightValue(form: FormModel, visibilityObj: WidgetVisibilityModel): string {
|
public getRightValue(form: FormModel, visibilityObj: WidgetVisibilityModel): string {
|
||||||
let valueFound = '';
|
let valueFound = '';
|
||||||
if (visibilityObj.rightType === WidgetTypeEnum.variable) {
|
if (visibilityObj.rightType === WidgetTypeEnum.variable) {
|
||||||
valueFound = this.getVariableValue(form, visibilityObj.rightValue, this.processVarList);
|
valueFound = this.getVariableValue(form, visibilityObj.rightValue, this.processVarList);
|
||||||
@ -154,7 +143,7 @@ export class WidgetVisibilityService {
|
|||||||
return valueFound;
|
return valueFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
getFormValue(form: FormModel, fieldId: string): any {
|
public getFormValue(form: FormModel, fieldId: string): any {
|
||||||
const formField = this.getFormFieldById(form, fieldId);
|
const formField = this.getFormFieldById(form, fieldId);
|
||||||
let value;
|
let value;
|
||||||
|
|
||||||
@ -168,18 +157,18 @@ export class WidgetVisibilityService {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
isFormFieldValid(formField: FormFieldModel): boolean {
|
public isFormFieldValid(formField: FormFieldModel): boolean {
|
||||||
return formField && formField.isValid;
|
return formField && formField.isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
getFieldValue(valueList: any, fieldId: string): any {
|
public getFieldValue(valueList: any, fieldId: string): any {
|
||||||
let labelFilterByName;
|
let labelFilterByName;
|
||||||
let valueFound;
|
let valueFound;
|
||||||
if (fieldId && fieldId.indexOf('_LABEL') > 0) {
|
if (fieldId && fieldId.indexOf('_LABEL') > 0) {
|
||||||
labelFilterByName = fieldId.substring(0, fieldId.length - 6);
|
labelFilterByName = fieldId.substring(0, fieldId.length - 6);
|
||||||
if (valueList[labelFilterByName]) {
|
if (valueList[labelFilterByName]) {
|
||||||
if (Array.isArray(valueList[labelFilterByName])) {
|
if (Array.isArray(valueList[labelFilterByName])) {
|
||||||
valueFound = valueList[labelFilterByName].map(({ name }) => name);
|
valueFound = valueList[labelFilterByName].map(({name}) => name);
|
||||||
} else {
|
} else {
|
||||||
valueFound = valueList[labelFilterByName].name;
|
valueFound = valueList[labelFilterByName].name;
|
||||||
}
|
}
|
||||||
@ -187,7 +176,7 @@ export class WidgetVisibilityService {
|
|||||||
} else if (valueList[fieldId] && valueList[fieldId].id) {
|
} else if (valueList[fieldId] && valueList[fieldId].id) {
|
||||||
valueFound = valueList[fieldId].id;
|
valueFound = valueList[fieldId].id;
|
||||||
} else if (valueList[fieldId] && Array.isArray(valueList[fieldId])) {
|
} else if (valueList[fieldId] && Array.isArray(valueList[fieldId])) {
|
||||||
valueFound = valueList[fieldId].map(({ id }) => id);
|
valueFound = valueList[fieldId].map(({id}) => id);
|
||||||
} else {
|
} else {
|
||||||
valueFound = valueList[fieldId];
|
valueFound = valueList[fieldId];
|
||||||
}
|
}
|
||||||
@ -198,11 +187,11 @@ export class WidgetVisibilityService {
|
|||||||
return value === undefined || value === null;
|
return value === undefined || value === null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getFormFieldById(form: FormModel, fieldId: string): FormFieldModel {
|
public getFormFieldById(form: FormModel, fieldId: string): FormFieldModel {
|
||||||
return form.getFormFields().find((formField: FormFieldModel) => this.isSearchedField(formField, fieldId));
|
return form.getFormFields().find((formField: FormFieldModel) => this.isSearchedField(formField, fieldId));
|
||||||
}
|
}
|
||||||
|
|
||||||
searchValueInForm(formField: FormFieldModel, fieldId: string): string {
|
public searchValueInForm(formField: FormFieldModel, fieldId: string): string {
|
||||||
let fieldValue = '';
|
let fieldValue = '';
|
||||||
|
|
||||||
if (formField) {
|
if (formField) {
|
||||||
@ -219,7 +208,7 @@ export class WidgetVisibilityService {
|
|||||||
return fieldValue;
|
return fieldValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
isParentTabVisible(form: FormModel, currentFormField: FormFieldModel | TabModel): boolean {
|
private isParentTabVisible(form: FormModel, currentFormField: FormFieldModel | TabModel): boolean {
|
||||||
const containers = this.getFormTabContainers(form);
|
const containers = this.getFormTabContainers(form);
|
||||||
let isVisible: boolean = true;
|
let isVisible: boolean = true;
|
||||||
containers.map((container: ContainerModel) => {
|
containers.map((container: ContainerModel) => {
|
||||||
@ -281,7 +270,7 @@ export class WidgetVisibilityService {
|
|||||||
return (field.id && fieldToFind) ? field.id.toUpperCase() === fieldToFind.toUpperCase() : false;
|
return (field.id && fieldToFind) ? field.id.toUpperCase() === fieldToFind.toUpperCase() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getVariableValue(form: FormModel, name: string, processVarList: TaskProcessVariableModel[]): string {
|
public getVariableValue(form: FormModel, name: string, processVarList: TaskProcessVariableModel[]): string {
|
||||||
const processVariableValue = this.getProcessVariableValue(name, processVarList);
|
const processVariableValue = this.getProcessVariableValue(name, processVarList);
|
||||||
const variableDefaultValue = form.getDefaultFormVariableValue(name);
|
const variableDefaultValue = form.getDefaultFormVariableValue(name);
|
||||||
|
|
||||||
@ -303,7 +292,7 @@ export class WidgetVisibilityService {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
evaluateCondition(leftValue: any, rightValue: any, operator: string): boolean | undefined {
|
public evaluateCondition(leftValue: any, rightValue: any, operator: string): boolean | undefined {
|
||||||
switch (operator) {
|
switch (operator) {
|
||||||
case '==':
|
case '==':
|
||||||
return leftValue + '' === rightValue + '';
|
return leftValue + '' === rightValue + '';
|
||||||
@ -339,28 +328,7 @@ export class WidgetVisibilityService {
|
|||||||
this.processVarList = [];
|
this.processVarList = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
getTaskProcessVariable(taskId: string): Observable<TaskProcessVariableModel[]> {
|
|
||||||
return from(this.taskFormsApi.getTaskFormVariables(taskId))
|
|
||||||
.pipe(
|
|
||||||
map((res) => {
|
|
||||||
const jsonRes = this.toJson(res);
|
|
||||||
this.processVarList = jsonRes;
|
|
||||||
return jsonRes;
|
|
||||||
}),
|
|
||||||
catchError(() => this.handleError())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson(res: any): any {
|
|
||||||
return res || {};
|
|
||||||
}
|
|
||||||
|
|
||||||
private isValidCondition(condition: WidgetVisibilityModel): boolean {
|
private isValidCondition(condition: WidgetVisibilityModel): boolean {
|
||||||
return !!(condition && condition.operator);
|
return !!(condition && condition.operator);
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleError() {
|
|
||||||
this.logService.error('Error while performing a call');
|
|
||||||
return throwError('Error while performing a call - Server error');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -16,16 +16,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Observable, from, throwError } from 'rxjs';
|
import { Observable, from, throwError, of } from 'rxjs';
|
||||||
import { UserProcessModel } from '../models/user-process.model';
|
import { UserProcessModel } from '../models/user-process.model';
|
||||||
import { AlfrescoApiService } from './alfresco-api.service';
|
import { AlfrescoApiService } from './alfresco-api.service';
|
||||||
import { LogService } from './log.service';
|
import { LogService } from './log.service';
|
||||||
import { catchError, map } from 'rxjs/operators';
|
import { catchError, combineAll, defaultIfEmpty, map, switchMap } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
TaskActionsApi,
|
TaskActionsApi,
|
||||||
UsersApi,
|
UsersApi,
|
||||||
ResultListDataRepresentationLightUserRepresentation
|
ResultListDataRepresentationLightUserRepresentation, ActivitiGroupsApi
|
||||||
} from '@alfresco/js-api';
|
} from '@alfresco/js-api';
|
||||||
|
import { GroupModel } from '../form';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -44,10 +45,35 @@ export class PeopleProcessService {
|
|||||||
return this._userApi;
|
return this._userApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_groupsApi: ActivitiGroupsApi;
|
||||||
|
get groupsApi(): ActivitiGroupsApi {
|
||||||
|
this._groupsApi = this._groupsApi ?? new ActivitiGroupsApi(this.apiService.getInstance());
|
||||||
|
return this._groupsApi;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(private apiService: AlfrescoApiService,
|
constructor(private apiService: AlfrescoApiService,
|
||||||
private logService: LogService) {
|
private logService: LogService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of groups in a workflow.
|
||||||
|
*
|
||||||
|
* @param filter Filter to select specific groups
|
||||||
|
* @param groupId Group ID for the search
|
||||||
|
* @returns Array of groups
|
||||||
|
*/
|
||||||
|
getWorkflowGroups(filter: string, groupId?: string): Observable<GroupModel[]> {
|
||||||
|
const option: any = { filter };
|
||||||
|
if (groupId) {
|
||||||
|
option.groupId = groupId;
|
||||||
|
}
|
||||||
|
return from(this.groupsApi.getGroups(option))
|
||||||
|
.pipe(
|
||||||
|
map((response: any) => response.data || []),
|
||||||
|
catchError((err) => this.handleError(err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets information about users across all tasks.
|
* Gets information about users across all tasks.
|
||||||
*
|
*
|
||||||
@ -55,15 +81,21 @@ export class PeopleProcessService {
|
|||||||
* @param searchWord Filter text to search for
|
* @param searchWord Filter text to search for
|
||||||
* @returns Array of user information objects
|
* @returns Array of user information objects
|
||||||
*/
|
*/
|
||||||
getWorkflowUsers(taskId?: string, searchWord?: string): Observable<UserProcessModel[]> {
|
getWorkflowUsers(taskId?: string, searchWord?: string, groupId?: string): Observable<UserProcessModel[]> {
|
||||||
const option = { excludeTaskId: taskId, filter: searchWord };
|
const option = { excludeTaskId: taskId, filter: searchWord, groupId };
|
||||||
|
|
||||||
return from(this.getWorkflowUserApi(option))
|
return from(this.getWorkflowUserApi(option))
|
||||||
.pipe(
|
.pipe(
|
||||||
map((response: any) => response.data || []),
|
switchMap(response => response.data as UserProcessModel[] || []),
|
||||||
|
map((user) => {
|
||||||
|
user.userImage = this.getUserProfileImageApi(user.id.toString());
|
||||||
|
return of(user);
|
||||||
|
}),
|
||||||
|
combineAll(),
|
||||||
|
defaultIfEmpty([]),
|
||||||
catchError((err) => this.handleError(err))
|
catchError((err) => this.handleError(err))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the profile picture URL for the specified user.
|
* Gets the profile picture URL for the specified user.
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,110 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
FormModel, setupTestBed
|
||||||
|
} from '@alfresco/adf-core';
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
DebugElement, ViewChild
|
||||||
|
} from '@angular/core';
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
|
||||||
|
import { FormCloudComponent } from './form-cloud.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'adf-cloud-form-with-custom-outcomes',
|
||||||
|
template: `
|
||||||
|
<adf-cloud-form #adfCloudForm>
|
||||||
|
<adf-cloud-form-custom-outcomes>
|
||||||
|
<button mat-button id="adf-custom-outcome-1" (click)="onCustomButtonOneClick()">
|
||||||
|
CUSTOM-BUTTON-1
|
||||||
|
</button>
|
||||||
|
<button mat-button id="adf-custom-outcome-2" (click)="onCustomButtonTwoClick()">
|
||||||
|
CUSTOM-BUTTON-2
|
||||||
|
</button>
|
||||||
|
</adf-cloud-form-custom-outcomes>
|
||||||
|
</adf-cloud-form>`
|
||||||
|
})
|
||||||
|
class FormCloudWithCustomOutComesComponent {
|
||||||
|
|
||||||
|
@ViewChild('adfCloudForm', { static: true })
|
||||||
|
adfCloudForm: FormCloudComponent;
|
||||||
|
|
||||||
|
onCustomButtonOneClick() {
|
||||||
|
}
|
||||||
|
|
||||||
|
onCustomButtonTwoClick() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('FormCloudWithCustomOutComesComponent', () => {
|
||||||
|
|
||||||
|
let fixture: ComponentFixture<FormCloudWithCustomOutComesComponent>;
|
||||||
|
let customComponent: FormCloudWithCustomOutComesComponent;
|
||||||
|
let debugElement: DebugElement;
|
||||||
|
|
||||||
|
setupTestBed({
|
||||||
|
imports: [
|
||||||
|
TranslateModule.forRoot(),
|
||||||
|
ProcessServiceCloudTestingModule
|
||||||
|
],
|
||||||
|
declarations: [FormCloudWithCustomOutComesComponent]
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(FormCloudWithCustomOutComesComponent);
|
||||||
|
customComponent = fixture.componentInstance;
|
||||||
|
debugElement = fixture.debugElement;
|
||||||
|
const formRepresentation = {
|
||||||
|
fields: [
|
||||||
|
{ id: 'container1' }
|
||||||
|
],
|
||||||
|
outcomes: [
|
||||||
|
{ id: 'outcome-1', name: 'outcome 1' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const form = new FormModel(formRepresentation);
|
||||||
|
customComponent.adfCloudForm.form = form;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fixture.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to inject custom outcomes and click on custom outcomes', async () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const onCustomButtonOneSpy = spyOn(customComponent, 'onCustomButtonOneClick').and.callThrough();
|
||||||
|
const buttonOneBtn = debugElement.query(By.css('#adf-custom-outcome-1'));
|
||||||
|
const buttonTwoBtn = debugElement.query(By.css('#adf-custom-outcome-2'));
|
||||||
|
expect(buttonOneBtn).not.toBeNull();
|
||||||
|
expect(buttonTwoBtn).not.toBeNull();
|
||||||
|
|
||||||
|
buttonOneBtn.nativeElement.click();
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
|
expect(onCustomButtonOneSpy).toHaveBeenCalled();
|
||||||
|
expect(buttonOneBtn.nativeElement.innerText).toBe('CUSTOM-BUTTON-1');
|
||||||
|
expect(buttonTwoBtn.nativeElement.innerText).toBe('CUSTOM-BUTTON-2');
|
||||||
|
});
|
||||||
|
});
|
@ -17,56 +17,42 @@
|
|||||||
|
|
||||||
/* eslint-disable @typescript-eslint/naming-convention */
|
/* eslint-disable @typescript-eslint/naming-convention */
|
||||||
|
|
||||||
|
import { VersionCompatibilityService } from '@alfresco/adf-content-services';
|
||||||
import {
|
import {
|
||||||
Component,
|
AlfrescoApiService, ContentLinkModel, CoreModule,
|
||||||
DebugElement,
|
|
||||||
SimpleChange,
|
|
||||||
NgModule,
|
|
||||||
Injector,
|
|
||||||
ComponentFactoryResolver,
|
|
||||||
ViewChild
|
|
||||||
} from '@angular/core';
|
|
||||||
import { By } from '@angular/platform-browser';
|
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
import { Observable, of, throwError } from 'rxjs';
|
|
||||||
import {
|
|
||||||
CoreModule,
|
|
||||||
FormFieldModel,
|
FormFieldModel,
|
||||||
FormFieldTypes,
|
FormFieldTypes,
|
||||||
FormModel,
|
FormModel,
|
||||||
FormOutcomeEvent,
|
FormOutcomeEvent,
|
||||||
FormOutcomeModel,
|
FormOutcomeModel, FormRenderingService, FormService, setupTestBed,
|
||||||
setupTestBed,
|
TRANSLATION_PROVIDER, UploadWidgetContentLinkModel, WidgetVisibilityService
|
||||||
TRANSLATION_PROVIDER,
|
|
||||||
WidgetVisibilityService,
|
|
||||||
FormService,
|
|
||||||
UploadWidgetContentLinkModel,
|
|
||||||
ContentLinkModel,
|
|
||||||
AlfrescoApiService
|
|
||||||
} from '@alfresco/adf-core';
|
} from '@alfresco/adf-core';
|
||||||
import { VersionCompatibilityService } from '@alfresco/adf-content-services';
|
import { Node } from '@alfresco/js-api';
|
||||||
|
import { ESCAPE } from '@angular/cdk/keycodes';
|
||||||
|
import { HarnessLoader } from '@angular/cdk/testing';
|
||||||
|
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||||
|
import {
|
||||||
|
Component, ComponentFactoryResolver, Injector, SimpleChange
|
||||||
|
} from '@angular/core';
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { MatDialogHarness } from '@angular/material/dialog/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||||
|
import { Observable, of, throwError } from 'rxjs';
|
||||||
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
|
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
|
||||||
import { FormCloudService } from '../services/form-cloud.service';
|
import { FormCloudModule } from '../form-cloud.module';
|
||||||
import { FormCloudComponent } from './form-cloud.component';
|
|
||||||
import {
|
import {
|
||||||
cloudFormMock,
|
cloudFormMock,
|
||||||
conditionalUploadWidgetsMock,
|
conditionalUploadWidgetsMock,
|
||||||
emptyFormRepresentationJSON,
|
emptyFormRepresentationJSON,
|
||||||
fakeCloudForm,
|
fakeCloudForm, fakeMetadataForm, multilingualForm
|
||||||
multilingualForm,
|
|
||||||
fakeMetadataForm
|
|
||||||
} from '../mocks/cloud-form.mock';
|
} from '../mocks/cloud-form.mock';
|
||||||
import { FormCloudRepresentation } from '../models/form-cloud-representation.model';
|
import { FormCloudRepresentation } from '../models/form-cloud-representation.model';
|
||||||
import { FormCloudModule } from '../form-cloud.module';
|
import { FormCloudService } from '../services/form-cloud.service';
|
||||||
import { TranslateService, TranslateModule } from '@ngx-translate/core';
|
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
|
||||||
import { CloudFormRenderingService } from './cloud-form-rendering.service';
|
import { CloudFormRenderingService } from './cloud-form-rendering.service';
|
||||||
import { Node } from '@alfresco/js-api';
|
import { FormCloudComponent } from './form-cloud.component';
|
||||||
import { ESCAPE } from '@angular/cdk/keycodes';
|
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
|
||||||
import { HarnessLoader } from '@angular/cdk/testing';
|
|
||||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
|
||||||
import { MatDialogHarness } from '@angular/material/dialog/testing';
|
|
||||||
|
|
||||||
const mockOauth2Auth: any = {
|
const mockOauth2Auth: any = {
|
||||||
oauth2Auth: {
|
oauth2Auth: {
|
||||||
@ -83,7 +69,6 @@ describe('FormCloudComponent', () => {
|
|||||||
let matDialog: MatDialog;
|
let matDialog: MatDialog;
|
||||||
let visibilityService: WidgetVisibilityService;
|
let visibilityService: WidgetVisibilityService;
|
||||||
let formRenderingService: CloudFormRenderingService;
|
let formRenderingService: CloudFormRenderingService;
|
||||||
let translateService: TranslateService;
|
|
||||||
let documentRootLoader: HarnessLoader;
|
let documentRootLoader: HarnessLoader;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -95,13 +80,6 @@ describe('FormCloudComponent', () => {
|
|||||||
typeId = 'CustomWidget';
|
typeId = 'CustomWidget';
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [CustomWidget],
|
|
||||||
exports: [CustomWidget]
|
|
||||||
})
|
|
||||||
class CustomUploadModule {
|
|
||||||
}
|
|
||||||
|
|
||||||
const buildWidget = (type: string, injector: Injector): any => {
|
const buildWidget = (type: string, injector: Injector): any => {
|
||||||
const resolver = formRenderingService.getComponentTypeResolver(type);
|
const resolver = formRenderingService.getComponentTypeResolver(type);
|
||||||
const widgetType = resolver(null);
|
const widgetType = resolver(null);
|
||||||
@ -115,25 +93,14 @@ describe('FormCloudComponent', () => {
|
|||||||
|
|
||||||
setupTestBed({
|
setupTestBed({
|
||||||
imports: [
|
imports: [
|
||||||
NoopAnimationsModule,
|
ProcessServiceCloudTestingModule
|
||||||
TranslateModule.forRoot(),
|
|
||||||
CoreModule.forRoot(),
|
|
||||||
FormCloudModule,
|
|
||||||
CustomUploadModule
|
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{
|
|
||||||
provide: TRANSLATION_PROVIDER,
|
|
||||||
multi: true,
|
|
||||||
useValue: {
|
|
||||||
name: 'app',
|
|
||||||
source: 'resources'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
provide: VersionCompatibilityService,
|
provide: VersionCompatibilityService,
|
||||||
useValue: {}
|
useValue: {}
|
||||||
}
|
},
|
||||||
|
{ provide: FormRenderingService, useClass: CloudFormRenderingService }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -144,7 +111,6 @@ describe('FormCloudComponent', () => {
|
|||||||
formRenderingService = TestBed.inject(CloudFormRenderingService);
|
formRenderingService = TestBed.inject(CloudFormRenderingService);
|
||||||
formCloudService = TestBed.inject(FormCloudService);
|
formCloudService = TestBed.inject(FormCloudService);
|
||||||
|
|
||||||
translateService = TestBed.inject(TranslateService);
|
|
||||||
matDialog = TestBed.inject(MatDialog);
|
matDialog = TestBed.inject(MatDialog);
|
||||||
|
|
||||||
visibilityService = TestBed.inject(WidgetVisibilityService);
|
visibilityService = TestBed.inject(WidgetVisibilityService);
|
||||||
@ -1100,121 +1066,77 @@ describe('FormCloudComponent', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Multilingual Form', () => {
|
|
||||||
it('should translate form labels on language change', async () => {
|
|
||||||
spyOn(formCloudService, 'getForm').and.returnValue(of(multilingualForm));
|
|
||||||
const formId = '123';
|
|
||||||
const appName = 'test-app';
|
|
||||||
formComponent.formId = formId;
|
|
||||||
formComponent.appVersion = 1;
|
|
||||||
|
|
||||||
formComponent.ngOnChanges({ appName: new SimpleChange(null, appName, true) });
|
|
||||||
expect(formCloudService.getForm).toHaveBeenCalledWith(appName, formId, 1);
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(getLabelValue('textField')).toEqual('Text field');
|
|
||||||
expect(getLabelValue('fildUploadField')).toEqual('File Upload');
|
|
||||||
expect(getLabelValue('dateField')).toEqual('Date field (D-M-YYYY)');
|
|
||||||
expect(getLabelValue('amountField')).toEqual('Amount field');
|
|
||||||
|
|
||||||
fixture.ngZone.run(() => translateService.use('fr'));
|
|
||||||
|
|
||||||
await fixture.whenStable();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(getLabelValue('textField')).toEqual('Champ de texte');
|
|
||||||
expect(getLabelValue('fildUploadField')).toEqual('Téléchargement de fichiers');
|
|
||||||
expect(getLabelValue('dateField')).toEqual('Champ de date (D-M-YYYY)');
|
|
||||||
expect(getLabelValue('amountField')).toEqual('Champ Montant');
|
|
||||||
});
|
|
||||||
|
|
||||||
const getLabelValue = (containerId: string): string => {
|
|
||||||
const label = fixture.debugElement.nativeElement.querySelector(`[id="field-${containerId}-container"] label`);
|
|
||||||
return label.innerText;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@Component({
|
describe('Multilingual Form', () => {
|
||||||
selector: 'adf-cloud-form-with-custom-outcomes',
|
let translateService: TranslateService;
|
||||||
template: `
|
let formCloudService: FormCloudService;
|
||||||
<adf-cloud-form #adfCloudForm>
|
let formComponent: FormCloudComponent;
|
||||||
<adf-cloud-form-custom-outcomes>
|
let fixture: ComponentFixture<FormCloudComponent>;
|
||||||
<button mat-button id="adf-custom-outcome-1" (click)="onCustomButtonOneClick()">
|
|
||||||
CUSTOM-BUTTON-1
|
|
||||||
</button>
|
|
||||||
<button mat-button id="adf-custom-outcome-2" (click)="onCustomButtonTwoClick()">
|
|
||||||
CUSTOM-BUTTON-2
|
|
||||||
</button>
|
|
||||||
</adf-cloud-form-custom-outcomes>
|
|
||||||
</adf-cloud-form>`
|
|
||||||
})
|
|
||||||
|
|
||||||
class FormCloudWithCustomOutComesComponent {
|
|
||||||
|
|
||||||
@ViewChild('adfCloudForm', { static: true })
|
|
||||||
adfCloudForm: FormCloudComponent;
|
|
||||||
|
|
||||||
onCustomButtonOneClick() {
|
|
||||||
}
|
|
||||||
|
|
||||||
onCustomButtonTwoClick() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('FormCloudWithCustomOutComesComponent', () => {
|
|
||||||
|
|
||||||
let fixture: ComponentFixture<FormCloudWithCustomOutComesComponent>;
|
|
||||||
let customComponent: FormCloudWithCustomOutComesComponent;
|
|
||||||
let debugElement: DebugElement;
|
|
||||||
|
|
||||||
setupTestBed({
|
setupTestBed({
|
||||||
imports: [
|
imports: [
|
||||||
|
NoopAnimationsModule,
|
||||||
TranslateModule.forRoot(),
|
TranslateModule.forRoot(),
|
||||||
ProcessServiceCloudTestingModule
|
CoreModule.forRoot()
|
||||||
],
|
],
|
||||||
declarations: [FormCloudWithCustomOutComesComponent]
|
providers: [
|
||||||
|
{
|
||||||
|
provide: TRANSLATION_PROVIDER,
|
||||||
|
multi: true,
|
||||||
|
useValue: {
|
||||||
|
name: 'app',
|
||||||
|
source: 'resources'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(FormCloudWithCustomOutComesComponent);
|
translateService = TestBed.inject(TranslateService);
|
||||||
customComponent = fixture.componentInstance;
|
formCloudService = TestBed.inject(FormCloudService);
|
||||||
debugElement = fixture.debugElement;
|
|
||||||
const formRepresentation = {
|
|
||||||
fields: [
|
|
||||||
{ id: 'container1' }
|
|
||||||
],
|
|
||||||
outcomes: [
|
|
||||||
{ id: 'outcome-1', name: 'outcome 1' }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
const form = new FormModel(formRepresentation);
|
fixture = TestBed.createComponent(FormCloudComponent);
|
||||||
customComponent.adfCloudForm.form = form;
|
formComponent = fixture.componentInstance;
|
||||||
|
formComponent.form = formComponent.parseForm(fakeMetadataForm);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
it('should translate form labels on language change', async () => {
|
||||||
fixture.destroy();
|
spyOn(formCloudService, 'getForm').and.returnValue(of(multilingualForm));
|
||||||
});
|
const formId = '123';
|
||||||
|
const appName = 'test-app';
|
||||||
|
formComponent.formId = formId;
|
||||||
|
formComponent.appVersion = 1;
|
||||||
|
|
||||||
it('should be able to inject custom outcomes and click on custom outcomes', async () => {
|
formComponent.ngOnChanges({ appName: new SimpleChange(null, appName, true) });
|
||||||
fixture.detectChanges();
|
expect(formCloudService.getForm).toHaveBeenCalledWith(appName, formId, 1);
|
||||||
|
|
||||||
const onCustomButtonOneSpy = spyOn(customComponent, 'onCustomButtonOneClick').and.callThrough();
|
fixture.ngZone.run(() => translateService.use('fr'));
|
||||||
const buttonOneBtn = debugElement.query(By.css('#adf-custom-outcome-1'));
|
|
||||||
const buttonTwoBtn = debugElement.query(By.css('#adf-custom-outcome-2'));
|
|
||||||
expect(buttonOneBtn).not.toBeNull();
|
|
||||||
expect(buttonTwoBtn).not.toBeNull();
|
|
||||||
|
|
||||||
buttonOneBtn.nativeElement.click();
|
|
||||||
fixture.detectChanges();
|
|
||||||
await fixture.whenStable();
|
await fixture.whenStable();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(onCustomButtonOneSpy).toHaveBeenCalled();
|
expect(getLabelValue('textField')).toEqual('Champ de texte');
|
||||||
expect(buttonOneBtn.nativeElement.innerText).toBe('CUSTOM-BUTTON-1');
|
expect(getLabelValue('fildUploadField')).toEqual('Téléchargement de fichiers');
|
||||||
expect(buttonTwoBtn.nativeElement.innerText).toBe('CUSTOM-BUTTON-2');
|
expect(getLabelValue('dateField')).toEqual('Champ de date (D-M-YYYY)');
|
||||||
|
expect(getLabelValue('amountField')).toEqual('Champ Montant');
|
||||||
|
|
||||||
|
fixture.ngZone.run(() => translateService.use('en'));
|
||||||
|
|
||||||
|
await fixture.whenStable();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(getLabelValue('textField')).toEqual('Text field');
|
||||||
|
expect(getLabelValue('fildUploadField')).toEqual('File Upload');
|
||||||
|
expect(getLabelValue('dateField')).toEqual('Date field (D-M-YYYY)');
|
||||||
|
expect(getLabelValue('amountField')).toEqual('Amount field');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const getLabelValue = (containerId: string): string => {
|
||||||
|
const label = fixture.debugElement.nativeElement.querySelector(`[id="field-${containerId}-container"] label`);
|
||||||
|
return label.innerText;
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('retrieve metadata on submit', () => {
|
describe('retrieve metadata on submit', () => {
|
||||||
|
@ -824,14 +824,6 @@ describe('AttachFileCloudWidgetComponent', () => {
|
|||||||
expect(widget.field.params.fileSource.destinationFolderPath.value).toBe('mock-folder-id');
|
expect(widget.field.params.fileSource.destinationFolderPath.value).toBe('mock-folder-id');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it should get a destination folder path value from a folder variable', () => {
|
|
||||||
createUploadWidgetField(form, 'attach-file-attach', [], mockAllFileSourceWithFolderVariablePathType);
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(widget.field.params.fileSource.destinationFolderPath.type).toBe('folder');
|
|
||||||
expect(widget.field.params.fileSource.destinationFolderPath.value).toBe('mock-folder-id');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('it should set destination folder path value to undefined if mapped variable deleted/renamed', () => {
|
it('it should set destination folder path value to undefined if mapped variable deleted/renamed', () => {
|
||||||
createUploadWidgetField(form, 'attach-file-attach', [], mockAllFileSourceWithRenamedFolderVariablePathType);
|
createUploadWidgetField(form, 'attach-file-attach', [], mockAllFileSourceWithRenamedFolderVariablePathType);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
@ -71,7 +71,6 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
describe('Simple Dropdown', () => {
|
describe('Simple Dropdown', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyOn(formService, 'getRestFieldValues').and.callFake(() => of(fakeOptionList));
|
|
||||||
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
||||||
id: 'dropdown-id',
|
id: 'dropdown-id',
|
||||||
name: 'date-name',
|
name: 'date-name',
|
||||||
@ -85,13 +84,14 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should require field with restUrl', () => {
|
it('should require field with restUrl', () => {
|
||||||
|
spyOn(formCloudService, 'getRestWidgetData');
|
||||||
widget.field = new FormFieldModel(new FormModel());
|
widget.field = new FormFieldModel(new FormModel());
|
||||||
widget.ngOnInit();
|
widget.ngOnInit();
|
||||||
expect(formService.getRestFieldValues).not.toHaveBeenCalled();
|
expect(formCloudService.getRestWidgetData).not.toHaveBeenCalled();
|
||||||
|
|
||||||
widget.field = new FormFieldModel(null, { restUrl: null });
|
widget.field = new FormFieldModel(null, { restUrl: null });
|
||||||
widget.ngOnInit();
|
widget.ngOnInit();
|
||||||
expect(formService.getRestFieldValues).not.toHaveBeenCalled();
|
expect(formCloudService.getRestWidgetData).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should select the default value when an option is chosen as default', async () => {
|
it('should select the default value when an option is chosen as default', async () => {
|
||||||
@ -339,46 +339,13 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
await fixture.whenStable();
|
await fixture.whenStable();
|
||||||
|
|
||||||
|
expect(element.querySelector('.adf-invalid')).toBeTruthy();
|
||||||
|
|
||||||
const requiredErrorElement = fixture.debugElement.query(By.css('.adf-dropdown-required-message .adf-error-text'));
|
const requiredErrorElement = fixture.debugElement.query(By.css('.adf-dropdown-required-message .adf-error-text'));
|
||||||
expect(requiredErrorElement.nativeElement.innerText).toEqual('FORM.FIELD.REQUIRED');
|
expect(requiredErrorElement.nativeElement.innerText).toEqual('FORM.FIELD.REQUIRED');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when is required', () => {
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
widget.field = new FormFieldModel( new FormModel({ taskId: '<id>' }), {
|
|
||||||
type: FormFieldTypes.DROPDOWN,
|
|
||||||
required: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be able to display label with asterisk', async () => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
await fixture.whenStable();
|
|
||||||
|
|
||||||
const asterisk: HTMLElement = element.querySelector('.adf-asterisk');
|
|
||||||
|
|
||||||
expect(asterisk).toBeTruthy();
|
|
||||||
expect(asterisk.textContent).toEqual('*');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be invalid if no default option after interaction', async () => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
await fixture.whenStable();
|
|
||||||
|
|
||||||
expect(element.querySelector('.adf-invalid')).toBeFalsy();
|
|
||||||
|
|
||||||
const dropdownSelect = element.querySelector('.adf-select');
|
|
||||||
dropdownSelect.dispatchEvent(new Event('blur'));
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
await fixture.whenStable();
|
|
||||||
|
|
||||||
expect(element.querySelector('.adf-invalid')).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('filter', () => {
|
describe('filter', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -135,7 +135,7 @@ describe('RadioButtonsCloudWidgetComponent', () => {
|
|||||||
expect(widget.field.isValid).toBe(true);
|
expect(widget.field.isValid).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to set a Radio Button widget as required', () => {
|
it('should set Radio Button as valid when required and not empty', () => {
|
||||||
widget.field = new FormFieldModel(new FormModel({}), {
|
widget.field = new FormFieldModel(new FormModel({}), {
|
||||||
id: 'radio-id',
|
id: 'radio-id',
|
||||||
name: 'radio-name-label',
|
name: 'radio-name-label',
|
||||||
|
@ -20,7 +20,6 @@ import {
|
|||||||
AlfrescoApiService,
|
AlfrescoApiService,
|
||||||
FormValues,
|
FormValues,
|
||||||
AppConfigService,
|
AppConfigService,
|
||||||
FormOutcomeModel,
|
|
||||||
FormModel,
|
FormModel,
|
||||||
FormFieldOption
|
FormFieldOption
|
||||||
} from '@alfresco/adf-core';
|
} from '@alfresco/adf-core';
|
||||||
@ -232,17 +231,7 @@ export class FormCloudService extends BaseCloudService implements FormCloudServi
|
|||||||
formValues[variable.name] = variable.value;
|
formValues[variable.name] = variable.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
const form = new FormModel(flattenForm, formValues, readOnly);
|
return new FormModel(flattenForm, formValues, readOnly);
|
||||||
if (!json.fields) {
|
|
||||||
form.outcomes = [
|
|
||||||
new FormOutcomeModel(form, {
|
|
||||||
id: '$save',
|
|
||||||
name: FormOutcomeModel.SAVE_ACTION,
|
|
||||||
isSystem: true
|
|
||||||
})
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return form;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -306,7 +306,7 @@ describe('Task Cloud Service', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw error if appName is not defined when querying by id', (done) => {
|
it('should throw error if appName is not defined when querying by id with update playload', (done) => {
|
||||||
const appName = null;
|
const appName = null;
|
||||||
const taskId = '68d54a8f';
|
const taskId = '68d54a8f';
|
||||||
const updatePayload = { description: 'New description' };
|
const updatePayload = { description: 'New description' };
|
||||||
|
@ -338,7 +338,7 @@ describe('TaskFormCloudComponent', () => {
|
|||||||
component.onError({});
|
component.onError({});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should emit taskCompleted when task is completed', () => {
|
it('should reload when task is completed', () => {
|
||||||
spyOn(taskCloudService, 'completeTask').and.returnValue(of({}));
|
spyOn(taskCloudService, 'completeTask').and.returnValue(of({}));
|
||||||
const reloadSpy = spyOn(component, 'ngOnChanges').and.callThrough();
|
const reloadSpy = spyOn(component, 'ngOnChanges').and.callThrough();
|
||||||
|
|
||||||
@ -350,7 +350,7 @@ describe('TaskFormCloudComponent', () => {
|
|||||||
expect(reloadSpy).toHaveBeenCalled();
|
expect(reloadSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should emit taskClaimed when task is claimed', () => {
|
it('should reload when task is claimed', () => {
|
||||||
spyOn(taskCloudService, 'claimTask').and.returnValue(of({}));
|
spyOn(taskCloudService, 'claimTask').and.returnValue(of({}));
|
||||||
spyOn(component, 'hasCandidateUsers').and.returnValue(true);
|
spyOn(component, 'hasCandidateUsers').and.returnValue(true);
|
||||||
const reloadSpy = spyOn(component, 'ngOnChanges').and.callThrough();
|
const reloadSpy = spyOn(component, 'ngOnChanges').and.callThrough();
|
||||||
|
@ -168,18 +168,6 @@ describe('TaskHeaderCloudComponent', () => {
|
|||||||
expect(valueEl.nativeElement.value).toBe('67c4z2a8f-01f3-11e9-8e36-0a58646002ad');
|
expect(valueEl.nativeElement.value).toBe('67c4z2a8f-01f3-11e9-8e36-0a58646002ad');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display process instance id', async () => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
await fixture.whenStable();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
const labelEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-label-processInstanceId"]'));
|
|
||||||
const valueEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-processInstanceId"]'));
|
|
||||||
|
|
||||||
expect(labelEl.nativeElement.textContent.trim()).toBe('ADF_CLOUD_TASK_HEADER.PROPERTIES.PROCESS_INSTANCE_ID');
|
|
||||||
expect(valueEl.nativeElement.value).toBe('67c4z2a8f-01f3-11e9-8e36-0a58646002ad');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should display placeholder if no due date', async () => {
|
it('should display placeholder if no due date', async () => {
|
||||||
component.taskDetails.dueDate = null;
|
component.taskDetails.dueDate = null;
|
||||||
component.refreshData();
|
component.refreshData();
|
||||||
|
@ -80,4 +80,5 @@ module.exports = function (config) {
|
|||||||
browsers: ['Chrome'],
|
browsers: ['Chrome'],
|
||||||
singleRun: true
|
singleRun: true
|
||||||
});
|
});
|
||||||
|
process.env.TZ = 'UTC';
|
||||||
};
|
};
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||||
import { ProcessContentService } from '@alfresco/adf-core';
|
import { ProcessContentService } from '../form/services/process-content.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-create-process-attachment',
|
selector: 'adf-create-process-attachment',
|
||||||
|
@ -19,10 +19,11 @@ import { SimpleChange } from '@angular/core';
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
|
|
||||||
import { ProcessContentService, setupTestBed } from '@alfresco/adf-core';
|
import { setupTestBed } from '@alfresco/adf-core';
|
||||||
import { AttachmentComponent } from './create-task-attachment.component';
|
import { AttachmentComponent } from './create-task-attachment.component';
|
||||||
import { ProcessTestingModule } from '../testing/process.testing.module';
|
import { ProcessTestingModule } from '../testing/process.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { ProcessContentService } from '../form/services/process-content.service';
|
||||||
|
|
||||||
describe('AttachmentComponent', () => {
|
describe('AttachmentComponent', () => {
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||||
import { ProcessContentService } from '@alfresco/adf-core';
|
import { ProcessContentService } from '../form/services/process-content.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-create-task-attachment',
|
selector: 'adf-create-task-attachment',
|
||||||
|
@ -18,12 +18,13 @@
|
|||||||
import { SimpleChange, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
import { SimpleChange, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
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 { ProcessContentService, setupTestBed } from '@alfresco/adf-core';
|
import { setupTestBed } from '@alfresco/adf-core';
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
import { ProcessAttachmentListComponent } from './process-attachment-list.component';
|
import { ProcessAttachmentListComponent } from './process-attachment-list.component';
|
||||||
import { ProcessTestingModule } from '../testing/process.testing.module';
|
import { ProcessTestingModule } from '../testing/process.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { mockEmittedProcessAttachments, mockProcessAttachments } from '../mock/process/process-attachments.mock';
|
import { mockEmittedProcessAttachments, mockProcessAttachments } from '../mock/process/process-attachments.mock';
|
||||||
|
import { ProcessContentService } from '../form/services/process-content.service';
|
||||||
|
|
||||||
describe('ProcessAttachmentListComponent', () => {
|
describe('ProcessAttachmentListComponent', () => {
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ContentService, EmptyListComponent, ThumbnailService, ProcessContentService } from '@alfresco/adf-core';
|
import { ContentService, EmptyListComponent, ThumbnailService } from '@alfresco/adf-core';
|
||||||
import {
|
import {
|
||||||
AfterContentInit,
|
AfterContentInit,
|
||||||
ContentChild,
|
ContentChild,
|
||||||
@ -28,6 +28,7 @@ import {
|
|||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
ViewEncapsulation
|
ViewEncapsulation
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import { ProcessContentService } from '../form/services/process-content.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-process-attachment-list',
|
selector: 'adf-process-attachment-list',
|
||||||
|
@ -20,10 +20,11 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
import { TaskAttachmentListComponent } from './task-attachment-list.component';
|
import { TaskAttachmentListComponent } from './task-attachment-list.component';
|
||||||
import { ProcessContentService, setupTestBed } from '@alfresco/adf-core';
|
import { setupTestBed } from '@alfresco/adf-core';
|
||||||
import { ProcessTestingModule } from '../testing/process.testing.module';
|
import { ProcessTestingModule } from '../testing/process.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { mockEmittedTaskAttachments, mockTaskAttachments } from '../mock/task/task-attachments.mock';
|
import { mockEmittedTaskAttachments, mockTaskAttachments } from '../mock/task/task-attachments.mock';
|
||||||
|
import { ProcessContentService } from '../form/services/process-content.service';
|
||||||
|
|
||||||
describe('TaskAttachmentList', () => {
|
describe('TaskAttachmentList', () => {
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ContentService, ThumbnailService, EmptyListComponent, ProcessContentService } from '@alfresco/adf-core';
|
import { ContentService, ThumbnailService, EmptyListComponent } from '@alfresco/adf-core';
|
||||||
import {
|
import {
|
||||||
AfterContentInit,
|
AfterContentInit,
|
||||||
ContentChild,
|
ContentChild,
|
||||||
@ -28,6 +28,7 @@ import {
|
|||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
ViewEncapsulation
|
ViewEncapsulation
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import { ProcessContentService } from '../form/services/process-content.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-task-attachment-list',
|
selector: 'adf-task-attachment-list',
|
||||||
|
@ -15,11 +15,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { FormFieldModel } from '../components/widgets/core/form-field.model';
|
import { FormFieldModel, FormFieldEvent, FormModel } from '@alfresco/adf-core';
|
||||||
import { FormModel } from '../components/widgets/core/form.model';
|
import { DynamicRowValidationSummary } from '../widgets/dynamic-table/editors/models/dynamic-row-validation-summary.model';
|
||||||
import { DynamicRowValidationSummary } from '../components/widgets/dynamic-table/dynamic-row-validation-summary.model';
|
import { DynamicTableRow } from '../widgets/dynamic-table/editors/models/dynamic-table-row.model';
|
||||||
import { DynamicTableRow } from '../components/widgets/dynamic-table/dynamic-table-row.model';
|
|
||||||
import { FormFieldEvent } from './form-field.event';
|
|
||||||
|
|
||||||
export class ValidateDynamicTableRowEvent extends FormFieldEvent {
|
export class ValidateDynamicTableRowEvent extends FormFieldEvent {
|
||||||
|
|
@ -17,22 +17,19 @@
|
|||||||
|
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { FormService } from '../services/form.service';
|
import { setupTestBed, CoreTestingModule } from '@alfresco/adf-core';
|
||||||
import { FormListComponent } from './form-list.component';
|
import { FormListComponent } from './form-list.component';
|
||||||
import { setupTestBed } from '../../testing/setup-test-bed';
|
import { ModelService } from '../services/model.service';
|
||||||
import { CoreTestingModule } from '../../testing/core.testing.module';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
describe('TaskAttachmentList', () => {
|
describe('TaskAttachmentList', () => {
|
||||||
|
|
||||||
let component: FormListComponent;
|
let component: FormListComponent;
|
||||||
let fixture: ComponentFixture<FormListComponent>;
|
let fixture: ComponentFixture<FormListComponent>;
|
||||||
let service: FormService;
|
let modelService: ModelService;
|
||||||
let element: HTMLElement;
|
let element: HTMLElement;
|
||||||
|
|
||||||
setupTestBed({
|
setupTestBed({
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule.forRoot(),
|
|
||||||
CoreTestingModule
|
CoreTestingModule
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
@ -41,13 +38,13 @@ describe('TaskAttachmentList', () => {
|
|||||||
fixture = TestBed.createComponent(FormListComponent);
|
fixture = TestBed.createComponent(FormListComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
element = fixture.debugElement.nativeElement;
|
element = fixture.debugElement.nativeElement;
|
||||||
service = TestBed.inject(FormService);
|
modelService = TestBed.inject(ModelService);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show the forms as a list', async () => {
|
it('should show the forms as a list', async () => {
|
||||||
spyOn(service, 'getForms').and.returnValue(of([
|
spyOn(modelService, 'getForms').and.returnValue(of([
|
||||||
{ name: 'FakeName-1', lastUpdatedByFullName: 'FakeUser-1', lastUpdated: '2017-01-02' },
|
{name: 'FakeName-1', lastUpdatedByFullName: 'FakeUser-1', lastUpdated: '2017-01-02'},
|
||||||
{ name: 'FakeName-2', lastUpdatedByFullName: 'FakeUser-2', lastUpdated: '2017-01-03' }
|
{name: 'FakeName-2', lastUpdatedByFullName: 'FakeUser-2', lastUpdated: '2017-01-03'}
|
||||||
]));
|
]));
|
||||||
|
|
||||||
component.ngOnChanges();
|
component.ngOnChanges();
|
@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, Input, OnChanges, ViewEncapsulation } from '@angular/core';
|
import { Component, Input, OnChanges, ViewEncapsulation } from '@angular/core';
|
||||||
import { FormService } from '../services/form.service';
|
import { ModelService } from '../services/model.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-form-list',
|
selector: 'adf-form-list',
|
||||||
@ -29,7 +29,7 @@ export class FormListComponent implements OnChanges {
|
|||||||
@Input()
|
@Input()
|
||||||
forms: any [] = [];
|
forms: any [] = [];
|
||||||
|
|
||||||
constructor(protected formService: FormService) {
|
constructor(protected modelService: ModelService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
@ -41,7 +41,7 @@ export class FormListComponent implements OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getForms() {
|
getForms() {
|
||||||
this.formService.getForms().subscribe((forms) => {
|
this.modelService.getForms().subscribe((forms) => {
|
||||||
this.forms.push(...forms);
|
this.forms.push(...forms);
|
||||||
});
|
});
|
||||||
}
|
}
|
@ -25,18 +25,23 @@ import {
|
|||||||
DebugElement
|
DebugElement
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { TaskRepresentation } from '@alfresco/js-api';
|
||||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||||
import { Observable, of, throwError } from 'rxjs';
|
import { Observable, of, throwError } from 'rxjs';
|
||||||
import {
|
import {
|
||||||
FormFieldModel, FormFieldTypes, FormModel, FormOutcomeEvent, FormOutcomeModel,
|
FormFieldModel, FormFieldTypes, FormModel, FormOutcomeEvent, FormOutcomeModel,
|
||||||
FormService, WidgetVisibilityService, NodeService, ContainerModel, fakeForm,
|
FormService, WidgetVisibilityService, ContainerModel, fakeForm,
|
||||||
setupTestBed,
|
setupTestBed,
|
||||||
NodeMetadata
|
NodeMetadata, NodesApiService
|
||||||
} from '@alfresco/adf-core';
|
} from '@alfresco/adf-core';
|
||||||
import { FormComponent } from './form.component';
|
import { FormComponent } from './form.component';
|
||||||
import { ProcessFormRenderingService } from './process-form-rendering.service';
|
import { ProcessFormRenderingService } from './process-form-rendering.service';
|
||||||
import { ProcessTestingModule } from '../testing/process.testing.module';
|
import { ProcessTestingModule } from '../testing/process.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { TaskFormService } from './services/task-form.service';
|
||||||
|
import { TaskService } from './services/task.service';
|
||||||
|
import { EditorService } from './services/editor.service';
|
||||||
|
import { ModelService } from './services/model.service';
|
||||||
|
|
||||||
describe('FormComponent', () => {
|
describe('FormComponent', () => {
|
||||||
|
|
||||||
@ -45,7 +50,11 @@ describe('FormComponent', () => {
|
|||||||
|
|
||||||
let formService: FormService;
|
let formService: FormService;
|
||||||
let visibilityService: WidgetVisibilityService;
|
let visibilityService: WidgetVisibilityService;
|
||||||
let nodeService: NodeService;
|
let taskFormService: TaskFormService;
|
||||||
|
let taskService: TaskService;
|
||||||
|
let editorService: EditorService;
|
||||||
|
let modelService: ModelService;
|
||||||
|
let nodeService: NodesApiService;
|
||||||
let formRenderingService: ProcessFormRenderingService;
|
let formRenderingService: ProcessFormRenderingService;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -87,8 +96,12 @@ describe('FormComponent', () => {
|
|||||||
visibilityService = TestBed.inject(WidgetVisibilityService);
|
visibilityService = TestBed.inject(WidgetVisibilityService);
|
||||||
spyOn(visibilityService, 'refreshVisibility').and.stub();
|
spyOn(visibilityService, 'refreshVisibility').and.stub();
|
||||||
|
|
||||||
|
nodeService = TestBed.inject(NodesApiService);
|
||||||
formService = TestBed.inject(FormService);
|
formService = TestBed.inject(FormService);
|
||||||
nodeService = TestBed.inject(NodeService);
|
taskService = TestBed.inject(TaskService);
|
||||||
|
taskFormService = TestBed.inject(TaskFormService);
|
||||||
|
editorService = TestBed.inject(EditorService);
|
||||||
|
modelService = TestBed.inject(ModelService);
|
||||||
formRenderingService = TestBed.inject(ProcessFormRenderingService);
|
formRenderingService = TestBed.inject(ProcessFormRenderingService);
|
||||||
|
|
||||||
fixture = TestBed.createComponent(FormComponent);
|
fixture = TestBed.createComponent(FormComponent);
|
||||||
@ -159,14 +172,14 @@ describe('FormComponent', () => {
|
|||||||
it('should enable custom outcome buttons', () => {
|
it('should enable custom outcome buttons', () => {
|
||||||
const formModel = new FormModel();
|
const formModel = new FormModel();
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
const outcome = new FormOutcomeModel(formModel, { id: 'action1', name: 'Action 1' });
|
const outcome = new FormOutcomeModel(formModel, {id: 'action1', name: 'Action 1'});
|
||||||
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow controlling [complete] button visibility', () => {
|
it('should allow controlling [complete] button visibility', () => {
|
||||||
const formModel = new FormModel();
|
const formModel = new FormModel();
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
const outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.SAVE_ACTION });
|
const outcome = new FormOutcomeModel(formModel, {id: '$save', name: FormOutcomeModel.SAVE_ACTION});
|
||||||
|
|
||||||
formComponent.showSaveButton = true;
|
formComponent.showSaveButton = true;
|
||||||
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
||||||
@ -179,7 +192,7 @@ describe('FormComponent', () => {
|
|||||||
const formModel = new FormModel();
|
const formModel = new FormModel();
|
||||||
formModel.readOnly = true;
|
formModel.readOnly = true;
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
const outcome = new FormOutcomeModel(formModel, { id: '$complete', name: FormOutcomeModel.COMPLETE_ACTION });
|
const outcome = new FormOutcomeModel(formModel, {id: '$complete', name: FormOutcomeModel.COMPLETE_ACTION});
|
||||||
|
|
||||||
formComponent.showCompleteButton = true;
|
formComponent.showCompleteButton = true;
|
||||||
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
||||||
@ -189,23 +202,23 @@ describe('FormComponent', () => {
|
|||||||
const formModel = new FormModel();
|
const formModel = new FormModel();
|
||||||
formModel.readOnly = true;
|
formModel.readOnly = true;
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
const outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.SAVE_ACTION });
|
const outcome = new FormOutcomeModel(formModel, {id: '$save', name: FormOutcomeModel.SAVE_ACTION});
|
||||||
|
|
||||||
formComponent.showSaveButton = true;
|
formComponent.showSaveButton = true;
|
||||||
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeFalsy();
|
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show [custom-outcome] button with readOnly form and selected custom-outcome', () => {
|
it('should show [custom-outcome] button with readOnly form and selected custom-outcome', () => {
|
||||||
const formModel = new FormModel({ selectedOutcome: 'custom-outcome' });
|
const formModel = new FormModel({selectedOutcome: 'custom-outcome'});
|
||||||
formModel.readOnly = true;
|
formModel.readOnly = true;
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
let outcome = new FormOutcomeModel(formModel, { id: '$customoutome', name: 'custom-outcome' });
|
let outcome = new FormOutcomeModel(formModel, {id: '$customoutome', name: 'custom-outcome'});
|
||||||
|
|
||||||
formComponent.showCompleteButton = true;
|
formComponent.showCompleteButton = true;
|
||||||
formComponent.showSaveButton = true;
|
formComponent.showSaveButton = true;
|
||||||
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
||||||
|
|
||||||
outcome = new FormOutcomeModel(formModel, { id: '$customoutome2', name: 'custom-outcome2' });
|
outcome = new FormOutcomeModel(formModel, {id: '$customoutome2', name: 'custom-outcome2'});
|
||||||
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeFalsy();
|
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -213,7 +226,7 @@ describe('FormComponent', () => {
|
|||||||
const formModel = new FormModel();
|
const formModel = new FormModel();
|
||||||
formModel.readOnly = false;
|
formModel.readOnly = false;
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
const outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.COMPLETE_ACTION });
|
const outcome = new FormOutcomeModel(formModel, {id: '$save', name: FormOutcomeModel.COMPLETE_ACTION});
|
||||||
|
|
||||||
formComponent.showCompleteButton = true;
|
formComponent.showCompleteButton = true;
|
||||||
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
|
||||||
@ -240,44 +253,6 @@ describe('FormComponent', () => {
|
|||||||
expect(formComponent.getFormByTaskId).toHaveBeenCalledWith(taskId);
|
expect(formComponent.getFormByTaskId).toHaveBeenCalledWith(taskId);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get process variable if is a process task', () => {
|
|
||||||
spyOn(formService, 'getTaskForm').and.callFake((currentTaskId) => new Observable((observer) => {
|
|
||||||
observer.next({ taskId: currentTaskId });
|
|
||||||
observer.complete();
|
|
||||||
}));
|
|
||||||
|
|
||||||
spyOn(visibilityService, 'getTaskProcessVariable').and.returnValue(of(null));
|
|
||||||
spyOn(formService, 'getTask').and.callFake((currentTaskId) => new Observable((observer) => {
|
|
||||||
observer.next({ taskId: currentTaskId, processDefinitionId: '10201' });
|
|
||||||
observer.complete();
|
|
||||||
}));
|
|
||||||
const taskId = '123';
|
|
||||||
|
|
||||||
formComponent.taskId = taskId;
|
|
||||||
formComponent.loadForm();
|
|
||||||
|
|
||||||
expect(visibilityService.getTaskProcessVariable).toHaveBeenCalledWith(taskId);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not get process variable if is not a process task', () => {
|
|
||||||
spyOn(formService, 'getTaskForm').and.callFake((currentTaskId) => new Observable((observer) => {
|
|
||||||
observer.next({ taskId: currentTaskId });
|
|
||||||
observer.complete();
|
|
||||||
}));
|
|
||||||
|
|
||||||
spyOn(visibilityService, 'getTaskProcessVariable').and.returnValue(of(null));
|
|
||||||
spyOn(formService, 'getTask').and.callFake((currentTaskId) => new Observable((observer) => {
|
|
||||||
observer.next({ taskId: currentTaskId, processDefinitionId: 'null' });
|
|
||||||
observer.complete();
|
|
||||||
}));
|
|
||||||
const taskId = '123';
|
|
||||||
|
|
||||||
formComponent.taskId = taskId;
|
|
||||||
formComponent.loadForm();
|
|
||||||
|
|
||||||
expect(visibilityService.getTaskProcessVariable).toHaveBeenCalledWith(taskId);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get form definition by form id on load', () => {
|
it('should get form definition by form id on load', () => {
|
||||||
spyOn(formComponent, 'getFormDefinitionByFormId').and.stub();
|
spyOn(formComponent, 'getFormDefinitionByFormId').and.stub();
|
||||||
const formId = 123;
|
const formId = 123;
|
||||||
@ -289,13 +264,13 @@ describe('FormComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should refresh visibility when the form is loaded', () => {
|
it('should refresh visibility when the form is loaded', () => {
|
||||||
spyOn(formService, 'getFormDefinitionById').and.returnValue(of(JSON.parse(JSON.stringify(fakeForm))));
|
spyOn(editorService, 'getFormDefinitionById').and.returnValue(of(JSON.parse(JSON.stringify(fakeForm))));
|
||||||
const formId = 123;
|
const formId = 123;
|
||||||
|
|
||||||
formComponent.formId = formId;
|
formComponent.formId = formId;
|
||||||
formComponent.loadForm();
|
formComponent.loadForm();
|
||||||
|
|
||||||
expect(formService.getFormDefinitionById).toHaveBeenCalledWith(formId);
|
expect(editorService.getFormDefinitionById).toHaveBeenCalledWith(formId);
|
||||||
expect(visibilityService.refreshVisibility).toHaveBeenCalled();
|
expect(visibilityService.refreshVisibility).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -314,7 +289,7 @@ describe('FormComponent', () => {
|
|||||||
const taskId = '<task id>';
|
const taskId = '<task id>';
|
||||||
|
|
||||||
const change = new SimpleChange(null, taskId, true);
|
const change = new SimpleChange(null, taskId, true);
|
||||||
formComponent.ngOnChanges({ taskId: change });
|
formComponent.ngOnChanges({taskId: change});
|
||||||
|
|
||||||
expect(formComponent.getFormByTaskId).toHaveBeenCalledWith(taskId);
|
expect(formComponent.getFormByTaskId).toHaveBeenCalledWith(taskId);
|
||||||
});
|
});
|
||||||
@ -324,7 +299,7 @@ describe('FormComponent', () => {
|
|||||||
const formId = '123';
|
const formId = '123';
|
||||||
|
|
||||||
const change = new SimpleChange(null, formId, true);
|
const change = new SimpleChange(null, formId, true);
|
||||||
formComponent.ngOnChanges({ formId: change });
|
formComponent.ngOnChanges({formId: change});
|
||||||
|
|
||||||
expect(formComponent.getFormDefinitionByFormId).toHaveBeenCalledWith(formId);
|
expect(formComponent.getFormDefinitionByFormId).toHaveBeenCalledWith(formId);
|
||||||
});
|
});
|
||||||
@ -334,7 +309,7 @@ describe('FormComponent', () => {
|
|||||||
const formName = '<form>';
|
const formName = '<form>';
|
||||||
|
|
||||||
const change = new SimpleChange(null, formName, true);
|
const change = new SimpleChange(null, formName, true);
|
||||||
formComponent.ngOnChanges({ formName: change });
|
formComponent.ngOnChanges({formName: change});
|
||||||
|
|
||||||
expect(formComponent.getFormDefinitionByFormName).toHaveBeenCalledWith(formName);
|
expect(formComponent.getFormDefinitionByFormName).toHaveBeenCalledWith(formName);
|
||||||
});
|
});
|
||||||
@ -359,7 +334,7 @@ describe('FormComponent', () => {
|
|||||||
spyOn(formComponent, 'getFormDefinitionByFormId').and.stub();
|
spyOn(formComponent, 'getFormDefinitionByFormId').and.stub();
|
||||||
spyOn(formComponent, 'getFormDefinitionByFormName').and.stub();
|
spyOn(formComponent, 'getFormDefinitionByFormName').and.stub();
|
||||||
|
|
||||||
formComponent.ngOnChanges({ tag: new SimpleChange(null, 'hello world', true) });
|
formComponent.ngOnChanges({tag: new SimpleChange(null, 'hello world', true)});
|
||||||
|
|
||||||
expect(formComponent.getFormByTaskId).not.toHaveBeenCalled();
|
expect(formComponent.getFormByTaskId).not.toHaveBeenCalled();
|
||||||
expect(formComponent.getFormDefinitionByFormId).not.toHaveBeenCalled();
|
expect(formComponent.getFormDefinitionByFormId).not.toHaveBeenCalled();
|
||||||
@ -369,7 +344,7 @@ describe('FormComponent', () => {
|
|||||||
it('should complete form on custom outcome click', () => {
|
it('should complete form on custom outcome click', () => {
|
||||||
const formModel = new FormModel();
|
const formModel = new FormModel();
|
||||||
const outcomeName = 'Custom Action';
|
const outcomeName = 'Custom Action';
|
||||||
const outcome = new FormOutcomeModel(formModel, { id: 'custom1', name: outcomeName });
|
const outcome = new FormOutcomeModel(formModel, {id: 'custom1', name: outcomeName});
|
||||||
|
|
||||||
let saved = false;
|
let saved = false;
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
@ -434,7 +409,7 @@ describe('FormComponent', () => {
|
|||||||
it('should do nothing when clicking outcome for readonly form', () => {
|
it('should do nothing when clicking outcome for readonly form', () => {
|
||||||
const formModel = new FormModel();
|
const formModel = new FormModel();
|
||||||
const outcomeName = 'Custom Action';
|
const outcomeName = 'Custom Action';
|
||||||
const outcome = new FormOutcomeModel(formModel, { id: 'custom1', name: outcomeName });
|
const outcome = new FormOutcomeModel(formModel, {id: 'custom1', name: outcomeName});
|
||||||
|
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
spyOn(formComponent, 'completeTaskForm').and.stub();
|
spyOn(formComponent, 'completeTaskForm').and.stub();
|
||||||
@ -453,7 +428,7 @@ describe('FormComponent', () => {
|
|||||||
it('should require loaded form when clicking outcome', () => {
|
it('should require loaded form when clicking outcome', () => {
|
||||||
const formModel = new FormModel();
|
const formModel = new FormModel();
|
||||||
const outcomeName = 'Custom Action';
|
const outcomeName = 'Custom Action';
|
||||||
const outcome = new FormOutcomeModel(formModel, { id: 'custom1', name: outcomeName });
|
const outcome = new FormOutcomeModel(formModel, {id: 'custom1', name: outcomeName});
|
||||||
|
|
||||||
formComponent.readOnly = false;
|
formComponent.readOnly = false;
|
||||||
formComponent.form = null;
|
formComponent.form = null;
|
||||||
@ -462,7 +437,7 @@ describe('FormComponent', () => {
|
|||||||
|
|
||||||
it('should not execute unknown system outcome', () => {
|
it('should not execute unknown system outcome', () => {
|
||||||
const formModel = new FormModel();
|
const formModel = new FormModel();
|
||||||
const outcome = new FormOutcomeModel(formModel, { id: 'unknown', name: 'Unknown', isSystem: true });
|
const outcome = new FormOutcomeModel(formModel, {id: 'unknown', name: 'Unknown', isSystem: true});
|
||||||
|
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
expect(formComponent.onOutcomeClicked(outcome)).toBeFalsy();
|
expect(formComponent.onOutcomeClicked(outcome)).toBeFalsy();
|
||||||
@ -470,26 +445,26 @@ describe('FormComponent', () => {
|
|||||||
|
|
||||||
it('should require custom action name to complete form', () => {
|
it('should require custom action name to complete form', () => {
|
||||||
const formModel = new FormModel();
|
const formModel = new FormModel();
|
||||||
let outcome = new FormOutcomeModel(formModel, { id: 'custom' });
|
let outcome = new FormOutcomeModel(formModel, {id: 'custom'});
|
||||||
|
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
expect(formComponent.onOutcomeClicked(outcome)).toBeFalsy();
|
expect(formComponent.onOutcomeClicked(outcome)).toBeFalsy();
|
||||||
|
|
||||||
outcome = new FormOutcomeModel(formModel, { id: 'custom', name: 'Custom' });
|
outcome = new FormOutcomeModel(formModel, {id: 'custom', name: 'Custom'});
|
||||||
spyOn(formComponent, 'completeTaskForm').and.stub();
|
spyOn(formComponent, 'completeTaskForm').and.stub();
|
||||||
expect(formComponent.onOutcomeClicked(outcome)).toBeTruthy();
|
expect(formComponent.onOutcomeClicked(outcome)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch and parse form by task id', (done) => {
|
it('should fetch and parse form by task id', (done) => {
|
||||||
spyOn(formService, 'getTask').and.returnValue(of({}));
|
spyOn(taskService, 'getTask').and.returnValue(of(<TaskRepresentation>{}));
|
||||||
spyOn(formService, 'getTaskForm').and.callFake((currentTaskId) => new Observable((observer) => {
|
spyOn(taskFormService, 'getTaskForm').and.callFake((currentTaskId) => new Observable((observer) => {
|
||||||
observer.next({ taskId: currentTaskId });
|
observer.next({taskId: currentTaskId});
|
||||||
observer.complete();
|
observer.complete();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const taskId = '456';
|
const taskId = '456';
|
||||||
formComponent.formLoaded.subscribe(() => {
|
formComponent.formLoaded.subscribe(() => {
|
||||||
expect(formService.getTaskForm).toHaveBeenCalledWith(taskId);
|
expect(taskFormService.getTaskForm).toHaveBeenCalledWith(taskId);
|
||||||
expect(formComponent.form).toBeDefined();
|
expect(formComponent.form).toBeDefined();
|
||||||
expect(formComponent.form.taskId).toBe(taskId);
|
expect(formComponent.form.taskId).toBe(taskId);
|
||||||
done();
|
done();
|
||||||
@ -502,9 +477,9 @@ describe('FormComponent', () => {
|
|||||||
it('should handle error when getting form by task id', (done) => {
|
it('should handle error when getting form by task id', (done) => {
|
||||||
const error = 'Some error';
|
const error = 'Some error';
|
||||||
|
|
||||||
spyOn(formService, 'getTask').and.returnValue(of({}));
|
spyOn(taskService, 'getTask').and.returnValue(of(<TaskRepresentation>{}));
|
||||||
spyOn(formComponent, 'handleError').and.stub();
|
spyOn(formComponent, 'handleError').and.stub();
|
||||||
spyOn(formService, 'getTaskForm').and.callFake(() => throwError(error));
|
spyOn(taskFormService, 'getTaskForm').and.callFake(() => throwError(error));
|
||||||
|
|
||||||
formComponent.getFormByTaskId('123').then((_) => {
|
formComponent.getFormByTaskId('123').then((_) => {
|
||||||
expect(formComponent.handleError).toHaveBeenCalledWith(error);
|
expect(formComponent.handleError).toHaveBeenCalledWith(error);
|
||||||
@ -513,9 +488,9 @@ describe('FormComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should apply readonly state when getting form by task id', (done) => {
|
it('should apply readonly state when getting form by task id', (done) => {
|
||||||
spyOn(formService, 'getTask').and.returnValue(of({}));
|
spyOn(taskService, 'getTask').and.returnValue(of(<TaskRepresentation>{}));
|
||||||
spyOn(formService, 'getTaskForm').and.callFake((taskId) => new Observable((observer) => {
|
spyOn(taskFormService, 'getTaskForm').and.callFake((taskId) => new Observable((observer) => {
|
||||||
observer.next({ taskId });
|
observer.next({taskId});
|
||||||
observer.complete();
|
observer.complete();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -528,8 +503,8 @@ describe('FormComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch and parse form definition by id', () => {
|
it('should fetch and parse form definition by id', () => {
|
||||||
spyOn(formService, 'getFormDefinitionById').and.callFake((currentFormId) => new Observable((observer) => {
|
spyOn(editorService, 'getFormDefinitionById').and.callFake((currentFormId) => new Observable((observer) => {
|
||||||
observer.next({ id: currentFormId });
|
observer.next({id: currentFormId});
|
||||||
observer.complete();
|
observer.complete();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -549,20 +524,20 @@ describe('FormComponent', () => {
|
|||||||
const error = 'Some error';
|
const error = 'Some error';
|
||||||
|
|
||||||
spyOn(formComponent, 'handleError').and.stub();
|
spyOn(formComponent, 'handleError').and.stub();
|
||||||
spyOn(formService, 'getFormDefinitionById').and.callFake(() => throwError(error));
|
spyOn(editorService, 'getFormDefinitionById').and.callFake(() => throwError(error));
|
||||||
|
|
||||||
formComponent.getFormDefinitionByFormId(123);
|
formComponent.getFormDefinitionByFormId(123);
|
||||||
expect(formComponent.handleError).toHaveBeenCalledWith(error);
|
expect(formComponent.handleError).toHaveBeenCalledWith(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch and parse form definition by form name', () => {
|
it('should fetch and parse form definition by form name', () => {
|
||||||
spyOn(formService, 'getFormDefinitionByName').and.callFake((currentFormName) => new Observable((observer) => {
|
spyOn(modelService, 'getFormDefinitionByName').and.callFake((currentFormName) => new Observable((observer) => {
|
||||||
observer.next(currentFormName);
|
observer.next(currentFormName);
|
||||||
observer.complete();
|
observer.complete();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
spyOn(formService, 'getFormDefinitionById').and.callFake((currentFormName) => new Observable((observer) => {
|
spyOn(editorService, 'getFormDefinitionById').and.callFake((currentFormName) => new Observable((observer) => {
|
||||||
observer.next({ name: currentFormName });
|
observer.next({name: currentFormName});
|
||||||
observer.complete();
|
observer.complete();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -574,13 +549,13 @@ describe('FormComponent', () => {
|
|||||||
formComponent.getFormDefinitionByFormName(formName);
|
formComponent.getFormDefinitionByFormName(formName);
|
||||||
|
|
||||||
expect(loaded).toBeTruthy();
|
expect(loaded).toBeTruthy();
|
||||||
expect(formService.getFormDefinitionByName).toHaveBeenCalledWith(formName);
|
expect(modelService.getFormDefinitionByName).toHaveBeenCalledWith(formName);
|
||||||
expect(formComponent.form).toBeDefined();
|
expect(formComponent.form).toBeDefined();
|
||||||
expect(formComponent.form.name).toBe(formName);
|
expect(formComponent.form.name).toBe(formName);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save task form and raise corresponding event', () => {
|
it('should save task form and raise corresponding event', () => {
|
||||||
spyOn(formService, 'saveTaskForm').and.callFake(() => new Observable((observer) => {
|
spyOn(taskFormService, 'saveTaskForm').and.callFake(() => new Observable((observer) => {
|
||||||
observer.next();
|
observer.next();
|
||||||
observer.complete();
|
observer.complete();
|
||||||
}));
|
}));
|
||||||
@ -595,31 +570,31 @@ describe('FormComponent', () => {
|
|||||||
const formModel = new FormModel({
|
const formModel = new FormModel({
|
||||||
taskId: '123',
|
taskId: '123',
|
||||||
fields: [
|
fields: [
|
||||||
{ id: 'field1' },
|
{id: 'field1'},
|
||||||
{ id: 'field2' }
|
{id: 'field2'}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
formComponent.saveTaskForm();
|
formComponent.saveTaskForm();
|
||||||
|
|
||||||
expect(formService.saveTaskForm).toHaveBeenCalledWith(formModel.taskId, formModel.values);
|
expect(taskFormService.saveTaskForm).toHaveBeenCalledWith(formModel.taskId, formModel.values);
|
||||||
expect(saved).toBeTruthy();
|
expect(saved).toBeTruthy();
|
||||||
expect(savedForm).toEqual(formModel);
|
expect(savedForm).toEqual(formModel);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle error during form save', () => {
|
it('should handle error during form save', () => {
|
||||||
const error = 'Error';
|
const error = 'Error';
|
||||||
spyOn(formService, 'saveTaskForm').and.callFake(() => throwError(error));
|
spyOn(taskFormService, 'saveTaskForm').and.callFake(() => throwError(error));
|
||||||
spyOn(formComponent, 'handleError').and.stub();
|
spyOn(formComponent, 'handleError').and.stub();
|
||||||
|
|
||||||
formComponent.form = new FormModel({ taskId: '123' });
|
formComponent.form = new FormModel({taskId: '123'});
|
||||||
formComponent.saveTaskForm();
|
formComponent.saveTaskForm();
|
||||||
|
|
||||||
expect(formComponent.handleError).toHaveBeenCalledWith(error);
|
expect(formComponent.handleError).toHaveBeenCalledWith(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should require form with task id to save', () => {
|
it('should require form with task id to save', () => {
|
||||||
spyOn(formService, 'saveTaskForm').and.stub();
|
spyOn(taskFormService, 'saveTaskForm').and.stub();
|
||||||
|
|
||||||
formComponent.form = null;
|
formComponent.form = null;
|
||||||
formComponent.saveTaskForm();
|
formComponent.saveTaskForm();
|
||||||
@ -627,11 +602,11 @@ describe('FormComponent', () => {
|
|||||||
formComponent.form = new FormModel();
|
formComponent.form = new FormModel();
|
||||||
formComponent.saveTaskForm();
|
formComponent.saveTaskForm();
|
||||||
|
|
||||||
expect(formService.saveTaskForm).not.toHaveBeenCalled();
|
expect(taskFormService.saveTaskForm).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should require form with task id to complete', () => {
|
it('should require form with task id to complete', () => {
|
||||||
spyOn(formService, 'completeTaskForm').and.stub();
|
spyOn(taskFormService, 'completeTaskForm').and.stub();
|
||||||
|
|
||||||
formComponent.form = null;
|
formComponent.form = null;
|
||||||
formComponent.completeTaskForm('save');
|
formComponent.completeTaskForm('save');
|
||||||
@ -639,11 +614,11 @@ describe('FormComponent', () => {
|
|||||||
formComponent.form = new FormModel();
|
formComponent.form = new FormModel();
|
||||||
formComponent.completeTaskForm('complete');
|
formComponent.completeTaskForm('complete');
|
||||||
|
|
||||||
expect(formService.completeTaskForm).not.toHaveBeenCalled();
|
expect(taskFormService.completeTaskForm).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should complete form and raise corresponding event', () => {
|
it('should complete form and raise corresponding event', () => {
|
||||||
spyOn(formService, 'completeTaskForm').and.callFake(() => new Observable((observer) => {
|
spyOn(taskFormService, 'completeTaskForm').and.callFake(() => new Observable((observer) => {
|
||||||
observer.next();
|
observer.next();
|
||||||
observer.complete();
|
observer.complete();
|
||||||
}));
|
}));
|
||||||
@ -655,15 +630,15 @@ describe('FormComponent', () => {
|
|||||||
const formModel = new FormModel({
|
const formModel = new FormModel({
|
||||||
taskId: '123',
|
taskId: '123',
|
||||||
fields: [
|
fields: [
|
||||||
{ id: 'field1' },
|
{id: 'field1'},
|
||||||
{ id: 'field2' }
|
{id: 'field2'}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
formComponent.form = formModel;
|
formComponent.form = formModel;
|
||||||
formComponent.completeTaskForm(outcome);
|
formComponent.completeTaskForm(outcome);
|
||||||
|
|
||||||
expect(formService.completeTaskForm).toHaveBeenCalledWith(formModel.taskId, formModel.values, outcome);
|
expect(taskFormService.completeTaskForm).toHaveBeenCalledWith(formModel.taskId, formModel.values, outcome);
|
||||||
expect(completed).toBeTruthy();
|
expect(completed).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -675,7 +650,7 @@ describe('FormComponent', () => {
|
|||||||
const form = formComponent.parseForm({
|
const form = formComponent.parseForm({
|
||||||
id: 1,
|
id: 1,
|
||||||
fields: [
|
fields: [
|
||||||
{ id: 'field1', type: FormFieldTypes.CONTAINER }
|
{id: 'field1', type: FormFieldTypes.CONTAINER}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -688,7 +663,7 @@ describe('FormComponent', () => {
|
|||||||
it('should provide outcomes for form definition', () => {
|
it('should provide outcomes for form definition', () => {
|
||||||
spyOn(formComponent, 'getFormDefinitionOutcomes').and.callThrough();
|
spyOn(formComponent, 'getFormDefinitionOutcomes').and.callThrough();
|
||||||
|
|
||||||
const form = formComponent.parseForm({ id: 1 });
|
const form = formComponent.parseForm({id: 1});
|
||||||
expect(formComponent.getFormDefinitionOutcomes).toHaveBeenCalledWith(form);
|
expect(formComponent.getFormDefinitionOutcomes).toHaveBeenCalledWith(form);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -753,7 +728,7 @@ describe('FormComponent', () => {
|
|||||||
|
|
||||||
const nodeId = '<id>';
|
const nodeId = '<id>';
|
||||||
const change = new SimpleChange(null, nodeId, false);
|
const change = new SimpleChange(null, nodeId, false);
|
||||||
formComponent.ngOnChanges({ nodeId: change });
|
formComponent.ngOnChanges({nodeId: change});
|
||||||
|
|
||||||
expect(nodeService.getNodeMetadata).toHaveBeenCalledWith(nodeId);
|
expect(nodeService.getNodeMetadata).toHaveBeenCalledWith(nodeId);
|
||||||
expect(formComponent.loadFormFromActiviti).toHaveBeenCalled();
|
expect(formComponent.loadFormFromActiviti).toHaveBeenCalled();
|
||||||
@ -973,10 +948,10 @@ describe('FormComponent', () => {
|
|||||||
id: 'option_2',
|
id: 'option_2',
|
||||||
name: 'test2'
|
name: 'test2'
|
||||||
};
|
};
|
||||||
formValues.radio = { id: 'option_2', name: 'Option 2' };
|
formValues.radio = {id: 'option_2', name: 'Option 2'};
|
||||||
const change = new SimpleChange(null, formValues, false);
|
const change = new SimpleChange(null, formValues, false);
|
||||||
formComponent.data = formValues;
|
formComponent.data = formValues;
|
||||||
formComponent.ngOnChanges({ data: change });
|
formComponent.ngOnChanges({data: change});
|
||||||
|
|
||||||
formFields = formComponent.form.getFormFields();
|
formFields = formComponent.form.getFormFields();
|
||||||
dropdownField = formFields.find((field) => field.id === 'dropdownId');
|
dropdownField = formFields.find((field) => field.id === 'dropdownId');
|
||||||
@ -996,7 +971,7 @@ describe('FormComponent', () => {
|
|||||||
formValues.radio = 'option_3';
|
formValues.radio = 'option_3';
|
||||||
const change = new SimpleChange(null, formValues, false);
|
const change = new SimpleChange(null, formValues, false);
|
||||||
formComponent.data = formValues;
|
formComponent.data = formValues;
|
||||||
formComponent.ngOnChanges({ data: change });
|
formComponent.ngOnChanges({data: change});
|
||||||
|
|
||||||
formFields = formComponent.form.getFormFields();
|
formFields = formComponent.form.getFormFields();
|
||||||
radioFieldById = formFields.find((field) => field.id === 'radio');
|
radioFieldById = formFields.find((field) => field.id === 'radio');
|
||||||
@ -1021,7 +996,7 @@ describe('FormComponent', () => {
|
|||||||
|
|
||||||
class FormWithCustomOutComesComponent {
|
class FormWithCustomOutComesComponent {
|
||||||
|
|
||||||
@ViewChild('adfForm', { static: true })
|
@ViewChild('adfForm', {static: true})
|
||||||
adfForm: FormComponent;
|
adfForm: FormComponent;
|
||||||
|
|
||||||
onCustomButtonOneClick() {
|
onCustomButtonOneClick() {
|
||||||
@ -1051,10 +1026,10 @@ describe('FormWithCustomOutComesComponent', () => {
|
|||||||
debugElement = fixture.debugElement;
|
debugElement = fixture.debugElement;
|
||||||
const formRepresentation = {
|
const formRepresentation = {
|
||||||
fields: [
|
fields: [
|
||||||
{ id: 'container1' }
|
{id: 'container1'}
|
||||||
],
|
],
|
||||||
outcomes: [
|
outcomes: [
|
||||||
{ id: 'outcome-1', name: 'outcome 1' }
|
{id: 'outcome-1', name: 'outcome 1'}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,13 +15,41 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, EventEmitter, Input, Output, ViewEncapsulation, SimpleChanges, OnInit, OnDestroy, OnChanges } from '@angular/core';
|
import {
|
||||||
import { EcmModelService, NodeService, WidgetVisibilityService,
|
Component,
|
||||||
FormService, FormBaseComponent, FormOutcomeModel,
|
EventEmitter,
|
||||||
FormEvent, FormErrorEvent, FormFieldModel,
|
Input,
|
||||||
FormModel, FormOutcomeEvent, FormValues, ContentLinkModel } from '@alfresco/adf-core';
|
Output,
|
||||||
import { Observable, of, Subject } from 'rxjs';
|
ViewEncapsulation,
|
||||||
|
SimpleChanges,
|
||||||
|
OnInit,
|
||||||
|
OnDestroy,
|
||||||
|
OnChanges
|
||||||
|
} from '@angular/core';
|
||||||
|
import {
|
||||||
|
WidgetVisibilityService,
|
||||||
|
FormService,
|
||||||
|
FormBaseComponent,
|
||||||
|
FormOutcomeModel,
|
||||||
|
FormEvent,
|
||||||
|
FormErrorEvent,
|
||||||
|
FormFieldModel,
|
||||||
|
FormModel,
|
||||||
|
FormOutcomeEvent,
|
||||||
|
FormValues,
|
||||||
|
ContentLinkModel,
|
||||||
|
NodesApiService,
|
||||||
|
FormDefinitionModel,
|
||||||
|
TaskProcessVariableModel
|
||||||
|
} from '@alfresco/adf-core';
|
||||||
|
import { from, Observable, of, Subject } from 'rxjs';
|
||||||
import { switchMap, takeUntil } from 'rxjs/operators';
|
import { switchMap, takeUntil } from 'rxjs/operators';
|
||||||
|
import { EcmModelService } from './services/ecm-model.service';
|
||||||
|
import { ModelService } from './services/model.service';
|
||||||
|
import { EditorService } from './services/editor.service';
|
||||||
|
import { TaskService } from './services/task.service';
|
||||||
|
import { TaskFormService } from './services/task-form.service';
|
||||||
|
import { TaskRepresentation } from '@alfresco/js-api';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-form',
|
selector: 'adf-form',
|
||||||
@ -59,7 +87,7 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
|||||||
data: FormValues;
|
data: FormValues;
|
||||||
|
|
||||||
/** The form will set a prefixed space for invisible fields. */
|
/** The form will set a prefixed space for invisible fields. */
|
||||||
@Input()
|
@Input()
|
||||||
enableFixedSpacedForm: boolean = true;
|
enableFixedSpacedForm: boolean = true;
|
||||||
|
|
||||||
/** Emitted when the form is submitted with the `Save` or custom outcomes. */
|
/** Emitted when the form is submitted with the `Save` or custom outcomes. */
|
||||||
@ -87,9 +115,13 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
|||||||
protected onDestroy$ = new Subject<boolean>();
|
protected onDestroy$ = new Subject<boolean>();
|
||||||
|
|
||||||
constructor(protected formService: FormService,
|
constructor(protected formService: FormService,
|
||||||
|
protected taskFormService: TaskFormService,
|
||||||
|
protected taskService: TaskService,
|
||||||
|
protected editorService: EditorService,
|
||||||
|
protected modelService: ModelService,
|
||||||
protected visibilityService: WidgetVisibilityService,
|
protected visibilityService: WidgetVisibilityService,
|
||||||
protected ecmModelService: EcmModelService,
|
protected ecmModelService: EcmModelService,
|
||||||
protected nodeService: NodeService) {
|
protected nodeService: NodesApiService) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,13 +200,13 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
findProcessVariablesByTaskId(taskId: string): Observable<any> {
|
findProcessVariablesByTaskId(taskId: string): Observable<TaskProcessVariableModel[]> {
|
||||||
return this.formService.getTask(taskId).pipe(
|
return this.taskService.getTask(taskId).pipe(
|
||||||
switchMap((task: any) => {
|
switchMap((task: TaskRepresentation) => {
|
||||||
if (this.isAProcessTask(task)) {
|
if (this.isAProcessTask(task)) {
|
||||||
return this.visibilityService.getTaskProcessVariable(taskId);
|
return this.taskFormService.getTaskProcessVariable(taskId);
|
||||||
} else {
|
} else {
|
||||||
return of({});
|
return of([]);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -186,13 +218,13 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
|||||||
|
|
||||||
getFormByTaskId(taskId: string): Promise<FormModel> {
|
getFormByTaskId(taskId: string): Promise<FormModel> {
|
||||||
return new Promise<FormModel>(resolve => {
|
return new Promise<FormModel>(resolve => {
|
||||||
this.findProcessVariablesByTaskId(taskId).subscribe(() => {
|
this.findProcessVariablesByTaskId(taskId).subscribe((taskProcessVariables) => {
|
||||||
this.formService
|
this.taskFormService
|
||||||
.getTaskForm(taskId)
|
.getTaskForm(taskId)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
(form) => {
|
(form) => {
|
||||||
const parsedForm = this.parseForm(form);
|
const parsedForm = this.parseForm(form);
|
||||||
this.visibilityService.refreshVisibility(parsedForm);
|
this.visibilityService.refreshVisibility(parsedForm, taskProcessVariables);
|
||||||
parsedForm.validateForm();
|
parsedForm.validateForm();
|
||||||
this.form = parsedForm;
|
this.form = parsedForm;
|
||||||
this.onFormLoaded(this.form);
|
this.onFormLoaded(this.form);
|
||||||
@ -208,7 +240,7 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
|||||||
}
|
}
|
||||||
|
|
||||||
getFormDefinitionByFormId(formId: number) {
|
getFormDefinitionByFormId(formId: number) {
|
||||||
this.formService
|
this.editorService
|
||||||
.getFormDefinitionById(formId)
|
.getFormDefinitionById(formId)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
(form) => {
|
(form) => {
|
||||||
@ -225,11 +257,11 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
|||||||
}
|
}
|
||||||
|
|
||||||
getFormDefinitionByFormName(formName: string) {
|
getFormDefinitionByFormName(formName: string) {
|
||||||
this.formService
|
this.modelService
|
||||||
.getFormDefinitionByName(formName)
|
.getFormDefinitionByName(formName)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
(id) => {
|
(id) => {
|
||||||
this.formService.getFormDefinitionById(id).subscribe(
|
this.editorService.getFormDefinitionById(id).subscribe(
|
||||||
(form) => {
|
(form) => {
|
||||||
this.form = this.parseForm(form);
|
this.form = this.parseForm(form);
|
||||||
this.visibilityService.refreshVisibility(this.form);
|
this.visibilityService.refreshVisibility(this.form);
|
||||||
@ -249,7 +281,7 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
|||||||
|
|
||||||
saveTaskForm() {
|
saveTaskForm() {
|
||||||
if (this.form && this.form.taskId) {
|
if (this.form && this.form.taskId) {
|
||||||
this.formService
|
this.taskFormService
|
||||||
.saveTaskForm(this.form.taskId, this.form.values)
|
.saveTaskForm(this.form.taskId, this.form.values)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
() => {
|
() => {
|
||||||
@ -263,7 +295,7 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
|||||||
|
|
||||||
completeTaskForm(outcome?: string) {
|
completeTaskForm(outcome?: string) {
|
||||||
if (this.form && this.form.taskId) {
|
if (this.form && this.form.taskId) {
|
||||||
this.formService
|
this.taskFormService
|
||||||
.completeTaskForm(this.form.taskId, this.form.values, outcome)
|
.completeTaskForm(this.form.taskId, this.form.values, outcome)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
() => {
|
() => {
|
||||||
@ -300,7 +332,7 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
|||||||
*/
|
*/
|
||||||
getFormDefinitionOutcomes(form: FormModel): FormOutcomeModel[] {
|
getFormDefinitionOutcomes(form: FormModel): FormOutcomeModel[] {
|
||||||
return [
|
return [
|
||||||
new FormOutcomeModel(form, { id: '$save', name: FormOutcomeModel.SAVE_ACTION, isSystem: true })
|
new FormOutcomeModel(form, {id: '$save', name: FormOutcomeModel.SAVE_ACTION, isSystem: true})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,10 +343,10 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadFormFromActiviti(nodeType: string): any {
|
loadFormFromActiviti(nodeType: string): any {
|
||||||
this.formService.searchFrom(nodeType).subscribe(
|
this.modelService.searchFrom(nodeType).subscribe(
|
||||||
(form) => {
|
(form) => {
|
||||||
if (!form) {
|
if (!form) {
|
||||||
this.formService.createFormFromANode(nodeType).subscribe((formMetadata) => {
|
this.createFormFromANode(nodeType).subscribe((formMetadata) => {
|
||||||
this.loadFormFromFormId(formMetadata.id);
|
this.loadFormFromFormId(formMetadata.id);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -327,6 +359,33 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Form with a field for each metadata property.
|
||||||
|
*
|
||||||
|
* @param formName Name of the new form
|
||||||
|
* @returns The new form
|
||||||
|
*/
|
||||||
|
createFormFromANode(formName: string): Observable<any> {
|
||||||
|
return new Observable((observer) => {
|
||||||
|
this.modelService.createForm(formName).subscribe(
|
||||||
|
(form) => {
|
||||||
|
this.ecmModelService.searchEcmType(formName, EcmModelService.MODEL_NAME).subscribe(
|
||||||
|
(customType) => {
|
||||||
|
const formDefinitionModel = new FormDefinitionModel(form.id, form.name, form.lastUpdatedByFullName, form.lastUpdated, customType.entry.properties);
|
||||||
|
from(
|
||||||
|
this.editorService.saveForm(form.id, formDefinitionModel)
|
||||||
|
).subscribe((formData) => {
|
||||||
|
observer.next(formData);
|
||||||
|
observer.complete();
|
||||||
|
}, (err) => this.handleError(err));
|
||||||
|
},
|
||||||
|
(err) => this.handleError(err));
|
||||||
|
},
|
||||||
|
(err) => this.handleError(err));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
protected storeFormAsMetadata() {
|
protected storeFormAsMetadata() {
|
||||||
if (this.saveMetadata) {
|
if (this.saveMetadata) {
|
||||||
this.ecmModelService.createEcmTypeForActivitiForm(this.formName, this.form).subscribe((type) => {
|
this.ecmModelService.createEcmTypeForActivitiForm(this.formName, this.form).subscribe((type) => {
|
||||||
|
@ -21,17 +21,23 @@ import { of } from 'rxjs';
|
|||||||
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 { formDefinitionDropdownField, formDefinitionTwoTextFields,
|
import {
|
||||||
formDefinitionRequiredField, FormService, setupTestBed,
|
formDefinitionDropdownField, formDefinitionTwoTextFields,
|
||||||
|
formDefinitionRequiredField, setupTestBed,
|
||||||
formDefVisibilitiFieldDependsOnNextOne, formDefVisibilitiFieldDependsOnPreviousOne,
|
formDefVisibilitiFieldDependsOnNextOne, formDefVisibilitiFieldDependsOnPreviousOne,
|
||||||
formReadonlyTwoTextFields } from '@alfresco/adf-core';
|
formReadonlyTwoTextFields
|
||||||
|
} from '@alfresco/adf-core';
|
||||||
import { FormComponent } from './form.component';
|
import { FormComponent } from './form.component';
|
||||||
import { ProcessTestingModule } from '../testing/process.testing.module';
|
import { ProcessTestingModule } from '../testing/process.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { TaskService } from './services/task.service';
|
||||||
|
import { TaskFormService } from './services/task-form.service';
|
||||||
|
import { TaskRepresentation } from '@alfresco/js-api';
|
||||||
|
|
||||||
describe('FormComponent UI and visibility', () => {
|
describe('FormComponent UI and visibility', () => {
|
||||||
let component: FormComponent;
|
let component: FormComponent;
|
||||||
let service: FormService;
|
let taskService: TaskService;
|
||||||
|
let taskFormService: TaskFormService;
|
||||||
let fixture: ComponentFixture<FormComponent>;
|
let fixture: ComponentFixture<FormComponent>;
|
||||||
|
|
||||||
const openSelect = () => {
|
const openSelect = () => {
|
||||||
@ -50,7 +56,8 @@ describe('FormComponent UI and visibility', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(FormComponent);
|
fixture = TestBed.createComponent(FormComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
service = TestBed.inject(FormService);
|
taskService = TestBed.inject(TaskService);
|
||||||
|
taskFormService = TestBed.inject(TaskFormService);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@ -60,11 +67,11 @@ describe('FormComponent UI and visibility', () => {
|
|||||||
describe('Validation icon', () => {
|
describe('Validation icon', () => {
|
||||||
|
|
||||||
it('should display valid icon for valid form', () => {
|
it('should display valid icon for valid form', () => {
|
||||||
spyOn(service, 'getTask').and.returnValue(of({}));
|
spyOn(taskService, 'getTask').and.returnValue(of(<TaskRepresentation>{}));
|
||||||
spyOn(service, 'getTaskForm').and.returnValue(of(formDefinitionTwoTextFields));
|
spyOn(taskFormService, 'getTaskForm').and.returnValue(of(formDefinitionTwoTextFields));
|
||||||
|
|
||||||
const change = new SimpleChange(null, 1, true);
|
const change = new SimpleChange(null, 1, true);
|
||||||
component.ngOnChanges({ taskId: change });
|
component.ngOnChanges({taskId: change});
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.query(By.css('#adf-valid-form-icon'))).toBeDefined();
|
expect(fixture.debugElement.query(By.css('#adf-valid-form-icon'))).toBeDefined();
|
||||||
expect(fixture.debugElement.query(By.css('#adf-valid-form-icon'))).not.toBeNull();
|
expect(fixture.debugElement.query(By.css('#adf-valid-form-icon'))).not.toBeNull();
|
||||||
@ -72,11 +79,11 @@ describe('FormComponent UI and visibility', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display invalid icon for valid form', () => {
|
it('should display invalid icon for valid form', () => {
|
||||||
spyOn(service, 'getTask').and.returnValue(of({}));
|
spyOn(taskService, 'getTask').and.returnValue(of(<TaskRepresentation>{}));
|
||||||
spyOn(service, 'getTaskForm').and.returnValue(of(formDefinitionRequiredField));
|
spyOn(taskFormService, 'getTaskForm').and.returnValue(of(formDefinitionRequiredField));
|
||||||
|
|
||||||
const change = new SimpleChange(null, 1, true);
|
const change = new SimpleChange(null, 1, true);
|
||||||
component.ngOnChanges({ taskId: change });
|
component.ngOnChanges({taskId: change});
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.query(By.css('#adf-valid-form-icon'))).toBeNull();
|
expect(fixture.debugElement.query(By.css('#adf-valid-form-icon'))).toBeNull();
|
||||||
expect(fixture.debugElement.query(By.css('#adf-invalid-form-icon'))).toBeDefined();
|
expect(fixture.debugElement.query(By.css('#adf-invalid-form-icon'))).toBeDefined();
|
||||||
@ -84,11 +91,11 @@ describe('FormComponent UI and visibility', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT display validation icon when [showValidationIcon] is false', () => {
|
it('should NOT display validation icon when [showValidationIcon] is false', () => {
|
||||||
spyOn(service, 'getTask').and.returnValue(of({}));
|
spyOn(taskService, 'getTask').and.returnValue(of(<TaskRepresentation>{}));
|
||||||
spyOn(service, 'getTaskForm').and.returnValue(of(formDefinitionTwoTextFields));
|
spyOn(taskFormService, 'getTaskForm').and.returnValue(of(formDefinitionTwoTextFields));
|
||||||
|
|
||||||
const change = new SimpleChange(null, 1, true);
|
const change = new SimpleChange(null, 1, true);
|
||||||
component.ngOnChanges({ taskId: change });
|
component.ngOnChanges({taskId: change});
|
||||||
component.showValidationIcon = false;
|
component.showValidationIcon = false;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(fixture.debugElement.query(By.css('#adf-valid-form-icon'))).toBeNull();
|
expect(fixture.debugElement.query(By.css('#adf-valid-form-icon'))).toBeNull();
|
||||||
@ -99,11 +106,11 @@ describe('FormComponent UI and visibility', () => {
|
|||||||
describe('form definition', () => {
|
describe('form definition', () => {
|
||||||
|
|
||||||
it('should display two text fields form definition', () => {
|
it('should display two text fields form definition', () => {
|
||||||
spyOn(service, 'getTask').and.returnValue(of({}));
|
spyOn(taskService, 'getTask').and.returnValue(of(<TaskRepresentation>{}));
|
||||||
spyOn(service, 'getTaskForm').and.returnValue(of(formDefinitionTwoTextFields));
|
spyOn(taskFormService, 'getTaskForm').and.returnValue(of(formDefinitionTwoTextFields));
|
||||||
|
|
||||||
const change = new SimpleChange(null, 1, true);
|
const change = new SimpleChange(null, 1, true);
|
||||||
component.ngOnChanges({ taskId: change });
|
component.ngOnChanges({taskId: change});
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const firstNameEl = fixture.debugElement.query(By.css('#firstname'));
|
const firstNameEl = fixture.debugElement.query(By.css('#firstname'));
|
||||||
@ -116,11 +123,11 @@ describe('FormComponent UI and visibility', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display dropdown field', async () => {
|
it('should display dropdown field', async () => {
|
||||||
spyOn(service, 'getTask').and.returnValue(of({}));
|
spyOn(taskService, 'getTask').and.returnValue(of(<TaskRepresentation>{}));
|
||||||
spyOn(service, 'getTaskForm').and.returnValue(of(formDefinitionDropdownField));
|
spyOn(taskFormService, 'getTaskForm').and.returnValue(of(formDefinitionDropdownField));
|
||||||
|
|
||||||
const change = new SimpleChange(null, 1, true);
|
const change = new SimpleChange(null, 1, true);
|
||||||
component.ngOnChanges({ taskId: change });
|
component.ngOnChanges({taskId: change});
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
await fixture.whenStable();
|
await fixture.whenStable();
|
||||||
|
|
||||||
@ -150,11 +157,11 @@ describe('FormComponent UI and visibility', () => {
|
|||||||
describe('Visibility conditions', () => {
|
describe('Visibility conditions', () => {
|
||||||
|
|
||||||
it('should hide the field based on the next one', () => {
|
it('should hide the field based on the next one', () => {
|
||||||
spyOn(service, 'getTask').and.returnValue(of({}));
|
spyOn(taskService, 'getTask').and.returnValue(of(<TaskRepresentation>{}));
|
||||||
spyOn(service, 'getTaskForm').and.returnValue(of(formDefVisibilitiFieldDependsOnNextOne));
|
spyOn(taskFormService, 'getTaskForm').and.returnValue(of(formDefVisibilitiFieldDependsOnNextOne));
|
||||||
|
|
||||||
const change = new SimpleChange(null, 1, true);
|
const change = new SimpleChange(null, 1, true);
|
||||||
component.ngOnChanges({ taskId: change });
|
component.ngOnChanges({taskId: change});
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const firstEl = fixture.debugElement.query(By.css('#field-country-container'));
|
const firstEl = fixture.debugElement.query(By.css('#field-country-container'));
|
||||||
@ -167,11 +174,11 @@ describe('FormComponent UI and visibility', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should hide the field based on the previous one', () => {
|
it('should hide the field based on the previous one', () => {
|
||||||
spyOn(service, 'getTask').and.returnValue(of({}));
|
spyOn(taskService, 'getTask').and.returnValue(of(<TaskRepresentation>{}));
|
||||||
spyOn(service, 'getTaskForm').and.returnValue(of(formDefVisibilitiFieldDependsOnPreviousOne));
|
spyOn(taskFormService, 'getTaskForm').and.returnValue(of(formDefVisibilitiFieldDependsOnPreviousOne));
|
||||||
|
|
||||||
const change = new SimpleChange(null, 1, true);
|
const change = new SimpleChange(null, 1, true);
|
||||||
component.ngOnChanges({ taskId: change });
|
component.ngOnChanges({taskId: change});
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const firstEl = fixture.debugElement.query(By.css('#name'));
|
const firstEl = fixture.debugElement.query(By.css('#name'));
|
||||||
@ -184,11 +191,11 @@ describe('FormComponent UI and visibility', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should show the hidden field when the visibility condition change to true', () => {
|
it('should show the hidden field when the visibility condition change to true', () => {
|
||||||
spyOn(service, 'getTask').and.returnValue(of({}));
|
spyOn(taskService, 'getTask').and.returnValue(of(<TaskRepresentation>{}));
|
||||||
spyOn(service, 'getTaskForm').and.returnValue(of(formDefVisibilitiFieldDependsOnNextOne));
|
spyOn(taskFormService, 'getTaskForm').and.returnValue(of(formDefVisibilitiFieldDependsOnNextOne));
|
||||||
|
|
||||||
const change = new SimpleChange(null, 1, true);
|
const change = new SimpleChange(null, 1, true);
|
||||||
component.ngOnChanges({ taskId: change });
|
component.ngOnChanges({taskId: change});
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
let firstEl = fixture.debugElement.query(By.css('#field-country-container'));
|
let firstEl = fixture.debugElement.query(By.css('#field-country-container'));
|
||||||
@ -209,11 +216,11 @@ describe('FormComponent UI and visibility', () => {
|
|||||||
|
|
||||||
describe('Readonly Form', () => {
|
describe('Readonly Form', () => {
|
||||||
it('should display two text fields readonly', async () => {
|
it('should display two text fields readonly', async () => {
|
||||||
spyOn(service, 'getTask').and.returnValue(of({}));
|
spyOn(taskService, 'getTask').and.returnValue(of(<TaskRepresentation>{}));
|
||||||
spyOn(service, 'getTaskForm').and.returnValue(of(formReadonlyTwoTextFields));
|
spyOn(taskFormService, 'getTaskForm').and.returnValue(of(formReadonlyTwoTextFields));
|
||||||
|
|
||||||
const change = new SimpleChange(null, 1, true);
|
const change = new SimpleChange(null, 1, true);
|
||||||
component.ngOnChanges({ taskId: change });
|
component.ngOnChanges({taskId: change});
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
await fixture.whenStable();
|
await fixture.whenStable();
|
||||||
|
@ -21,21 +21,48 @@ import { CoreModule } from '@alfresco/adf-core';
|
|||||||
import { FormComponent } from './form.component';
|
import { FormComponent } from './form.component';
|
||||||
import { StartFormComponent } from './start-form.component';
|
import { StartFormComponent } from './start-form.component';
|
||||||
import { FormCustomOutcomesComponent } from './form-custom-outcomes.component';
|
import { FormCustomOutcomesComponent } from './form-custom-outcomes.component';
|
||||||
|
import { DocumentWidgetComponent } from './widgets/document/document.widget';
|
||||||
|
import { ContentWidgetComponent } from './widgets/document/content.widget';
|
||||||
|
import { UploadWidgetComponent } from './widgets/upload/upload.widget';
|
||||||
|
import { FormListComponent } from './form-list/form-list.component';
|
||||||
|
import { FunctionalGroupWidgetComponent } from './widgets/functional-group/functional-group.widget';
|
||||||
|
import { PeopleWidgetComponent } from './widgets/people/people.widget';
|
||||||
|
import { RadioButtonsWidgetComponent } from './widgets/radio-buttons/radio-buttons.widget';
|
||||||
|
import { TypeaheadWidgetComponent } from './widgets/typeahead/typeahead.widget';
|
||||||
|
import { DropdownWidgetComponent } from './widgets/dropdown/dropdown.widget';
|
||||||
|
import { DynamicTableModule } from './widgets/dynamic-table/dynamic-table.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
|
DynamicTableModule,
|
||||||
CoreModule,
|
CoreModule,
|
||||||
MaterialModule
|
MaterialModule
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
|
UploadWidgetComponent,
|
||||||
FormComponent,
|
FormComponent,
|
||||||
StartFormComponent,
|
StartFormComponent,
|
||||||
FormCustomOutcomesComponent
|
FormCustomOutcomesComponent,
|
||||||
|
DocumentWidgetComponent,
|
||||||
|
ContentWidgetComponent,
|
||||||
|
PeopleWidgetComponent,
|
||||||
|
FunctionalGroupWidgetComponent,
|
||||||
|
FormListComponent,
|
||||||
|
RadioButtonsWidgetComponent,
|
||||||
|
DropdownWidgetComponent,
|
||||||
|
TypeaheadWidgetComponent
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
FormComponent,
|
FormComponent,
|
||||||
StartFormComponent,
|
StartFormComponent,
|
||||||
FormCustomOutcomesComponent
|
FormCustomOutcomesComponent,
|
||||||
|
PeopleWidgetComponent,
|
||||||
|
FunctionalGroupWidgetComponent,
|
||||||
|
RadioButtonsWidgetComponent,
|
||||||
|
TypeaheadWidgetComponent,
|
||||||
|
DropdownWidgetComponent,
|
||||||
|
FormListComponent
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class FormModule {}
|
export class FormModule {
|
||||||
|
}
|
||||||
|
@ -0,0 +1,103 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ProcessFormRenderingService } from './process-form-rendering.service';
|
||||||
|
import { FormFieldModel, FormFieldTypes } from '@alfresco/adf-core';
|
||||||
|
import { AttachFolderWidgetComponent } from './widgets/content-widget/attach-folder-widget.component';
|
||||||
|
import { DropdownWidgetComponent } from './widgets/dropdown/dropdown.widget';
|
||||||
|
import { DynamicTableWidgetComponent } from './widgets/dynamic-table/dynamic-table.widget';
|
||||||
|
import { FunctionalGroupWidgetComponent } from './widgets/functional-group/functional-group.widget';
|
||||||
|
import { PeopleWidgetComponent } from './widgets/people/people.widget';
|
||||||
|
import { RadioButtonsWidgetComponent } from './widgets/radio-buttons/radio-buttons.widget';
|
||||||
|
import { TypeaheadWidgetComponent } from './widgets/typeahead/typeahead.widget';
|
||||||
|
import { DocumentWidgetComponent } from './widgets/document/document.widget';
|
||||||
|
import { AttachFileWidgetComponent } from './widgets/content-widget/attach-file-widget.component';
|
||||||
|
|
||||||
|
describe('ProcessFormRenderingService', () => {
|
||||||
|
|
||||||
|
let service: ProcessFormRenderingService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
service = new ProcessFormRenderingService();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve Upload field as Upload widget', () => {
|
||||||
|
const field = new FormFieldModel(null, {
|
||||||
|
type: FormFieldTypes.UPLOAD,
|
||||||
|
params: {
|
||||||
|
link: null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const type = service.resolveComponentType(field);
|
||||||
|
expect(type).toBe(AttachFileWidgetComponent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve Upload widget for Upload', () => {
|
||||||
|
const resolver = service.getComponentTypeResolver(FormFieldTypes.UPLOAD);
|
||||||
|
const type = resolver(null);
|
||||||
|
expect(type).toBe(AttachFileWidgetComponent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve Upload widget for dropdown', () => {
|
||||||
|
const resolver = service.getComponentTypeResolver(FormFieldTypes.DROPDOWN);
|
||||||
|
const type = resolver(null);
|
||||||
|
expect(type).toBe(DropdownWidgetComponent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve Upload widget for typeahead', () => {
|
||||||
|
const resolver = service.getComponentTypeResolver(FormFieldTypes.TYPEAHEAD);
|
||||||
|
const type = resolver(null);
|
||||||
|
expect(type).toBe(TypeaheadWidgetComponent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve Upload widget for radio button', () => {
|
||||||
|
const resolver = service.getComponentTypeResolver(FormFieldTypes.RADIO_BUTTONS);
|
||||||
|
const type = resolver(null);
|
||||||
|
expect(type).toBe(RadioButtonsWidgetComponent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve Upload widget for select folder', () => {
|
||||||
|
const resolver = service.getComponentTypeResolver(FormFieldTypes.ATTACH_FOLDER);
|
||||||
|
const type = resolver(null);
|
||||||
|
expect(type).toBe(AttachFolderWidgetComponent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve Upload widget for document', () => {
|
||||||
|
const resolver = service.getComponentTypeResolver(FormFieldTypes.DOCUMENT);
|
||||||
|
const type = resolver(null);
|
||||||
|
expect(type).toBe(DocumentWidgetComponent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve Upload widget for people', () => {
|
||||||
|
const resolver = service.getComponentTypeResolver(FormFieldTypes.PEOPLE);
|
||||||
|
const type = resolver(null);
|
||||||
|
expect(type).toBe(PeopleWidgetComponent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve Upload widget for group', () => {
|
||||||
|
const resolver = service.getComponentTypeResolver(FormFieldTypes.FUNCTIONAL_GROUP);
|
||||||
|
const type = resolver(null);
|
||||||
|
expect(type).toBe(FunctionalGroupWidgetComponent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve Upload widget for dynamic table', () => {
|
||||||
|
const resolver = service.getComponentTypeResolver(FormFieldTypes.DYNAMIC_TABLE);
|
||||||
|
const type = resolver(null);
|
||||||
|
expect(type).toBe(DynamicTableWidgetComponent);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -16,9 +16,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { FormRenderingService } from '@alfresco/adf-core';
|
import {
|
||||||
import { AttachFileWidgetComponent } from '../content-widget/attach-file-widget.component';
|
FormFieldTypes,
|
||||||
import { AttachFolderWidgetComponent } from '../content-widget/attach-folder-widget.component';
|
FormRenderingService
|
||||||
|
} from '@alfresco/adf-core';
|
||||||
|
import { AttachFileWidgetComponent } from './widgets/content-widget/attach-file-widget.component';
|
||||||
|
import { AttachFolderWidgetComponent } from './widgets/content-widget/attach-folder-widget.component';
|
||||||
|
import { DocumentWidgetComponent } from './widgets/document/document.widget';
|
||||||
|
import { PeopleWidgetComponent } from './widgets/people/people.widget';
|
||||||
|
import { FunctionalGroupWidgetComponent } from './widgets/functional-group/functional-group.widget';
|
||||||
|
import { RadioButtonsWidgetComponent } from './widgets/radio-buttons/radio-buttons.widget';
|
||||||
|
import { TypeaheadWidgetComponent } from './widgets/typeahead/typeahead.widget';
|
||||||
|
import { DynamicTableWidgetComponent } from './widgets/dynamic-table/dynamic-table.widget';
|
||||||
|
import { DropdownWidgetComponent } from './widgets/dropdown/dropdown.widget';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -28,8 +38,15 @@ export class ProcessFormRenderingService extends FormRenderingService {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.register({
|
this.register({
|
||||||
upload: () => AttachFileWidgetComponent,
|
[FormFieldTypes.DROPDOWN]: () => DropdownWidgetComponent,
|
||||||
'select-folder': () => AttachFolderWidgetComponent
|
[FormFieldTypes.TYPEAHEAD]: () => TypeaheadWidgetComponent,
|
||||||
|
[FormFieldTypes.RADIO_BUTTONS]: () => RadioButtonsWidgetComponent,
|
||||||
|
[FormFieldTypes.UPLOAD]: () => AttachFileWidgetComponent,
|
||||||
|
[FormFieldTypes.ATTACH_FOLDER]: () => AttachFolderWidgetComponent,
|
||||||
|
[FormFieldTypes.DOCUMENT]: () => DocumentWidgetComponent,
|
||||||
|
[FormFieldTypes.PEOPLE]: () => PeopleWidgetComponent,
|
||||||
|
[FormFieldTypes.FUNCTIONAL_GROUP]: () => FunctionalGroupWidgetComponent,
|
||||||
|
[FormFieldTypes.DYNAMIC_TABLE]: () => DynamicTableWidgetComponent
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,23 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
export * from './widgets/index';
|
||||||
|
|
||||||
|
export * from './services/ecm-model.service';
|
||||||
|
export * from './services/editor.service';
|
||||||
|
export * from './services/process-content.service';
|
||||||
|
export * from './services/task.service';
|
||||||
|
export * from './services/task-form.service';
|
||||||
|
export * from './services/process-definition.service';
|
||||||
|
export * from './services/activiti-alfresco.service';
|
||||||
|
export * from './process-form-rendering.service';
|
||||||
|
|
||||||
|
export * from './events/validate-dynamic-table-row.event';
|
||||||
|
|
||||||
|
|
||||||
|
export * from './form-list/form-list.component';
|
||||||
export * from './form.component';
|
export * from './form.component';
|
||||||
export * from './start-form.component';
|
export * from './start-form.component';
|
||||||
export * from './process-form-rendering.service';
|
|
||||||
export * from './form-custom-outcomes.component';
|
export * from './form-custom-outcomes.component';
|
||||||
|
|
||||||
export * from './form.module';
|
export * from './form.module';
|
||||||
|
@ -15,9 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AlfrescoApiService } from '../../services/alfresco-api.service';
|
import { AlfrescoApiService, LogService, SitesService, ExternalContent, ExternalContentLink } from '@alfresco/adf-core';
|
||||||
import { LogService } from '../../services/log.service';
|
|
||||||
import { SitesService } from '../../services/sites.service';
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
IntegrationAlfrescoOnPremiseApi,
|
IntegrationAlfrescoOnPremiseApi,
|
||||||
@ -26,8 +24,6 @@ import {
|
|||||||
ActivitiContentApi
|
ActivitiContentApi
|
||||||
} from '@alfresco/js-api';
|
} from '@alfresco/js-api';
|
||||||
import { Observable, from, throwError } from 'rxjs';
|
import { Observable, from, throwError } from 'rxjs';
|
||||||
import { ExternalContent } from '../components/widgets/core/external-content';
|
|
||||||
import { ExternalContentLink } from '../components/widgets/core/external-content-link';
|
|
||||||
import { map, catchError } from 'rxjs/operators';
|
import { map, catchError } from 'rxjs/operators';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
@ -16,11 +16,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { FormModel } from '../components/widgets/core/form.model';
|
import { FormModel, setupTestBed, CoreTestingModule } from '@alfresco/adf-core';
|
||||||
import { EcmModelService } from './ecm-model.service';
|
import { EcmModelService } from './ecm-model.service';
|
||||||
import { setupTestBed } from '../../testing/setup-test-bed';
|
|
||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { CoreTestingModule } from '../../testing/core.testing.module';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
declare let jasmine: any;
|
declare let jasmine: any;
|
@ -15,11 +15,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { LogService } from '../../services/log.service';
|
import { AlfrescoApiService, LogService, FormModel } from '@alfresco/adf-core';
|
||||||
import { AlfrescoApiService } from '../../services/alfresco-api.service';
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Observable, from } from 'rxjs';
|
import { Observable, from } from 'rxjs';
|
||||||
import { FormModel } from '../components/widgets/core/form.model';
|
|
||||||
import { map, catchError } from 'rxjs/operators';
|
import { map, catchError } from 'rxjs/operators';
|
||||||
import { CustomModelApi } from '@alfresco/js-api';
|
import { CustomModelApi } from '@alfresco/js-api';
|
||||||
|
|
||||||
@ -216,7 +214,7 @@ export class EcmModelService {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
handleError(err: any): any {
|
private handleError(err: any): any {
|
||||||
this.logService.error(err);
|
this.logService.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
97
lib/process-services/src/lib/form/services/editor.service.ts
Normal file
97
lib/process-services/src/lib/form/services/editor.service.ts
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { AlfrescoApiService, FormDefinitionModel, LogService } from '@alfresco/adf-core';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Observable, from, throwError } from 'rxjs';
|
||||||
|
import { FormModelsApi } from '@alfresco/js-api';
|
||||||
|
import { catchError, map } from 'rxjs/operators';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class EditorService {
|
||||||
|
|
||||||
|
static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error';
|
||||||
|
static GENERIC_ERROR_MESSAGE: string = 'Server error';
|
||||||
|
|
||||||
|
_editorApi: FormModelsApi;
|
||||||
|
get editorApi(): FormModelsApi {
|
||||||
|
this._editorApi = this._editorApi ?? new FormModelsApi(this.apiService.getInstance());
|
||||||
|
return this._editorApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(private apiService: AlfrescoApiService, private logService: LogService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a form.
|
||||||
|
*
|
||||||
|
* @param formId ID of the form to save
|
||||||
|
* @param formModel Model data for the form
|
||||||
|
* @returns Data for the saved form
|
||||||
|
*/
|
||||||
|
saveForm(formId: number, formModel: FormDefinitionModel): Observable<any> {
|
||||||
|
return from(
|
||||||
|
this.editorApi.saveForm(formId, formModel)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a form definition.
|
||||||
|
*
|
||||||
|
* @param formId ID of the target form
|
||||||
|
* @returns Form definition
|
||||||
|
*/
|
||||||
|
getFormDefinitionById(formId: number): Observable<any> {
|
||||||
|
return from(this.editorApi.getForm(formId))
|
||||||
|
.pipe(
|
||||||
|
map(this.toJson),
|
||||||
|
catchError((err) => this.handleError(err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a JSON representation of form data.
|
||||||
|
*
|
||||||
|
* @param res Object representing form data
|
||||||
|
* @returns JSON data
|
||||||
|
*/
|
||||||
|
toJson(res: any) {
|
||||||
|
if (res) {
|
||||||
|
return res || {};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reports an error message.
|
||||||
|
*
|
||||||
|
* @param error Data object with optional `message` and `status` fields for the error
|
||||||
|
* @returns Error message
|
||||||
|
*/
|
||||||
|
private handleError(error: any): Observable<any> {
|
||||||
|
let errMsg = EditorService.UNKNOWN_ERROR_MESSAGE;
|
||||||
|
if (error) {
|
||||||
|
errMsg = (error.message) ? error.message :
|
||||||
|
error.status ? `${error.status} - ${error.statusText}` : EditorService.GENERIC_ERROR_MESSAGE;
|
||||||
|
}
|
||||||
|
this.logService.error(errMsg);
|
||||||
|
return throwError(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
162
lib/process-services/src/lib/form/services/model.service.ts
Normal file
162
lib/process-services/src/lib/form/services/model.service.ts
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { AlfrescoApiService, LogService } from '@alfresco/adf-core';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Observable, from, throwError } from 'rxjs';
|
||||||
|
import { ModelsApi } from '@alfresco/js-api';
|
||||||
|
import { catchError, map } from 'rxjs/operators';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class ModelService {
|
||||||
|
|
||||||
|
static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error';
|
||||||
|
static GENERIC_ERROR_MESSAGE: string = 'Server error';
|
||||||
|
|
||||||
|
_modelsApi: ModelsApi;
|
||||||
|
get modelsApi(): ModelsApi {
|
||||||
|
this._modelsApi = this._modelsApi ?? new ModelsApi(this.apiService.getInstance());
|
||||||
|
return this._modelsApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(private apiService: AlfrescoApiService, private logService: LogService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Form.
|
||||||
|
*
|
||||||
|
* @param formName Name of the new form
|
||||||
|
* @returns The new form
|
||||||
|
*/
|
||||||
|
createForm(formName: string): Observable<any> {
|
||||||
|
const dataModel = {
|
||||||
|
name: formName,
|
||||||
|
description: '',
|
||||||
|
modelType: 2,
|
||||||
|
stencilSet: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
return from(
|
||||||
|
this.modelsApi.createModel(dataModel)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all the forms.
|
||||||
|
*
|
||||||
|
* @returns List of form models
|
||||||
|
*/
|
||||||
|
getForms(): Observable<any> {
|
||||||
|
const opts = {
|
||||||
|
modelType: 2
|
||||||
|
};
|
||||||
|
|
||||||
|
return from(this.modelsApi.getModels(opts))
|
||||||
|
.pipe(
|
||||||
|
map(this.toJsonArray),
|
||||||
|
catchError((err) => this.handleError(err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a JSON array representation of form data.
|
||||||
|
*
|
||||||
|
* @param res Object representing form data
|
||||||
|
* @returns JSON data
|
||||||
|
*/
|
||||||
|
toJsonArray(res: any) {
|
||||||
|
if (res) {
|
||||||
|
return res.data || [];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for a form by name.
|
||||||
|
*
|
||||||
|
* @param name The form name to search for
|
||||||
|
* @returns Form model(s) matching the search name
|
||||||
|
*/
|
||||||
|
searchFrom(name: string): Observable<any> {
|
||||||
|
const opts = {
|
||||||
|
modelType: 2
|
||||||
|
};
|
||||||
|
|
||||||
|
return from(
|
||||||
|
this.modelsApi.getModels(opts)
|
||||||
|
)
|
||||||
|
.pipe(
|
||||||
|
map((forms: any) => forms.data.find((formData) => formData.name === name)),
|
||||||
|
catchError((err) => this.handleError(err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the form definition with a given name.
|
||||||
|
*
|
||||||
|
* @param name The form name
|
||||||
|
* @returns Form definition
|
||||||
|
*/
|
||||||
|
getFormDefinitionByName(name: string): Observable<any> {
|
||||||
|
const opts = {
|
||||||
|
filter: 'myReusableForms',
|
||||||
|
filterText: name,
|
||||||
|
modelType: 2
|
||||||
|
};
|
||||||
|
|
||||||
|
return from(this.modelsApi.getModels(opts))
|
||||||
|
.pipe(
|
||||||
|
map(this.getFormId),
|
||||||
|
catchError((err) => this.handleError(err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ID of a form.
|
||||||
|
*
|
||||||
|
* @param form Object representing a form
|
||||||
|
* @returns ID string
|
||||||
|
*/
|
||||||
|
getFormId(form: any): string {
|
||||||
|
let result = null;
|
||||||
|
|
||||||
|
if (form && form.data && form.data.length > 0) {
|
||||||
|
result = form.data[0].id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Reports an error message.
|
||||||
|
*
|
||||||
|
* @param error Data object with optional `message` and `status` fields for the error
|
||||||
|
* @returns Error message
|
||||||
|
*/
|
||||||
|
private handleError(error: any): Observable<any> {
|
||||||
|
let errMsg = ModelService.UNKNOWN_ERROR_MESSAGE;
|
||||||
|
if (error) {
|
||||||
|
errMsg = (error.message) ? error.message :
|
||||||
|
error.status ? `${error.status} - ${error.statusText}` : ModelService.GENERIC_ERROR_MESSAGE;
|
||||||
|
}
|
||||||
|
this.logService.error(errMsg);
|
||||||
|
return throwError(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -18,9 +18,8 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { ProcessContentService } from './process-content.service';
|
import { ProcessContentService } from './process-content.service';
|
||||||
import { setupTestBed } from '../../testing/setup-test-bed';
|
|
||||||
import { CoreTestingModule } from '../../testing/core.testing.module';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { setupTestBed, CoreTestingModule } from '@alfresco/adf-core';
|
||||||
|
|
||||||
declare let jasmine: any;
|
declare let jasmine: any;
|
||||||
|
|
@ -15,8 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AlfrescoApiService } from '../../services/alfresco-api.service';
|
import { AlfrescoApiService, LogService } from '@alfresco/adf-core';
|
||||||
import { LogService } from '../../services/log.service';
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { ActivitiContentApi, RelatedContentRepresentation } from '@alfresco/js-api';
|
import { ActivitiContentApi, RelatedContentRepresentation } from '@alfresco/js-api';
|
||||||
import { Observable, from, throwError } from 'rxjs';
|
import { Observable, from, throwError } from 'rxjs';
|
@ -0,0 +1,100 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { AlfrescoApiService, LogService } from '@alfresco/adf-core';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Observable, from, throwError } from 'rxjs';
|
||||||
|
import { ProcessDefinitionsApi } from '@alfresco/js-api';
|
||||||
|
import { catchError } from 'rxjs/operators';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class ProcessDefinitionService {
|
||||||
|
|
||||||
|
static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error';
|
||||||
|
static GENERIC_ERROR_MESSAGE: string = 'Server error';
|
||||||
|
|
||||||
|
_processDefinitionsApi: ProcessDefinitionsApi;
|
||||||
|
get processDefinitionsApi(): ProcessDefinitionsApi {
|
||||||
|
this._processDefinitionsApi = this._processDefinitionsApi ?? new ProcessDefinitionsApi(this.apiService.getInstance());
|
||||||
|
return this._processDefinitionsApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(private apiService: AlfrescoApiService, private logService: LogService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets values of fields populated by a REST backend using a process ID.
|
||||||
|
*
|
||||||
|
* @param processDefinitionId Process identifier
|
||||||
|
* @param field Field identifier
|
||||||
|
* @returns Field values
|
||||||
|
*/
|
||||||
|
getRestFieldValuesByProcessId(processDefinitionId: string, field: string): Observable<any> {
|
||||||
|
return from(this.processDefinitionsApi.getRestFieldValues(processDefinitionId, field))
|
||||||
|
.pipe(
|
||||||
|
catchError((err) => this.handleError(err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets column values of fields populated by a REST backend using a process ID.
|
||||||
|
*
|
||||||
|
* @param processDefinitionId Process identifier
|
||||||
|
* @param field Field identifier
|
||||||
|
* @param column Column identifier
|
||||||
|
* @returns Field values
|
||||||
|
*/
|
||||||
|
getRestFieldValuesColumnByProcessId(processDefinitionId: string, field: string, column?: string): Observable<any> {
|
||||||
|
return from(this.processDefinitionsApi.getRestTableFieldValues(processDefinitionId, field, column))
|
||||||
|
.pipe(
|
||||||
|
catchError((err) => this.handleError(err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a JSON representation of form data.
|
||||||
|
*
|
||||||
|
* @param res Object representing form data
|
||||||
|
* @returns JSON data
|
||||||
|
*/
|
||||||
|
toJson(res: any) {
|
||||||
|
if (res) {
|
||||||
|
return res || {};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reports an error message.
|
||||||
|
*
|
||||||
|
* @param error Data object with optional `message` and `status` fields for the error
|
||||||
|
* @returns Error message
|
||||||
|
*/
|
||||||
|
private handleError(error: any): Observable<any> {
|
||||||
|
let errMsg = ProcessDefinitionService.UNKNOWN_ERROR_MESSAGE;
|
||||||
|
if (error) {
|
||||||
|
errMsg = (error.message) ? error.message :
|
||||||
|
error.status ? `${error.status} - ${error.statusText}` : ProcessDefinitionService.GENERIC_ERROR_MESSAGE;
|
||||||
|
}
|
||||||
|
this.logService.error(errMsg);
|
||||||
|
return throwError(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
157
lib/process-services/src/lib/form/services/task-form.service.ts
Normal file
157
lib/process-services/src/lib/form/services/task-form.service.ts
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { AlfrescoApiService, FormValues, LogService, TaskProcessVariableModel } from '@alfresco/adf-core';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { from, Observable, throwError } from 'rxjs';
|
||||||
|
import { CompleteFormRepresentation, SaveFormRepresentation, TaskFormsApi } from '@alfresco/js-api';
|
||||||
|
import { catchError, map } from 'rxjs/operators';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class TaskFormService {
|
||||||
|
|
||||||
|
static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error';
|
||||||
|
static GENERIC_ERROR_MESSAGE: string = 'Server error';
|
||||||
|
|
||||||
|
_taskFormsApi: TaskFormsApi;
|
||||||
|
get taskFormsApi(): TaskFormsApi {
|
||||||
|
this._taskFormsApi = this._taskFormsApi ?? new TaskFormsApi(this.apiService.getInstance());
|
||||||
|
return this._taskFormsApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(private apiService: AlfrescoApiService, private logService: LogService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a task form.
|
||||||
|
*
|
||||||
|
* @param taskId Task Id
|
||||||
|
* @param formValues Form Values
|
||||||
|
* @returns Null response when the operation is complete
|
||||||
|
*/
|
||||||
|
saveTaskForm(taskId: string, formValues: FormValues): Observable<any> {
|
||||||
|
const saveFormRepresentation = { values: formValues } as SaveFormRepresentation;
|
||||||
|
|
||||||
|
return from(this.taskFormsApi.saveTaskForm(taskId, saveFormRepresentation))
|
||||||
|
.pipe(
|
||||||
|
catchError((err) => this.handleError(err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Completes a Task Form.
|
||||||
|
*
|
||||||
|
* @param taskId Task Id
|
||||||
|
* @param formValues Form Values
|
||||||
|
* @param outcome Form Outcome
|
||||||
|
* @returns Null response when the operation is complete
|
||||||
|
*/
|
||||||
|
completeTaskForm(taskId: string, formValues: FormValues, outcome?: string): Observable<any> {
|
||||||
|
const completeFormRepresentation = { values: formValues } as CompleteFormRepresentation;
|
||||||
|
if (outcome) {
|
||||||
|
completeFormRepresentation.outcome = outcome;
|
||||||
|
}
|
||||||
|
|
||||||
|
return from(this.taskFormsApi.completeTaskForm(taskId, completeFormRepresentation))
|
||||||
|
.pipe(
|
||||||
|
catchError((err) => this.handleError(err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a form related to a task.
|
||||||
|
*
|
||||||
|
* @param taskId ID of the target task
|
||||||
|
* @returns Form definition
|
||||||
|
*/
|
||||||
|
getTaskForm(taskId: string): Observable<any> {
|
||||||
|
return from(this.taskFormsApi.getTaskForm(taskId))
|
||||||
|
.pipe(
|
||||||
|
map(this.toJson),
|
||||||
|
catchError((err) => this.handleError(err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets values of fields populated by a REST backend.
|
||||||
|
*
|
||||||
|
* @param taskId Task identifier
|
||||||
|
* @param field Field identifier
|
||||||
|
* @returns Field values
|
||||||
|
*/
|
||||||
|
getRestFieldValues(taskId: string, field: string): Observable<any> {
|
||||||
|
return from(this.taskFormsApi.getRestFieldValues(taskId, field))
|
||||||
|
.pipe(
|
||||||
|
catchError((err) => this.handleError(err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets column values of fields populated by a REST backend.
|
||||||
|
*
|
||||||
|
* @param taskId Task identifier
|
||||||
|
* @param field Field identifier
|
||||||
|
* @param column Column identifier
|
||||||
|
* @returns Field values
|
||||||
|
*/
|
||||||
|
getRestFieldValuesColumn(taskId: string, field: string, column?: string): Observable<any> {
|
||||||
|
return from(this.taskFormsApi.getRestFieldColumnValues(taskId, field, column))
|
||||||
|
.pipe(
|
||||||
|
catchError((err) => this.handleError(err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTaskProcessVariable(taskId: string): Observable<TaskProcessVariableModel[]> {
|
||||||
|
return from(this.taskFormsApi.getTaskFormVariables(taskId))
|
||||||
|
.pipe(
|
||||||
|
map((res) => this.toJson(res)),
|
||||||
|
catchError((err) => this.handleError(err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a JSON representation of form data.
|
||||||
|
*
|
||||||
|
* @param res Object representing form data
|
||||||
|
* @returns JSON data
|
||||||
|
*/
|
||||||
|
toJson(res: any) {
|
||||||
|
if (res) {
|
||||||
|
return res || {};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reports an error message.
|
||||||
|
*
|
||||||
|
* @param error Data object with optional `message` and `status` fields for the error
|
||||||
|
* @returns Error message
|
||||||
|
*/
|
||||||
|
private handleError(error: any): Observable<any> {
|
||||||
|
let errMsg = TaskFormService.UNKNOWN_ERROR_MESSAGE;
|
||||||
|
if (error) {
|
||||||
|
errMsg = (error.message) ? error.message :
|
||||||
|
error.status ? `${error.status} - ${error.statusText}` : TaskFormService.GENERIC_ERROR_MESSAGE;
|
||||||
|
}
|
||||||
|
this.logService.error(errMsg);
|
||||||
|
return throwError(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
85
lib/process-services/src/lib/form/services/task.service.ts
Normal file
85
lib/process-services/src/lib/form/services/task.service.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { AlfrescoApiService, LogService } from '@alfresco/adf-core';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Observable, from, throwError } from 'rxjs';
|
||||||
|
import { TaskRepresentation, TasksApi } from '@alfresco/js-api';
|
||||||
|
import { catchError, map } from 'rxjs/operators';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class TaskService {
|
||||||
|
|
||||||
|
static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error';
|
||||||
|
static GENERIC_ERROR_MESSAGE: string = 'Server error';
|
||||||
|
|
||||||
|
_taskApi: TasksApi;
|
||||||
|
get taskApi(): TasksApi {
|
||||||
|
this._taskApi = this._taskApi ?? new TasksApi(this.apiService.getInstance());
|
||||||
|
return this._taskApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(private apiService: AlfrescoApiService, private logService: LogService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a task.
|
||||||
|
*
|
||||||
|
* @param taskId Task Id
|
||||||
|
* @returns Task info
|
||||||
|
*/
|
||||||
|
getTask(taskId: string): Observable<TaskRepresentation> {
|
||||||
|
return from(this.taskApi.getTask(taskId))
|
||||||
|
.pipe(
|
||||||
|
map(this.toJson),
|
||||||
|
catchError((err) => this.handleError(err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a JSON representation of form data.
|
||||||
|
*
|
||||||
|
* @param res Object representing form data
|
||||||
|
* @returns JSON data
|
||||||
|
*/
|
||||||
|
toJson(res: any) {
|
||||||
|
if (res) {
|
||||||
|
return res || {};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reports an error message.
|
||||||
|
*
|
||||||
|
* @param error Data object with optional `message` and `status` fields for the error
|
||||||
|
* @returns Error message
|
||||||
|
*/
|
||||||
|
private handleError(error: any): Observable<any> {
|
||||||
|
let errMsg = TaskService.UNKNOWN_ERROR_MESSAGE;
|
||||||
|
if (error) {
|
||||||
|
errMsg = (error.message) ? error.message :
|
||||||
|
error.status ? `${error.status} - ${error.statusText}` : TaskService.GENERIC_ERROR_MESSAGE;
|
||||||
|
}
|
||||||
|
this.logService.error(errMsg);
|
||||||
|
return throwError(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -25,18 +25,19 @@ import {
|
|||||||
taskFormSingleUploadMock, taskFormMultipleUploadMock, preselectedSingleNode, preselectedMultipleeNode
|
taskFormSingleUploadMock, taskFormMultipleUploadMock, preselectedSingleNode, preselectedMultipleeNode
|
||||||
} from './start-form.component.mock';
|
} from './start-form.component.mock';
|
||||||
import { StartFormComponent } from './start-form.component';
|
import { StartFormComponent } from './start-form.component';
|
||||||
import { FormService, WidgetVisibilityService, setupTestBed, FormModel, FormOutcomeModel } from '@alfresco/adf-core';
|
import { WidgetVisibilityService, setupTestBed, FormModel, FormOutcomeModel } from '@alfresco/adf-core';
|
||||||
import { TranslateService, TranslateModule } from '@ngx-translate/core';
|
import { TranslateService, TranslateModule } from '@ngx-translate/core';
|
||||||
import { ProcessTestingModule } from '../testing/process.testing.module';
|
import { ProcessTestingModule } from '../testing/process.testing.module';
|
||||||
|
import { ProcessService } from '../process-list/services/process.service';
|
||||||
|
|
||||||
describe('StartFormComponent', () => {
|
describe('StartFormComponent', () => {
|
||||||
|
|
||||||
let formService: FormService;
|
|
||||||
let component: StartFormComponent;
|
let component: StartFormComponent;
|
||||||
let fixture: ComponentFixture<StartFormComponent>;
|
let fixture: ComponentFixture<StartFormComponent>;
|
||||||
let getStartFormSpy: jasmine.Spy;
|
let getStartFormSpy: jasmine.Spy;
|
||||||
let visibilityService: WidgetVisibilityService;
|
let visibilityService: WidgetVisibilityService;
|
||||||
let translate: TranslateService;
|
let translate: TranslateService;
|
||||||
|
let processService: ProcessService;
|
||||||
|
|
||||||
const exampleId1 = 'my:process1';
|
const exampleId1 = 'my:process1';
|
||||||
const exampleId2 = 'my:process2';
|
const exampleId2 = 'my:process2';
|
||||||
@ -52,11 +53,11 @@ describe('StartFormComponent', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(StartFormComponent);
|
fixture = TestBed.createComponent(StartFormComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
formService = TestBed.inject(FormService);
|
processService = TestBed.inject(ProcessService);
|
||||||
visibilityService = TestBed.inject(WidgetVisibilityService);
|
visibilityService = TestBed.inject(WidgetVisibilityService);
|
||||||
translate = TestBed.inject(TranslateService);
|
translate = TestBed.inject(TranslateService);
|
||||||
|
|
||||||
getStartFormSpy = spyOn(formService, 'getStartFormDefinition').and.returnValue(of({
|
getStartFormSpy = spyOn(processService, 'getStartFormDefinition').and.returnValue(of({
|
||||||
processDefinitionName: 'my:process'
|
processDefinitionName: 'my:process'
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -71,27 +72,27 @@ describe('StartFormComponent', () => {
|
|||||||
it('should load start form on change if processDefinitionId defined', () => {
|
it('should load start form on change if processDefinitionId defined', () => {
|
||||||
component.processDefinitionId = exampleId1;
|
component.processDefinitionId = exampleId1;
|
||||||
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
|
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
|
||||||
expect(formService.getStartFormDefinition).toHaveBeenCalled();
|
expect(processService.getStartFormDefinition).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should load start form when processDefinitionId changed', () => {
|
it('should load start form when processDefinitionId changed', () => {
|
||||||
component.processDefinitionId = exampleId1;
|
component.processDefinitionId = exampleId1;
|
||||||
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
|
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
|
||||||
expect(formService.getStartFormDefinition).toHaveBeenCalled();
|
expect(processService.getStartFormDefinition).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check visibility when the start form is loaded', () => {
|
it('should check visibility when the start form is loaded', () => {
|
||||||
spyOn(visibilityService, 'refreshVisibility');
|
spyOn(visibilityService, 'refreshVisibility');
|
||||||
component.processDefinitionId = exampleId1;
|
component.processDefinitionId = exampleId1;
|
||||||
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
|
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
|
||||||
expect(formService.getStartFormDefinition).toHaveBeenCalled();
|
expect(processService.getStartFormDefinition).toHaveBeenCalled();
|
||||||
expect(visibilityService.refreshVisibility).toHaveBeenCalled();
|
expect(visibilityService.refreshVisibility).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not load start form when changes notified but no change to processDefinitionId', () => {
|
it('should not load start form when changes notified but no change to processDefinitionId', () => {
|
||||||
component.processDefinitionId = undefined;
|
component.processDefinitionId = undefined;
|
||||||
component.ngOnChanges({ otherProp: new SimpleChange(exampleId1, exampleId2, true) });
|
component.ngOnChanges({ otherProp: new SimpleChange(exampleId1, exampleId2, true) });
|
||||||
expect(formService.getStartFormDefinition).not.toHaveBeenCalled();
|
expect(processService.getStartFormDefinition).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to inject sigle file as value into the form with an upload single widget', () => {
|
it('should be able to inject sigle file as value into the form with an upload single widget', () => {
|
||||||
|
@ -30,6 +30,11 @@ import {
|
|||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { FormComponent } from './form.component';
|
import { FormComponent } from './form.component';
|
||||||
import { ContentLinkModel, FormService, WidgetVisibilityService, FormOutcomeModel } from '@alfresco/adf-core';
|
import { ContentLinkModel, FormService, WidgetVisibilityService, FormOutcomeModel } from '@alfresco/adf-core';
|
||||||
|
import { ProcessService } from '../process-list/services/process.service';
|
||||||
|
import { EditorService } from './services/editor.service';
|
||||||
|
import { ModelService } from './services/model.service';
|
||||||
|
import { TaskFormService } from './services/task-form.service';
|
||||||
|
import { TaskService } from './services/task.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-start-form',
|
selector: 'adf-start-form',
|
||||||
@ -70,8 +75,13 @@ export class StartFormComponent extends FormComponent implements OnChanges, OnIn
|
|||||||
@ViewChild('outcomesContainer')
|
@ViewChild('outcomesContainer')
|
||||||
outcomesContainer: ElementRef = null;
|
outcomesContainer: ElementRef = null;
|
||||||
|
|
||||||
constructor(formService: FormService, visibilityService: WidgetVisibilityService) {
|
constructor(public processService: ProcessService,
|
||||||
super(formService, visibilityService, null, null);
|
taskFormService: TaskFormService,
|
||||||
|
taskService: TaskService,
|
||||||
|
editorService: EditorService,
|
||||||
|
modelService: ModelService,
|
||||||
|
formService: FormService, visibilityService: WidgetVisibilityService) {
|
||||||
|
super(formService, taskFormService, taskService, editorService, modelService, visibilityService, null, null);
|
||||||
this.showTitle = false;
|
this.showTitle = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,9 +109,9 @@ export class StartFormComponent extends FormComponent implements OnChanges, OnIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadStartForm(processId: string) {
|
loadStartForm(processId: string) {
|
||||||
this.formService.getProcessInstance(processId)
|
this.processService.getProcess(processId)
|
||||||
.subscribe((instance: any) => {
|
.subscribe((instance: any) => {
|
||||||
this.formService
|
this.processService
|
||||||
.getStartFormInstance(processId)
|
.getStartFormInstance(processId)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
(form) => {
|
(form) => {
|
||||||
@ -117,7 +127,7 @@ export class StartFormComponent extends FormComponent implements OnChanges, OnIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
getStartFormDefinition(processId: string) {
|
getStartFormDefinition(processId: string) {
|
||||||
this.formService
|
this.processService
|
||||||
.getStartFormDefinition(processId)
|
.getStartFormDefinition(processId)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
(form) => {
|
(form) => {
|
||||||
|
@ -19,7 +19,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|||||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||||
import { ContentModule, ContentNodeSelectorPanelComponent, DocumentListService } from '@alfresco/adf-content-services';
|
import { ContentModule, ContentNodeSelectorPanelComponent, DocumentListService } from '@alfresco/adf-content-services';
|
||||||
import { EventEmitter, NO_ERRORS_SCHEMA } from '@angular/core';
|
import { EventEmitter, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { ProcessTestingModule } from '../testing/process.testing.module';
|
import { ProcessTestingModule } from '../../../testing/process.testing.module';
|
||||||
import { AttachFileWidgetDialogComponent } from './attach-file-widget-dialog.component';
|
import { AttachFileWidgetDialogComponent } from './attach-file-widget-dialog.component';
|
||||||
import { setupTestBed, AuthenticationService, SitesService, AlfrescoApiService, NodesApiService } from '@alfresco/adf-core';
|
import { setupTestBed, AuthenticationService, SitesService, AlfrescoApiService, NodesApiService } from '@alfresco/adf-core';
|
||||||
import { AttachFileWidgetDialogComponentData } from './attach-file-widget-dialog-component.interface';
|
import { AttachFileWidgetDialogComponentData } from './attach-file-widget-dialog-component.interface';
|
@ -20,7 +20,7 @@ import { MatDialog } from '@angular/material/dialog';
|
|||||||
import { AttachFileWidgetDialogService } from './attach-file-widget-dialog.service';
|
import { AttachFileWidgetDialogService } from './attach-file-widget-dialog.service';
|
||||||
import { Subject, of } from 'rxjs';
|
import { Subject, of } from 'rxjs';
|
||||||
import { setupTestBed } from '@alfresco/adf-core';
|
import { setupTestBed } from '@alfresco/adf-core';
|
||||||
import { ProcessTestingModule } from '../testing/process.testing.module';
|
import { ProcessTestingModule } from '../../../testing/process.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
describe('AttachFileWidgetDialogService', () => {
|
describe('AttachFileWidgetDialogService', () => {
|
@ -40,7 +40,7 @@
|
|||||||
(click)="openSelectDialogFromFileSource()">
|
(click)="openSelectDialogFromFileSource()">
|
||||||
{{field.params?.fileSource?.name}}
|
{{field.params?.fileSource?.name}}
|
||||||
<mat-icon>
|
<mat-icon>
|
||||||
<img alt="alfresco" class="adf-attach-widget__image-logo" src="../assets/images/alfresco-flower.svg">
|
<img alt="alfresco" class="adf-attach-widget__image-logo" src="../../../assets/images/alfresco-flower.svg">
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<div *ngIf="!isDefinedSourceFolder()">
|
<div *ngIf="!isDefinedSourceFolder()">
|
||||||
@ -49,7 +49,7 @@
|
|||||||
(click)="openSelectDialog(repo)">
|
(click)="openSelectDialog(repo)">
|
||||||
{{repo.name}}
|
{{repo.name}}
|
||||||
<mat-icon>
|
<mat-icon>
|
||||||
<img alt="alfresco" class="adf-attach-widget__image-logo" src="../assets/images/alfresco-flower.svg">
|
<img alt="alfresco" class="adf-attach-widget__image-logo" src="../../../assets/images/alfresco-flower.svg">
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
@ -23,8 +23,6 @@ import {
|
|||||||
FormModel,
|
FormModel,
|
||||||
FormFieldTypes,
|
FormFieldTypes,
|
||||||
FormService,
|
FormService,
|
||||||
ProcessContentService,
|
|
||||||
ActivitiContentService,
|
|
||||||
FormFieldMetadata,
|
FormFieldMetadata,
|
||||||
setupTestBed,
|
setupTestBed,
|
||||||
DownloadService
|
DownloadService
|
||||||
@ -32,9 +30,11 @@ import {
|
|||||||
import { ContentNodeDialogService, ContentModule } from '@alfresco/adf-content-services';
|
import { ContentNodeDialogService, ContentModule } from '@alfresco/adf-content-services';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { Node } from '@alfresco/js-api';
|
import { Node } from '@alfresco/js-api';
|
||||||
import { ProcessTestingModule } from '../testing/process.testing.module';
|
import { ProcessTestingModule } from '../../../testing/process.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { AttachFileWidgetDialogService } from './attach-file-widget-dialog.service';
|
import { AttachFileWidgetDialogService } from './attach-file-widget-dialog.service';
|
||||||
|
import { ActivitiContentService } from '../../services/activiti-alfresco.service';
|
||||||
|
import { ProcessContentService } from '../../services/process-content.service';
|
||||||
|
|
||||||
const fakeRepositoryListAnswer = [
|
const fakeRepositoryListAnswer = [
|
||||||
{
|
{
|
@ -19,16 +19,13 @@
|
|||||||
|
|
||||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
ActivitiContentService,
|
|
||||||
AppConfigService,
|
AppConfigService,
|
||||||
AppConfigValues,
|
AppConfigValues,
|
||||||
ContentService,
|
ContentService,
|
||||||
DownloadService,
|
DownloadService,
|
||||||
FormService,
|
FormService,
|
||||||
LogService,
|
LogService,
|
||||||
ProcessContentService,
|
ThumbnailService
|
||||||
ThumbnailService,
|
|
||||||
UploadWidgetComponent
|
|
||||||
} from '@alfresco/adf-core';
|
} from '@alfresco/adf-core';
|
||||||
import { ContentNodeDialogService } from '@alfresco/adf-content-services';
|
import { ContentNodeDialogService } from '@alfresco/adf-content-services';
|
||||||
import {
|
import {
|
||||||
@ -40,6 +37,9 @@ import {
|
|||||||
import { from, of, Subject, zip } from 'rxjs';
|
import { from, of, Subject, zip } from 'rxjs';
|
||||||
import { mergeMap, takeUntil } from 'rxjs/operators';
|
import { mergeMap, takeUntil } from 'rxjs/operators';
|
||||||
import { AttachFileWidgetDialogService } from './attach-file-widget-dialog.service';
|
import { AttachFileWidgetDialogService } from './attach-file-widget-dialog.service';
|
||||||
|
import { UploadWidgetComponent } from '../upload/upload.widget';
|
||||||
|
import { ProcessContentService } from '../../services/process-content.service';
|
||||||
|
import { ActivitiContentService } from '../../services/activiti-alfresco.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'attach-widget',
|
selector: 'attach-widget',
|
@ -27,7 +27,7 @@ import {
|
|||||||
import { ContentNodeDialogService } from '@alfresco/adf-content-services';
|
import { ContentNodeDialogService } from '@alfresco/adf-content-services';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { Node } from '@alfresco/js-api';
|
import { Node } from '@alfresco/js-api';
|
||||||
import { ProcessTestingModule } from '../testing/process.testing.module';
|
import { ProcessTestingModule } from '../../../testing/process.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
const fakeMinimalNode: Node = {
|
const fakeMinimalNode: Node = {
|
@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { MaterialModule } from '../material.module';
|
import { MaterialModule } from '../../../material.module';
|
||||||
import { CoreModule } from '@alfresco/adf-core';
|
import { CoreModule } from '@alfresco/adf-core';
|
||||||
import { ContentNodeSelectorModule } from '@alfresco/adf-content-services';
|
import { ContentNodeSelectorModule } from '@alfresco/adf-content-services';
|
||||||
|
|
@ -18,15 +18,16 @@
|
|||||||
import { SimpleChange } from '@angular/core';
|
import { SimpleChange } from '@angular/core';
|
||||||
import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { ContentService } from '../../../../services';
|
import {
|
||||||
|
ContentService,
|
||||||
|
ContentLinkModel,
|
||||||
|
CoreTestingModule,
|
||||||
|
setupTestBed
|
||||||
|
} from '@alfresco/adf-core';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
|
|
||||||
import { ProcessContentService } from '../../../services/process-content.service';
|
|
||||||
import { ContentLinkModel } from '../index';
|
|
||||||
import { ContentWidgetComponent } from './content.widget';
|
import { ContentWidgetComponent } from './content.widget';
|
||||||
import { setupTestBed } from '../../../../testing/setup-test-bed';
|
|
||||||
import { CoreTestingModule } from '../../../../testing/core.testing.module';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { ProcessContentService } from '../../services/process-content.service';
|
||||||
|
|
||||||
declare let jasmine: any;
|
declare let jasmine: any;
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ describe('ContentWidgetComponent', () => {
|
|||||||
|
|
||||||
const createFakeImageBlob = () => {
|
const createFakeImageBlob = () => {
|
||||||
const data = atob('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==');
|
const data = atob('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==');
|
||||||
return new Blob([data], { type: 'image/png' });
|
return new Blob([data], {type: 'image/png'});
|
||||||
};
|
};
|
||||||
|
|
||||||
const createFakePdfBlob = (): Blob => {
|
const createFakePdfBlob = (): Blob => {
|
||||||
@ -59,7 +60,7 @@ describe('ContentWidgetComponent', () => {
|
|||||||
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
|
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
|
||||||
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
|
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
|
||||||
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
|
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
|
||||||
return new Blob([pdfData], { type: 'application/pdf' });
|
return new Blob([pdfData], {type: 'application/pdf'});
|
||||||
};
|
};
|
||||||
|
|
||||||
setupTestBed({
|
setupTestBed({
|
||||||
@ -115,7 +116,7 @@ describe('ContentWidgetComponent', () => {
|
|||||||
|
|
||||||
const contentId = 1;
|
const contentId = 1;
|
||||||
const change = new SimpleChange(null, contentId, true);
|
const change = new SimpleChange(null, contentId, true);
|
||||||
component.ngOnChanges({ id: change });
|
component.ngOnChanges({id: change});
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||||
status: 200,
|
status: 200,
|
||||||
@ -155,7 +156,7 @@ describe('ContentWidgetComponent', () => {
|
|||||||
|
|
||||||
const contentId = 1;
|
const contentId = 1;
|
||||||
const change = new SimpleChange(null, contentId, true);
|
const change = new SimpleChange(null, contentId, true);
|
||||||
component.ngOnChanges({ id: change });
|
component.ngOnChanges({id: change});
|
||||||
|
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||||
status: 200,
|
status: 200,
|
||||||
@ -183,7 +184,7 @@ describe('ContentWidgetComponent', () => {
|
|||||||
|
|
||||||
const contentId = 1;
|
const contentId = 1;
|
||||||
const change = new SimpleChange(null, contentId, true);
|
const change = new SimpleChange(null, contentId, true);
|
||||||
component.ngOnChanges({ id: change });
|
component.ngOnChanges({id: change});
|
||||||
|
|
||||||
component.contentLoaded.subscribe(() => {
|
component.contentLoaded.subscribe(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
@ -15,13 +15,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ContentService } from '../../../../services/content.service';
|
import { ContentService, LogService, ContentLinkModel, FormService } from '@alfresco/adf-core';
|
||||||
import { LogService } from '../../../../services/log.service';
|
|
||||||
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
|
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { ProcessContentService } from '../../../services/process-content.service';
|
import { ProcessContentService } from '../../services/process-content.service';
|
||||||
import { ContentLinkModel } from '../core/content-link.model';
|
|
||||||
import { FormService } from '../../../services/form.service';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-content',
|
selector: 'adf-content',
|
@ -16,8 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
|
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
|
||||||
import { FormService } from '../../../services/form.service';
|
import { FormService, WidgetComponent } from '@alfresco/adf-core';
|
||||||
import { WidgetComponent } from '../widget.component';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-form-document-widget',
|
selector: 'adf-form-document-widget',
|
||||||
@ -41,7 +40,7 @@ export class DocumentWidgetComponent extends WidgetComponent implements OnInit {
|
|||||||
hasFile: boolean = false;
|
hasFile: boolean = false;
|
||||||
|
|
||||||
constructor(public formService: FormService) {
|
constructor(public formService: FormService) {
|
||||||
super(formService);
|
super(formService);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user