import { LoadNextLevelEvent , MenuItemSelectedEvent , NodeCheckedEvent , NodeCollapsedEvent , NodeCreatedEvent , NodeExpandedEvent , NodeIndeterminedEvent , NodeMovedEvent , NodeRemovedEvent , NodeRenamedEvent , NodeSelectedEvent , NodeUncheckedEvent , NodeUnselectedEvent , NodeHoveredEvent } from './tree.events' ; import { RenamableNode } from './tree.types' ; import { Tree } from './tree' ; import { TreeController } from './tree-controller' ; import { Observable } from 'rxjs/Observable' ; import { Subject } from 'rxjs/Subject' ; import { ElementRef , Inject , Injectable } from '@angular/core' ; import { NodeDraggableService } from './draggable/node-draggable.service' ; import { NodeDraggableEvent } from './draggable/draggable.events' ; import { isEmpty } from './utils/fn.utils' ; @ Injectable ( ) export class TreeService { public nodeMoved$ : Subject < NodeMovedEvent > = new Subject < NodeMovedEvent > ( ) ; public nodeRemoved$ : Subject < NodeRemovedEvent > = new Subject < NodeRemovedEvent > ( ) ; public nodeRenamed$ : Subject < NodeRenamedEvent > = new Subject < NodeRenamedEvent > ( ) ; public nodeCreated$ : Subject < NodeCreatedEvent > = new Subject < NodeCreatedEvent > ( ) ; public nodeSelected$ : Subject < NodeSelectedEvent > = new Subject < NodeSelectedEvent > ( ) ; public nodeHovered$ : Subject < NodeHoveredEvent > = new Subject < NodeHoveredEvent > ( ) ; public nodeUnselected$ : Subject < NodeUnselectedEvent > = new Subject < NodeUnselectedEvent > ( ) ; public nodeExpanded$ : Subject < NodeExpandedEvent > = new Subject < NodeExpandedEvent > ( ) ; public nodeCollapsed$ : Subject < NodeCollapsedEvent > = new Subject < NodeCollapsedEvent > ( ) ; public menuItemSelected$ : Subject < MenuItemSelectedEvent > = new Subject < MenuItemSelectedEvent > ( ) ; public loadNextLevel$ : Subject < LoadNextLevelEvent > = new Subject < LoadNextLevelEvent > ( ) ; public nodeChecked$ : Subject < NodeCheckedEvent > = new Subject < NodeCheckedEvent > ( ) ; public nodeUnchecked$ : Subject < NodeUncheckedEvent > = new Subject < NodeUncheckedEvent > ( ) ; public nodeIndetermined$ : Subject < NodeIndeterminedEvent > = new Subject < NodeIndeterminedEvent > ( ) ; private controllers : Map < string | number , TreeController > = new Map ( ) ; public constructor ( @ Inject ( NodeDraggableService ) private nodeDraggableService ) { this . nodeRemoved$ . subscribe ( ( e ) => e . node . removeItselfFromParent ( ) ) ; } public unselectStream ( tree ) { return this . nodeSelected$ . filter ( ( e ) => tree !== e . node ) ; } public fireNodeRemoved ( tree ) { this . nodeRemoved$ . next ( new NodeRemovedEvent ( tree , tree . positionInParent ) ) ; } public fireNodeCreated ( tree ) { this . nodeCreated$ . next ( new NodeCreatedEvent ( tree ) ) ; } public fireNodeSelected ( tree ) { this . nodeSelected$ . next ( new NodeSelectedEvent ( tree ) ) ; } public fireNodeHovered ( tree ) { this . nodeHovered$ . next ( new NodeHoveredEvent ( tree ) ) ; } public fireNodeUnselected ( tree ) { this . nodeUnselected$ . next ( new NodeUnselectedEvent ( tree ) ) ; } public fireNodeRenamed ( oldValue , tree ) { this . nodeRenamed$ . next ( new NodeRenamedEvent ( tree , oldValue , tree . value ) ) ; } public fireNodeMoved ( tree , parent ) { this . nodeMoved$ . next ( new NodeMovedEvent ( tree , parent ) ) ; } public fireMenuItemSelected ( tree , selectedItem ) { this . menuItemSelected$ . next ( new MenuItemSelectedEvent ( tree , selectedItem ) ) ; } public fireNodeSwitchFoldingType ( tree ) { if ( tree . isNodeExpanded ( ) ) { this . fireNodeExpanded ( tree ) ; if ( this . shouldFireLoadNextLevel ( tree ) ) { this . fireLoadNextLevel ( tree ) ; } } else if ( tree . isNodeCollapsed ( ) ) { this . fireNodeCollapsed ( tree ) ; } } private fireNodeExpanded ( tree ) { this . nodeExpanded$ . next ( new NodeExpandedEvent ( tree ) ) ; } private fireNodeCollapsed ( tree ) { this . nodeCollapsed$ . next ( new NodeCollapsedEvent ( tree ) ) ; } private fireLoadNextLevel ( tree ) { this . loadNextLevel$ . next ( new LoadNextLevelEvent ( tree ) ) ; } public fireNodeChecked ( tree ) { this . nodeChecked$ . next ( new NodeCheckedEvent ( tree ) ) ; } public fireNodeUnchecked ( tree ) { this . nodeUnchecked$ . next ( new NodeUncheckedEvent ( tree ) ) ; } public draggedStream ( tree , element ) { return this . nodeDraggableService . draggableNodeEvents$ . filter ( ( e ) => e . target === element ) . filter ( ( e ) => ! e . captured . tree . hasChild ( tree ) ) ; } public setController ( id , controller ) { this . controllers . set ( id , controller ) ; } public deleteController ( id ) { if ( this . controllers . has ( id ) ) { this . controllers . delete ( id ) ; } } public getController ( id ) { if ( this . controllers . has ( id ) ) { return this . controllers . get ( id ) ; } return null ; } public hasController ( id ) { return this . controllers . has ( id ) ; } private shouldFireLoadNextLevel ( tree ) { const shouldLoadNextLevel = tree . node . emitLoadNextLevel && ! tree . node . loadChildren && ! tree . childrenAreBeingLoaded ( ) && isEmpty ( tree . children ) ; if ( shouldLoadNextLevel ) { tree . loadingChildrenRequested ( ) ; } return shouldLoadNextLevel ; } public fireNodeIndetermined ( tree ) { this . nodeIndetermined$ . next ( new NodeIndeterminedEvent ( tree ) ) ; } }