@ -26,9 +26,9 @@ async function getAttributes() {
async function showAttributes ( ) {
async function showAttributes ( ) {
$promotedAttributesContainer . empty ( ) ;
$promotedAttributesContainer . empty ( ) ;
$attributeList . hide ( ) ;
$attributeList . hide ( ) .empty ( ) ;
const note Id = noteDetailService . getCurrentNote Id ( ) ;
const note = noteDetailService . getCurrentNote ( ) ;
const attributes = await attributePromise ;
const attributes = await attributePromise ;
@ -37,15 +37,75 @@ async function showAttributes() {
&& ! attr . name . startsWith ( "child:" )
&& ! attr . name . startsWith ( "child:" )
&& attr . value . isPromoted ) ;
&& attr . value . isPromoted ) ;
let idx = 1 ;
if ( promoted . length > 0 ) {
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 ) {
const $tr = await createPromotedAttributeRow ( definitionAttr , valueAttr ) ;
$tbody . append ( $tr ) ;
}
}
async function createRow ( definitionAttr , valueAttr ) {
// 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 ) ;
}
else if ( note . type !== 'relation-map' ) {
if ( attributes . length > 0 ) {
for ( const attribute of attributes ) {
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 ;
}
async function createPromotedAttributeRow ( definitionAttr , valueAttr ) {
const definition = definitionAttr . value ;
const definition = definitionAttr . value ;
const inputId = "promoted-input-" + idx ;
const $tr = $ ( "<tr>" ) ;
const $tr = $ ( "<tr>" ) ;
const $labelCell = $ ( "<th>" ) . append ( valueAttr . name ) ;
const $labelCell = $ ( "<th>" ) . append ( valueAttr . name ) ;
const $input = $ ( "<input>" )
const $input = $ ( "<input>" )
. prop ( "id" , inputId )
. prop ( "tabindex" , definitionAttr . position )
. 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-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-type" , valueAttr . type )
@ -55,8 +115,6 @@ async function showAttributes() {
. addClass ( "promoted-attribute-input" )
. addClass ( "promoted-attribute-input" )
. change ( promotedAttributeChanged ) ;
. change ( promotedAttributeChanged ) ;
idx ++ ;
const $inputCell = $ ( "<td>" ) . append ( $ ( "<div>" ) . addClass ( "input-group" ) . append ( $input ) ) ;
const $inputCell = $ ( "<td>" ) . append ( $ ( "<div>" ) . addClass ( "input-group" ) . append ( $input ) ) ;
const $actionCell = $ ( "<td>" ) ;
const $actionCell = $ ( "<td>" ) ;
@ -170,7 +228,7 @@ async function showAttributes() {
. addClass ( "jam jam-plus pointer" )
. addClass ( "jam jam-plus pointer" )
. prop ( "title" , "Add new attribute" )
. prop ( "title" , "Add new attribute" )
. click ( async ( ) => {
. click ( async ( ) => {
const $new = await crea teRow( definitionAttr , {
const $new = await crea tePromotedAttribu teRow( definitionAttr , {
attributeId : "" ,
attributeId : "" ,
type : valueAttr . type ,
type : valueAttr . type ,
name : definitionAttr . name ,
name : definitionAttr . name ,
@ -199,72 +257,6 @@ async function showAttributes() {
return $tr ;
return $tr ;
}
}
if ( promoted . length > 0 ) {
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 ) {
const $tr = await createRow ( definitionAttr , valueAttr ) ;
$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 ) ;
}
else {
$attributeListInner . empty ( ) ;
if ( attributes . length > 0 ) {
for ( const attribute of attributes ) {
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 ;
}
async function promotedAttributeChanged ( event ) {
async function promotedAttributeChanged ( event ) {
const $attr = $ ( event . target ) ;
const $attr = $ ( event . target ) ;