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 2021/05/03 08:27:17 UTC

[brooklyn-ui] branch master updated (6951421 -> 6242e55)

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

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


    from 6951421  Merge branch 'quick-fixes'
     new 9cecc37  Display node hierarchy in App Inspector based on known relationships in the node tree
     new 143eb61  Dimm entity name on view mode change instead of background colour of the node
     new 13567b3  Highlight the view switch button if parent/child view is not selected
     new 087248e  Add docs for relationship view logic
     new 8e475be  Support child/parent flip when parent is hosted under child in 'host_for/hosted_on' relationship
     new d954019  Highlight changed relationships in a switched view
     new 0b7d438  Do not highlight nodes in 'parent/child' view; tidy up docs
     new 6242e55  This closes #199

The 8 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../app/components/entity-tree/entity-node.html    |  22 +-
 .../app/components/entity-tree/entity-node.less    |  37 +++
 .../entity-tree/entity-tree.directive.js           | 305 ++++++++++++++++++++-
 .../app/components/entity-tree/entity-tree.html    |   2 +-
 .../app/views/main/main.controller.js              |  20 ++
 ui-modules/app-inspector/app/views/main/main.less  |   7 +
 .../app/views/main/main.template.html              |  16 +-
 7 files changed, 401 insertions(+), 8 deletions(-)

[brooklyn-ui] 01/08: Display node hierarchy in App Inspector based on known relationships in the node tree

Posted by he...@apache.org.
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

commit 9cecc3748d72c7b7272467d789238d62b921b3d0
Author: Mykola Mandra <my...@cloudsoftcorp.com>
AuthorDate: Mon Apr 26 12:42:05 2021 +0100

    Display node hierarchy in App Inspector based on known relationships in the node tree
    
    Signed-off-by: Mykola Mandra <my...@cloudsoftcorp.com>
---
 .../app/components/entity-tree/entity-node.html    |  14 +-
 .../app/components/entity-tree/entity-node.less    |   3 +
 .../entity-tree/entity-tree.directive.js           | 185 ++++++++++++++++++++-
 .../app/components/entity-tree/entity-tree.html    |   2 +-
 .../app/views/main/main.controller.js              |  21 +++
 ui-modules/app-inspector/app/views/main/main.less  |   7 +
 .../app/views/main/main.template.html              |  16 +-
 7 files changed, 241 insertions(+), 7 deletions(-)

diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-node.html b/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
index dd5fd6d..cbc417f 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
@@ -17,7 +17,7 @@
   under the License.
 -->
 <div class="entity-node">
-    <div ng-if="isOpen" class="entity-node-item" ng-class="{'active': isSelected()}" uib-popover-template="'EntityNodeInfoTemplate.html'" popover-trigger="'mouseenter'" popover-placement="right" popover-popup-delay="1000">
+    <div ng-if="isOpen" class="entity-node-item" ng-class="{ 'active': isSelected(), 'secondary' : !isInSpotlight() }" uib-popover-template="'EntityNodeInfoTemplate.html'" popover-trigger="'mouseenter'" popover-placement="right" popover-popup-delay="1000">
         <a ng-href="{{getHref()}}" class="entity-node-link">
             <brooklyn-status-icon value="{{entity.serviceState}}" ng-if="entity.serviceState || entity.applicationId"></brooklyn-status-icon>
             <i class="fa fa-2x fa-external-link" ng-if="!entity.serviceState && !entity.applicationId"></i>
@@ -25,14 +25,20 @@
             <span class="node-icon"><img ng-src="{{ iconUrl }}"/></span>
         </a>
         <div class="entity-node-toggle-wrapper">
-          <div class="entity-node-toggle" ng-if="entity.children.length > 0 || entity.members.length > 0" ng-click="onToggle($event)" >
+          <div class="entity-node-toggle" ng-if="entitiesInCurrentView(entity.children) > 0 || entitiesInCurrentView(entity.members) > 0" ng-click="onToggle($event)" >
             <span class="glyphicon" ng-class="isChildrenOpen ? 'glyphicon-chevron-up' : 'glyphicon-chevron-down'"></span>
           </div>
         </div>
     </div>
     <div class="entity-node-children" ng-show="isChildrenOpen">
-        <entity-node ng-repeat="child in entity.children track by child.id" entity="child" application-id="applicationId"></entity-node>
-        <entity-node ng-if="!entity.children || entity.children.length === 0" ng-repeat="child in entity.members track by child.id" entity="child" application-id="applicationId"></entity-node>
+        <!-- Entity children -->
+        <entity-node ng-repeat="child in entity.children track by child.id"
+                     ng-show="child.viewModes.has(viewMode)"
+                     entity="child" application-id="applicationId" view-mode="viewMode"></entity-node>
+        <!-- Or entity members -->
+        <entity-node ng-repeat="child in entity.members track by child.id"
+                     ng-show="child.viewModes.has(viewMode) && (!entity.children || entity.children.length === 0)"
+                     entity="child" application-id="applicationId" view-mode="viewMode"></entity-node>
     </div>
     <script type="text/ng-template" id="EntityNodeInfoTemplate.html">
         <table ng-if="isOpen" class="info-table">
diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-node.less b/ui-modules/app-inspector/app/components/entity-tree/entity-node.less
index 0ec4b46..a3fe401 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-node.less
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-node.less
@@ -47,6 +47,9 @@
     border-radius: @border-radius-base;
     box-shadow: 0 1px 2px rgba(0,0,0,0.1);
     transition: all .2s ease-in-out;
+    &.secondary {
+      background-color: lighten(@brand-primary, 55%);
+    }
     &:hover {
       background-color: @body-bg;
     }
diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js b/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
index f6d3426..43aad2c 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
@@ -30,6 +30,12 @@ import {detailState} from '../../views/main/inspect/activities/detail/detail.con
 import {managementState} from '../../views/main/inspect/management/management.controller';
 import {detailState as managementDetailState} from '../../views/main/inspect/management/detail/detail.controller';
 import {HIDE_INTERSTITIAL_SPINNER_EVENT} from 'brooklyn-ui-utils/interstitial-spinner/interstitial-spinner';
+import {
+    RELATIONSHIP_HOST_FOR,
+    RELATIONSHIP_HOSTED_ON,
+    VIEW_HOST_FOR_HOSTED_ON,
+    VIEW_PARENT_CHILD
+} from '../../views/main/main.controller';
 
 const MODULE_NAME = 'inspector.entity.tree';
 
@@ -44,7 +50,9 @@ export function entityTreeDirective() {
         restrict: 'E',
         template: entityTreeTemplate,
         scope: {
-           sortReverse: '=',
+            sortReverse: '=',
+            viewModes: '=',
+            viewMode: '<'
         },
         controller: ['$scope', '$state', 'applicationApi', 'entityApi', 'iconService', 'brWebNotifications', controller],
         controllerAs: 'vm'
@@ -59,6 +67,7 @@ export function entityTreeDirective() {
 
         applicationApi.applicationsTree().then((response)=> {
             vm.applications = response.data;
+            analyzeRelationships(vm.applications);
 
             observers.push(response.subscribe((response)=> {
                 response.data
@@ -79,6 +88,7 @@ export function entityTreeDirective() {
                     });
 
                 vm.applications = response.data;
+                analyzeRelationships(vm.applications);
 
                 function spawnNotification(app, opts) {
                     iconService.get(app).then((icon)=> {
@@ -90,6 +100,166 @@ export function entityTreeDirective() {
                     });
                 }
             }));
+
+            // TODO SMART-143
+            function analyzeRelationships(entityTree) {
+                let entities = entityTreeToArray(entityTree);
+                let relationships = findAllRelationships(entities);
+
+                // Initialize entity tree with 'parent/child' view first (default view).
+                initParentChildView(entities);
+
+                // Identify new view modes based on relationships. This adds a drop-down menu with new views if found any.
+                updateViewModes(relationships);
+
+                // Re-arrange entity tree for 'host_for/hosted_on' view if present.
+                if ($scope.viewModes.has(VIEW_HOST_FOR_HOSTED_ON)) {
+                    addHostForHostedOnView(entities, relationships);
+                }
+            }
+
+            // TODO SMART-143
+            function entityTreeToArray(entities) {
+                let children = [];
+                if (!Array.isArray(entities) || entities.length === 0) {
+                    return children;
+                }
+                entities.forEach(entity => {
+                    children = children.concat(entityTreeToArray(entity.children));
+                    children = children.concat(entityTreeToArray(entity.members));
+                })
+                return entities.concat(children);
+            }
+
+            // TODO SMART-143
+            function addHostForHostedOnView(entities, relationships) {
+                entities.forEach(entity => {
+                    let relationship = relationships.find(r => r.id === entity.id);
+                    if (relationship && relationship.name === RELATIONSHIP_HOST_FOR) {
+                        displayEntityInView(entity, VIEW_HOST_FOR_HOSTED_ON);
+                        spotlightEntityInView(entity, VIEW_HOST_FOR_HOSTED_ON);
+
+                        relationship.targets.forEach(target => {
+                            let child = entities.find(e => e.id === target);
+                            if (child) {
+                                spotlightEntityInView(child, VIEW_HOST_FOR_HOSTED_ON);
+                                if (child.parentId !== entity.id) { // Move (copy) child under 'hosted_on' entity.
+                                    let childCopy = Object.assign({}, child); // Copy entity
+
+                                    // Display in 'host_for/hosted_on' view only.
+                                    childCopy.viewModes = null;
+                                    displayEntityInView(childCopy, VIEW_HOST_FOR_HOSTED_ON);
+
+                                    let parent = findEntity(entities, child.parentId);
+                                    if (parent) {
+                                        childCopy.name += ' (' + parent.name + ')';
+                                    }
+
+                                    if (!entity.children) {
+                                        entity.children = [childCopy];
+                                    } else {
+                                        entity.children.push(childCopy);
+                                    }
+                                }
+                                displayParentsInView(entities, child.parentId, VIEW_HOST_FOR_HOSTED_ON);
+                            }
+                        });
+                    } else if (!relationship || relationship.name !== RELATIONSHIP_HOSTED_ON) {
+                        // Display original position for any other entity under 'host_for/hosted_on' view.
+                        displayEntityInView(entity, VIEW_HOST_FOR_HOSTED_ON);
+                        // Spotlight will not be on entities that are required to be displayed but do not belong to this view.
+                    }
+                });
+            }
+
+            // TODO SMART-143
+            function displayParentsInView(entities, id, viewMode) {
+                let entity = findEntity(entities, id);
+                if (entity) {
+                    displayEntityInView(entity, viewMode);
+                    displayParentsInView(entities, entity.parentId, viewMode);
+                }
+            }
+
+            // TODO SMART-143
+            function findEntity(entities, id) {
+                return entities.find(entity => entity.id === id);
+            }
+
+            // TODO SMART-143
+            function displayEntityInView(entity, viewMode) {
+                if (!entity.viewModes) {
+                    entity.viewModes = new Set([viewMode]);
+                } else {
+                    entity.viewModes.add(viewMode);
+                }
+            }
+
+            // TODO SMART-143
+            function spotlightEntityInView(entity, viewMode) {
+                if (!entity.viewModesSpotLight) {
+                    entity.viewModesSpotLight = new Set([viewMode]);
+                } else {
+                    entity.viewModesSpotLight.add(viewMode);
+                }
+            }
+
+            /**
+             * Initializes entity tree with 'parent/child' view mode. This is a default view mode.
+             *
+             * @param {Object} entities The entity tree to initialize with 'parent/child' view mode.
+             */
+            function initParentChildView(entities) {
+                entities.forEach(entity => {
+                    displayEntityInView(entity, VIEW_PARENT_CHILD);
+                    spotlightEntityInView(entity, VIEW_PARENT_CHILD);
+                });
+            }
+
+            /**
+             * Identifies new view modes based on relationships between entities. Updates $scope.viewModes set.
+             *
+             * @param {Object} relationships The entity tree relationships.
+             */
+            function updateViewModes(relationships) {
+                let viewModesDiscovered = new Set([VIEW_PARENT_CHILD]); // 'parent/child' view mode is a minimum required
+
+                relationships.forEach(relationship => {
+                    relationship.targets.forEach(id => {
+                        let target = relationships.find(item => item.id === id);
+                        if (target) {
+                            let uniqueRelationshipName = [relationship.name, target.name].sort().join('/'); // e.g. host_for/hosted_on
+                            viewModesDiscovered.add(uniqueRelationshipName);
+                        }
+                    })
+                });
+
+                $scope.viewModes = viewModesDiscovered; // Refresh view modes
+            }
+
+            // TODO SMART-143
+            function findAllRelationships(entities) {
+                let relationships = [];
+
+                if (!Array.isArray(entities) || entities.length === 0) {
+                    return relationships;
+                }
+
+                entities.forEach(entity => {
+                    if (Array.isArray(entity.relations)) {
+                        entity.relations.forEach(r => {
+                            let relationship = {
+                                id: entity.id,
+                                name: r.type.name.split('/')[0], // read name up until '/', e.g. take 'hosted_on' from 'hosted_on/oU7i'
+                                targets: Array.isArray(r.targets) ? r.targets : []
+                            }
+                            relationships.push(relationship)
+                        });
+                    }
+                });
+
+                return relationships;
+            }
         });
 
         $scope.$on('$destroy', ()=> {
@@ -107,6 +277,7 @@ export function entityNodeDirective() {
         scope: {
             entity: '<',
             applicationId: '<',
+            viewMode: '<'
         },
         link: link,
         controller: ['$scope', '$state', '$stateParams', 'iconService', controller]
@@ -189,5 +360,17 @@ export function entityNodeDirective() {
             }
         };
 
+        // TODO SMART-143
+        $scope.isInSpotlight = function() {
+            return $scope.entity.viewModesSpotLight.has($scope.viewMode);
+        };
+
+        // TODO SMART-143
+        $scope.entitiesInCurrentView = (entities) => {
+            if (!entities) {
+                return 0;
+            }
+            return entities.filter(entity => entity.viewModes.has($scope.viewMode)).length || 0;
+        }
     }
 }
diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-tree.html b/ui-modules/app-inspector/app/components/entity-tree/entity-tree.html
index b105215..4906d1e 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-tree.html
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-tree.html
@@ -16,7 +16,7 @@
   specific language governing permissions and limitations
   under the License.
 -->
-<entity-node ng-repeat="application in vm.applications | orderBy: sortReverse? '-creationTimeUtc': 'creationTimeUtc' track by application.id" entity="application" application-id="application.id"></entity-node>
+<entity-node ng-repeat="application in vm.applications | orderBy: sortReverse? '-creationTimeUtc': 'creationTimeUtc' track by application.id" entity="application" application-id="application.id" view-mode="viewMode"></entity-node>
 <p class="expand-tree-message text-center" ng-if="vm.applications.length > 0"><small><kbd>shift</kbd> + <kbd>{{navigator.appVersion.indexOf("Mac") !== -1 ? '⌘' : '⊞'}}</kbd> + click to expand all children</small></p>
 <div class="empty-tree text-muted text-center" ng-if="vm.applications.length === 0">
     <hr />
diff --git a/ui-modules/app-inspector/app/views/main/main.controller.js b/ui-modules/app-inspector/app/views/main/main.controller.js
index 31502f8..c268bc2 100644
--- a/ui-modules/app-inspector/app/views/main/main.controller.js
+++ b/ui-modules/app-inspector/app/views/main/main.controller.js
@@ -27,6 +27,15 @@ export const mainState = {
     controllerAs: 'ctrl'
 };
 
+// Entity relationship constants
+export const RELATIONSHIP_HOST_FOR = 'host_for';
+export const RELATIONSHIP_HOSTED_ON = 'hosted_on';
+
+// View mode constants
+export const RELATIONSHIP_VIEW_DELIMITER = '/';
+export const VIEW_PARENT_CHILD = 'parent/child';
+export const VIEW_HOST_FOR_HOSTED_ON = RELATIONSHIP_HOST_FOR + RELATIONSHIP_VIEW_DELIMITER + RELATIONSHIP_HOSTED_ON;
+
 const savedSortReverse = 'app-inspector-sort-reverse';
 
 export function mainController($scope, $q, brWebNotifications, brBrandInfo) {
@@ -36,6 +45,18 @@ export function mainController($scope, $q, brWebNotifications, brBrandInfo) {
 
     ctrl.composerUrl = brBrandInfo.blueprintComposerBaseUrl;
 
+    // TODO SMART-143
+    ctrl.viewMode = VIEW_PARENT_CHILD;
+    ctrl.viewModes = new Set([VIEW_PARENT_CHILD]);
+    ctrl.viewModesArray = () => Array.from(ctrl.viewModes); // Array from set for ng-repeat component
+
+    // TODO SMART-143
+    $scope.$watch('ctrl.viewModes', () => {
+        if (!ctrl.viewModes.has(ctrl.viewMode)) {
+            ctrl.viewMode = VIEW_PARENT_CHILD; // Default to 'parent/child' view if current is not available anymore.
+        }
+    });
+
     ctrl.sortReverse = localStorage && localStorage.getItem(savedSortReverse) !== null ?
         JSON.parse(localStorage.getItem(savedSortReverse)) :
         true;
diff --git a/ui-modules/app-inspector/app/views/main/main.less b/ui-modules/app-inspector/app/views/main/main.less
index 527554f..2e2ebde 100644
--- a/ui-modules/app-inspector/app/views/main/main.less
+++ b/ui-modules/app-inspector/app/views/main/main.less
@@ -52,5 +52,12 @@
   .entity-tree-action-bar {
     margin-right: -0.5rem;
   }
+
+  .view-mode-item {
+    &.active {
+      color: #fff;
+      background-color: @brand-primary;
+    }
+  }
 }
 
diff --git a/ui-modules/app-inspector/app/views/main/main.template.html b/ui-modules/app-inspector/app/views/main/main.template.html
index f3bec97..a4165b5 100644
--- a/ui-modules/app-inspector/app/views/main/main.template.html
+++ b/ui-modules/app-inspector/app/views/main/main.template.html
@@ -29,6 +29,20 @@
                                     <span class="glyphicon" ng-class="ctrl.sortReverse ? 'fa fa-sort-amount-desc' : 'fa fa-sort-amount-asc'"></span>
                                 </div>
                             </button>
+                            <div class="btn-group" ng-if="ctrl.viewModes.size > 1" uib-dropdown>
+                                <button class="btn btn-sm btn-default" uib-tooltip="Switch view" tooltip-append-to-body="true" uib-dropdown-toggle/>
+                                    <div>
+                                        <span class="fa fa-sitemap"></span>
+                                    </div>
+                                </button>
+                                <ul class="dropdown-menu" uib-dropdown-menu>
+                                    <li ng-repeat="viewMode in ctrl.viewModesArray()">
+                                        <a class="view-mode-item"
+                                           ng-click="ctrl.viewMode = viewMode"
+                                           ng-class="{'active': ctrl.viewMode === viewMode}">{{viewMode}}</a>
+                                    </li>
+                                </ul>
+                            </div>
                         </div>
                         <div class="entity-tree-header-section">
                             <button class="btn btn-link entity-tree-action"
@@ -51,7 +65,7 @@
                         </div>
                     </div>
 
-                    <entity-tree sort-reverse="ctrl.sortReverse"></entity-tree>
+                    <entity-tree sort-reverse="ctrl.sortReverse" view-mode="ctrl.viewMode" view-modes="ctrl.viewModes"></entity-tree>
                 </br-card-content>
             </br-card>
 

[brooklyn-ui] 08/08: This closes #199

Posted by he...@apache.org.
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

commit 6242e5539e81848148609d802abeacfd1fa9ac7e
Merge: 6951421 0b7d438
Author: Alex Heneveld <al...@cloudsoftcorp.com>
AuthorDate: Mon May 3 09:27:10 2021 +0100

    This closes #199

 .../app/components/entity-tree/entity-node.html    |  22 +-
 .../app/components/entity-tree/entity-node.less    |  37 +++
 .../entity-tree/entity-tree.directive.js           | 305 ++++++++++++++++++++-
 .../app/components/entity-tree/entity-tree.html    |   2 +-
 .../app/views/main/main.controller.js              |  20 ++
 ui-modules/app-inspector/app/views/main/main.less  |   7 +
 .../app/views/main/main.template.html              |  16 +-
 7 files changed, 401 insertions(+), 8 deletions(-)

[brooklyn-ui] 05/08: Support child/parent flip when parent is hosted under child in 'host_for/hosted_on' relationship

Posted by he...@apache.org.
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

commit 8e475be57e5f8787b20a2021143dcda653f03de2
Author: Mykola Mandra <my...@cloudsoftcorp.com>
AuthorDate: Tue Apr 27 14:26:53 2021 +0100

    Support child/parent flip when parent is hosted under child in 'host_for/hosted_on' relationship
    
    Signed-off-by: Mykola Mandra <my...@cloudsoftcorp.com>
---
 .../app/components/entity-tree/entity-node.html    |   8 +-
 .../entity-tree/entity-tree.directive.js           | 120 ++++++++++++++++-----
 2 files changed, 100 insertions(+), 28 deletions(-)

diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-node.html b/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
index 3f11c35..69ccc43 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
@@ -25,7 +25,9 @@
             <span class="node-icon"><img ng-src="{{ iconUrl }}"/></span>
         </a>
         <div class="entity-node-toggle-wrapper">
-          <div class="entity-node-toggle" ng-if="entitiesInCurrentView(entity.children) > 0 || entitiesInCurrentView(entity.members) > 0" ng-click="onToggle($event)" >
+          <div class="entity-node-toggle"
+               ng-if="entitiesInCurrentView(entity.children) > 0 || entitiesInCurrentView(entity.members) > 0 || entitiesInCurrentView(entity.otherNodes) > 0"
+               ng-click="onToggle($event)" >
             <span class="glyphicon" ng-class="isChildrenOpen ? 'glyphicon-chevron-up' : 'glyphicon-chevron-down'"></span>
           </div>
         </div>
@@ -39,6 +41,10 @@
         <entity-node ng-repeat="child in entity.members track by child.id"
                      ng-show="child.viewModes.has(viewMode) && (!entity.children || entity.children.length === 0)"
                      entity="child" application-id="applicationId" view-mode="viewMode"></entity-node>
+        <!-- Other nodes under entity -->
+        <entity-node ng-repeat="child in entity.otherNodes track by child.id"
+                     ng-show="child.viewModes.has(viewMode)"
+                     entity="child" application-id="applicationId" view-mode="viewMode"></entity-node>
     </div>
     <script type="text/ng-template" id="EntityNodeInfoTemplate.html">
         <table ng-if="isOpen" class="info-table">
diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js b/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
index 07ba97d..eeec3c6 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
@@ -120,6 +120,7 @@ export function entityTreeDirective() {
                 if ($scope.viewModes.has(VIEW_HOST_FOR_HOSTED_ON)) {
                     addHostForHostedOnView(entities, relationships);
                 }
+                console.log('-------------THE END-------------------------');
             }
 
             /**
@@ -129,16 +130,15 @@ export function entityTreeDirective() {
              * @returns {Array.<Object>} The array of all entities found in the tree.
              */
             function entityTreeToArray(entities) {
-                let children = [];
+                let nodes = [];
                 if (!Array.isArray(entities) || entities.length === 0) {
-                    return children;
+                    return nodes;
                 }
                 entities.forEach(entity => {
-                    children = children.concat(entityTreeToArray(entity.children));
-                    children = children.concat(entityTreeToArray(entity.members));
-                })
-
-                return entities.concat(children);
+                    nodes = nodes.concat(entityTreeToArray(entity.children));
+                    nodes = nodes.concat(entityTreeToArray(entity.members));
+                });
+                return entities.concat(nodes);
             }
 
             /**
@@ -149,46 +149,100 @@ export function entityTreeDirective() {
              * @param {Array.<Object>} relationships The relationships of entities.
              */
             function addHostForHostedOnView(entities, relationships) {
+
+                // Look through all entities found in the entity tree
                 entities.forEach(entity => {
+
+                    // Check if entity has 'host_for/hosted_on' relationship.
                     let relationship = relationships.find(r => r.id === entity.id);
                     if (relationship && relationship.name === RELATIONSHIP_HOST_FOR) {
+
+                        // Label every 'host_for' entity to display and highlight in 'host_for/hosted_on' view mode.
                         displayEntityInView(entity, VIEW_HOST_FOR_HOSTED_ON);
                         highlightEntityInView(entity, VIEW_HOST_FOR_HOSTED_ON);
 
+                        // Look for 'hosted_on' entities under 'host_for', flip of move them and label to display in
+                        // 'host_for/hosted_on' view mode respectively.
                         relationship.targets.forEach(target => {
-                            let child = entities.find(e => e.id === target);
-                            if (child) {
-                                highlightEntityInView(child, VIEW_HOST_FOR_HOSTED_ON);
-                                if (child.parentId !== entity.id) { // Move (copy) child under 'hosted_on' entity.
-                                    let childCopy = Object.assign({}, child); // Copy entity
-
-                                    // Display in 'host_for/hosted_on' view only.
-                                    childCopy.viewModes = null;
-                                    displayEntityInView(childCopy, VIEW_HOST_FOR_HOSTED_ON);
-
-                                    let parent = findEntity(entities, child.parentId);
-                                    if (parent) {
-                                        childCopy.name += ' (' + parent.name + ')';
-                                    }
+                            let relatedEntity = entities.find(e => e.id === target);
+                            if (relatedEntity) {
+                                highlightEntityInView(relatedEntity, VIEW_HOST_FOR_HOSTED_ON);
+                                displayParentsInView(entities, relatedEntity.parentId, VIEW_HOST_FOR_HOSTED_ON);
+
+                                // Re-arrange the tree if related 'hosted_on' entity is not a child of 'host_for'.
+                                if (relatedEntity.parentId !== entity.id) {
 
-                                    if (!entity.children) {
-                                        entity.children = [childCopy];
+                                    if (relatedEntity.id === entity.parentId) {
+                                        // 4.1. Flip 'hosted_on' parent with a 'host_for' child.
+                                        flipParentAndChild(relatedEntity, entity, entities, VIEW_HOST_FOR_HOSTED_ON);
                                     } else {
-                                        entity.children.push(childCopy);
+                                        // 4.2. Move 'hosted_on' entity to a new 'host_for' parent.
+                                        moveEntityToParent(relatedEntity, entity, entities, VIEW_HOST_FOR_HOSTED_ON);
                                     }
                                 }
-                                displayParentsInView(entities, child.parentId, VIEW_HOST_FOR_HOSTED_ON);
                             }
                         });
                     } else if (!relationship || relationship.name !== RELATIONSHIP_HOSTED_ON) {
-                        // Display original position for any other entity under 'host_for/hosted_on' view.
+
+                        // Display original position for any other entity under 'host_for/hosted_on' view. Do no highlight
+                        // entities that are required to be displayed but do not belong to this view.
                         displayEntityInView(entity, VIEW_HOST_FOR_HOSTED_ON);
-                        // Spotlight will never be on entities that are required to be displayed but do not belong to this view.
                     }
                 });
             }
 
             /**
+             * Flips parent entity with its child.
+             *
+             * @param parent The parent entity to flip with its child.
+             * @param child The child entity to flip with its parent.
+             * @param {Array.<Object>} entities The entity tree converted to array.
+             * @param {string} viewMode The view mode to display copy of the entity in only.
+             */
+            function flipParentAndChild(parent, child, entities, viewMode) {
+                console.log('Flip parent with a child!', parent, child);
+                let parentOfTheParent = findEntity(entities, parent.parentId);
+                if (parentOfTheParent) {
+                    hideEntityInView(child, viewMode);
+                    let childCopy = moveEntityToParent(child, parentOfTheParent, entities, viewMode);
+                    moveEntityToParent(parent, childCopy, entities, viewMode);
+                }
+            }
+
+            /**
+             * Moves entity to a new parent, creates copy of the entity under parent.otherNodes.
+             *
+             * @param {Object} entity The entity to move.
+             * @param {Object} parent The parent to move entity to.
+             * @param {Array.<Object>} entities The entity tree converted to array.
+             * @param {string} viewMode The view mode to display copy of the entity in only.
+             * @returns {Object} The copy of the entity under parent.otherNodes.
+             */
+            function moveEntityToParent(entity, parent, entities, viewMode) {
+                // 1. Create a copy.
+                let entityCopy = Object.assign({}, entity);
+
+                // 2. Include the name of the original parent.
+                let parentOfEntity = findEntity(entities, entityCopy.parentId);
+                if (parentOfEntity) {
+                    entityCopy.name += ' (' + parentOfEntity.name + ')';
+                }
+
+                // 3. Label it to display in a view mode specified only.
+                entityCopy.viewModes = null;
+                displayEntityInView(entityCopy, viewMode);
+
+                // 4. Add copy under otherNodes.
+                if (!parent.otherNodes) {
+                    parent.otherNodes = [entityCopy];
+                } else {
+                    parent.otherNodes.push(entityCopy);
+                }
+
+                return entityCopy;
+            }
+
+            /**
              * Labels all parents to display for a particular view mode starting from a specified ID, traverses the node
              * tree recursively, bottom-up.
              *
@@ -216,6 +270,18 @@ export function entityTreeDirective() {
             }
 
             /**
+             * Labels entity to not display in particular view mode.
+             *
+             * @param {Object} entity The entity to label.
+             * @param {string} viewMode The view mode to not display entity in.
+             */
+            function hideEntityInView(entity, viewMode) {
+                if (entity.viewModes) {
+                    entity.viewModes.delete(viewMode);
+                }
+            }
+
+            /**
              * Labels entity to display in particular view mode.
              *
              * @param {Object} entity The entity to label.

[brooklyn-ui] 06/08: Highlight changed relationships in a switched view

Posted by he...@apache.org.
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

commit d9540198f86bf45bb308826c9b070e3f1974a853
Author: Mykola Mandra <my...@cloudsoftcorp.com>
AuthorDate: Tue Apr 27 16:12:25 2021 +0100

    Highlight changed relationships in a switched view
    
    Signed-off-by: Mykola Mandra <my...@cloudsoftcorp.com>
---
 .../app/components/entity-tree/entity-node.html    | 14 ++++----
 .../app/components/entity-tree/entity-node.less    | 40 ++++++++++++++++++++--
 .../entity-tree/entity-tree.directive.js           | 29 +++++++++-------
 3 files changed, 60 insertions(+), 23 deletions(-)

diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-node.html b/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
index 69ccc43..8227a3a 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
@@ -17,16 +17,16 @@
   under the License.
 -->
 <div class="entity-node">
-    <div ng-if="isOpen" class="entity-node-item" ng-class="{ 'active': isSelected() }" uib-popover-template="'EntityNodeInfoTemplate.html'" popover-trigger="'mouseenter'" popover-placement="right" popover-popup-delay="1000">
+    <div ng-if="isOpen" class="entity-node-item" ng-class="{ 'active': isSelected(), 'highlight' : isChanged() && !isSelected() }" uib-popover-template="'EntityNodeInfoTemplate.html'" popover-trigger="'mouseenter'" popover-placement="right" popover-popup-delay="1000">
         <a ng-href="{{getHref()}}" class="entity-node-link">
             <brooklyn-status-icon value="{{entity.serviceState}}" ng-if="entity.serviceState || entity.applicationId"></brooklyn-status-icon>
             <i class="fa fa-2x fa-external-link" ng-if="!entity.serviceState && !entity.applicationId"></i>
-            <span ng-class="{ 'secondary' : isSecondary() }">{{entity.name}}</span>
+            <span>{{entity.name}}</span>
             <span class="node-icon"><img ng-src="{{ iconUrl }}"/></span>
         </a>
         <div class="entity-node-toggle-wrapper">
           <div class="entity-node-toggle"
-               ng-if="entitiesInCurrentView(entity.children) > 0 || entitiesInCurrentView(entity.members) > 0 || entitiesInCurrentView(entity.otherNodes) > 0"
+               ng-if="nodesInCurrentView() > 0"
                ng-click="onToggle($event)" >
             <span class="glyphicon" ng-class="isChildrenOpen ? 'glyphicon-chevron-up' : 'glyphicon-chevron-down'"></span>
           </div>
@@ -35,15 +35,15 @@
     <div class="entity-node-children" ng-show="isChildrenOpen">
         <!-- Entity children -->
         <entity-node ng-repeat="child in entity.children track by child.id"
-                     ng-show="child.viewModes.has(viewMode)"
+                     ng-if="child.viewModes.has(viewMode)"
                      entity="child" application-id="applicationId" view-mode="viewMode"></entity-node>
         <!-- Or entity members -->
         <entity-node ng-repeat="child in entity.members track by child.id"
-                     ng-show="child.viewModes.has(viewMode) && (!entity.children || entity.children.length === 0)"
+                     ng-if="child.viewModes.has(viewMode) && (!entity.children || entity.children.length === 0)"
                      entity="child" application-id="applicationId" view-mode="viewMode"></entity-node>
         <!-- Other nodes under entity -->
         <entity-node ng-repeat="child in entity.otherNodes track by child.id"
-                     ng-show="child.viewModes.has(viewMode)"
+                     ng-if="child.viewModes.has(viewMode)"
                      entity="child" application-id="applicationId" view-mode="viewMode"></entity-node>
     </div>
     <script type="text/ng-template" id="EntityNodeInfoTemplate.html">
@@ -58,7 +58,7 @@
             </tr>
             <tr>
                 <td><b>Number of children</b></td>
-                <td>{{entity.children.length || 0}}</td>
+                <td>{{nodesInCurrentView()}}</td>
             </tr>
         </table>
     </script>
diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-node.less b/ui-modules/app-inspector/app/components/entity-tree/entity-node.less
index f8ff200..5537805 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-node.less
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-node.less
@@ -47,6 +47,13 @@
     border-radius: @border-radius-base;
     box-shadow: 0 1px 2px rgba(0,0,0,0.1);
     transition: all .2s ease-in-out;
+    &.highlight {
+      animation: fadeOut 1s;
+      -webkit-animation: fadeOut 1s;
+      -moz-animation: fadeOut 1s;
+      -o-animation: fadeOut 1s;
+      -ms-animation: fadeOut 1s;
+    }
     &:hover {
       background-color: @body-bg;
     }
@@ -73,9 +80,6 @@
         flex-grow: 1;
         padding-top: 3px;
         margin-left: 10px;
-        &.secondary {
-          color: @gray-lighter;
-        }
       }
     }
     .entity-node-toggle-wrapper {
@@ -107,4 +111,34 @@
     padding-top: 0;
     margin-top: -1px;
   }
+
+  @keyframes fadeOut {
+    0% {background-color: lighten(@brand-primary, 50%);}
+    50% {background-color: lighten(@brand-primary, 50%);}
+    100% {background-color: transparent}
+  }
+
+  @-moz-keyframes fadeOut {
+    0% {background-color: lighten(@brand-primary, 50%);}
+    50% {background-color: lighten(@brand-primary, 50%);}
+    100% {background-color: transparent}
+  }
+
+  @-webkit-keyframes fadeOut {
+    0% {background-color: lighten(@brand-primary, 50%);}
+    50% {background-color: lighten(@brand-primary, 50%);}
+    100% {background-color: transparent}
+  }
+
+  @-o-keyframes fadeOut {
+    0% {background-color: lighten(@brand-primary, 50%);}
+    50% {background-color: lighten(@brand-primary, 50%);}
+    100% {background-color: transparent}
+  }
+
+  @-ms-keyframes fadeOut {
+    0% {background-color: lighten(@brand-primary, 50%);}
+    50% {background-color: lighten(@brand-primary, 50%);}
+    100% {background-color: transparent}
+  }
 }
diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js b/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
index eeec3c6..0ea3b69 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
@@ -120,7 +120,6 @@ export function entityTreeDirective() {
                 if ($scope.viewModes.has(VIEW_HOST_FOR_HOSTED_ON)) {
                     addHostForHostedOnView(entities, relationships);
                 }
-                console.log('-------------THE END-------------------------');
             }
 
             /**
@@ -200,7 +199,6 @@ export function entityTreeDirective() {
              * @param {string} viewMode The view mode to display copy of the entity in only.
              */
             function flipParentAndChild(parent, child, entities, viewMode) {
-                console.log('Flip parent with a child!', parent, child);
                 let parentOfTheParent = findEntity(entities, parent.parentId);
                 if (parentOfTheParent) {
                     hideEntityInView(child, viewMode);
@@ -471,24 +469,29 @@ export function entityNodeDirective() {
         };
 
         /**
-         * @returns {boolean} True if entity is a secondary in a current view, false otherwise. Secondary entity is one
-         * that is not part of relationship view the id currently displayed.
+         * @returns {boolean} True if entity is changed in a current view, false otherwise.
          */
-        $scope.isSecondary = function() {
-            return !$scope.entity.viewModesHighlight.has($scope.viewMode);
+        $scope.isChanged = function() {
+            return $scope.entity.viewModesHighlight.has($scope.viewMode) && $scope.viewMode !== VIEW_PARENT_CHILD;
         };
 
         /**
-         * Counts amount of entities that are expected to be displayed in the current view.
+         * Counts amount of entity nodes that are expected to be displayed in the current view.
          *
-         * @param {Array.<Object>} entities The array of entities to count amount for.
-         * @returns {number} Amount of entities in the current view.
+         * @returns {number} Amount of entity nodes in the current view.
          */
-        $scope.entitiesInCurrentView = (entities) => {
-            if (!entities) {
-                return 0;
+        $scope.nodesInCurrentView = () => {
+            let amount = 0;
+            if ($scope.entity.children) {
+                amount += $scope.entity.children.filter(entity => entity.viewModes.has($scope.viewMode)).length;
             }
-            return entities.filter(entity => entity.viewModes.has($scope.viewMode)).length || 0;
+            if ($scope.entity.members) {
+                amount += $scope.entity.members.filter(entity => entity.viewModes.has($scope.viewMode)).length;
+            }
+            if ($scope.entity.otherNodes) {
+                amount += $scope.entity.otherNodes.filter(entity => entity.viewModes.has($scope.viewMode)).length;
+            }
+            return amount;
         }
     }
 }

[brooklyn-ui] 04/08: Add docs for relationship view logic

Posted by he...@apache.org.
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

commit 087248e82a187d3798c965f64ea0f715f92facf1
Author: Mykola Mandra <my...@cloudsoftcorp.com>
AuthorDate: Tue Apr 27 09:01:24 2021 +0100

    Add docs for relationship view logic
    
    Signed-off-by: Mykola Mandra <my...@cloudsoftcorp.com>
---
 .../entity-tree/entity-tree.directive.js           | 96 +++++++++++++++++-----
 .../app/views/main/main.controller.js              |  4 +-
 2 files changed, 75 insertions(+), 25 deletions(-)

diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js b/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
index 5d4ebcd..07ba97d 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
@@ -101,7 +101,11 @@ export function entityTreeDirective() {
                 }
             }));
 
-            // TODO SMART-143
+            /**
+             * Analyzes relationships of the entity tree and prepares mode views, e.g. 'parent/child' and 'host_for/hosted_on'.
+             *
+             * @param {Array} entityTree The entity tree to process and prepare view modes for.
+             */
             function analyzeRelationships(entityTree) {
                 let entities = entityTreeToArray(entityTree);
                 let relationships = findAllRelationships(entities);
@@ -118,7 +122,12 @@ export function entityTreeDirective() {
                 }
             }
 
-            // TODO SMART-143
+            /**
+             * Converts entity tree to array of entities.
+             *
+             * @param {Array.<Object>} entities The entity tree to convert.
+             * @returns {Array.<Object>} The array of all entities found in the tree.
+             */
             function entityTreeToArray(entities) {
                 let children = [];
                 if (!Array.isArray(entities) || entities.length === 0) {
@@ -128,21 +137,28 @@ export function entityTreeDirective() {
                     children = children.concat(entityTreeToArray(entity.children));
                     children = children.concat(entityTreeToArray(entity.members));
                 })
+
                 return entities.concat(children);
             }
 
-            // TODO SMART-143
+            /**
+             * Extends entity tree with 'host_for/hosted_on' view mode. Moves entities (creates copies) if their host is
+             * not a parent and labels them to display under 'host_for/hosted_on' view mode only.
+             *
+             * @param {Array.<Object>} entities The entity tree converted to array.
+             * @param {Array.<Object>} relationships The relationships of entities.
+             */
             function addHostForHostedOnView(entities, relationships) {
                 entities.forEach(entity => {
                     let relationship = relationships.find(r => r.id === entity.id);
                     if (relationship && relationship.name === RELATIONSHIP_HOST_FOR) {
                         displayEntityInView(entity, VIEW_HOST_FOR_HOSTED_ON);
-                        spotlightEntityInView(entity, VIEW_HOST_FOR_HOSTED_ON);
+                        highlightEntityInView(entity, VIEW_HOST_FOR_HOSTED_ON);
 
                         relationship.targets.forEach(target => {
                             let child = entities.find(e => e.id === target);
                             if (child) {
-                                spotlightEntityInView(child, VIEW_HOST_FOR_HOSTED_ON);
+                                highlightEntityInView(child, VIEW_HOST_FOR_HOSTED_ON);
                                 if (child.parentId !== entity.id) { // Move (copy) child under 'hosted_on' entity.
                                     let childCopy = Object.assign({}, child); // Copy entity
 
@@ -167,12 +183,19 @@ export function entityTreeDirective() {
                     } else if (!relationship || relationship.name !== RELATIONSHIP_HOSTED_ON) {
                         // Display original position for any other entity under 'host_for/hosted_on' view.
                         displayEntityInView(entity, VIEW_HOST_FOR_HOSTED_ON);
-                        // Spotlight will not be on entities that are required to be displayed but do not belong to this view.
+                        // Spotlight will never be on entities that are required to be displayed but do not belong to this view.
                     }
                 });
             }
 
-            // TODO SMART-143
+            /**
+             * Labels all parents to display for a particular view mode starting from a specified ID, traverses the node
+             * tree recursively, bottom-up.
+             *
+             * @param {Array.<Object>} entities The array of entities to search parents to label.
+             * @param {string} id The ID of a parent entity to start labelling.
+             * @param {string} viewMode The view mode to display parent in.
+             */
             function displayParentsInView(entities, id, viewMode) {
                 let entity = findEntity(entities, id);
                 if (entity) {
@@ -181,12 +204,23 @@ export function entityTreeDirective() {
                 }
             }
 
-            // TODO SMART-143
+            /**
+             * Attempts to find entity with ID specified in array of entities.
+             *
+             * @param {Array.<Object>} entities The array of entities to search for a particular entity in.
+             * @param {string} id The ID of entity to look for.
+             * @returns {Object} The entity with ID requested, and undefined otherwise.
+             */
             function findEntity(entities, id) {
-                return entities.find(entity => entity.id === id);
+                return entities.find(entity => entity.id === id) || null;
             }
 
-            // TODO SMART-143
+            /**
+             * Labels entity to display in particular view mode.
+             *
+             * @param {Object} entity The entity to label.
+             * @param {string} viewMode The view mode to display entity in.
+             */
             function displayEntityInView(entity, viewMode) {
                 if (!entity.viewModes) {
                     entity.viewModes = new Set([viewMode]);
@@ -195,12 +229,17 @@ export function entityTreeDirective() {
                 }
             }
 
-            // TODO SMART-143
-            function spotlightEntityInView(entity, viewMode) {
-                if (!entity.viewModesSpotLight) {
-                    entity.viewModesSpotLight = new Set([viewMode]);
+            /**
+             * Labels entity to highlight in particular view mode.
+             *
+             * @param {Object} entity The entity to label.
+             * @param {string} viewMode The view mode to highlight entity in.
+             */
+            function highlightEntityInView(entity, viewMode) {
+                if (!entity.viewModesHighlight) {
+                    entity.viewModesHighlight = new Set([viewMode]);
                 } else {
-                    entity.viewModesSpotLight.add(viewMode);
+                    entity.viewModesHighlight.add(viewMode);
                 }
             }
 
@@ -212,14 +251,14 @@ export function entityTreeDirective() {
             function initParentChildView(entities) {
                 entities.forEach(entity => {
                     displayEntityInView(entity, VIEW_PARENT_CHILD);
-                    spotlightEntityInView(entity, VIEW_PARENT_CHILD);
+                    highlightEntityInView(entity, VIEW_PARENT_CHILD);
                 });
             }
 
             /**
-             * Identifies new view modes based on relationships between entities. Updates $scope.viewModes set.
+             * Identifies new view modes based on relationships between entities. Updates {@link $scope.viewModes} set.
              *
-             * @param {Object} relationships The entity tree relationships.
+             * @param {Array.<Object>} relationships The relationships of entities.
              */
             function updateViewModes(relationships) {
                 let viewModesDiscovered = new Set([VIEW_PARENT_CHILD]); // 'parent/child' view mode is a minimum required
@@ -237,7 +276,12 @@ export function entityTreeDirective() {
                 $scope.viewModes = viewModesDiscovered; // Refresh view modes
             }
 
-            // TODO SMART-143
+            /**
+             * Finds relationships in array of entities.
+             *
+             * @param {Array.<Object>} entities The array of entities to search relationships in.
+             * @returns {Array.<Object>} Relationships found in entities.
+             */
             function findAllRelationships(entities) {
                 let relationships = [];
 
@@ -360,12 +404,20 @@ export function entityNodeDirective() {
             }
         };
 
-        // TODO SMART-143
+        /**
+         * @returns {boolean} True if entity is a secondary in a current view, false otherwise. Secondary entity is one
+         * that is not part of relationship view the id currently displayed.
+         */
         $scope.isSecondary = function() {
-            return !$scope.entity.viewModesSpotLight.has($scope.viewMode);
+            return !$scope.entity.viewModesHighlight.has($scope.viewMode);
         };
 
-        // TODO SMART-143
+        /**
+         * Counts amount of entities that are expected to be displayed in the current view.
+         *
+         * @param {Array.<Object>} entities The array of entities to count amount for.
+         * @returns {number} Amount of entities in the current view.
+         */
         $scope.entitiesInCurrentView = (entities) => {
             if (!entities) {
                 return 0;
diff --git a/ui-modules/app-inspector/app/views/main/main.controller.js b/ui-modules/app-inspector/app/views/main/main.controller.js
index 3007d22..3f6cbde 100644
--- a/ui-modules/app-inspector/app/views/main/main.controller.js
+++ b/ui-modules/app-inspector/app/views/main/main.controller.js
@@ -45,13 +45,11 @@ export function mainController($scope, $q, brWebNotifications, brBrandInfo) {
 
     ctrl.composerUrl = brBrandInfo.blueprintComposerBaseUrl;
 
-    // TODO SMART-143
+    // View mode feature components, required in entity-tree and entity-node directives.
     ctrl.viewMode = VIEW_PARENT_CHILD;
     ctrl.viewModes = new Set([VIEW_PARENT_CHILD]);
     ctrl.viewModesArray = () => Array.from(ctrl.viewModes); // Array from set for ng-repeat component
     ctrl.isDefaultViewMode = () => ctrl.viewMode === VIEW_PARENT_CHILD; // 'parent/child' is a default view mode
-
-    // TODO SMART-143
     $scope.$watch('ctrl.viewModes', () => {
         if (!ctrl.viewModes.has(ctrl.viewMode)) {
             ctrl.viewMode = VIEW_PARENT_CHILD; // Default to 'parent/child' view if current is not available anymore.

[brooklyn-ui] 07/08: Do not highlight nodes in 'parent/child' view; tidy up docs

Posted by he...@apache.org.
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

commit 0b7d4382083d9f787e807ed090cf93a78fc77fc9
Author: Mykola Mandra <my...@cloudsoftcorp.com>
AuthorDate: Tue Apr 27 16:32:06 2021 +0100

    Do not highlight nodes in 'parent/child' view; tidy up docs
    
    Signed-off-by: Mykola Mandra <my...@cloudsoftcorp.com>
---
 .../app/components/entity-tree/entity-node.html           |  2 +-
 .../app/components/entity-tree/entity-tree.directive.js   | 15 +++++++--------
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-node.html b/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
index 8227a3a..c7e854a 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
@@ -17,7 +17,7 @@
   under the License.
 -->
 <div class="entity-node">
-    <div ng-if="isOpen" class="entity-node-item" ng-class="{ 'active': isSelected(), 'highlight' : isChanged() && !isSelected() }" uib-popover-template="'EntityNodeInfoTemplate.html'" popover-trigger="'mouseenter'" popover-placement="right" popover-popup-delay="1000">
+    <div ng-if="isOpen" class="entity-node-item" ng-class="{ 'active': isSelected(), 'highlight' : isHighlight() && !isSelected() }" uib-popover-template="'EntityNodeInfoTemplate.html'" popover-trigger="'mouseenter'" popover-placement="right" popover-popup-delay="1000">
         <a ng-href="{{getHref()}}" class="entity-node-link">
             <brooklyn-status-icon value="{{entity.serviceState}}" ng-if="entity.serviceState || entity.applicationId"></brooklyn-status-icon>
             <i class="fa fa-2x fa-external-link" ng-if="!entity.serviceState && !entity.applicationId"></i>
diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js b/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
index 0ea3b69..759f7e9 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
@@ -104,7 +104,7 @@ export function entityTreeDirective() {
             /**
              * Analyzes relationships of the entity tree and prepares mode views, e.g. 'parent/child' and 'host_for/hosted_on'.
              *
-             * @param {Array} entityTree The entity tree to process and prepare view modes for.
+             * @param {Array.<Object>} entityTree The entity tree to process and prepare view modes for.
              */
             function analyzeRelationships(entityTree) {
                 let entities = entityTreeToArray(entityTree);
@@ -193,8 +193,8 @@ export function entityTreeDirective() {
             /**
              * Flips parent entity with its child.
              *
-             * @param parent The parent entity to flip with its child.
-             * @param child The child entity to flip with its parent.
+             * @param {Object} parent The parent entity to flip with its child.
+             * @param {Object} child The child entity to flip with its parent.
              * @param {Array.<Object>} entities The entity tree converted to array.
              * @param {string} viewMode The view mode to display copy of the entity in only.
              */
@@ -310,12 +310,11 @@ export function entityTreeDirective() {
             /**
              * Initializes entity tree with 'parent/child' view mode. This is a default view mode.
              *
-             * @param {Object} entities The entity tree to initialize with 'parent/child' view mode.
+             * @param {Array.<Object>} entities The entity tree to initialize with 'parent/child' view mode.
              */
             function initParentChildView(entities) {
                 entities.forEach(entity => {
                     displayEntityInView(entity, VIEW_PARENT_CHILD);
-                    highlightEntityInView(entity, VIEW_PARENT_CHILD);
                 });
             }
 
@@ -469,10 +468,10 @@ export function entityNodeDirective() {
         };
 
         /**
-         * @returns {boolean} True if entity is changed in a current view, false otherwise.
+         * @returns {boolean} True if to highlight entity in a current view, false otherwise.
          */
-        $scope.isChanged = function() {
-            return $scope.entity.viewModesHighlight.has($scope.viewMode) && $scope.viewMode !== VIEW_PARENT_CHILD;
+        $scope.isHighlight = function() {
+            return $scope.entity.viewModesHighlight.has($scope.viewMode);
         };
 
         /**

[brooklyn-ui] 03/08: Highlight the view switch button if parent/child view is not selected

Posted by he...@apache.org.
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

commit 13567b387d705900922d0dd814ba893c201ccdcf
Author: Mykola Mandra <my...@cloudsoftcorp.com>
AuthorDate: Mon Apr 26 14:49:34 2021 +0100

    Highlight the view switch button if parent/child view is not selected
    
    Signed-off-by: Mykola Mandra <my...@cloudsoftcorp.com>
---
 ui-modules/app-inspector/app/views/main/main.controller.js | 1 +
 ui-modules/app-inspector/app/views/main/main.template.html | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/ui-modules/app-inspector/app/views/main/main.controller.js b/ui-modules/app-inspector/app/views/main/main.controller.js
index c268bc2..3007d22 100644
--- a/ui-modules/app-inspector/app/views/main/main.controller.js
+++ b/ui-modules/app-inspector/app/views/main/main.controller.js
@@ -49,6 +49,7 @@ export function mainController($scope, $q, brWebNotifications, brBrandInfo) {
     ctrl.viewMode = VIEW_PARENT_CHILD;
     ctrl.viewModes = new Set([VIEW_PARENT_CHILD]);
     ctrl.viewModesArray = () => Array.from(ctrl.viewModes); // Array from set for ng-repeat component
+    ctrl.isDefaultViewMode = () => ctrl.viewMode === VIEW_PARENT_CHILD; // 'parent/child' is a default view mode
 
     // TODO SMART-143
     $scope.$watch('ctrl.viewModes', () => {
diff --git a/ui-modules/app-inspector/app/views/main/main.template.html b/ui-modules/app-inspector/app/views/main/main.template.html
index a4165b5..51672f9 100644
--- a/ui-modules/app-inspector/app/views/main/main.template.html
+++ b/ui-modules/app-inspector/app/views/main/main.template.html
@@ -30,7 +30,7 @@
                                 </div>
                             </button>
                             <div class="btn-group" ng-if="ctrl.viewModes.size > 1" uib-dropdown>
-                                <button class="btn btn-sm btn-default" uib-tooltip="Switch view" tooltip-append-to-body="true" uib-dropdown-toggle/>
+                                <button class="btn btn-sm" ng-class="ctrl.isDefaultViewMode() ? 'btn-default' : 'btn-primary'" uib-tooltip="Switch view" tooltip-append-to-body="true" uib-dropdown-toggle/>
                                     <div>
                                         <span class="fa fa-sitemap"></span>
                                     </div>

[brooklyn-ui] 02/08: Dimm entity name on view mode change instead of background colour of the node

Posted by he...@apache.org.
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

commit 143eb615136268d0a8da36a0356588dafd7adb6e
Author: Mykola Mandra <my...@cloudsoftcorp.com>
AuthorDate: Mon Apr 26 14:44:05 2021 +0100

    Dimm entity name on view mode change instead of background colour of the node
    
    Signed-off-by: Mykola Mandra <my...@cloudsoftcorp.com>
---
 .../app-inspector/app/components/entity-tree/entity-node.html       | 4 ++--
 .../app-inspector/app/components/entity-tree/entity-node.less       | 6 +++---
 .../app/components/entity-tree/entity-tree.directive.js             | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-node.html b/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
index cbc417f..3f11c35 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-node.html
@@ -17,11 +17,11 @@
   under the License.
 -->
 <div class="entity-node">
-    <div ng-if="isOpen" class="entity-node-item" ng-class="{ 'active': isSelected(), 'secondary' : !isInSpotlight() }" uib-popover-template="'EntityNodeInfoTemplate.html'" popover-trigger="'mouseenter'" popover-placement="right" popover-popup-delay="1000">
+    <div ng-if="isOpen" class="entity-node-item" ng-class="{ 'active': isSelected() }" uib-popover-template="'EntityNodeInfoTemplate.html'" popover-trigger="'mouseenter'" popover-placement="right" popover-popup-delay="1000">
         <a ng-href="{{getHref()}}" class="entity-node-link">
             <brooklyn-status-icon value="{{entity.serviceState}}" ng-if="entity.serviceState || entity.applicationId"></brooklyn-status-icon>
             <i class="fa fa-2x fa-external-link" ng-if="!entity.serviceState && !entity.applicationId"></i>
-            <span>{{entity.name}}</span>
+            <span ng-class="{ 'secondary' : isSecondary() }">{{entity.name}}</span>
             <span class="node-icon"><img ng-src="{{ iconUrl }}"/></span>
         </a>
         <div class="entity-node-toggle-wrapper">
diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-node.less b/ui-modules/app-inspector/app/components/entity-tree/entity-node.less
index a3fe401..f8ff200 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-node.less
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-node.less
@@ -47,9 +47,6 @@
     border-radius: @border-radius-base;
     box-shadow: 0 1px 2px rgba(0,0,0,0.1);
     transition: all .2s ease-in-out;
-    &.secondary {
-      background-color: lighten(@brand-primary, 55%);
-    }
     &:hover {
       background-color: @body-bg;
     }
@@ -76,6 +73,9 @@
         flex-grow: 1;
         padding-top: 3px;
         margin-left: 10px;
+        &.secondary {
+          color: @gray-lighter;
+        }
       }
     }
     .entity-node-toggle-wrapper {
diff --git a/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js b/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
index 43aad2c..5d4ebcd 100644
--- a/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
+++ b/ui-modules/app-inspector/app/components/entity-tree/entity-tree.directive.js
@@ -361,8 +361,8 @@ export function entityNodeDirective() {
         };
 
         // TODO SMART-143
-        $scope.isInSpotlight = function() {
-            return $scope.entity.viewModesSpotLight.has($scope.viewMode);
+        $scope.isSecondary = function() {
+            return !$scope.entity.viewModesSpotLight.has($scope.viewMode);
         };
 
         // TODO SMART-143