import { SerializedNode , UrlTemplate , SerializedUrlTemplate , WorkspaceField , GraphWorkspaceSavedObject , SerializedWorkspaceState , IndexPatternSavedObject , AdvancedSettings , GraphData , Workspace , SerializedField , } from '../../types' ; import { outlinkEncoders } from '../../helpers/outlink_encoders' ; import { urlTemplateIconChoicesByClass , getSuitableIcon , colorChoices , iconChoicesByClass , } from '../../helpers/style_choices' ; import { IndexPattern , indexPatterns as indexPatternsUtils , } from '../../../../../../src/plugins/data/public' ; const defaultAdvancedSettings = { useSignificance : true , sampleSize : 2000 , timeoutMillis : 5000 , maxValuesPerDoc : 1 , minDocCount : 3 , } ; function deserializeUrlTemplate ( { encoderID , iconClass , ... serializableProps } ) { const encoder = outlinkEncoders . find ( ( outlinkEncoder ) => outlinkEncoder . id === encoderID ) ; if ( ! encoder ) { return ; } const template = { ... serializableProps , encoder , icon : null , } ; if ( iconClass ) { const iconCandidate = urlTemplateIconChoicesByClass [ iconClass ] ; template . icon = iconCandidate ? iconCandidate : null ; } return template ; } param savedWorkspace param indexPatterns export function migrateLegacyIndexPatternRef ( savedWorkspace , indexPatterns ) { const legacyIndexPatternRef = savedWorkspace . legacyIndexPatternRef ; if ( ! legacyIndexPatternRef ) { return { success : true } ; } const indexPatternId = indexPatterns . find ( ( pattern ) => pattern . attributes . title === legacyIndexPatternRef ) ?. id ; if ( ! indexPatternId ) { return { success : false , missingIndexPattern : legacyIndexPatternRef } ; } const serializedWorkspaceState = JSON . parse ( savedWorkspace . wsState ) ; serializedWorkspaceState . indexPattern = indexPatternId ! ; savedWorkspace . wsState = JSON . stringify ( serializedWorkspaceState ) ; delete savedWorkspace . legacyIndexPatternRef ; return { success : true } ; } export function lookupIndexPatternId ( savedWorkspace ) { const serializedWorkspaceState = JSON . parse ( savedWorkspace . wsState ) ; return serializedWorkspaceState . indexPattern ; } export function mapFields ( indexPattern ) { const blockedFieldNames = [ '_id' , '_index' , '_score' , '_source' , '_type' ] ; const defaultHopSize = 5 ; return indexPattern . getNonScriptedFields ( ) . filter ( ( field ) => field . isMapped && ! blockedFieldNames . includes ( field . name ) && ! indexPatternsUtils . isNestedField ( field ) ) . map ( ( field , index ) => ( { name : field . name , hopSize : defaultHopSize , lastValidHopSize : defaultHopSize , icon : getSuitableIcon ( field . name ) , color : colorChoices [ index % colorChoices . length ] , selected : false , type : field . type , aggregatable : Boolean ( field . aggregatable ) , } ) ) . sort ( ( a , b ) => { if ( a . name < b . name ) { return - 1 ; } else if ( a . name > b . name ) { return 1 ; } return 0 ; } ) ; } function getFieldsWithWorkspaceSettings ( indexPattern , selectedFields ) { const allFields = mapFields ( indexPattern ) ; selectedFields . forEach ( ( serializedField ) => { const workspaceField = allFields . find ( ( field ) => field . name === serializedField . name ) ; if ( ! workspaceField ) { return ; } workspaceField . hopSize = serializedField . hopSize ; workspaceField . lastValidHopSize = serializedField . lastValidHopSize ; workspaceField . color = serializedField . color ; workspaceField . icon = iconChoicesByClass [ serializedField . iconClass ] ! ; workspaceField . selected = true ; } ) ; return allFields ; } function getBlocklistedNodes ( serializedWorkspaceState , allFields ) { return serializedWorkspaceState . blocklist . map ( ( serializedNode ) => { const currentField = allFields . find ( ( field ) => field . name === serializedNode . field ) ! ; return { x : 0 , y : 0 , label : serializedNode . label , color : serializedNode . color , icon : currentField . icon , parent : null , scaledSize : 0 , data : { field : serializedNode . field , term : serializedNode . term , } , } ; } ) ; } function resolveGroups ( nodes , workspaceInstance ) { nodes . forEach ( ( { field , term , x , y , parent } ) => { const nodeId = makeNodeId ( field , term ) ; const workspaceNode = workspaceInstance . nodesMap [ nodeId ] ; workspaceNode . x = x ; workspaceNode . y = y ; if ( parent !== null ) { const { field : parentField , term : parentTerm } = nodes [ parent ] ; const parentId = makeNodeId ( parentField , parentTerm ) ; workspaceNode . parent = workspaceInstance . nodesMap [ parentId ] ; } } ) ; } function getNodesAndEdges ( persistedWorkspaceState , allFields ) { return { nodes : persistedWorkspaceState . vertices . map ( ( serializedNode ) => ( { ... serializedNode , id : '' , icon : allFields . find ( ( field ) => field . name === serializedNode . field ) ! . icon , data : { field : serializedNode . field , term : serializedNode . term , } , } ) ) , edges : persistedWorkspaceState . links . map ( ( serializedEdge ) => ( { ... serializedEdge , id : '' , } ) ) , } ; } export function makeNodeId ( field , term ) { return field + '..' + term ; } export function savedWorkspaceToAppState ( savedWorkspace , indexPattern , workspaceInstance ) { const persistedWorkspaceState = JSON . parse ( savedWorkspace . wsState ) ; const urlTemplates = persistedWorkspaceState . urlTemplates . map ( deserializeUrlTemplate ) . filter ( ( template ) : template is UrlTemplate => Boolean ( template ) ) ; const allFields = getFieldsWithWorkspaceSettings ( indexPattern , persistedWorkspaceState . selectedFields ) ; const selectedFields = allFields . filter ( ( field ) => field . selected ) ; workspaceInstance . options . vertex_fields = selectedFields ; const advancedSettings = Object . assign ( { } , defaultAdvancedSettings , persistedWorkspaceState . exploreControls ) ; if ( advancedSettings . sampleDiversityField ) { const serializedField = advancedSettings . sampleDiversityField ; advancedSettings . sampleDiversityField = allFields . find ( ( field ) => field . name === serializedField . name ) ; } workspaceInstance . options . exploreControls = advancedSettings ; const graph = getNodesAndEdges ( persistedWorkspaceState , allFields ) ; workspaceInstance . mergeGraph ( graph ) ; resolveGroups ( persistedWorkspaceState . vertices , workspaceInstance ) ; const blocklistedNodes = getBlocklistedNodes ( persistedWorkspaceState , allFields ) ; workspaceInstance . blocklistedNodes . push ( ... blocklistedNodes ) ; return { urlTemplates , advancedSettings , allFields , } ; }