2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								import  server  from  "./server.js" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  utils  from  "./utils.js" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  messagingService  from  "./messaging.js" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  treeUtils  from  "./tree_utils.js" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  noteAutocompleteService  from  "./note_autocomplete.js" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  linkService  from  "./link.js" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  noteDetailService  from  "./note_detail.js" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  $attributeList  =  $ ( "#attribute-list" ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  $attributeListInner  =  $ ( "#attribute-list-inner" ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  $promotedAttributesContainer  =  $ ( "#note-detail-promoted-attributes" ) ;  
						 
					
						
							
								
									
										
										
										
											2018-11-30 17:18:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  $savedIndicator  =  $ ( "#saved-indicator" ) ;  
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								let  attributePromise ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-24 23:08:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  invalidateAttributes ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    attributePromise  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function  reloadAttributes ( )  {  
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    attributePromise  =  server . get ( 'notes/'  +  noteDetailService . getCurrentNoteId ( )  +  '/attributes' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-24 23:08:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								async  function  refreshAttributes ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    reloadAttributes ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    await  showAttributes ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								async  function  getAttributes ( )  {  
						 
					
						
							
								
									
										
										
										
											2018-12-24 23:08:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! attributePromise )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        reloadAttributes ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  await  attributePromise ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								async  function  showAttributes ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    $promotedAttributesContainer . empty ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 22:14:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    $attributeList . hide ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    $attributeListInner . empty ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 19:25:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  note  =  noteDetailService . getCurrentNote ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  attributes  =  await  attributePromise ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  promoted  =  attributes . filter ( attr  => 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ( attr . type  ===  'label-definition'  ||  attr . type  ===  'relation-definition' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        &&  ! attr . name . startsWith ( "child:" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        &&  attr . value . isPromoted ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 22:14:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  hidePromotedAttributes  =  attributes . some ( attr  =>  attr . type  ===  'label'  &&  attr . name  ===  'hidePromotedAttributes' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( promoted . length  >  0  &&  ! hidePromotedAttributes )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        const  $tbody  =  $ ( "<tbody>" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( const  definitionAttr  of  promoted )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  definitionType  =  definitionAttr . type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  valueType  =  definitionType . substr ( 0 ,  definitionType . length  -  11 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            let  valueAttrs  =  attributes . filter ( el  =>  el . name  ===  definitionAttr . name  &&  el . type  ===  valueType ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( valueAttrs . length  ===  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                valueAttrs . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    attributeId :  "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    type :  valueType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    name :  definitionAttr . name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    value :  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( definitionAttr . value . multiplicityType  ===  'singlevalue' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                valueAttrs  =  valueAttrs . slice ( 0 ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( const  valueAttr  of  valueAttrs )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 19:25:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                const  $tr  =  await  createPromotedAttributeRow ( definitionAttr ,  valueAttr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $tbody . append ( $tr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // we replace the whole content in one step so there can't be any race conditions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // (previously we saw promoted attributes doubling)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $promotedAttributesContainer . empty ( ) . append ( $tbody ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 19:25:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( note . type  !==  'relation-map' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-01 15:29:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // display only "own" notes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  ownedAttributes  =  attributes . filter ( attr  =>  attr . noteId  ===  note . noteId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ownedAttributes . length  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( const  attribute  of  ownedAttributes )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                if  ( attribute . type  ===  'label' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    $attributeListInner . append ( utils . formatLabel ( attribute )  +  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else  if  ( attribute . type  ===  'relation' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( attribute . value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        $attributeListInner . append ( '@'  +  attribute . name  +  "=" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        $attributeListInner . append ( await  linkService . createNoteLink ( attribute . value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        $attributeListInner . append ( " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        messagingService . logError ( ` Relation  ${ attribute . attributeId }  has empty target ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else  if  ( attribute . type  ===  'label-definition'  ||  attribute . type  ===  'relation-definition' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    $attributeListInner . append ( attribute . name  +  " definition " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    messagingService . logError ( "Unknown attr type: "  +  attribute . type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $attributeList . show ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  attributes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 19:25:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								async  function  createPromotedAttributeRow ( definitionAttr ,  valueAttr )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  definition  =  definitionAttr . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  $tr  =  $ ( "<tr>" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  $labelCell  =  $ ( "<th>" ) . append ( valueAttr . name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  $input  =  $ ( "<input>" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . prop ( "tabindex" ,  definitionAttr . position ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . prop ( "attribute-id" ,  valueAttr . isOwned  ?  valueAttr . attributeId  :  '' )  // if not owned, we'll force creation of a new attribute instead of updating the inherited one
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . prop ( "attribute-type" ,  valueAttr . type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . prop ( "attribute-name" ,  valueAttr . name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . prop ( "value" ,  valueAttr . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . addClass ( "form-control" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . addClass ( "promoted-attribute-input" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . change ( promotedAttributeChanged ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  $inputCell  =  $ ( "<td>" ) . append ( $ ( "<div>" ) . addClass ( "input-group" ) . append ( $input ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  $actionCell  =  $ ( "<td>" ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-01 20:53:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  $multiplicityCell  =  $ ( "<td>" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . addClass ( "multiplicity" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . attr ( "nowrap" ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 19:25:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    $tr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . append ( $labelCell ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . append ( $inputCell ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . append ( $actionCell ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . append ( $multiplicityCell ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( valueAttr . type  ===  'label' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( definition . labelType  ===  'text' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $input . prop ( "type" ,  "text" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // no need to await for this, can be done asynchronously
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            server . get ( 'attributes/values/'  +  encodeURIComponent ( valueAttr . name ) ) . then ( attributeValues  =>  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( attributeValues . length  ===  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                attributeValues  =  attributeValues . map ( attribute  =>  {  return  {  value :  attribute  } ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $input . autocomplete ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    appendTo :  document . querySelector ( 'body' ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    hint :  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    autoselect :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    openOnFocus :  true , 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-27 13:13:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    minLength :  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    tabAutocomplete :  false 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 19:25:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } ,  [ { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    displayKey :  'value' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    source :  function  ( term ,  cb )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        term  =  term . toLowerCase ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        const  filtered  =  attributeValues . filter ( attr  =>  attr . value . toLowerCase ( ) . includes ( term ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        cb ( filtered ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  if  ( definition . labelType  ===  'number' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $input . prop ( "type" ,  "number" ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-30 17:36:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            let  step  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( let  i  =  0 ;  i  <  ( definition . numberPrecision  ||  0 )  &&  i  <  10 ;  i ++ )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                step  /=  10 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $input . prop ( "step" ,  step ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 19:25:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  if  ( definition . labelType  ===  'boolean' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $input . prop ( "type" ,  "checkbox" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( valueAttr . value  ===  "true" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $input . prop ( "checked" ,  "checked" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  if  ( definition . labelType  ===  'date' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $input . prop ( "type" ,  "date" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  if  ( definition . labelType  ===  'url' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $input . prop ( "placeholder" ,  "http://website..." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-14 11:24:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  $openButton  =  $ ( "<span>" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                . addClass ( "input-group-text open-external-link-button jam jam-arrow-up-right" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                . prop ( "title" ,  "Open external link" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                . click ( ( )  =>  window . open ( $input . val ( ) ,  '_blank' ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 19:25:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-14 11:24:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            $input . after ( $ ( "<div>" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                . addClass ( "input-group-append" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                . append ( $openButton ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 19:25:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            messagingService . logError ( "Unknown labelType="  +  definitionAttr . labelType ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( valueAttr . type  ===  'relation' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( valueAttr . value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $input . val ( await  treeUtils . getNoteTitle ( valueAttr . value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // no need to wait for this
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        noteAutocompleteService . initNoteAutocomplete ( $input ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $input . on ( 'autocomplete:selected' ,  function ( event ,  suggestion ,  dataset )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            promotedAttributeChanged ( event ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-14 00:05:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        $input . setSelectedPath ( valueAttr . value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 19:25:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        messagingService . logError ( "Unknown attribute type="  +  valueAttr . type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( definition . multiplicityType  ===  "multivalue" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  addButton  =  $ ( "<span>" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . addClass ( "jam jam-plus pointer" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . prop ( "title" ,  "Add new attribute" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . click ( async  ( )  =>  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  $new  =  await  createPromotedAttributeRow ( definitionAttr ,  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    attributeId :  "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    type :  valueAttr . type , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    name :  definitionAttr . name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    value :  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $tr . after ( $new ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $new . find ( 'input' ) . focus ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  removeButton  =  $ ( "<span>" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-14 11:24:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            . addClass ( "jam jam-trash-alt pointer" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 19:25:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            . prop ( "title" ,  "Remove this attribute" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . click ( async  ( )  =>  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( valueAttr . attributeId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    await  server . remove ( "notes/"  +  noteId  +  "/attributes/"  +  valueAttr . attributeId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $tr . remove ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-14 11:24:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        $multiplicityCell . append ( addButton ) . append ( "  " ) . append ( removeButton ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 19:25:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  $tr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								async  function  promotedAttributeChanged ( event )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  $attr  =  $ ( event . target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    let  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( $attr . prop ( "type" )  ===  "checkbox" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        value  =  $attr . is ( ':checked' )  ?  "true"  :  "false" ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( $attr . prop ( "attribute-type" )  ===  "relation" )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-12 23:34:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  selectedPath  =  $attr . getSelectedPath ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-12 23:34:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        value  =  selectedPath  ?  treeUtils . getNoteIdFromNotePath ( selectedPath )  :  "" ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        value  =  $attr . val ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  result  =  await  server . put ( "notes/"  +  noteDetailService . getCurrentNoteId ( )  +  "/attribute" ,  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        attributeId :  $attr . prop ( "attribute-id" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        type :  $attr . prop ( "attribute-type" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        name :  $attr . prop ( "attribute-name" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        value :  value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    $attr . prop ( "attribute-id" ,  result . attributeId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-30 17:18:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // animate only if it's not being animated already, this is important especially for e.g. number inputs
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // which can be changed many times in a second by clicking on higher/lower buttons.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( $savedIndicator . queue ( ) . length  ===  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $savedIndicator . fadeOut ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $savedIndicator . fadeIn ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								export  default  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    getAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    showAttributes , 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-24 23:08:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    refreshAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    invalidateAttributes 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:01:25 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}