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 <[email protected]> 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 <[email protected]> --- .../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.
