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 2018/11/08 15:28:46 UTC

[1/3] brooklyn-ui git commit: Apply naming convention for templates used with $templateCache

Repository: brooklyn-ui
Updated Branches:
  refs/heads/master bf3477bfd -> 43c154c39


Apply naming convention for templates used with $templateCache

This is using the following: <module-id>/(component|view)/<component-id>/<template-id>.html


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/fd169a7b
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/fd169a7b
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/fd169a7b

Branch: refs/heads/master
Commit: fd169a7bea1c9ac9b35f9e9f6cdc4a7b6f9a15d3
Parents: bf3477b
Author: Thomas Bouron <th...@cloudsoftcorp.com>
Authored: Wed Nov 7 09:39:34 2018 +0000
Committer: Thomas Bouron <th...@cloudsoftcorp.com>
Committed: Wed Nov 7 11:38:53 2018 +0000

----------------------------------------------------------------------
 .../catalog-selector.directive.js               |  8 ++-----
 .../catalog-selector.template.html              |  4 ++--
 .../spec-editor/spec-editor.template.html       | 24 ++++++++++----------
 3 files changed, 16 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/fd169a7b/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.directive.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.directive.js b/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.directive.js
index b8b3bc6..9e8774b 100644
--- a/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.directive.js
+++ b/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.directive.js
@@ -411,12 +411,8 @@ function controller($scope, $element, $timeout, $q, $uibModal, $log, $templateCa
     // it is used by catalogSelectorFiltersFilter; 
     $scope.filterPaletteItemsForMode = (items) => items;
 
-    // downstream can override this to insert lines below the header
-    $scope.customSubHeadTemplateName = 'composer-palette-empty-sub-head';
-    $templateCache.put($scope.customSubHeadTemplateName, '');
-    
-    $scope.customFooterTemplateName = 'composer-palette-default-footer';
-    $templateCache.put($scope.customFooterTemplateName, footerTemplate);
+    $templateCache.put('blueprint-composer/component/catalog-selector/subhead.html', '');
+    $templateCache.put('blueprint-composer/component/catalog-selector/footer.html', footerTemplate);
 
     // allow downstream to configure this controller and/or scope
     (composerOverrides.configurePaletteController || function() {})(this, $scope, $element);

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/fd169a7b/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.template.html
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.template.html b/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.template.html
index 3b6eaa3..5b4ddb9 100644
--- a/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.template.html
+++ b/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.template.html
@@ -92,7 +92,7 @@
                 </ul>
               </span>
             </div>
-            <ng-include src="customSubHeadTemplateName"/>
+            <ng-include src="blueprint-composer/component/catalog-selector/subhead.html"/>
         </div>
       </div>
 
@@ -146,7 +146,7 @@
 
         <div class="catalog-palette-footer">
             <div uib-pagination total-items="searchedItems.length" items-per-page="pagination.itemsPerPage" ng-model="pagination.page" boundary-link-numbers="true" rotate="false" max-size="4" ng-show="searchedItems.length > pagination.itemsPerPage" class="pagination-sm pull-right"></div>
-            <ng-include src="customFooterTemplateName"/>
+            <ng-include src="blueprint-composer/component/catalog-selector/footer.html"/>
         </div>
     </div>
 </div>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/fd169a7b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
index 937bbaa..8dec82b 100644
--- a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
+++ b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
@@ -309,7 +309,7 @@
                                             class="open-entity-spec"
                                             title="Open in spec editor"
                                             ng-focus="specEditor.recordFocus(item)"></a>
-                                <ng-include src="'AdjunctTemplate.html'"></ng-include>
+                                <ng-include src="'blueprint-composer/component/spec-editor/adjunct.html'"></ng-include>
                             </div>
                             <a ng-if="!config[item.name][REPLACED_DSL_ENTITYSPEC]" ui-sref="main.graphical.edit.add({entityId: model._id, family: 'spec', configKey: item.name})" class="no-spec">
                                 (no spec set)
@@ -341,8 +341,8 @@
 </br-collapsible>
 
 <!-- ENTITY LOCATION -->
-<ng-include src="'SpecEditorLocationSection.html'"></ng-include>
-<script type="text/ng-template" id="SpecEditorLocationSection.html">
+<ng-include src="'blueprint-composer/component/spec-editor/section-locations.html'"></ng-include>
+<script type="text/ng-template" id="blueprint-composer/component/spec-editor/section-locations.html">
   <br-collapsible ng-if="[FAMILIES.ENTITY, FAMILIES.SPEC].indexOf(model.family) > -1" state="state.location.open">
     <heading>
         Location
@@ -371,8 +371,8 @@
 </script>
 
 <!-- ENTITY POLICIES -->
-<ng-include src="'SpecEditorPoliciesSection.html'"></ng-include>
-<script type="text/ng-template" id="SpecEditorPoliciesSection.html">
+<ng-include src="'blueprint-composer/component/spec-editor/section-policies.html'"></ng-include>
+<script type="text/ng-template" id="blueprint-composer/component/spec-editor/section-policies.html">
   <br-collapsible ng-if="[FAMILIES.ENTITY, FAMILIES.SPEC].indexOf(model.family) > -1" state="state.policy.open">
     <heading>
         Policies
@@ -400,15 +400,15 @@
 
         <div ng-repeat="adjunct in filteredPolicies = (model.getPoliciesAsArray() | specEditorType:state.policy.search) track by adjunct._id" class="spec-policy spec-adjunct">
             <a ui-sref="main.graphical.edit.policy({entityId: model._id, policyId: adjunct._id})"></a>
-            <ng-include src="'AdjunctTemplate.html'"></ng-include>
+            <ng-include src="'blueprint-composer/component/spec-editor/adjunct.html'"></ng-include>
         </div>
     </div>
   </br-collapsible>
 </script>
 
 <!-- ENTITY ENRICHERS -->
-<ng-include src="'SpecEditorEnrichersSection.html'"></ng-include>
-<script type="text/ng-template" id="SpecEditorEnrichersSection.html">
+<ng-include src="'blueprint-composer/component/spec-editor/section-enrichers.html'"></ng-include>
+<script type="text/ng-template" id="blueprint-composer/component/spec-editor/section-enrichers.html">
   <br-collapsible ng-if="[FAMILIES.ENTITY, FAMILIES.SPEC].indexOf(model.family) > -1" state="state.enricher.open">
     <heading>
         Enrichers
@@ -436,14 +436,14 @@
 
         <div ng-repeat="adjunct in filteredEnrichers = (model.getEnrichersAsArray() | specEditorType:state.enricher.search) track by adjunct._id" class="spec-enricher spec-adjunct">
             <a ui-sref="main.graphical.edit.enricher({entityId: model._id, enricherId: adjunct._id})"></a>
-            <ng-include src="'AdjunctTemplate.html'"></ng-include>
+            <ng-include src="'blueprint-composer/component/spec-editor/adjunct.html'"></ng-include>
         </div>
     </div>
   </br-collapsible>
 </script>
 
-<ng-include src="'SpecEditorOtherSections.html'"></ng-include>
-<script type="text/ng-template" id="SpecEditorOtherSections.html">
+<ng-include src="'blueprint-composer/component/spec-editor/section-others.html'"></ng-include>
+<script type="text/ng-template" id="blueprint-composer/component/spec-editor/section-others.html">
 </script>
 
 
@@ -494,7 +494,7 @@
 <!--TYPEAHEAD TEMPLATE :: END-->
 
 <!--ADJUNCT TEMPLATE :: START-->
-<script type="text/ng-template" id="AdjunctTemplate.html">
+<script type="text/ng-template" id="blueprint-composer/component/spec-editor/adjunct.html">
     <div class="media" ng-class="{'has-issues': adjunct.hasIssues()}">
         <div class="media-left media-middle">
             <img ng-src="{{adjunct.icon}}" alt="{{adjunct | entityName}} logo" class="media-object" />


[2/3] brooklyn-ui git commit: Modularise components for blueprint composer + update directive to use $templateCache

Posted by he...@apache.org.
Modularise components for blueprint composer + update directive to use $templateCache


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/0f72a003
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/0f72a003
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/0f72a003

Branch: refs/heads/master
Commit: 0f72a003dfdb272bbb6990865fd07bc419de3c78
Parents: fd169a7
Author: Thomas Bouron <th...@cloudsoftcorp.com>
Authored: Wed Nov 7 11:32:20 2018 +0000
Committer: Thomas Bouron <th...@cloudsoftcorp.com>
Committed: Wed Nov 7 13:34:45 2018 +0000

----------------------------------------------------------------------
 .../blueprint-data-manager.directive.js         |  28 +-
 .../breacrumbs/breadcrumbs.directive.js         |  44 +-
 .../catalog-saver/catalog-saver.directive.js    |  22 +-
 .../catalog-selector.directive.js               | 569 ++++++++++---------
 .../catalog-selector.template.html              |  10 +-
 .../suggestion-dropdown.html                    |   2 +-
 .../custom-config-widget/suggestion-dropdown.js |  13 +-
 .../components/designer/designer.directive.js   |  21 +-
 .../app/components/dsl-editor/dsl-editor.js     |  12 +-
 .../app/components/dsl-viewer/dsl-viewer.js     |  12 +-
 .../factories/object-cache.factory.js           |   9 +
 .../factories/recursion-helper.factory.js       |  61 --
 .../app/components/filters/entity.filter.js     |  11 +
 .../app/components/filters/locations.filter.js  |   9 +
 .../providers/action-service.provider.js        |  11 +-
 .../providers/blueprint-service.provider.js     |   8 +
 .../providers/dsl-service.provider.js           |   7 +
 .../providers/palette-dragndrop.provider.js     |   7 +
 .../providers/recently-used-service.provider.js |   8 +
 .../spec-editor/spec-editor.template.html       |  16 +-
 ui-modules/blueprint-composer/app/index.js      |  55 +-
 21 files changed, 510 insertions(+), 425 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/blueprint-data-manager/blueprint-data-manager.directive.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/blueprint-data-manager/blueprint-data-manager.directive.js b/ui-modules/blueprint-composer/app/components/blueprint-data-manager/blueprint-data-manager.directive.js
index b3e0eac..e448d53 100644
--- a/ui-modules/blueprint-composer/app/components/blueprint-data-manager/blueprint-data-manager.directive.js
+++ b/ui-modules/blueprint-composer/app/components/blueprint-data-manager/blueprint-data-manager.directive.js
@@ -16,15 +16,27 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import template from "./blueprint-data-manager.template.html";
-import {saveAs} from "file-saver/FileSaver";
-const VALID_FILENAME_REGEX = /^.*\.ya?ml$/
-const FILETYPE_TOKEN_REGEX = /^.*\.(.*)$/
+import angular from 'angular';
+import template from './blueprint-data-manager.template.html';
+import {saveAs} from 'file-saver/FileSaver';
+
+const MODULE_NAME = 'brooklyn.components.blueprint-data-manager';
+const TEMPLATE_URL = 'blueprint-composer/component/blueprint-data-manager/index.html';
+const VALID_FILENAME_REGEX = /^.*\.ya?ml$/;
+const FILETYPE_TOKEN_REGEX = /^.*\.(.*)$/;
+
+angular.module(MODULE_NAME, [])
+    .directive('blueprintDataManager', blueprintDataManagerDirective)
+    .run(['$templateCache', templateCache]);
+
+export default MODULE_NAME;
 
 export function blueprintDataManagerDirective() {
     return {
         restrict: 'E',
-        template: template,
+        templateUrl: function(tElement, tAttrs) {
+            return tAttrs.templateUrl || TEMPLATE_URL;
+        },
         controller: ['$rootScope', '$scope', '$element', '$document', 'blueprintService', 'brSnackbar', controller]
     };
 
@@ -88,7 +100,7 @@ export function blueprintDataManagerDirective() {
         function readFile(file) {
             if (VALID_FILENAME_REGEX.test(file.name)) {
                 var reader = new FileReader();
-                reader.addEventListener("load", function () {
+                reader.addEventListener('load', function () {
                     try {
                         var yaml = reader.result;
                         blueprintService.setFromYaml(yaml, true);
@@ -118,3 +130,7 @@ export function blueprintDataManagerDirective() {
         });
     }
 }
+
+function templateCache($templateCache) {
+    $templateCache.put(TEMPLATE_URL, template);
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/breacrumbs/breadcrumbs.directive.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/breacrumbs/breadcrumbs.directive.js b/ui-modules/blueprint-composer/app/components/breacrumbs/breadcrumbs.directive.js
index 72b6ea8..6c5edd1 100644
--- a/ui-modules/blueprint-composer/app/components/breacrumbs/breadcrumbs.directive.js
+++ b/ui-modules/blueprint-composer/app/components/breacrumbs/breadcrumbs.directive.js
@@ -16,33 +16,49 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import angular from 'angular';
 import template from './breadcrumbs.template.html';
 
+const MODULE_NAME = 'brooklyn.components.breadcrumbs';
+const TEMPLATE_URL = 'blueprint-composer/component/breadcrumbs/index.html';
+
+angular.module(MODULE_NAME, [])
+    .directive('breadcrumbs', breadcrumbsDirective)
+    .run(['$templateCache', templateCache]);
+
+export default MODULE_NAME;
+
 export function breadcrumbsDirective() {
     return {
         restrict: 'E',
+        templateUrl: function(tElement, tAttrs) {
+            return tAttrs.templateUrl || TEMPLATE_URL;
+        },
         scope: {
             entity: '<',
             current: '<'
         },
-        template: template,
         link: link
-    }
-}
+    };
 
-function link(scope) {
-    if (scope.entity) {
-        scope.breadcrumbs = [];
-        if (scope.current) {
-            scope.breadcrumbs.push(scope.current);
-        }
+    function link(scope) {
+        if (scope.entity) {
+            scope.breadcrumbs = [];
+            if (scope.current) {
+                scope.breadcrumbs.push(scope.current);
+            }
 
-        let currentEntity = scope.entity;
-        while (currentEntity.hasParent()) {
+            let currentEntity = scope.entity;
+            while (currentEntity.hasParent()) {
+                scope.breadcrumbs.push(currentEntity);
+                currentEntity = currentEntity.parent;
+            }
             scope.breadcrumbs.push(currentEntity);
-            currentEntity = currentEntity.parent;
+            scope.breadcrumbs.reverse();
         }
-        scope.breadcrumbs.push(currentEntity);
-        scope.breadcrumbs.reverse();
     }
+}
+
+function templateCache($templateCache) {
+    $templateCache.put(TEMPLATE_URL, template);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/catalog-saver/catalog-saver.directive.js
----------------------------------------------------------------------
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 cb6f0ea..bdfaa67 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
@@ -23,10 +23,10 @@ import template from './catalog-saver.template.html';
 import modalTemplate from './catalog-saver.modal.template.html';
 import jsYaml from 'js-yaml';
 import brUtils from 'brooklyn-ui-utils/utils/general';
-import {yamlState} from "../../views/main/yaml/yaml.state";
-import {graphicalState} from "../../views/main/graphical/graphical.state";
 
 const MODULE_NAME = 'brooklyn.components.catalog-saver';
+const TEMPLATE_URL = 'blueprint-composer/component/catalog-saver/index.html';
+const TEMPLATE_MODAL_URL = 'blueprint-composer/component/catalog-saver/modal.html';
 
 const REASONS = {
     new: 0,
@@ -43,14 +43,17 @@ const TYPES = [
 
 angular.module(MODULE_NAME, [angularAnimate, uibModal, brUtils])
     .directive('catalogSaver', ['$rootScope', '$uibModal', '$injector', 'composerOverrides', saveToCatalogModalDirective])
-    .directive('catalogVersion', ['$parse', catalogVersionDirective]);
+    .directive('catalogVersion', ['$parse', catalogVersionDirective])
+    .run(['$templateCache', templateCache]);
 
 export default MODULE_NAME;
 
 export function saveToCatalogModalDirective($rootScope, $uibModal, $injector, composerOverrides) {
     return {
         restrict: 'E',
-        template: template,
+        templateUrl: function (tElement, tAttrs) {
+            return tAttrs.templateUrl || TEMPLATE_URL;
+        },
         scope: {
             config: '='
         },
@@ -60,14 +63,12 @@ export function saveToCatalogModalDirective($rootScope, $uibModal, $injector, co
     function link($scope, $element) {
         $scope.buttonText = $scope.config.label || ($scope.config.itemType ? `Update ${$scope.config.name || $scope.config.symbolicName}` : 'Add to catalog');
 
-        $injector.get('$templateCache').put('catalog-saver.modal.template.html', modalTemplate);
-
         $scope.activateModal = () => {
             // Override callback to update catalog configuration data in other applications
             $scope.config = (composerOverrides.updateCatalogConfig || (($scope, $element) => $scope.config))($scope, $element);
 
             let modalInstance = $uibModal.open({
-                templateUrl: 'catalog-saver.modal.template.html',
+                templateUrl: TEMPLATE_MODAL_URL,
                 size: 'save',
                 controller: ['$scope', 'blueprintService', 'paletteApi', 'brUtilsGeneral', CatalogItemModalController],
                 scope: $scope,
@@ -162,7 +163,7 @@ export function catalogVersionDirective($parse) {
         link: link
     };
 
-    function link (scope, elm, attr, ctrl) {
+    function link(scope, elm, attr, ctrl) {
         if (!ctrl) {
             return;
         }
@@ -188,3 +189,8 @@ export function catalogVersionDirective($parse) {
         };
     }
 }
+
+function templateCache($templateCache) {
+    $templateCache.put(TEMPLATE_URL, template);
+    $templateCache.put(TEMPLATE_MODAL_URL, modalTemplate);
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.directive.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.directive.js b/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.directive.js
index 9e8774b..2cad3ef 100644
--- a/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.directive.js
+++ b/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.directive.js
@@ -22,6 +22,10 @@ import template from './catalog-selector.template.html';
 import footerTemplate from './catalog-selector-palette-footer.html';
 import { distanceInWordsToNow } from 'date-fns';
 
+const MODULE_NAME = 'brooklyn.composer.component.catalog-selector';
+const TEMPLATE_URL = 'blueprint-composer/component/catalog-selector/index.html';
+const TEMPLATE_SUBHEAD_URL = 'blueprint-composer/component/catalog-selector/subhead.html';
+const TEMPLATE_FOOTER_URL = 'blueprint-composer/component/catalog-selector/footer.html';
 const MIN_ROWS_PER_PAGE = 4;
 
 const PALETTE_VIEW_ORDERS = {
@@ -43,9 +47,20 @@ const PALETTE_VIEW_MODES = {
 // fields in either bundle or type record:
 const FIELDS_TO_SEARCH = ['displayName', 'name', 'symbolicName', 'type', 'version', 'containingBundle', 'description', 'displayTags', 'tags', 'supertypes'];
 
+angular.module(MODULE_NAME, [])
+    .directive('catalogSelector', catalogSelectorDirective)
+    .filter('catalogSelectorSearch', catalogSelectorSearchFilter)
+    .filter('catalogSelectorFilters', catalogSelectorFiltersFilter)
+    .run(['$templateCache', templateCache]);
+
+export default MODULE_NAME;
+
 export function catalogSelectorDirective() {
     return {
         restrict: 'E',
+        templateUrl: function (tElement, tAttrs) {
+            return tAttrs.templateUrl || TEMPLATE_URL;
+        },
         scope: {
             family: '<',
             onSelect: '&', // action to do when item is selected
@@ -56,36 +71,291 @@ export function catalogSelectorDirective() {
             state: '<?', // for shared state usage
             mode: '@?',  // for use by downstream projects to pass in special modes to do add'l processing / rendering
         },
-        template: template,
         controller: ['$scope', '$element', '$timeout', '$q', '$uibModal', '$log', '$templateCache', 'paletteApi', 'paletteDragAndDropService', 'iconGenerator', 'composerOverrides', 'recentlyUsedService', controller],
         link: link,
     };
-}
 
-function link($scope, $element, attrs, controller) {
-    let main = angular.element($element[0].querySelector(".catalog-palette-main"));
 
-    // repaginate when load completes (and items are shown), or it is resized
-    $scope.$watchGroup(
-        [ () => $scope.isLoading, () => main[0].offsetHeight, () => $scope.state.viewMode.itemsPerRow ],
-        (values) => controller.$timeout( () => repaginate($scope, $element) ) );
-    // also repaginate on window resize    
-    angular.element(window).bind('resize', () => repaginate($scope, $element));
-}
-
-function repaginate($scope, $element) {
-    let rowsPerPage = $scope.rowsPerPage;
-    if (!rowsPerPage) {
+    function link($scope, $element, attrs, controller) {
         let main = angular.element($element[0].querySelector(".catalog-palette-main"));
-        if (!main || main[0].offsetHeight==0) {
-            // no main, or hidden, or items per page fixed
-            return;
+
+        // repaginate when load completes (and items are shown), or it is resized
+        $scope.$watchGroup(
+            [() => $scope.isLoading, () => main[0].offsetHeight, () => $scope.state.viewMode.itemsPerRow],
+            (values) => controller.$timeout(() => repaginate($scope, $element)));
+        // also repaginate on window resize
+        angular.element(window).bind('resize', () => repaginate($scope, $element));
+
+        $scope.templateUrls = {
+            subhead: TEMPLATE_SUBHEAD_URL,
+            footer: TEMPLATE_FOOTER_URL
         }
-        let header = angular.element(main[0].querySelector(".catalog-palette-header"));
-        let footer = angular.element(main[0].querySelector(".catalog-palette-footer"));
-        rowsPerPage = Math.max(MIN_ROWS_PER_PAGE, Math.floor( (main[0].offsetHeight - header[0].offsetHeight - footer[0].offsetHeight - 16) / ($scope.state.viewMode.rowHeightPx || 96)) );
     }
-    $scope.$apply( () => $scope.pagination.itemsPerPage = rowsPerPage * $scope.state.viewMode.itemsPerRow );
+
+    function controller($scope, $element, $timeout, $q, $uibModal, $log, $templateCache, paletteApi, paletteDragAndDropService, iconGenerator, composerOverrides, recentlyUsedService) {
+        this.$timeout = $timeout;
+
+        $scope.viewModes = PALETTE_VIEW_MODES;
+        $scope.viewOrders = PALETTE_VIEW_ORDERS;
+
+        if (!$scope.state) $scope.state = {};
+        if (!$scope.state.viewMode) $scope.state.viewMode = PALETTE_VIEW_MODES.normal;
+
+        $scope.pagination = {
+            page: 1,
+            itemsPerPage: $scope.state.viewMode.itemsPerRow * ($scope.rowsPerPage || 1)  // will fill out after load
+        };
+
+        $scope.getEntityNameForPalette = function(item, entityName) {
+            return (composerOverrides.getEntityNameForPalette ||
+                // above can be overridden with function of signature below to customize display name in palette
+                function(item, entityName, scope) { return entityName; }
+            )(item, entityName, $scope);
+        };
+
+        $scope.getPlaceHolder = function () {
+            return 'Search';
+        };
+
+        $scope.isLoading = true;
+
+        $scope.$watch('search', () => {
+            $scope.freeFormTile = {
+                symbolicName: $scope.search,
+                name: $scope.search,
+                displayName: $scope.search,
+                supertypes: ($scope.family ? [ $scope.family.superType ] : []),
+            };
+        });
+
+        $scope.getItems = function (search) {
+            let defer = $q.resolve([]);
+
+            switch ($scope.family) {
+                case EntityFamily.ENTITY:
+                case EntityFamily.SPEC:
+                    defer = paletteApi.getTypes({params: {supertype: 'entity', fragment: search}});
+                    break;
+                case EntityFamily.POLICY:
+                    defer = paletteApi.getTypes({params: {supertype: 'policy', fragment: search}});
+                    break;
+                case EntityFamily.ENRICHER:
+                    defer = paletteApi.getTypes({params: {supertype: 'enricher', fragment: search}});
+                    break;
+                case EntityFamily.LOCATION:
+                    defer = paletteApi.getLocations();
+                    break;
+            }
+
+            return defer.then(data => {
+                data = $scope.filterPaletteItemsForMode(data, $scope);
+                data.forEach( recentlyUsedService.embellish );
+                return data;
+
+            }).catch(error => {
+                return [];
+            }).finally(() => {
+                $scope.isLoading = false;
+            });
+        };
+        function tryMarkUsed(item) {
+            try {
+                recentlyUsedService.markUsed(item);
+            } catch (e) {
+                // session storage can get full; usually the culprit is icons not this,
+                // but we may wish to clear out old items to ensure we don't bleed here
+                $log.warn("Could not mark item as used: "+item, e);
+            }
+        }
+        $scope.mouseInfoPopover = (item, enter) => {
+            if ($scope.popoverModal && $scope.popoverVisible && $scope.popover==item) {
+                // ignore if modal
+                return;
+            }
+            $scope.popoverModal = false;
+            if (enter) {
+                $scope.popover = item;
+                $scope.popoverVisible = true;
+            } else {
+                $scope.popoverVisible = false;
+            }
+        };
+        $scope.onClickItem = (item, isInfoIcon, $event) => {
+            if (!isInfoIcon && $scope.iconSelects) {
+                $scope.onSelectItem(item);
+            } else if ($scope.popoverModal && $scope.popoverVisible && $scope.popover == item) {
+                $scope.closePopover();
+            } else {
+                $scope.popover = item;
+                $scope.popoverVisible = true;
+                $scope.popoverModal = true;
+            }
+            $event.stopPropagation();
+        };
+        $scope.closePopover = () => {
+            $scope.popoverVisible = false;
+            $scope.popoverModal = false;
+        };
+        $scope.getOnSelectText = function (item) {
+            if (!($scope.onSelectText)) return "Select";
+            return $scope.onSelectText({item: item});
+        };
+        $scope.onSelectItem = function (item) {
+            $scope.closePopover();
+            if (angular.isFunction($scope.onSelect)) {
+                tryMarkUsed(item);
+                $scope.onSelect({item: item});
+            }
+            $scope.search = '';
+        };
+        $scope.onDragItem = function (item, event) {
+            let frame = document.createElement('div');
+            frame.classList.add('drag-frame');
+            event.target.appendChild(frame);
+            setTimeout(function() {
+                // can remove at end of this cycle, browser will have grabbed its drag image
+                frame.parentNode.removeChild(frame);
+            }, 0);
+            /* have tried many other ways to get a nice drag image;
+               this seems to work best, adding an empty div which forces the size to be larger,
+               so when grabbing the image it grabs the drop-shadow.
+               things that _didn't_ work include:
+               - styling event.target now then unstyling (normally this would work, in posts on the web, but it doesn't here; angular?)
+               - make a restyled cloned copy offscreen (this comes so close but remote img srcs aren't loaded
+             */
+
+            paletteDragAndDropService.dragStart(item);
+        };
+        $scope.onDragEnd = function (item, event) {
+            paletteDragAndDropService.dragEnd();
+            tryMarkUsed(item);
+        };
+
+        $scope.getOpenCatalogLink = (item) => {
+            return "/brooklyn-ui-catalog/#!/bundles/"+item.containingBundle.replace(":","/")+"/types/"+item.symbolicName+"/"+item.version;
+        };
+        $scope.sortBy = function (order) {
+            let newFirst = {};
+            if (order) {
+                newFirst[order.id] = order;
+            }
+            $scope.state.currentOrder = Object.assign(newFirst, $scope.state.currentOrder, newFirst);
+            $scope.state.currentOrderFields = [];
+            $scope.state.currentOrderValues = [];
+            Object.values($scope.state.currentOrder).forEach( it => {
+                $scope.state.currentOrderValues.push(it);
+                $scope.state.currentOrderFields.push(it.field);
+            });
+        };
+        if (!$scope.state.currentOrder) $scope.state.currentOrder = Object.assign({}, PALETTE_VIEW_ORDERS);
+        $scope.sortBy();
+
+        $scope.allowFreeForm = function () {
+            return [
+                EntityFamily.LOCATION
+            ].indexOf($scope.family) > -1;
+        };
+        $scope.isReserved = function () {
+            if (!$scope.reservedKeys || !angular.isArray($scope.reservedKeys)) {
+                return false;
+            }
+            return $scope.reservedKeys.indexOf($scope.search) > -1;
+        };
+        $scope.onImageError = (scope, el, attrs) => {
+            $log.warn("Icon for "+attrs.itemId+" at "+angular.element(el).attr("src")+" could not be loaded; generating icon");
+            angular.element(el).attr("src", iconGenerator(attrs.itemId));
+        };
+
+        // Init
+        $scope.items = [];
+        function getDisplayTags(tags) {
+            if (!tags || !tags.length || !tags.reduce) return tags;
+            return tags.reduce((result, tag) => {
+                if (!(/[=:\[\]()]/.exec(tag))) {
+                    result.push(tag);
+                }
+                return result;
+            }, []);
+        }
+        $scope.getItems().then((items)=> {
+            // add displayTags, as any tag that doesn't contain = : or ( ) [ ]
+            // any tag that is an object will be eliminated as it is toStringed to make [ object object ]
+            items.forEach(item => {
+                if (item.tags) {
+                    item.displayTags = getDisplayTags(item.tags);
+                }
+            });
+            $scope.items = items;
+        });
+        $scope.lastUsedText = (item) => {
+            if (item==null) return "";
+            let l = (Number)(item.lastUsed);
+            if (!l || isNaN(l) || l<=0) return "";
+            if (l < 100000) return 'Preselected for inclusion in "Recent" filter.';
+            return 'Last used: ' + distanceInWordsToNow(l, { includeSeconds: true, addSuffix: true });
+        };
+
+        $scope.showPaletteControls = false;
+        $scope.onFiltersShown = () => {
+            $timeout( () => {
+                // check do we need to show the multiline
+                let filters = angular.element($element[0].querySelector(".filters"));
+                $scope.$apply( () => $scope.filterSettings.filtersMultilineAvailable = filters[0].scrollHeight > filters[0].offsetHeight + 6 );
+
+                repaginate($scope, $element);
+            } );
+        };
+        $scope.togglePaletteControls = () => {
+            $scope.showPaletteControls = !$scope.showPaletteControls;
+            $timeout( () => repaginate($scope, $element) );
+        };
+        $scope.toggleShowAllFilters = () => {
+            $scope.filterSettings.showAllFilters = !$scope.filterSettings.showAllFilters;
+            $timeout( () => repaginate($scope, $element) );
+        };
+        $scope.filterSettings = {};
+
+        $scope.filters = [
+            { label: 'Recent', icon: 'clock-o', title: "Recently used and standard favorites", limitToOnePage: true,
+                filterInit: items => {
+                    $scope.recentItems = items.filter( i => i.lastUsed && i.lastUsed>0 );
+                    $scope.recentItems.sort( (a,b) => b.lastUsed - a.lastUsed );
+                    return $scope.recentItems;
+                }, enabled: false },
+        ];
+        $scope.disableFilters = (showFilters) => {
+            $scope.filters.forEach( f => f.enabled = false );
+            if (showFilters !== false) {
+                $scope.showPaletteControls = true;
+            }
+        };
+
+        // can be overridden to disable "open in catalog" button
+        $scope.allowOpenInCatalog = true;
+
+        // this can be overridden for palette sections/modes which show a subset of the types returned by the server;
+        // this is applied when the data is received from the server.
+        // it is used by catalogSelectorFiltersFilter;
+        $scope.filterPaletteItemsForMode = (items) => items;
+
+        // allow downstream to configure this controller and/or scope
+        (composerOverrides.configurePaletteController || function() {})(this, $scope, $element);
+    }
+
+    function repaginate($scope, $element) {
+        let rowsPerPage = $scope.rowsPerPage;
+        if (!rowsPerPage) {
+            let main = angular.element($element[0].querySelector(".catalog-palette-main"));
+            if (!main || main[0].offsetHeight == 0) {
+                // no main, or hidden, or items per page fixed
+                return;
+            }
+            let header = angular.element(main[0].querySelector(".catalog-palette-header"));
+            let footer = angular.element(main[0].querySelector(".catalog-palette-footer"));
+            rowsPerPage = Math.max(MIN_ROWS_PER_PAGE, Math.floor((main[0].offsetHeight - header[0].offsetHeight - footer[0].offsetHeight - 16) / ($scope.state.viewMode.rowHeightPx || 96)));
+        }
+        $scope.$apply(() => $scope.pagination.itemsPerPage = rowsPerPage * $scope.state.viewMode.itemsPerRow);
+    }
 }
 
 export function catalogSelectorSearchFilter() {
@@ -165,255 +435,8 @@ export function catalogSelectorFiltersFilter() {
     }
 }
 
-function controller($scope, $element, $timeout, $q, $uibModal, $log, $templateCache, paletteApi, paletteDragAndDropService, iconGenerator, composerOverrides, recentlyUsedService) {
-    this.$timeout = $timeout;
-
-    $scope.viewModes = PALETTE_VIEW_MODES;
-    $scope.viewOrders = PALETTE_VIEW_ORDERS;
-    
-    if (!$scope.state) $scope.state = {};
-    if (!$scope.state.viewMode) $scope.state.viewMode = PALETTE_VIEW_MODES.normal;
-    
-    $scope.pagination = {
-        page: 1,
-        itemsPerPage: $scope.state.viewMode.itemsPerRow * ($scope.rowsPerPage || 1)  // will fill out after load
-    };
-    
-    $scope.getEntityNameForPalette = function(item, entityName) {
-        return (composerOverrides.getEntityNameForPalette || 
-            // above can be overridden with function of signature below to customize display name in palette
-            function(item, entityName, scope) { return entityName; }
-        )(item, entityName, $scope);
-    }
-
-    $scope.getPlaceHolder = function () {
-        return 'Search';
-    };
-    
-    $scope.isLoading = true;
-
-    $scope.$watch('search', () => {
-        $scope.freeFormTile = {
-            symbolicName: $scope.search,
-            name: $scope.search,
-            displayName: $scope.search,
-            supertypes: ($scope.family ? [ $scope.family.superType ] : []),
-        };
-    });
-
-    $scope.getItems = function (search) {
-        let defer = $q.resolve([]);
-
-        switch ($scope.family) {
-            case EntityFamily.ENTITY:
-            case EntityFamily.SPEC:
-                defer = paletteApi.getTypes({params: {supertype: 'entity', fragment: search}});
-                break;
-            case EntityFamily.POLICY:
-                defer = paletteApi.getTypes({params: {supertype: 'policy', fragment: search}});
-                break;
-            case EntityFamily.ENRICHER:
-                defer = paletteApi.getTypes({params: {supertype: 'enricher', fragment: search}});
-                break;
-            case EntityFamily.LOCATION:
-                defer = paletteApi.getLocations();
-                break;
-        }
-
-        return defer.then(data => {
-            data = $scope.filterPaletteItemsForMode(data, $scope);
-            data.forEach( recentlyUsedService.embellish );
-            return data;
-            
-        }).catch(error => {
-            return [];
-        }).finally(() => {
-            $scope.isLoading = false;
-        });
-    };
-    function tryMarkUsed(item) {
-        try {
-            recentlyUsedService.markUsed(item);
-        } catch (e) {
-            // session storage can get full; usually the culprit is icons not this,
-            // but we may wish to clear out old items to ensure we don't bleed here
-            $log.warn("Could not mark item as used: "+item, e);
-        }
-    }
-    $scope.mouseInfoPopover = (item, enter) => {
-        if ($scope.popoverModal && $scope.popoverVisible && $scope.popover==item) {
-            // ignore if modal
-            return;
-        }
-        $scope.popoverModal = false;
-        if (enter) {
-            $scope.popover = item;
-            $scope.popoverVisible = true;
-        } else {
-            $scope.popoverVisible = false;
-        }
-    }
-    $scope.onClickItem = (item, isInfoIcon, $event) => {
-        if (!isInfoIcon && $scope.iconSelects) {
-            $scope.onSelectItem(item);
-        } else if ($scope.popoverModal && $scope.popoverVisible && $scope.popover == item) {
-            $scope.closePopover();
-        } else {
-            $scope.popover = item;
-            $scope.popoverVisible = true;
-            $scope.popoverModal = true;
-        }
-        $event.stopPropagation();
-    }
-    $scope.closePopover = () => {
-        $scope.popoverVisible = false;
-        $scope.popoverModal = false;
-    }
-    $scope.getOnSelectText = function (item) {
-        if (!($scope.onSelectText)) return "Select";
-        return $scope.onSelectText({item: item});
-    }
-    $scope.onSelectItem = function (item) {
-        $scope.closePopover();
-        if (angular.isFunction($scope.onSelect)) {
-            tryMarkUsed(item);
-            $scope.onSelect({item: item});
-        }
-        $scope.search = '';
-    };
-    $scope.onDragItem = function (item, event) {
-        let frame = document.createElement('div');
-        frame.classList.add('drag-frame');
-        event.target.appendChild(frame);
-        setTimeout(function() {
-            // can remove at end of this cycle, browser will have grabbed its drag image
-            frame.parentNode.removeChild(frame);
-        }, 0);
-        /* have tried many other ways to get a nice drag image;
-           this seems to work best, adding an empty div which forces the size to be larger,
-           so when grabbing the image it grabs the drop-shadow.
-           things that _didn't_ work include:
-           - styling event.target now then unstyling (normally this would work, in posts on the web, but it doesn't here; angular?)
-           - make a restyled cloned copy offscreen (this comes so close but remote img srcs aren't loaded
-         */
-        
-        paletteDragAndDropService.dragStart(item);
-    };
-    $scope.onDragEnd = function (item, event) {
-        paletteDragAndDropService.dragEnd();
-        tryMarkUsed(item);
-    };
-    
-    $scope.getOpenCatalogLink = (item) => {
-        return "/brooklyn-ui-catalog/#!/bundles/"+item.containingBundle.replace(":","/")+"/types/"+item.symbolicName+"/"+item.version;
-    }
-    $scope.sortBy = function (order) {
-        let newFirst = {};
-        if (order) {
-            newFirst[order.id] = order;
-        }
-        $scope.state.currentOrder = Object.assign(newFirst, $scope.state.currentOrder, newFirst);
-        $scope.state.currentOrderFields = [];
-        $scope.state.currentOrderValues = [];
-        Object.values($scope.state.currentOrder).forEach( it => {
-            $scope.state.currentOrderValues.push(it);
-            $scope.state.currentOrderFields.push(it.field);
-        });
-    };
-    if (!$scope.state.currentOrder) $scope.state.currentOrder = Object.assign({}, PALETTE_VIEW_ORDERS);
-    $scope.sortBy();
-    
-    $scope.allowFreeForm = function () {
-        return [
-            EntityFamily.LOCATION
-        ].indexOf($scope.family) > -1;
-    };
-    $scope.isReserved = function () {
-        if (!$scope.reservedKeys || !angular.isArray($scope.reservedKeys)) {
-            return false;
-        }
-        return $scope.reservedKeys.indexOf($scope.search) > -1;
-    };
-    $scope.onImageError = (scope, el, attrs) => {
-        $log.warn("Icon for "+attrs.itemId+" at "+angular.element(el).attr("src")+" could not be loaded; generating icon");
-        angular.element(el).attr("src", iconGenerator(attrs.itemId));
-    };
-
-    // Init
-    $scope.items = [];
-    function getDisplayTags(tags) {
-        if (!tags || !tags.length || !tags.reduce) return tags;
-        return tags.reduce((result, tag) => { 
-            if (!(/[=:\[\]()]/.exec(tag))) {
-                result.push(tag);
-            }
-            return result; 
-        }, []);
-    }
-    $scope.getItems().then((items)=> {
-        // add displayTags, as any tag that doesn't contain = : or ( ) [ ]
-        // any tag that is an object will be eliminated as it is toStringed to make [ object object ]
-        items.forEach(item => { 
-            if (item.tags) {
-                item.displayTags = getDisplayTags(item.tags); 
-            } 
-        });
-        $scope.items = items;
-    });
-    $scope.lastUsedText = (item) => {
-        if (item==null) return "";
-        let l = (Number)(item.lastUsed);
-        if (!l || isNaN(l) || l<=0) return "";
-        if (l < 100000) return 'Preselected for inclusion in "Recent" filter.';
-        return 'Last used: ' + distanceInWordsToNow(l, { includeSeconds: true, addSuffix: true });
-    }; 
-    
-    $scope.showPaletteControls = false;
-    $scope.onFiltersShown = () => {
-      $timeout( () => {
-        // check do we need to show the multiline
-        let filters = angular.element($element[0].querySelector(".filters"));
-        $scope.$apply( () => $scope.filterSettings.filtersMultilineAvailable = filters[0].scrollHeight > filters[0].offsetHeight + 6 );
-        
-        repaginate($scope, $element);
-      } );
-    };
-    $scope.togglePaletteControls = () => {
-        $scope.showPaletteControls = !$scope.showPaletteControls;
-        $timeout( () => repaginate($scope, $element) );
-    }
-    $scope.toggleShowAllFilters = () => {
-        $scope.filterSettings.showAllFilters = !$scope.filterSettings.showAllFilters;
-        $timeout( () => repaginate($scope, $element) );
-    };
-    $scope.filterSettings = {};
-
-    $scope.filters = [
-        { label: 'Recent', icon: 'clock-o', title: "Recently used and standard favorites", limitToOnePage: true,
-            filterInit: items => {
-                $scope.recentItems = items.filter( i => i.lastUsed && i.lastUsed>0 );
-                $scope.recentItems.sort( (a,b) => b.lastUsed - a.lastUsed );
-                return $scope.recentItems; 
-            }, enabled: false },
-    ];
-    $scope.disableFilters = (showFilters) => {
-        $scope.filters.forEach( f => f.enabled = false );
-        if (showFilters !== false) {
-            $scope.showPaletteControls = true;
-        }
-    }
-    
-    // can be overridden to disable "open in catalog" button
-    $scope.allowOpenInCatalog = true;
-    
-    // this can be overridden for palette sections/modes which show a subset of the types returned by the server;
-    // this is applied when the data is received from the server.
-    // it is used by catalogSelectorFiltersFilter; 
-    $scope.filterPaletteItemsForMode = (items) => items;
-
-    $templateCache.put('blueprint-composer/component/catalog-selector/subhead.html', '');
-    $templateCache.put('blueprint-composer/component/catalog-selector/footer.html', footerTemplate);
-
-    // allow downstream to configure this controller and/or scope
-    (composerOverrides.configurePaletteController || function() {})(this, $scope, $element);
+function templateCache($templateCache) {
+    $templateCache.put(TEMPLATE_URL, template);
+    $templateCache.put(TEMPLATE_SUBHEAD_URL, '');
+    $templateCache.put(TEMPLATE_FOOTER_URL, footerTemplate);
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.template.html
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.template.html b/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.template.html
index 5b4ddb9..79ea8e7 100644
--- a/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.template.html
+++ b/ui-modules/blueprint-composer/app/components/catalog-selector/catalog-selector.template.html
@@ -92,7 +92,7 @@
                 </ul>
               </span>
             </div>
-            <ng-include src="blueprint-composer/component/catalog-selector/subhead.html"/>
+            <ng-include src="templateUrls.subhead"/>
         </div>
       </div>
 
@@ -110,7 +110,7 @@
                         <h3>{{ getEntityNameForPalette(item, item | entityName) }}</h3>
                     </div>
                     <i class="fa fa-info-circle"
-                        uib-popover-template="'QuickInfoTemplate.html'"
+                        uib-popover-template="'blueprint-composer/component/catalog-selector/quick-info.html'"
                         ng-click="onClickItem(item, true, $event)"
                         popover-is-open="popover == item && popoverVisible"
                         popover-placement="right" popover-trigger="'none'"
@@ -131,7 +131,7 @@
                         <h3>{{freeFormTile | entityName}}</h3>
                     </div>
                     <i class="fa fa-info-circle"
-                        uib-popover-template="'QuickInfoTemplate.html'"
+                        uib-popover-template="'blueprint-composer/component/catalog-selector/quick-info.html'"
                         popover-is-open="popover == freeFormTile && popoverVisible"
                         popover-placement="right-top" popover-trigger="'none'"
                         popover-class="catalog-selector-popover" popover-append-to-body="true"
@@ -146,13 +146,13 @@
 
         <div class="catalog-palette-footer">
             <div uib-pagination total-items="searchedItems.length" items-per-page="pagination.itemsPerPage" ng-model="pagination.page" boundary-link-numbers="true" rotate="false" max-size="4" ng-show="searchedItems.length > pagination.itemsPerPage" class="pagination-sm pull-right"></div>
-            <ng-include src="blueprint-composer/component/catalog-selector/footer.html"/>
+            <ng-include src="templateUrls.footer"/>
         </div>
     </div>
 </div>
 
 <!-- QUICK INFO TEMPLATE :: START-->
-<script type="text/ng-template" id="QuickInfoTemplate.html">
+<script type="text/ng-template" id="blueprint-composer/component/catalog-selector/quick-info.html">
     <div class="palette-item-quick-info">
         <div class="quick-info-title">{{ popover | entityName }}
             <br-svg type="close" class="pull-right closer" ng-click="closePopover()"></br-svg>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/custom-config-widget/suggestion-dropdown.html
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/custom-config-widget/suggestion-dropdown.html b/ui-modules/blueprint-composer/app/components/custom-config-widget/suggestion-dropdown.html
index ad59161..93d35ac 100644
--- a/ui-modules/blueprint-composer/app/components/custom-config-widget/suggestion-dropdown.html
+++ b/ui-modules/blueprint-composer/app/components/custom-config-widget/suggestion-dropdown.html
@@ -22,7 +22,7 @@
         <span class="info-spec-configuration">
             <i class="fa fa-fw fa-info-circle" popover-trigger="'mouseenter'"
                 popover-title="{{item.label || item.name}}"
-                uib-popover-template="'ConfigInfoTemplate.html'"
+                uib-popover-template="'blueprint-composer/component/spec-editor/config-info.html'"
                 popover-class="spec-editor-popover" popover-placement="top-left" popover-append-to-body="true"></i>
             </span>
     </label>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/custom-config-widget/suggestion-dropdown.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/custom-config-widget/suggestion-dropdown.js b/ui-modules/blueprint-composer/app/components/custom-config-widget/suggestion-dropdown.js
index c32bc72..d58ec88 100644
--- a/ui-modules/blueprint-composer/app/components/custom-config-widget/suggestion-dropdown.js
+++ b/ui-modules/blueprint-composer/app/components/custom-config-widget/suggestion-dropdown.js
@@ -21,9 +21,11 @@ import angular from 'angular';
 import template from './suggestion-dropdown.html';
 
 const MODULE_NAME = 'brooklyn.components.custom-config-widget.suggestion-dropdown';
+const TEMPLATE_URL = 'blueprint-composer/component/suggestion-dropdown/index.html';
 
 angular.module(MODULE_NAME, [])
-    .directive('suggestionDropdown', ['$rootScope', suggestionDropdownDirective]);
+    .directive('suggestionDropdown', ['$rootScope', suggestionDropdownDirective])
+    .run(['$templateCache', templateCache]);
 
 export default MODULE_NAME;
 
@@ -31,13 +33,15 @@ export function suggestionDropdownDirective($rootScope) {
     return {
         require: "^^specEditor",  // only intended for use in spec editor, and calls functions on that controller
         restrict: 'E',
+        templateUrl: function (tElement, tAttrs) {
+            return tAttrs.templateUrl || TEMPLATE_URL;
+        },
         scope: {
             item: '=',
             params: '=',
             config: '=',
             model: '=',
         },
-        template: template,
         link: link,
     };
 
@@ -58,5 +62,8 @@ export function suggestionDropdownDirective($rootScope) {
             }
         };
     }
-    
+}
+
+function templateCache($templateCache) {
+    $templateCache.put(TEMPLATE_URL, template);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/designer/designer.directive.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/designer/designer.directive.js b/ui-modules/blueprint-composer/app/components/designer/designer.directive.js
index e704928..cbcb0ff 100644
--- a/ui-modules/blueprint-composer/app/components/designer/designer.directive.js
+++ b/ui-modules/blueprint-composer/app/components/designer/designer.directive.js
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import angular from 'angular';
 import {Entity} from "../util/model/entity.model";
 import {D3Blueprint} from "../util/d3-blueprint";
 import {EntityFamily} from '../util/model/entity.model';
@@ -23,19 +24,29 @@ import {graphicalEditEntityState} from '../../views/main/graphical/edit/entity/e
 import {graphicalEditSpecState} from '../../views/main/graphical/edit/spec/edit.spec.controller';
 import {graphicalEditPolicyState} from '../../views/main/graphical/edit/policy/edit.policy.controller';
 import {graphicalEditEnricherState} from '../../views/main/graphical/edit/enricher/edit.enricher.controller';
+
+const MODULE_NAME = 'brooklyn.components.designer';
+const TEMPLATE_URL = 'blueprint-composer/component/designer/index.html';
 const ANY_MEMBERSPEC_REGEX = /(^.*[m,M]ember[s,S]pec$)/;
 const TAG = 'DIRECTIVE :: DESIGNER :: ';
 
+angular.module(MODULE_NAME, [])
+    .directive('designer', ['$log', '$state', '$q', 'iconGenerator', 'catalogApi', 'blueprintService', 'brSnackbar', 'paletteDragAndDropService', designerDirective])
+    .run(['$templateCache', templateCache]);
+
+export default MODULE_NAME;
+
 export function designerDirective($log, $state, $q, iconGenerator, catalogApi, blueprintService, brSnackbar, paletteDragAndDropService) {
-    let directive = {
+    return {
         restrict: 'E',
+        templateUrl: function (tElement, tAttrs) {
+            return tAttrs.templateUrl || TEMPLATE_URL;
+        },
         scope: {
             onSelectionChange: '<?'
         },
-        template: '',
         link: link
     };
-    return directive;
 
     function link($scope, $element) {
         let blueprintGraph = new D3Blueprint($element[0]).center();
@@ -235,3 +246,7 @@ export function designerDirective($log, $state, $q, iconGenerator, catalogApi, b
         }
     }
 }
+
+function templateCache($templateCache) {
+    $templateCache.put(TEMPLATE_URL, '');
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/dsl-editor/dsl-editor.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/dsl-editor/dsl-editor.js b/ui-modules/blueprint-composer/app/components/dsl-editor/dsl-editor.js
index 707560b..6fb1d26 100644
--- a/ui-modules/blueprint-composer/app/components/dsl-editor/dsl-editor.js
+++ b/ui-modules/blueprint-composer/app/components/dsl-editor/dsl-editor.js
@@ -24,6 +24,7 @@ import brAutoFocus from 'brooklyn-ui-utils/autofocus/autofocus';
 import brUtils from 'brooklyn-ui-utils/utils/general';
 
 const MODULE_NAME = 'brooklyn.components.dsl-editor';
+const TEMPLATE_URL = 'blueprint-composer/component/dsl-editor/index.html';
 const DSL_KINDS = {
     ALL: {
         id: 'all',
@@ -48,14 +49,17 @@ const DSL_KINDS = {
 };
 
 angular.module(MODULE_NAME, [angularSanitize, brAutoFocus, brUtils])
-    .directive('dslEditor', ['$rootScope', '$filter', '$log', 'brUtilsGeneral', 'blueprintService', dslEditorDirective]);
+    .directive('dslEditor', ['$rootScope', '$filter', '$log', 'brUtilsGeneral', 'blueprintService', dslEditorDirective])
+    .run(['$templateCache', templateCache]);
 
 export default MODULE_NAME;
 
 export function dslEditorDirective($rootScope, $filter, $log, brUtilsGeneral, blueprintService) {
     return {
         restrict: 'E',
-        template: template,
+        templateUrl: function (tElement, tAttrs) {
+            return tAttrs.templateUrl || TEMPLATE_URL;
+        },
         scope: {
             definition: '=',
             entity: '=',
@@ -361,3 +365,7 @@ export function dslEditorDirective($rootScope, $filter, $log, brUtilsGeneral, bl
         return dsl && dsl.kind === KIND.TARGET && dsl.name === 'self';
     }
 }
+
+function templateCache($templateCache) {
+    $templateCache.put(TEMPLATE_URL, template);
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/dsl-viewer/dsl-viewer.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/dsl-viewer/dsl-viewer.js b/ui-modules/blueprint-composer/app/components/dsl-viewer/dsl-viewer.js
index abdd233..e751638 100644
--- a/ui-modules/blueprint-composer/app/components/dsl-viewer/dsl-viewer.js
+++ b/ui-modules/blueprint-composer/app/components/dsl-viewer/dsl-viewer.js
@@ -21,19 +21,23 @@ import template from './dsl-viewer.template.html';
 import {KIND} from '../util/model/dsl.model';
 
 const MODULE_NAME = 'brooklyn.components.dsl-viewer';
+const TEMPLATE_URL = 'blueprint-composer/component/dsl-viewer/index.html';
 
 angular.module(MODULE_NAME, [])
-    .directive('dslViewer', dslViewerDirective);
+    .directive('dslViewer', dslViewerDirective)
+    .run(['$templateCache', templateCache]);
 
 export default MODULE_NAME;
 
 export function dslViewerDirective() {
     return {
         restrict: 'E',
+        templateUrl: function (tElement, tAttrs) {
+            return tAttrs.templateUrl || TEMPLATE_URL;
+        },
         scope: {
             dsl: '<'
         },
-        template: template,
         link: link
     };
 
@@ -64,3 +68,7 @@ export function dslViewerDirective() {
         }
     }
 }
+
+function templateCache($templateCache) {
+    $templateCache.put(TEMPLATE_URL, template);
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/factories/object-cache.factory.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/factories/object-cache.factory.js b/ui-modules/blueprint-composer/app/components/factories/object-cache.factory.js
index cf714b4..a37f3a6 100644
--- a/ui-modules/blueprint-composer/app/components/factories/object-cache.factory.js
+++ b/ui-modules/blueprint-composer/app/components/factories/object-cache.factory.js
@@ -16,6 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import angular from 'angular';
+
+const MODULE_NAME = 'brooklyn.factory.object-cache';
+
+angular.module(MODULE_NAME, [])
+    .factory('objectCache', ['$cacheFactory', objectCacheFactory]);
+
+export default MODULE_NAME;
+
 export function objectCacheFactory($cacheFactory) {
     return $cacheFactory('blueprint-composer');
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/factories/recursion-helper.factory.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/factories/recursion-helper.factory.js b/ui-modules/blueprint-composer/app/components/factories/recursion-helper.factory.js
deleted file mode 100644
index cf0abae..0000000
--- a/ui-modules/blueprint-composer/app/components/factories/recursion-helper.factory.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-export function recursionHelperFactory($compile) {
-    return {
-        /**
-         * Manually compiles the element, fixing the recursion loop.
-         *
-         * @param {object} element
-         * @param {function} link a post link function,
-         *                   or an object with function(s) registered via pre and post properties.
-         *
-         */
-        compile: function (element, link) {
-            // Normalize the link parameter
-            if (angular.isFunction(link)) {
-                link = {post: link};
-            }
-
-            // Break the recursion loop by removing the contents
-            var contents = element.contents().remove();
-            var compiledContents;
-            return {
-                pre: (link && link.pre) ? link.pre : null,
-                /**
-                 * Compiles and re-adds the contents
-                 */
-                post: function (scope, element) {
-                    // Compile the contents
-                    if (!compiledContents) {
-                        compiledContents = $compile(contents);
-                    }
-                    // Re-add the compiled contents to the element
-                    compiledContents(scope, function (clone) {
-                        element.append(clone);
-                    });
-
-                    // Call the post-linking function, if any
-                    if (link && link.post) {
-                        link.post.apply(null, arguments);
-                    }
-                }
-            };
-        }
-    };
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/filters/entity.filter.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/filters/entity.filter.js b/ui-modules/blueprint-composer/app/components/filters/entity.filter.js
index 32a785b..34a1930 100644
--- a/ui-modules/blueprint-composer/app/components/filters/entity.filter.js
+++ b/ui-modules/blueprint-composer/app/components/filters/entity.filter.js
@@ -16,6 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import angular from 'angular';
+
+const MODULE_NAME = 'brooklyn.filters.entity';
+
+angular.module(MODULE_NAME, [])
+    .filter('entityName', entityNameFilter)
+    .filter('entityVersion', entityVersionFilter)
+    .filter('entityTypes', entityTypesFilter);
+
+export default MODULE_NAME;
+
 export function entityNameFilter() {
     return function (input) {
         var result = input ? (input.displayName || input.name || input.symbolicName || input.type || null) : null;

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/filters/locations.filter.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/filters/locations.filter.js b/ui-modules/blueprint-composer/app/components/filters/locations.filter.js
index c096944..7a1378c 100644
--- a/ui-modules/blueprint-composer/app/components/filters/locations.filter.js
+++ b/ui-modules/blueprint-composer/app/components/filters/locations.filter.js
@@ -16,6 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import angular from 'angular';
+
+const MODULE_NAME = 'brooklyn.filters.location';
+
+angular.module(MODULE_NAME, [])
+    .filter('locations', locationsFilter);
+
+export default MODULE_NAME;
+
 export function locationsFilter() {
     return function (input, search) {
         return input.then(function (response) {

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/providers/action-service.provider.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/providers/action-service.provider.js b/ui-modules/blueprint-composer/app/components/providers/action-service.provider.js
index 9f00374..a699d67 100644
--- a/ui-modules/blueprint-composer/app/components/providers/action-service.provider.js
+++ b/ui-modules/blueprint-composer/app/components/providers/action-service.provider.js
@@ -16,6 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import angular from 'angular';
+
+const MODULE_NAME = 'brooklyn.composer.service.action-service';
+
+angular.module(MODULE_NAME, [])
+    .provider('actionService', actionServiceProvider);
+
+export default MODULE_NAME;
+
 export function actionServiceProvider() {
     let actions = {};
     return {
@@ -41,7 +50,7 @@ function ActionService(actionsToAdd) {
     return {
         addAction: addAction,
         getActions: getActions
-    }
+    };
 
     function addAction(id, action) {
         if (!action || !action.hasOwnProperty('html')) {

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/providers/blueprint-service.provider.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/providers/blueprint-service.provider.js b/ui-modules/blueprint-composer/app/components/providers/blueprint-service.provider.js
index 69ba3f6..0140faf 100644
--- a/ui-modules/blueprint-composer/app/components/providers/blueprint-service.provider.js
+++ b/ui-modules/blueprint-composer/app/components/providers/blueprint-service.provider.js
@@ -16,13 +16,21 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import angular from 'angular';
 import {Entity, EntityFamily} from "../util/model/entity.model";
 import {Issue, ISSUE_LEVEL} from '../util/model/issue.model';
 import {Dsl} from "../util/model/dsl.model";
 import jsYaml from "js-yaml";
 import typeNotFoundIcon from "../../img/icon-not-found.svg";
 
+const MODULE_NAME = 'brooklyn.composer.service.blueprint-service';
 const TAG = 'SERVICE :: BLUEPRINT :: ';
+
+angular.module(MODULE_NAME, [])
+    .provider('blueprintService', blueprintServiceProvider);
+
+export default MODULE_NAME;
+
 export const RESERVED_KEYS = ['name', 'location', 'locations', 'type', 'services', 'brooklyn.config', 'brooklyn.children', 'brooklyn.enrichers', 'brooklyn.policies'];
 export const DSL_ENTITY_SPEC = '$brooklyn:entitySpec';
 

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/providers/dsl-service.provider.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/providers/dsl-service.provider.js b/ui-modules/blueprint-composer/app/components/providers/dsl-service.provider.js
index 3d5f665..ae89b37 100644
--- a/ui-modules/blueprint-composer/app/components/providers/dsl-service.provider.js
+++ b/ui-modules/blueprint-composer/app/components/providers/dsl-service.provider.js
@@ -16,11 +16,18 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import angular from 'angular';
 import {Dsl, DslParser, KIND} from "../util/model/dsl.model";
 import {Entity} from "../util/model/entity.model";
 
+const MODULE_NAME = 'brooklyn.composer.service.dsl-service';
 const TAG = 'SERVICE :: DSL :: ';
 
+angular.module(MODULE_NAME, [])
+    .provider('dslService', dslServiceProvider);
+
+export default MODULE_NAME;
+
 export function dslServiceProvider() {
     return {
         $get: ['$log', function ($log) {

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/providers/palette-dragndrop.provider.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/providers/palette-dragndrop.provider.js b/ui-modules/blueprint-composer/app/components/providers/palette-dragndrop.provider.js
index dee0836..1105880 100644
--- a/ui-modules/blueprint-composer/app/components/providers/palette-dragndrop.provider.js
+++ b/ui-modules/blueprint-composer/app/components/providers/palette-dragndrop.provider.js
@@ -16,10 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import angular from 'angular';
 import {Entity} from '../util/model/entity.model';
 
+const MODULE_NAME = 'brooklyn.composer.service.palette-dragndrop-service';
 const TAG = 'SERVICE :: DRAGNDROP :: ';
 
+angular.module(MODULE_NAME, [])
+    .provider('paletteDragAndDropService', paletteDragAndDropServiceProvider);
+
+export default MODULE_NAME;
+
 export function paletteDragAndDropServiceProvider() {
     return {
         $get: ['$log', function ($log) {

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/providers/recently-used-service.provider.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/providers/recently-used-service.provider.js b/ui-modules/blueprint-composer/app/components/providers/recently-used-service.provider.js
index cc48ab5..994932d 100644
--- a/ui-modules/blueprint-composer/app/components/providers/recently-used-service.provider.js
+++ b/ui-modules/blueprint-composer/app/components/providers/recently-used-service.provider.js
@@ -16,6 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import angular from 'angular';
+
+const MODULE_NAME = 'brooklyn.composer.service.recently-user';
+
+angular.module(MODULE_NAME, [])
+    .provider('recentlyUsedService', recentlyUsedServiceProvider);
+
+export default MODULE_NAME;
 
 export function recentlyUsedServiceProvider() {
     return {

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
index 8dec82b..bfd51a9 100644
--- a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
+++ b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
@@ -86,7 +86,7 @@
              placeholder="Add a new configuration key or open existing"
              class="form-control"
              uib-typeahead="config.name for config in state.config.add.list | filter:{name:$viewValue}"
-             typeahead-template-url="ConfigItemTemplate.html"
+             typeahead-template-url="blueprint-composer/component/spec-editor/config-item.html"
              typeahead-editable="true"
              typeahead-show-hint="true"
              typeahead-min-length="0"
@@ -146,7 +146,7 @@
                         <span class="info-spec-configuration">
                            <i class="fa fa-fw fa-info-circle" popover-trigger="'mouseenter'"
                                popover-title="{{item.label || item.name}}"
-                               uib-popover-template="'ConfigInfoTemplate.html'"
+                               uib-popover-template="'blueprint-composer/component/spec-editor/config-info.html'"
                                popover-class="spec-editor-popover" popover-placement="top-left" popover-append-to-body="true"></i>
                         </span>
                     </label>
@@ -379,7 +379,7 @@
         <span ng-if="getPoliciesIssues().length> 0" class="badge" ng-class="getBadgeClass(getPoliciesIssues())">{{getPoliciesIssues().length}}</span>
 
         <span class="pull-right" ng-show="$parent.stateWrapped.state">
-            <i class="fa fa-search collapsible-action" title="Filter policies" ng-click="$event.stopPropagation(); $event.preventDefault();" ng-class="{'text-success': state.policy.search.length > 0}" uib-popover-template="'SearchPolicyTemplate.html'" popover-placement="bottom-right" popover-trigger="'outsideClick'"></i>
+            <i class="fa fa-search collapsible-action" title="Filter policies" ng-click="$event.stopPropagation(); $event.preventDefault();" ng-class="{'text-success': state.policy.search.length > 0}" uib-popover-template="'blueprint-composer/component/spec-editor/search-policy.html'" popover-placement="bottom-right" popover-trigger="'outsideClick'"></i>
             <a class="fa fa-plus collapsible-action" title="Add policy" ui-sref="main.graphical.edit.add({entityId: model._id, family: 'policy'})" ng-click="$event.stopPropagation()" ></a>
         </span>
     </heading>
@@ -415,7 +415,7 @@
         <span ng-if="getEnrichersIssues().length> 0" class="badge" ng-class="getBadgeClass(getEnrichersIssues())">{{getEnrichersIssues().length}}</span>
 
         <span class="pull-right" ng-show="$parent.stateWrapped.state">
-            <i class="fa fa-search collapsible-action" title="Search enrichers" ng-click="$event.stopPropagation(); $event.preventDefault();" ng-class="{'text-success': state.enricher.search.length > 0}" uib-popover-template="'SearchEnricherTemplate.html'" popover-placement="bottom-right" popover-trigger="'outsideClick'"></i>
+            <i class="fa fa-search collapsible-action" title="Search enrichers" ng-click="$event.stopPropagation(); $event.preventDefault();" ng-class="{'text-success': state.enricher.search.length > 0}" uib-popover-template="'blueprint-composer/component/spec-editor/search-enricher.html'" popover-placement="bottom-right" popover-trigger="'outsideClick'"></i>
             <a class="fa fa-plus collapsible-action" title="Add enricher" ui-sref="main.graphical.edit.add({entityId: model._id, family: 'enricher'})" ng-click="$event.stopPropagation()" ></a>
         </span>
     </heading>
@@ -448,7 +448,7 @@
 
 
 <!-- CONFIG INFO TEMPLATE :: START -->
-<script type="text/ng-template" id="ConfigInfoTemplate.html">
+<script type="text/ng-template" id="blueprint-composer/component/spec-editor/config-info.html">
     <div class="config-item-quick-info">
         <div class="quick-info-metadata">
             <p><i class="mini-icon fa fa-fw fa-cog"></i> <samp class="type-symbolic-name">{{item.name}}</samp>
@@ -463,7 +463,7 @@
 <!-- CONFIG INFO TEMPLATE :: START-->
 
 <!-- SEARCH POLICY TEMPLATE :: START -->
-<script type="text/ng-template" id="SearchPolicyTemplate.html">
+<script type="text/ng-template" id="blueprint-composer/component/spec-editor/search-policy.html">
     <div ng-click="$event.stopPropagation(); $event.preventDefault();">
         <input ng-model="state.policy.search" type="text" class="form-control" placeholder="Search for a policy" auto-focus blur-on-enter />
     </div>
@@ -471,7 +471,7 @@
 <!--SEARCH POLICY TEMPLATE :: START-->
 
 <!-- SEARCH ENRICHER TEMPLATE :: START -->
-<script type="text/ng-template" id="SearchEnricherTemplate.html">
+<script type="text/ng-template" id="blueprint-composer/component/spec-editor/search-enricher.html">
     <div ng-click="$event.stopPropagation(); $event.preventDefault();">
         <input ng-model="state.enricher.search" type="text" class="form-control" placeholder="Search for an enricher" auto-focus blur-on-enter />
     </div>
@@ -479,7 +479,7 @@
 <!--SEARCH ENRICHER TEMPLATE :: START-->
 
 <!--TYPEAHEAD TEMPLATE :: START-->
-<script type="text/ng-template" id="ConfigItemTemplate.html">
+<script type="text/ng-template" id="blueprint-composer/component/spec-editor/config-item.html">
     <div class="dropdown-item" ng-init="item = match.model">
         <div class="dropdown-row">
             <span ng-bind-html="match.model.name | uibTypeaheadHighlight:query" class="config-name"></span>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0f72a003/ui-modules/blueprint-composer/app/index.js
----------------------------------------------------------------------
diff --git a/ui-modules/blueprint-composer/app/index.js b/ui-modules/blueprint-composer/app/index.js
index 7dc3720..34b3c5b 100755
--- a/ui-modules/blueprint-composer/app/index.js
+++ b/ui-modules/blueprint-composer/app/index.js
@@ -43,25 +43,19 @@ import paletteServiceProvider from "./components/providers/palette-service.provi
 import blueprintLoaderApiProvider from "./components/providers/blueprint-loader-api.provider";
 
 import brooklynApi from "brooklyn-ui-utils/brooklyn.api/brooklyn.api";
-import {designerDirective} from "./components/designer/designer.directive";
-import {
-    catalogSelectorDirective,
-    catalogSelectorSearchFilter,
-    catalogSelectorFiltersFilter,
-} from "./components/catalog-selector/catalog-selector.directive";
+import designer from './components/designer/designer.directive';
+import catalogSelector from './components/catalog-selector/catalog-selector.directive';
 import customActionDirective from "./components/custom-action/custom-action.directive";
 import customConfigSuggestionDropdown from "./components/custom-config-widget/suggestion-dropdown";
-import {onErrorDirective} from "./components/catalog-selector/on-error.directive";
-import {breadcrumbsDirective} from "./components/breacrumbs/breadcrumbs.directive";
-import {recursionHelperFactory} from "./components/factories/recursion-helper.factory";
-import {objectCacheFactory} from './components/factories/object-cache.factory';
-import {entityNameFilter, entityVersionFilter, entityTypesFilter} from "./components/filters/entity.filter";
-import {locationsFilter} from "./components/filters/locations.filter";
-import {blueprintServiceProvider} from "./components/providers/blueprint-service.provider";
-import {recentlyUsedServiceProvider} from "./components/providers/recently-used-service.provider";
-import {dslServiceProvider} from "./components/providers/dsl-service.provider";
-import {paletteDragAndDropServiceProvider} from "./components/providers/palette-dragndrop.provider";
-import {actionServiceProvider} from "./components/providers/action-service.provider";
+import breadcrumbs from "./components/breacrumbs/breadcrumbs.directive";
+import objectCache from './components/factories/object-cache.factory';
+import entityFilters from "./components/filters/entity.filter";
+import locationFilter from "./components/filters/locations.filter";
+import blueprintService from "./components/providers/blueprint-service.provider";
+import recentlyUsedService from "./components/providers/recently-used-service.provider";
+import dslService from "./components/providers/dsl-service.provider";
+import paletteDragAndDropService from "./components/providers/palette-dragndrop.provider";
+import actionService from "./components/providers/action-service.provider";
 import {mainState} from "./views/main/main.controller";
 import {yamlState} from "./views/main/yaml/yaml.state";
 import {graphicalState} from "./views/main/graphical/graphical.state";
@@ -76,28 +70,13 @@ import bottomSheet from "brooklyn-ui-utils/bottom-sheet/bottom-sheet";
 import stackViewer from 'angular-java-stack-viewer';
 import {EntityFamily} from "./components/util/model/entity.model";
 
-angular.module('app', [ngAnimate, ngResource, ngCookies, ngClipboard, uiRouter, 'ui.router.state.events', brCore, 
-        brServerStatus, brAutoFocus, brIconGenerator, brInterstitialSpinner, brooklynModuleLinks, brooklynUserManagement, 
-        brYamlEditor, brUtils, brSpecEditor, brooklynCatalogSaver, brooklynApi, bottomSheet, stackViewer, brDragndrop, 
-        customActionDirective, customConfigSuggestionDropdown, paletteApiProvider, paletteServiceProvider, blueprintLoaderApiProvider])
-    .directive('designer', ['$log', '$state', '$q', 'iconGenerator', 'catalogApi', 'blueprintService', 'brSnackbar', 'paletteDragAndDropService', designerDirective])
-    .directive('onError', onErrorDirective)
-    .directive('catalogSelector', catalogSelectorDirective)
-    .directive('breadcrumbs', breadcrumbsDirective)
-    .provider('blueprintService', blueprintServiceProvider)
-    .provider('recentlyUsedService', recentlyUsedServiceProvider)
-    .provider('dslService', dslServiceProvider)
-    .provider('paletteDragAndDropService', paletteDragAndDropServiceProvider)
-    .provider('actionService', actionServiceProvider)
+angular.module('app', [ngAnimate, ngResource, ngCookies, ngClipboard, uiRouter, 'ui.router.state.events', brCore,
+    brServerStatus, brAutoFocus, brIconGenerator, brInterstitialSpinner, brooklynModuleLinks, brooklynUserManagement,
+    brYamlEditor, brUtils, brSpecEditor, brooklynCatalogSaver, brooklynApi, bottomSheet, stackViewer, brDragndrop,
+    customActionDirective, customConfigSuggestionDropdown, paletteApiProvider, paletteServiceProvider, blueprintLoaderApiProvider,
+    breadcrumbs, catalogSelector, designer, objectCache, entityFilters, locationFilter, actionService, blueprintService,
+    dslService, paletteDragAndDropService, recentlyUsedService])
     .provider('composerOverrides', composerOverridesProvider)
-    .factory('recursionHelper', ['$compile', recursionHelperFactory])
-    .factory('objectCache', ['$cacheFactory', objectCacheFactory])
-    .filter('entityName', entityNameFilter)
-    .filter('entityVersion', entityVersionFilter)
-    .filter('entityTypes', entityTypesFilter)
-    .filter('locations', locationsFilter)
-    .filter('catalogSelectorSearch', catalogSelectorSearchFilter)
-    .filter('catalogSelectorFilters', catalogSelectorFiltersFilter)
     .filter('dslParamLabel', ['$filter', dslParamLabelFilter])
     .config(['$urlRouterProvider', '$stateProvider', '$logProvider', applicationConfig])
     .config(['actionServiceProvider', actionConfig])


[3/3] brooklyn-ui git commit: This closes #97

Posted by he...@apache.org.
This closes #97


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/43c154c3
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/43c154c3
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/43c154c3

Branch: refs/heads/master
Commit: 43c154c39813443406b286f15416137fca43044c
Parents: bf3477b 0f72a00
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Nov 8 15:28:31 2018 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Nov 8 15:28:31 2018 +0000

----------------------------------------------------------------------
 .../blueprint-data-manager.directive.js         |  28 +-
 .../breacrumbs/breadcrumbs.directive.js         |  44 +-
 .../catalog-saver/catalog-saver.directive.js    |  22 +-
 .../catalog-selector.directive.js               | 573 ++++++++++---------
 .../catalog-selector.template.html              |  10 +-
 .../suggestion-dropdown.html                    |   2 +-
 .../custom-config-widget/suggestion-dropdown.js |  13 +-
 .../components/designer/designer.directive.js   |  21 +-
 .../app/components/dsl-editor/dsl-editor.js     |  12 +-
 .../app/components/dsl-viewer/dsl-viewer.js     |  12 +-
 .../factories/object-cache.factory.js           |   9 +
 .../factories/recursion-helper.factory.js       |  61 --
 .../app/components/filters/entity.filter.js     |  11 +
 .../app/components/filters/locations.filter.js  |   9 +
 .../providers/action-service.provider.js        |  11 +-
 .../providers/blueprint-service.provider.js     |   8 +
 .../providers/dsl-service.provider.js           |   7 +
 .../providers/palette-dragndrop.provider.js     |   7 +
 .../providers/recently-used-service.provider.js |   8 +
 .../spec-editor/spec-editor.template.html       |  40 +-
 ui-modules/blueprint-composer/app/index.js      |  55 +-
 21 files changed, 522 insertions(+), 441 deletions(-)
----------------------------------------------------------------------