You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2022/07/21 12:08:04 UTC

[brooklyn-ui] branch master updated: fix bug with member spec flag not working in composer

This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-ui.git


The following commit(s) were added to refs/heads/master by this push:
     new 55b94d74 fix bug with member spec flag not working in composer
55b94d74 is described below

commit 55b94d74e374cd53ba2da2fb2194c8ddd1e1cb50
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Thu Jul 21 13:02:54 2022 +0100

    fix bug with member spec flag not working in composer
    
    and better handle errors
---
 .../app/components/util/d3-blueprint.js            | 28 +++++++++++++++-------
 .../app/components/util/model/entity.model.js      | 12 ++++++++--
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/ui-modules/blueprint-composer/app/components/util/d3-blueprint.js b/ui-modules/blueprint-composer/app/components/util/d3-blueprint.js
index 9a22a7c1..35593175 100755
--- a/ui-modules/blueprint-composer/app/components/util/d3-blueprint.js
+++ b/ui-modules/blueprint-composer/app/components/util/d3-blueprint.js
@@ -803,13 +803,14 @@ export function D3Blueprint(container, options) {
      */
     function nodeForEntity(entity) {
         let node = _d3DataHolder.nodes.find(d => {
-            let predicate = d.data._id === entity._id;
-            if (!!d.data.getClusterMemberspecEntity(PREDICATE_MEMBERSPEC)) {
-                predicate |= d.data.getClusterMemberspecEntity(PREDICATE_MEMBERSPEC)._id === entity._id;
+            if (d.data._id === entity._id) return true;
+            for (let child of Object.values(d.data.getClusterMemberspecEntities() || {})) {
+                if (child._id === entity._id) return true;
             }
-            return predicate;
+            return false;
         });
         if (!node) {
+            console.log("Cannot find", entity._id, _d3DataHolder.nodes.map(n => n.data._id));
             throw new Error('Node for Entity ' + entity._id + ' not found');
         }
         return node;
@@ -894,13 +895,13 @@ export function D3Blueprint(container, options) {
             .duration(_configHolder.transition)
             .attr('opacity', 1)
             .attr('stroke', 'red')
-            .attr('d', function(d) {
+            .attr('d', d => safe(() => {
                 const [x1,y1, dr, sweep, x2, y2, isLeftToRight] = getArcTransitionParameters(d);
 
                 d.isLeftToRight = isLeftToRight;
 
                 return `M ${x1},${y1} A ${dr},${dr} 0 0,${sweep} ${x2},${y2}`;
-            });
+            }, ()=>'', d));
 
         relationArcs.exit()
             .transition()
@@ -969,7 +970,7 @@ export function D3Blueprint(container, options) {
             .attr('startOffset', '59%') // 59% roughly reflects `middle of the arch` minus `node radius`.
             .insert('tspan')
             .attr('dy', getLabelOffset)
-            .html((d) => ('&#9608;'.repeat(getLabelText(d).length + 2))); // +2 spaces for padding
+            .html((d) => safe( () => ('&#9608;'.repeat(getLabelText(d).length + 2)), () => '', d)) // +2 spaces for padding
 
         relationLabelsEntered.insert('text') // Add label text on top of '&#9608;'s which is on top of the path.
             .attr('class', _configHolder.nodes.relationship.labelClass)
@@ -984,7 +985,7 @@ export function D3Blueprint(container, options) {
             .attr('startOffset', '59%') // 59% roughly reflects `middle of the arch` minus `node radius`.
             .insert('tspan')
             .attr('dy', getLabelOffset)
-            .attr('rotate', (d) => isLeftToRight(d) ? '0' : '180') // rotate text if arc goes as right-to-left
+            .attr('rotate', (d) => safe(()=>isLeftToRight(d) ? '0' : '180', () => '0', d)) // rotate text if arc goes as right-to-left
             .style('z-index', 9)
             .on('mouseover', d => {
                 if (d.labels.length > _configHolder.nodes.relationship.labelsToDisplay) {
@@ -999,7 +1000,16 @@ export function D3Blueprint(container, options) {
             .on('mouseout', () => {
                 _canvasTooltip.style('visibility', 'hidden');
             })
-            .html(getLabelText);
+            .html(d => safe(()=>getLabelText(d), ()=>'?', d));
+    }
+
+    function safe(main, recovery, context) {
+        try {
+            return main();
+        } catch (e) {
+            console.log("Error drawing", context || "", e);
+            return recovery();
+        }
     }
 
     function drawGhostNode() {
diff --git a/ui-modules/blueprint-composer/app/components/util/model/entity.model.js b/ui-modules/blueprint-composer/app/components/util/model/entity.model.js
index 7fd80c96..22e9d4a7 100644
--- a/ui-modules/blueprint-composer/app/components/util/model/entity.model.js
+++ b/ui-modules/blueprint-composer/app/components/util/model/entity.model.js
@@ -907,6 +907,14 @@ export function baseType(s) {
     return s;
 }
 
+function isDefinitelyEntitySpec(basetype) {
+    return basetype === EntityFamily.SPEC.superType;
+}
+
+function isPossiblyEntitySpec(basetype) {
+    return isDefinitelyEntitySpec(basetype) || basetype === 'java.lang.Object';
+}
+
 /**
  * Returns a map of <configkey> => Entity of all spec {Entity} defined in the configuration
  * @returns {*}
@@ -916,7 +924,7 @@ function getClusterMemberspecEntities() {
         return {};
     }
     return MISC_DATA.get(this).get('config')
-        .filter((config)=>{const t = baseType(config.type); return t === EntityFamily.SPEC.superType || t === 'java.lang.Object';})
+        .filter((config)=>isPossiblyEntitySpec(baseType(config.type)))
         .reduce((acc, config)=> {
             if (CONFIG.get(this).has(config.name)) {
                 const val = CONFIG.get(this).get(config.name)[DSL.ENTITY_SPEC];
@@ -938,7 +946,7 @@ function getClusterMemberspecEntity(predicate = ()=>(true)) {
     }
 
     return MISC_DATA.get(this).get('config')
-        .filter((config)=>(baseType(config.type) === EntityFamily.SPEC.superType))
+        .filter((config)=>isPossiblyEntitySpec(baseType(config.type)))
         .reduce((acc, config)=> {
             if (CONFIG.get(this).has(config.name)) {
                 let entityV = CONFIG.get(this).get(config.name)[DSL.ENTITY_SPEC];