This closes #142
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 9159b45..dd5fd6d 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
@@ -22,9 +22,12 @@
<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 class="node-icon"><img ng-src="{{ iconUrl }}"/></span>
</a>
- <div class="entity-node-toggle" ng-if="entity.children.length > 0 || entity.members.length > 0" ng-click="onToggle($event)" >
+ <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)" >
<span class="glyphicon" ng-class="isChildrenOpen ? 'glyphicon-chevron-up' : 'glyphicon-chevron-down'"></span>
+ </div>
</div>
</div>
<div class="entity-node-children" ng-show="isChildrenOpen">
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 619ee24..6b7e3c4 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
@@ -75,10 +75,27 @@
margin-left: 10px;
}
}
+ .entity-node-toggle-wrapper {
+ width: 38px;
+ flex-grow: 0;
+ }
.entity-node-toggle {
- flex-shrink: 1;
+ width: 38px;
padding: 12px;
cursor: row-resize;
}
}
+ .node-icon {
+ flex-grow: 0 !important;
+ max-height: 20px; //let it extend above and below span's boundaries
+ overflow: visible !important;
+ margin-top: -8px;
+ margin-left: 0 !important;
+ img {
+ .make-icon(36px);
+ }
+ img[src] {
+ margin-left: 10px;
+ }
+ }
}
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 b3f7c25..76183e7 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
@@ -78,11 +78,7 @@
vm.applications = response.data;
function spawnNotification(app, opts) {
- let baseType = app.type;
- if (baseType === 'org.apache.brooklyn.entity.stock.BasicApplication' && app.children.length === 1) {
- baseType = app.children[0].catalogItemId || app.children[0].type;
- }
- iconService.get(baseType).then((icon)=> {
+ iconService.get(app).then((icon)=> {
let options = Object.assign({
icon: app.iconUrl || icon,
}, opts);
@@ -110,7 +106,7 @@
applicationId: '<',
},
link: link,
- controller: ['$scope', '$state', '$stateParams', controller]
+ controller: ['$scope', '$state', '$stateParams', 'iconService', controller]
};
function link($scope) {
@@ -130,9 +126,10 @@
});
}
- function controller ($scope, $state, $stateParams) {
+ function controller ($scope, $state, $stateParams, iconService) {
$scope.isOpen = true;
-
+ iconService.get($scope.entity, true).then(value => $scope.iconUrl = value);
+
if ($stateParams.entityId === $scope.entity.id) {
$scope.$emit('notifyEntity', {
message: 'expandChildren',
diff --git a/ui-modules/app-inspector/app/views/main/inspect/summary/summary.controller.js b/ui-modules/app-inspector/app/views/main/inspect/summary/summary.controller.js
index 51b0af3..003613a 100644
--- a/ui-modules/app-inspector/app/views/main/inspect/summary/summary.controller.js
+++ b/ui-modules/app-inspector/app/views/main/inspect/summary/summary.controller.js
@@ -25,11 +25,11 @@
name: 'main.inspect.summary',
url: '/summary',
template: template,
- controller: ['$scope', '$state', '$stateParams', '$q', '$http', 'brSnackbar', 'entityApi', 'locationApi', summaryController],
+ controller: ['$scope', '$state', '$stateParams', '$q', '$http', 'brSnackbar', 'entityApi', 'locationApi', 'iconService', summaryController],
controllerAs: 'vm'
};
-export function summaryController($scope, $state, $stateParams, $q, $http, brSnackbar, entityApi, locationApi) {
+export function summaryController($scope, $state, $stateParams, $q, $http, brSnackbar, entityApi, locationApi, iconService) {
$scope.$emit(HIDE_INTERSTITIAL_SPINNER_EVENT);
const {
@@ -51,14 +51,14 @@
let observers = [];
entityApi.entity(applicationId, entityId).then((response)=> {
- vm.entity = response.data;
- vm.name = response.data.name;
- vm.error.entity = undefined;
- observers.push(response.subscribe((response)=> {
+ let set = (response) => {
vm.entity = response.data;
vm.name = response.data.name;
vm.error.entity = undefined;
- }));
+ iconService.get(response.data, true).then(value => vm.iconUrl = value);
+ };
+ set(response);
+ observers.push(response.subscribe(set));
}).catch((error)=> {
vm.error.entity = 'Cannot load entity with ID: ' + entityId;
});
diff --git a/ui-modules/app-inspector/app/views/main/inspect/summary/summary.less b/ui-modules/app-inspector/app/views/main/inspect/summary/summary.less
index ccd0ee0..059df66 100644
--- a/ui-modules/app-inspector/app/views/main/inspect/summary/summary.less
+++ b/ui-modules/app-inspector/app/views/main/inspect/summary/summary.less
@@ -20,14 +20,38 @@
.entity-header {
+
.entity-name {
+ display: flex;
border: none;
-webkit-font-smoothing: antialiased;
+ align-items: center;
+
+ .node-icon {
+ flex: 0 1 0px;
+ margin-left: 3px;
+ img[src] {
+ .make-icon(80px);
+ margin-right: 18px;
+ }
+ }
+
+ .node-name {
+ flex: 1 0 200px;
+ border: none;
+ }
+ .editable-wrap {
+ flex: 1 0 200px;
+ width: auto;
+ }
+
+ &.loading {
+ margin-left: 5px;
+ margin-top: 16px;
+ margin-bottom: 16px;
+ }
}
- .editable-wrap {
- width: 100%;
- }
-
+
.editable {
color: @primary-500;
height: 34px;
diff --git a/ui-modules/app-inspector/app/views/main/inspect/summary/summary.template.html b/ui-modules/app-inspector/app/views/main/inspect/summary/summary.template.html
index 8f5bea0..3d8f34d 100644
--- a/ui-modules/app-inspector/app/views/main/inspect/summary/summary.template.html
+++ b/ui-modules/app-inspector/app/views/main/inspect/summary/summary.template.html
@@ -19,8 +19,11 @@
<div class="entity-summary" ng-init="show = { status: true, mostRecentActivityInError: true, policies: true };">
<div class="tab-header">
<div class="entity-header">
- <h2 ng-if="!vm.entity" class="entity-name"><loading-state error="vm.error.entity"></loading-state></h2>
- <h2 ng-if="vm.entity" class="entity-name" editable-text="vm.name" blur="submit" buttons="no" blur="submit" onaftersave="vm.updateEntityName()">{{ vm.entity.name }}</h2>
+ <h2 ng-if="!vm.entity" class="entity-name loading"><loading-state error="vm.error.entity"></loading-state></h2>
+ <h2 ng-if="vm.entity" class="entity-name">
+ <span class="node-icon"><img ng-src="{{ vm.iconUrl }}"/></span>
+ <span class="node-name" editable-text="vm.name" blur="submit" buttons="no" blur="submit" onaftersave="vm.updateEntityName()">{{ vm.entity.name }}</span>
+ </h2>
</div>
<p ng-if="vm.sensors['main.uri']">
<a ng-href="{{vm.sensors['main.uri']}}">{{vm.sensors['main.uri']}}</a>
diff --git a/ui-modules/blueprint-composer/app/components/catalog-saver/catalog-saver.directive.js b/ui-modules/blueprint-composer/app/components/catalog-saver/catalog-saver.directive.js
index 435d758..705e085 100644
--- a/ui-modules/blueprint-composer/app/components/catalog-saver/catalog-saver.directive.js
+++ b/ui-modules/blueprint-composer/app/components/catalog-saver/catalog-saver.directive.js
@@ -225,7 +225,6 @@
link: function(scope, element, attr, ngModel) {
ngModel.$validators.composerBlueprintNameValidator = function(modelValue, viewValue) {
scope.updateDefaults(modelValue);
- console.log("valildating", scope.config.bundle, scope.config.symbolicName);
if (!ngModel.$isEmpty(modelValue)) {
// anything set is valid
return true;
diff --git a/ui-modules/blueprint-composer/app/index.less b/ui-modules/blueprint-composer/app/index.less
index e42474c..e91b16e 100644
--- a/ui-modules/blueprint-composer/app/index.less
+++ b/ui-modules/blueprint-composer/app/index.less
@@ -37,13 +37,6 @@
@import "components/dsl-editor/dsl-editor";
@import "components/dsl-viewer/dsl-viewer";
-.make-icon(@size) {
- width: auto;
- height: auto;
- max-width: @size;
- max-height: @size;
-}
-
.navbar {
margin-bottom: 0;
}
diff --git a/ui-modules/blueprint-composer/app/views/main/main.controller.js b/ui-modules/blueprint-composer/app/views/main/main.controller.js
index 87bf803..886b4a1 100644
--- a/ui-modules/blueprint-composer/app/views/main/main.controller.js
+++ b/ui-modules/blueprint-composer/app/views/main/main.controller.js
@@ -105,7 +105,6 @@
vm.saveToCatalogConfig = {};
if (edit) {
- console.log("edit", edit);
vm.saveToCatalogConfig = Object.assign(vm.saveToCatalogConfig, {
version: edit.type.version,
template: edit.type.template || false,
diff --git a/ui-modules/catalog/app/index.less b/ui-modules/catalog/app/index.less
index cbd7eea..18760e1 100644
--- a/ui-modules/catalog/app/index.less
+++ b/ui-modules/catalog/app/index.less
@@ -29,18 +29,6 @@
@import "views/bundle/type/type";
@import "views/bundle/type/modal";
-.make-icon(@size) {
- // this won't _increase_ size, that's more complicated. but it will cap both sizes while
- // keeping aspect ratio. if width or height are set they can interfere with the maxes to screw up aspect ratio.
- // https://stackoverflow.com/questions/12912048/how-to-maintain-aspect-ratio-using-html-img-tag
- width: auto;
- height: auto;
- max-width: @size;
- max-height: @size;
- // and center
- margin: auto;
-}
-
.snackbar {
z-index: 200;
}
diff --git a/ui-modules/home/app/index.less b/ui-modules/home/app/index.less
index a00daad..53be790 100644
--- a/ui-modules/home/app/index.less
+++ b/ui-modules/home/app/index.less
@@ -26,12 +26,6 @@
@import 'views/main/deploy/modal';
@import 'components/onboarding/onboarding';
-.make-icon(@size) {
- width: auto;
- height: auto;
- max-width: @size;
- max-height: @size;
-}
.hideMainContent {
display: none;
}
diff --git a/ui-modules/utils/br-core/style/mixins.less b/ui-modules/utils/br-core/style/mixins.less
index b4c8432..b33d574 100644
--- a/ui-modules/utils/br-core/style/mixins.less
+++ b/ui-modules/utils/br-core/style/mixins.less
@@ -55,3 +55,15 @@
font-size: 95%;
}
+.make-icon(@size) {
+ // this won't _increase_ size, that's more complicated. but it will cap both sizes while
+ // keeping aspect ratio. if width or height are set they can interfere with the maxes to screw up aspect ratio.
+ // https://stackoverflow.com/questions/12912048/how-to-maintain-aspect-ratio-using-html-img-tag
+ width: auto;
+ height: auto;
+ max-width: @size;
+ max-height: @size;
+ // and center
+ margin: auto;
+}
+
diff --git a/ui-modules/utils/icon-generator/icon-generator.js b/ui-modules/utils/icon-generator/icon-generator.js
index 682af6b..4839d88 100644
--- a/ui-modules/utils/icon-generator/icon-generator.js
+++ b/ui-modules/utils/icon-generator/icon-generator.js
@@ -63,17 +63,30 @@
}
export function iconGeneratorPipe(iconGenerator) {
- return function (input, field) {
- if (typeof(input) === 'object') {
+ return function (input, opts) {
+ let field, doNotAutogenerate=false;
+ if (opts) {
+ if (typeof opts === 'string') {
+ field = opts;
+ } else {
+ field = opts.field;
+ doNotAutogenerate = opts.doNotAutogenerate;
+ }
+ }
+ let generateFrom = input;
+ if (input && typeof(input) === 'object') {
if (input.hasOwnProperty('iconUrl') && input.iconUrl) {
return input.iconUrl;
} else if (input.hasOwnProperty('links') && input.links.hasOwnProperty('iconUrl') && input.links.iconUrl) {
return input.links.iconUrl;
} else if (input.hasOwnProperty(field || 'id')) {
- return iconGenerator(input[field || 'id'])
+ generateFrom = input[field || 'id'];
}
}
- return iconGenerator(input);
+ if (doNotAutogenerate) {
+ return null;
+ }
+ return iconGenerator(generateFrom);
}
}
@@ -104,21 +117,49 @@
export function iconServiceProvider() {
return {
- $get: ['$q', '$http', 'iconGenerator', function ($q, $http, iconGenerator) {
- return new IconService($q, $http, iconGenerator, new SessionsStorageWrapper(CACHE_NAME));
+ $get: ['$q', '$http', 'iconGenerator', '$log', function ($q, $http, iconGenerator, $log) {
+ return new IconService($q, $http, iconGenerator, $log, new SessionsStorageWrapper(CACHE_NAME));
}]
}
}
-function IconService($q, $http, iconGenerator, cache) {
+function IconService($q, $http, iconGenerator, $log, cache) {
this.get = getIcon;
- function getIcon(id) {
+ function getIcon(entityOrTypeId, doNotAutogenerate) {
let deferred = $q.defer();
+
+ let id;
+ if (typeof entityOrTypeId === 'string') {
+ id = entityOrTypeId;
+ } else if (typeof entityOrTypeId === 'object') {
+ if (entityOrTypeId.iconUrl) {
+ deferred.resolve(entityOrTypeId.iconUrl);
+ return deferred.promise;
+ }
+ if (entityOrTypeId.links && entityOrTypeId.links.iconUrl) {
+ deferred.resolve(entityOrTypeId.links.iconUrl);
+ return deferred.promise;
+ }
+ if (entityOrTypeId.catalogItemId) {
+ id = entity.catalogItemId;
+ } else if (entityOrTypeId.symbolicName) {
+ id = entity.symbolicName;
+ } else if (entityOrTypeId.type) {
+ let entity = entityOrTypeId;
+ id = entity.type;
+ if (id === 'org.apache.brooklyn.entity.stock.BasicApplication' && entity.children && entity.children.length === 1) {
+ id = entity.children[0].catalogItemId || entity.children[0].type;
+ }
+ }
+ }
+
let icon;
if (angular.isDefined(id)) {
icon = cache.get(id);
} else {
- deferred.reject('Icon ID no defined');
+ $log.warn('No ID found for item, cannot make icon - '+entityOrTypeId, entityOrTypeId);
+ deferred.reject('No ID found for item, cannot make icon - '+entityOrTypeId);
+ return deferred.promise;
}
if (angular.isUndefined(icon)) {
let path = id.split(':');
@@ -130,6 +171,8 @@
if (response.data.hasOwnProperty('iconUrl')) {
icon = response.data.iconUrl;
cache.put(id, icon);
+ } else if (doNotAutogenerate) {
+ icon = null;
} else {
icon = iconGenerator(id);
}