import { action , makeObservable } from 'mobx' ; import { injectable } from '@cloudbeaver/core-di' ; import { GraphQLService , CachedMapResource , ResourceKey , isResourceKeyList , NavNodeInfoFragment , ResourceKeyUtils , ICachedMapResourceMetadata , ResourceKeyList , resourceKeyList } from '@cloudbeaver/core-sdk' ; import { MetadataMap } from '@cloudbeaver/core-utils' ; import type { NavNode } from './EntityTypes' ; type NavNodeInfo = NavNodeInfoFragment ; export const ROOT_NODE_PATH = '' ; interface INodeMetadata extends ICachedMapResourceMetadata { withDetails : boolean ; } @ injectable ( ) export class NavNodeInfoResource extends CachedMapResource < string , NavNode > { protected metadata : MetadataMap < string , INodeMetadata > ; constructor ( private graphQLService ) { super ( ) ; makeObservable ( this , { setDetails : action , } ) ; this . metadata = new MetadataMap < string , INodeMetadata > ( ( ) => ( { outdated : true , loading : false , withDetails : false , exception : null , includes : [ ] , } ) ) ; } updateNode ( key , node ) ; updateNode ( key , nodes ) ; updateNode ( key , nodes ) ; updateNode ( key , nodes ) { const keyList = [ ] ; const values = [ ] ; ResourceKeyUtils . forEach ( key , ( key , i ) => { const value = i === - 1 ? ( nodes as NavNode ) : ( nodes as NavNode [ ] ) [ i ] ; const currentValue = this . get ( key ) ; if ( currentValue && value ) { Object . assign ( currentValue , value ) ; } else { keyList . push ( key ) ; values . push ( value ) ; } } ) ; if ( keyList . length > 0 ) { this . set ( resourceKeyList ( keyList ) , values ) ; } else { this . markUpdated ( key ) ; this . onItemAdd . execute ( key ) ; } } setDetails ( keyObject , state ) { ResourceKeyUtils . forEach ( keyObject , key => { const metadata = this . metadata . get ( key ) ; if ( metadata . withDetails !== state ) { metadata . outdated = true ; } metadata . withDetails = state ; } ) ; } setParent ( key , parentId ) ; setParent ( key , parentId ) ; setParent ( key , parentId ) ; setParent ( key , parentId ) { ResourceKeyUtils . forEach ( key , key => { const node = this . get ( key ) ; if ( node ) { node . parentId = parentId ; } } ) ; } protected async loader ( key ) { if ( isResourceKeyList ( key ) ) { const values = [ ] ; for ( const nodePath of key . list ) { values . push ( await this . loadNodeInfo ( nodePath ) ) ; } this . set ( key , values ) ; } else { this . set ( key , await this . loadNodeInfo ( key ) ) ; } return this . data ; } navNodeInfoToNavNode ( node , parentId ? ) { return { ... node , objectFeatures : node . object ?. features || [ ] , parentId : parentId || this . get ( node . id ) ?. parentId || ROOT_NODE_PATH , } ; } private async loadNodeInfo ( nodePath ) { const metadata = this . metadata . get ( nodePath ) ; const { navNodeInfo } = await this . graphQLService . sdk . navNodeInfo ( { nodePath , withDetails : metadata . withDetails , } ) ; return this . navNodeInfoToNavNode ( navNodeInfo ) ; } } export function getNodeName ( node ) { return `${ node . nodeType || 'Object' }${ node . name ? ' (' + node . name + ')' : '' }` ; }