@netgrif/components-core
Version:
Netgrif Application engine frontend core Angular library
307 lines (306 loc) • 16.3 kB
TypeScript
import { OnDestroy } from '@angular/core';
import { Filter } from '../../../filter/models/filter';
import { CaseResourceService } from '../../../resources/engine-endpoint/case-resource.service';
import { CaseTreeNode } from './model/case-tree-node';
import { TreeCaseViewService } from '../tree-case-view.service';
import { TaskResourceService } from '../../../resources/engine-endpoint/task-resource.service';
import { LoggerService } from '../../../logger/services/logger.service';
import { ImmediateData } from '../../../resources/interface/immediate-data';
import { Case } from '../../../resources/interface/case';
import { ProcessService } from '../../../process/process.service';
import { SideMenuService } from '../../../side-menu/services/side-menu.service';
import { Observable, Subject } from 'rxjs';
import { Page } from '../../../resources/interface/page';
import { TranslateService } from '@ngx-translate/core';
import { NestedTreeControl } from '@angular/cdk/tree';
import { MatTreeNestedDataSource } from '@angular/material/tree';
import { CaseGetRequestBody } from '../../../resources/interface/case-get-request-body';
import { CaseTreePath } from './model/case-tree-path';
import { ExpansionTree } from './model/expansion-tree';
import { ResultWithAfterActions } from '../../../utility/result-with-after-actions';
import { TreeCaseViewConfiguration } from './model/tree-case-view-configuration';
import * as i0 from "@angular/core";
export declare class CaseTreeService implements OnDestroy {
protected _caseResourceService: CaseResourceService;
protected _treeCaseViewService: TreeCaseViewService;
protected _taskResourceService: TaskResourceService;
protected _logger: LoggerService;
protected _processService: ProcessService;
protected _sideMenuService: SideMenuService;
protected _translateService: TranslateService;
protected _optionSelectorComponent: any;
protected _treeConfiguration: TreeCaseViewConfiguration;
static readonly DEFAULT_PAGE_SIZE = 50;
protected _currentNode: CaseTreeNode;
private _rootNodesFilter;
private readonly _treeDataSource;
private readonly _treeControl;
private _treeRootLoaded$;
private _rootNode;
private _showRoot;
/**
* Weather the tree is eager loaded or not.
*
* Defaults to `false`.
*
* It is not recommended to eager load large trees as each node sends a separate backend request to load its data.
*/
private _isEagerLoaded;
/**
* string id of the case, that is currently being reloaded, `undefined` if no case is currently being reloaded
*/
private _reloadedCaseId;
constructor(_caseResourceService: CaseResourceService, _treeCaseViewService: TreeCaseViewService, _taskResourceService: TaskResourceService, _logger: LoggerService, _processService: ProcessService, _sideMenuService: SideMenuService, _translateService: TranslateService, _optionSelectorComponent: any, _treeConfiguration: TreeCaseViewConfiguration);
ngOnDestroy(): void;
set rootFilter(filter: Filter);
get dataSource(): MatTreeNestedDataSource<CaseTreeNode>;
get treeControl(): NestedTreeControl<CaseTreeNode>;
get currentNode(): CaseTreeNode;
/**
* Emits a value whenever a new root node Filter is set.
*
* `true` is emitted if the root node was successfully loaded. `false` otherwise.
*
* On subscription emits the last emitted value (if any) to the subscriber.
*/
get treeRootLoaded$(): Observable<boolean>;
protected get _currentCase(): Case | undefined;
/**
* @returns an `Observable` of the {@link LoadingEmitter} representing the loading state of the root node.
* Returns `undefined` if the tree has not yet been initialized.
*
* Wait for an emission on the [treeRootLoaded$]{@link CaseTreeService#treeRootLoaded$} stream before getting this Observable.
*
* The first value emitted by the Observable is `false`, when the tree finishes initializing.
*/
get rootNodeLoading$(): Observable<boolean> | undefined;
/**
* @returns an `Observable` of the {@link LoadingEmitter} representing whether the root node is currently
* in the process of adding a new child node or not.
* Returns `undefined` if the tree has not yet been initialized.
*
* Wait for an emission on the [treeRootLoaded$]{@link CaseTreeService#treeRootLoaded$} stream before getting this Observable.
*
* The first value emitted by the Observable is `false`, when the tree finishes initializing.
*/
get rootNodeAddingChild$(): Observable<boolean> | undefined;
/**
* Weather the tree is eager loaded or not.
*
* Defaults to `false`.
*
* It is not recommended to eager load large trees as each node sends a separate backend request to load its data.
*/
get isEagerLoaded(): boolean;
/**
* Weather the tree is eager loaded or not.
*
* Defaults to `false`.
*
* It is not recommended to eager load large trees as each node sends a separate backend request to load its data.
*
* @param eager the new setting for eager loading
*/
set isEagerLoaded(eager: boolean);
/**
* Loads and populates the topmost level of the tree.
*
* The displayed cases are determined by this object's [rootFilter]{@link CaseTreeService#rootFilter}.
*
* Cases are loaded one page at a time and the tree is refreshed after each page.
* [finishedLoadingFirstLevel$]{@link CaseTreeService#treeRootLoaded$}
* will emit `true` once the last page loads successfully.
* `false` will be emitted if any of the requests fail.
*/
protected loadTreeRoot(): void;
/**
* Adds the loaded tree root to the display based on the setting.
* @param showRoot whether the root of the tree should be displayed in the tree or not.
* If the root is not displayed it's children will be displayed on the first level.
* @returns an Observable that emits when the tree finishes initialization.
*/
initializeTree(showRoot: boolean): Observable<void>;
/**
* Notifies the parent TreeCaseView that a case was clicked in the tree and it's Task should be displayed
*/
changeActiveNode(node: CaseTreeNode | undefined): void;
/**
* Toggles the expansion state of a node
* @param node the {@link CaseTreeNode} who's content should be toggled
*/
toggleNode(node: CaseTreeNode): void;
/**
* Expands the target node in the tree and reloads it's children if they are marked as dirty
* @param node the {@link CaseTreeNode} that should be expanded
* @returns emits `true` if the node is expanded and `false` if not. If the expansion causes more node expansions
* (e.g. eager loaded tree) then, the Observable emits after all the subtree expansions complete.
*/
protected expandNode(node: CaseTreeNode): Observable<boolean>;
/**
* Checks whether dirty children need to be reloaded and reloads them if needed.
* @param node the {@link CaseTreeNode} who's children are updated
* @returns emits when loading finishes
*/
protected updateNodeChildren(node: CaseTreeNode): Observable<void>;
/**
* Loads every page of children from the given number and updates the existing children.
*
* Missing nodes are removed. Existing nodes are marked as dirty. New nodes are added.
*
* Nodes are returned in their insertion order.
* @param node the {@link CaseTreeNode} who's children are updated
* @param pageNumber the number of the first page that should be loaded. All following pages are loaded as well
* @returns next is emitted when loading of all pages completes (regardless of the outcome)
*/
protected updatePageOfChildren(node: CaseTreeNode, pageNumber: number): Observable<void>;
/**
* Updates the children of the given {@link CaseTreeNode} with [Cases]{@link Case} from the provided {@link Page}.
* @param node the {@link CaseTreeNode} who's children are updated
* @param page the {@link Page} that contains the updated children
*/
protected updateCurrentChildrenWithNewPage(node: CaseTreeNode, page: Page<Case>): void;
/**
* @param node the {@link CaseTreeNode} who's children the {@link Filter} should return
* @returns a request body that finds all child cases of the given `node`.
* Returns `undefined` if the provided `node` doesn't contain enough information to create the request body.
*/
protected createChildRequestBody(node: CaseTreeNode): CaseGetRequestBody;
/**
* Adds a child to the root node.
*
* Useful if you are using the layout where the root node is hidden.
* @returns emits `true` if the child was successfully added, `false` if not
*/
addRootChildNode(): Observable<boolean>;
/**
* Adds a new child node to the given node based on the properties of the node's case
* @returns emits `true` if the child was successfully added, `false` if not
*/
addChildNode(clickedNode: CaseTreeNode): Observable<boolean>;
/**
* Creates a new case and adds it to the children of the specified node
* @param processIdentifier identifier of the process that should be created
* @param clickedNode the node that is the parent of the new case
* @param operationResult the result of the operation will be emitted into this stream when the operation completes
*/
protected createAndAddChildCase(processIdentifier: string, clickedNode: CaseTreeNode, operationResult: Subject<boolean>): void;
/**
* Updates the tree after adding a new child
* @param clickedNode the parent node
* @param newCaseRefValue the new value of the parent node's case ref
* @param operationResult the result of the operation will be emitted into this stream when the operation completes
*/
protected updateTreeAfterChildAdd(clickedNode: CaseTreeNode, newCaseRefValue: Array<string>, operationResult: Subject<boolean>): void;
/**
* removes the provided non-root node if the underlying case allows it.
*
* The underlying case is removed from the case ref of it's parent element with the help from the `remove`
* operation provided by case ref itself.
* @param node the node that should be removed from the tree
*/
removeNode(node: CaseTreeNode): void;
/**
* Expands all nodes in the tree dictated by the argument.
*
* @param path nodes that should be expanded along with their path from the root node
*/
expandPath(path: CaseTreePath): void;
/**
* Transforms a {@Link CaseTreePath} object into an {@link ExpansionTree} object.
* The result has all the common paths merged into single branches of the resulting tree structure.
*
* @param paths nodes that should be expanded along with their path from the root node
* @returns an {@link ExpansionTree} equivalent to the provided {@link CaseTreePath}
*/
protected convertPathToExpansionTree(paths: CaseTreePath): ExpansionTree;
/**
* Recursively expands all nodes from the provided array of nodes, that appear in the top level of the {@link ExpansionTree} object.
*
* @param levelNodes nodes from which the expansion should start
* @param targets a tree structure representing the nodes that are to be expanded recursively.
* The top level nodes are expanded first, from the provided `levelNodes`.
*/
protected expandLevel(levelNodes: Array<CaseTreeNode>, targets: ExpansionTree): void;
/**
* Deletes the subtrees rooted at the nodes that are present in the parent node's child case ref values,
* but are no longer present in the new value
* @param parentNode an inner node of the tree that had some of it's children removed
* @param newCaseRefValue the new value of the parent node's case ref
*/
protected deleteRemovedNodes(parentNode: CaseTreeNode, newCaseRefValue: Array<string>): void;
/**
* Deselects the currently selected node if it is a descendant of the provided node
* @param node the node who's descendants should be deselected
*/
protected deselectNodeIfDescendantOf(node: CaseTreeNode): void;
/**
* Performs a backend call on the given case, and sets the value of the case ref field in the transition defined by
* [CASE_REF_TRANSITION]{@link TreePetriflowIdentifiers#CASE_REF_TRANSITION}.
* @param caseId string ID of the case that should have it's tree case ref set
* @param newCaseRefValue the new value of the case ref field
*/
private performCaseRefCall;
/**
* Performs an update after adding or removing a node from the tree.
*
* If only one node was added adds it into the tree
*
* If only one node was removed removes it from the tree
*
* Otherwise collapses the affected node and marks it's children as dirty
*
* @param affectedNode node that had it's children changed
* @param newCaseRefValue new value of the caseRef field returned by backend
* @returns an `Observable` that emits an object with the [result]{@link ResultWithAfterActions#result} attribute set to `true` if
* the update completes successfully and `false` otherwise.
*/
private updateNodeChildrenFromChangedFields;
/**
* Adds a new child node to the `affectedNode` by adding the last Case from the `newCaseRefValue`
* @param affectedNode the node in the tree that had a child added - the parent node
* @param caseRefField the case ref field of the affected node
* @param newCaseRefValue the new value of the case ref field in the node
* @returns an `Observable` that emits `true` if a node was successfully added, `false` otherwise.
*/
protected processChildNodeAdd(affectedNode: CaseTreeNode, caseRefField: ImmediateData, newCaseRefValue: Array<string>): Observable<ResultWithAfterActions<boolean>>;
/**
* Adds a new child node to the target parent node.
* @param parentNode the nodes whose child should be added
* @param childCase the child case
* @returns the newly added node
*/
protected pushChildToTree(parentNode: CaseTreeNode, childCase: Case): CaseTreeNode;
/**
* Removes the deleted node from the children of the `affectedNode`
* @param affectedNode the node in the tree that had it's child removed
* @param caseRefField the case ref field of the affected node
* @param newCaseRefValues the new value of the case ref field in the node
* @returns an `Observable` that emits `true` when the remove operation completes.
*/
protected processChildNodeRemove(affectedNode: CaseTreeNode, caseRefField: ImmediateData, newCaseRefValues: Set<string>): Observable<ResultWithAfterActions<boolean>>;
/**
* @ignore
* Forces a rerender of the tree content
*/
private refreshTree;
/**
* Reloads the currently selected case node. The {@link Case} object held in the {@link CaseTreeNode} instance is not replaced,
* but the new Case is `Object.assign`-ed into it. This means that the reference to the Case instance is unchanged but references
* to all it's non-primitive attributes are changed.
*
* If a reload of the current node is initiated before the previous one completed, the new one is ignored.
*
* If the currently selected case changed before a response from backend was received the response is ignored.
*
* Note that the parent node, nor the child nodes are reloaded.
*/
protected reloadCurrentCase(): void;
/**
* Determines if anny of the case attributes that are visible on the tree changed.
* @param oldCase the previous version of the Case object, that is currently displayed on the tree
* @param newCase the new version of the Case object, that should replace the old one
*/
private determineCaseUpdate;
static ɵfac: i0.ɵɵFactoryDeclaration<CaseTreeService, [null, null, null, null, null, null, null, { optional: true; }, { optional: true; }]>;
static ɵprov: i0.ɵɵInjectableDeclaration<CaseTreeService>;
}