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 <[email protected]> Authored: Wed Nov 7 11:32:20 2018 +0000 Committer: Thomas Bouron <[email protected]> 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])
