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/07/26 10:50:31 UTC
[14/28] brooklyn-ui git commit: This adds the contributed
brooklyn-ui-angular code in the folder new/.
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/index.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/index.js b/new/ui-modules/blueprint-composer/app/index.js
new file mode 100755
index 0000000..f7a55b2
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/index.js
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+import angular from "angular";
+import ngAnimate from 'angular-animate';
+import ngResource from "angular-resource";
+import ngCookies from "angular-cookies";
+import uiRouter from "angular-ui-router";
+import "angular-ui-router/release/stateEvents";
+import ngClipboard from "ngclipboard";
+
+import brCore from 'brooklyn-ui-utils/br-core/br-core';
+
+import brDragndrop from "brooklyn-ui-utils/dragndrop/dragndrop.directive.js"
+import brServerStatus from 'brooklyn-ui-utils/server-status/server-status';
+import brAutoFocus from 'brooklyn-ui-utils/autofocus/autofocus';
+import brIconGenerator from 'brooklyn-ui-utils/icon-generator/icon-generator';
+import brInterstitialSpinner from 'brooklyn-ui-utils/interstitial-spinner/interstitial-spinner';
+import brooklynModuleLinks from 'brooklyn-ui-utils/module-links/module-links';
+import brooklynUserManagement from 'brooklyn-ui-utils/user-management/user-management';
+import brYamlEditor from 'brooklyn-ui-utils/yaml-editor/yaml-editor';
+import brUtils from 'brooklyn-ui-utils/utils/general';
+
+import brSpecEditor from 'components/spec-editor/spec-editor.directive';
+import brooklynCatalogSaver from 'components/catalog-saver/catalog-saver.directive';
+import paletteApiProvider from "./components/providers/palette-api.provider"
+
+import brooklynApi from "brooklyn-ui-utils/brooklyn.api/brooklyn.api";
+import {designerDirective} from "components/designer/designer.directive";
+import {
+ catalogSelectorDirective,
+ catalogSelectorSearchFilter,
+ catalogSelectorSortFilter
+} from "components/catalog-selector/catalog-selector.directive";
+import customActionDirective from "./components/custom-action/custom-action.directive";
+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 {dslServiceProvider} from "components/providers/dsl-service.provider";
+import {paletteDragAndDropServiceProvider} from "components/providers/palette-dragndrop.provider";
+import {actionServiceProvider} 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";
+import {graphicalEditState} from "views/main/graphical/edit/edit.controller";
+import {graphicalEditAddState} from "views/main/graphical/edit/add/add";
+import {graphicalEditEntityState} from "views/main/graphical/edit/entity/edit.entity.controller";
+import {graphicalEditPolicyState} from "views/main/graphical/edit/policy/edit.policy.controller";
+import {graphicalEditEnricherState} from "views/main/graphical/edit/enricher/edit.enricher.controller";
+import {graphicalEditSpecState} from "views/main/graphical/edit/spec/edit.spec.controller";
+import {graphicalEditDslState, dslParamLabelFilter} from "views/main/graphical/edit/dsl/edit.dsl.controller";
+import bottomSheet from "brooklyn-ui-utils/bottom-sheet/bottom-sheet";
+import stackViewer from 'angular-java-stack-viewer';
+
+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, paletteApiProvider])
+ .directive('designer', ['$log', '$state', '$q', 'iconGenerator', 'catalogApi', 'blueprintService', 'brSnackbar', 'paletteDragAndDropService', designerDirective])
+ .directive('onError', onErrorDirective)
+ .directive('catalogSelector', catalogSelectorDirective)
+ .directive('breadcrumbs', breadcrumbsDirective)
+ .provider('blueprintService', blueprintServiceProvider)
+ .provider('dslService', dslServiceProvider)
+ .provider('paletteDragAndDropService', paletteDragAndDropServiceProvider)
+ .provider('actionService', actionServiceProvider)
+ .factory('recursionHelper', ['$compile', recursionHelperFactory])
+ .factory('objectCache', ['$cacheFactory', objectCacheFactory])
+ .filter('entityName', entityNameFilter)
+ .filter('entityVersion', entityVersionFilter)
+ .filter('entityTypes', entityTypesFilter)
+ .filter('locations', locationsFilter)
+ .filter('catalogSelectorSearch', catalogSelectorSearchFilter)
+ .filter('catalogSelectorSort', ['$filter', catalogSelectorSortFilter])
+ .filter('dslParamLabel', ['$filter', dslParamLabelFilter])
+ .config(['$urlRouterProvider', '$stateProvider', '$logProvider', applicationConfig])
+ .config(['actionServiceProvider', actionConfig])
+ .run(['$rootScope', '$state', 'brSnackbar', errorHandler])
+ .run(['$http', httpConfig]);
+
+function applicationConfig($urlRouterProvider, $stateProvider, $logProvider) {
+ $logProvider.debugEnabled(false);
+ $urlRouterProvider
+ .otherwise(graphicalState.url);
+ $stateProvider
+ .state(mainState)
+ .state(yamlState)
+ .state(graphicalState)
+ .state(graphicalEditAddState)
+ .state(graphicalEditState)
+ .state(graphicalEditEntityState)
+ .state(graphicalEditPolicyState)
+ .state(graphicalEditEnricherState)
+ .state(graphicalEditSpecState)
+ .state(graphicalEditDslState);
+}
+
+function actionConfig(actionServiceProvider) {
+ actionServiceProvider.addAction("deploy", {html: '<button class="btn btn-success" ng-click="vm.deployApplication()" ng-disabled="vm.deploying">Deploy</button>'});
+ actionServiceProvider.addAction("add", {html: '<catalog-saver config="vm.saveToCatalogConfig"></catalog-saver>'});
+}
+
+function errorHandler($rootScope, $state, brSnackbar) {
+ $rootScope.$on('$stateChangeError', (event, toState, toParams, fromState, fromParams, error)=> {
+ brSnackbar.create(error.detail);
+ if (toState === yamlState) {
+ $state.go(toState);
+ } else {
+ $state.go(graphicalState);
+ }
+ });
+}
+
+function httpConfig($http){
+ $http.defaults.headers.common['X-Csrf-Token-Required-For-Requests'] = 'write';
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/index.less
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/index.less b/new/ui-modules/blueprint-composer/app/index.less
new file mode 100644
index 0000000..5baf074
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/index.less
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+@import '~brooklyn-shared/style/first.less';
+
+@import "~brooklyn-ui-utils/bottom-sheet/bottom-sheet.less";
+@import "~brooklyn-ui-utils/yaml-editor/yaml-editor.less";
+
+// Add project less files here
+@import "views/main/main";
+@import "views/main/graphical/edit/edit";
+@import "views/main/graphical/edit/dsl/edit.dsl.less";
+@import "views/main/graphical/graphical.state.less";
+@import "views/main/yaml/yaml";
+@import "components/designer/designer";
+@import "components/spec-editor/spec-editor";
+@import "components/catalog-selector/catalog-selector";
+@import "components/breacrumbs/breadcrumbs";
+@import "components/blueprint-data-manager/blueprint-data-manager.style.less";
+@import "components/catalog-saver/catalog-saver.less";
+@import "components/dsl-editor/dsl-editor";
+
+@gray-lighter: #E1E5E7;
+@gray-light: #818899;
+
+.make-icon(@size) {
+ width: auto;
+ height: auto;
+ max-width: @size;
+ max-height: @size;
+}
+
+.navbar {
+ margin-bottom: 0;
+}
+
+// Load last so that these style rules and var values trump others
+@import "~brooklyn-shared/style/last.less";
+
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/index.spec.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/index.spec.js b/new/ui-modules/blueprint-composer/app/index.spec.js
new file mode 100644
index 0000000..e241074
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/index.spec.js
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+describe('Blueprint composer module', () => {
+ it('has a dummy unit test', () => {
+ expect(true).toBeTruthy();
+ });
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/bottom-sheet.less
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/bottom-sheet.less b/new/ui-modules/blueprint-composer/app/views/main/bottom-sheet.less
new file mode 100644
index 0000000..21f6d23
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/bottom-sheet.less
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+@progress-border-radius: 0px;
+
+.bottom-sheet {
+ .progress {
+ margin-bottom: 0px;
+ }
+ .container-padding {
+ padding: 10px 15px;
+ overflow: hidden;
+
+ .bottom-sheet-links a {
+ margin-right: 10px;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/bottom-sheet.template.html
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/bottom-sheet.template.html b/new/ui-modules/blueprint-composer/app/views/main/bottom-sheet.template.html
new file mode 100644
index 0000000..833c453
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/bottom-sheet.template.html
@@ -0,0 +1,38 @@
+<!--
+ 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.
+-->
+<uib-progressbar class="progress-striped active" type="info" ng-if="ctrl.loading"></uib-progressbar>
+
+<div class="container-padding">
+ <h4 ng-if="ctrl.loading">Deploying...</h4>
+ <h4 ng-if="ctrl.error" class="text-danger">{{ctrl.error.title}}</h4>
+ <p ng-if="ctrl.error" class="text-muted">{{ctrl.error.message}}</p>
+ <p ng-if="ctrl.error.details" class="text-muted bottom-sheet-links">
+ <a class="text-danger" ng-click="ctrl.viewStackTrace = !ctrl.viewStackTrace">
+ <i class="fa fa-list-ul"></i> {{ctrl.viewStackTrace ? 'Hide' : 'View'}} stacktrace
+ </a>
+ <a class="text-muted" ngclipboard ngclipboard-success="ctrl.onClipboardSuccess(e)" ngclipboard-error="ctrl.onClipboardError(e)" data-clipboard-text="{{ctrl.error.details}}" uib-tooltip="Copied!" tooltip-trigger="{'copied': 'mouseleave'}" tooltip-placement="top">
+ <i class="fa fa-clipboard"></i> Copy stacktrace
+ </a>
+ </p>
+ <div ng-if="ctrl.error.details" tb-stack-viewer trace="ctrl.error.details" vendors="ctrl.vendors" uib-collapse="!ctrl.viewStackTrace"></div>
+ <div class="text-right">
+ <button ng-if="ctrl.error" ng-click="ctrl.investigate()" class="btn btn-default" title="Investigate issue"><i class="fa fa-search-minus" aria-hidden="true" aria-label="Investigate issue"></i></button>
+ <button ng-if="ctrl.error" ng-click="ctrl.close()" class="btn btn-danger">Dismiss</button>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/add/add.html
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/add/add.html b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/add/add.html
new file mode 100644
index 0000000..4e74a85
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/add/add.html
@@ -0,0 +1,27 @@
+<!--
+ 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.
+-->
+<section class="spec-parent">
+ <a ng-href="{{getParentLink()}}">{{getParentLinkLabel()}}</a>
+</section>
+
+<div class="panel-group"><div class="panel"><div class="panel-body">
+
+ <catalog-selector family="family" on-select="onTypeSelected(item)" items-per-page="catalogItemsPerPage"></catalog-selector>
+
+</div></div></div>
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/add/add.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/add/add.js b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/add/add.js
new file mode 100644
index 0000000..1d23ce1
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/add/add.js
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+import {graphicalEditEntityState} from '../entity/edit.entity.controller';
+import {graphicalEditSpecState} from '../spec/edit.spec.controller';
+import {graphicalEditPolicyState} from '../policy/edit.policy.controller';
+import {graphicalEditEnricherState} from '../enricher/edit.enricher.controller';
+import {Entity, EntityFamily} from '../../../../../components/util/model/entity.model';
+import template from './add.html';
+
+export const graphicalEditAddState = {
+ name: 'main.graphical.edit.add',
+ url: '/add/:family?configKey',
+ template: template,
+ controller: ['$scope', '$filter', '$state', '$stateParams', 'blueprintService', GraphicalEditAddController],
+ controllerAs: 'vm',
+};
+
+export function GraphicalEditAddController($scope, $filter, $state, $stateParams, blueprintService) {
+ switch ($stateParams.family) {
+ case EntityFamily.ENTITY.id.toLowerCase():
+ $scope.family = EntityFamily.ENTITY;
+ break;
+ case EntityFamily.SPEC.id.toLowerCase():
+ $scope.family = EntityFamily.SPEC;
+ $scope.configKey = $stateParams.configKey;
+ break;
+ case EntityFamily.POLICY.id.toLowerCase():
+ $scope.family = EntityFamily.POLICY;
+ break;
+ case EntityFamily.ENRICHER.id.toLowerCase():
+ $scope.family = EntityFamily.ENRICHER;
+ break;
+ case EntityFamily.LOCATION.id.toLowerCase():
+ $scope.family = EntityFamily.LOCATION;
+ break;
+ }
+
+ $scope.getParentLink = ()=> {
+ let state = graphicalEditEntityState;
+ let params = {entityId: $scope.entity.hasParent() ? $scope.entity.parent._id : $scope.entity._id};
+ if ($scope.entity.hasParent() && $scope.entity.parent.family === EntityFamily.SPEC) {
+ state = graphicalEditSpecState;
+ params = {entityId: $scope.entity.parent.parent._id, specId: $scope.entity.parent._id};
+ }
+
+ // We have a family, this means we are currently displaying the catalog selector
+ if ($scope.family) {
+ params = {entityId: $scope.entity._id};
+ if ($scope.entity.family === EntityFamily.SPEC) {
+ state = graphicalEditSpecState;
+ params = {entityId: $scope.entity.parent._id, specId: $scope.entity._id};
+ }
+ }
+
+ return $state.href(state, params);
+ };
+
+ $scope.getParentLinkLabel = ()=> {
+ let label = $filter('entityName')($scope.entity.parent) || 'New application';
+
+ if ($scope.family) {
+ label = $filter('entityName')($scope.entity) || 'New application';
+ }
+
+ return label;
+ };
+
+ $scope.onTypeSelected = (type)=> {
+ switch ($scope.family) {
+ case EntityFamily.ENTITY:
+ let newEntity = blueprintService.populateEntityFromApi(new Entity(), type);
+ $scope.entity.addChild(newEntity);
+ blueprintService.refreshEntityMetadata(newEntity, EntityFamily.ENTITY).then(() => {
+ $state.go(graphicalEditEntityState, {entityId: newEntity._id});
+ });
+ break;
+ case EntityFamily.SPEC:
+ let newSpec = blueprintService.populateEntityFromApi(new Entity(), type);
+ $scope.entity.setClusterMemberspecEntity($scope.configKey, newSpec);
+ blueprintService.refreshEntityMetadata(newSpec, EntityFamily.ENTITY).then(() => {
+ $state.go(graphicalEditSpecState, {specId: newSpec._id});
+ });
+ break;
+ case EntityFamily.POLICY:
+ let newPolicy = blueprintService.populateEntityFromApi(new Entity(), type);
+ $scope.entity.addPolicy(newPolicy);
+ blueprintService.refreshEntityMetadata(newPolicy, EntityFamily.POLICY).then(() => {
+ $state.go(graphicalEditPolicyState, {entityId: $scope.entity._id, policyId: newPolicy._id});
+ });
+ break;
+ case EntityFamily.ENRICHER:
+ let newEnricher = blueprintService.populateEntityFromApi(new Entity(), type);
+ $scope.entity.addEnricher(newEnricher);
+ blueprintService.refreshEntityMetadata(newEnricher, EntityFamily.ENRICHER).then(() => {
+ $state.go(graphicalEditEnricherState, {entityId: $scope.entity._id, enricherId: newEnricher._id});
+ });
+ break;
+ case EntityFamily.LOCATION:
+ blueprintService.populateLocationFromApi($scope.entity, type);
+ $state.go(graphicalEditEntityState, {entityId: $scope.entity._id});
+ break;
+ }
+ };
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/dsl/edit.dsl.controller.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/dsl/edit.dsl.controller.js b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/dsl/edit.dsl.controller.js
new file mode 100644
index 0000000..97188ce
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/dsl/edit.dsl.controller.js
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ */
+import template from './edit.dsl.template.html';
+import {Dsl, KIND} from '../../../../../components/util/model/dsl.model';
+
+function EditDslController($scope, $state, $stateParams, objectCache, state) {
+ $scope.state = state;
+
+ let dsl = state.rootDsl;
+ $scope.breadcrumbs = state.levels.map((level, index) => {
+ let ret = {
+ index: level + 1,
+ dsl: dsl,
+ view: {
+ name: graphicalEditDslState.name,
+ params: {
+ levels: state.levels.slice(0, index).join(',')
+ }
+ }
+ };
+ dsl = dsl.params[level + 1];
+ return ret;
+ });
+
+ $scope.$on('brooklyn.components.dsl-editor.select', (event, data) => {
+ let viewName = graphicalEditDslState.name;
+ let viewParams = $stateParams;
+
+ updateRootDsl(data.dsl);
+
+ if ($scope.state.levels.length === 0) {
+ if ($stateParams.index) {
+ $scope.state.entity.config.get($stateParams.for)[$stateParams.index] = $scope.state.rootDsl;
+ } else {
+ $scope.state.entity.addConfig($stateParams.for, $scope.state.rootDsl);
+ }
+ objectCache.removeAll();
+ viewName = $scope.state.view.name;
+ viewParams = $scope.state.view.params;
+ } else {
+ let levels = angular.copy($scope.state.levels);
+ levels.pop();
+ viewParams = {levels: levels.join(',')};
+ }
+
+ $state.go(viewName, viewParams);
+ });
+
+ $scope.$on('brooklyn.components.dsl-editor.nest', (event, data) => {
+ if ($scope.state.levels.length === 0 ) {
+ $scope.state.rootDsl = data.dsl;
+ objectCache.put(`${data.definition.name}.dsl`, $scope.state.rootDsl);
+ } else {
+ updateRootDsl(data.dsl);
+ }
+
+ let levels = angular.copy($scope.state.levels);
+ levels.push(data.index);
+
+ $state.go(graphicalEditDslState.name, {levels: levels.join(',')});
+ });
+
+ $scope.backUrl = () => {
+ return $state.href($scope.state.view.name, $scope.state.view.params);
+ };
+
+ function updateRootDsl(dsl) {
+ let cachedLevels = angular.copy($scope.state.levels);
+ let cachedIndex = cachedLevels.pop();
+
+ if (angular.isDefined(cachedIndex)) {
+ cachedLevels
+ .reduce((dsl, level) => (dsl.params[level + 1]), $scope.state.rootDsl)
+ .params.splice((cachedIndex || 0) + 1, 1, dsl);
+ } else {
+ $scope.state.rootDsl = dsl;
+ }
+ }
+}
+
+export function dslParamLabelFilter($filter) {
+ return function(input) {
+ if (input instanceof Dsl) {
+ switch (input.kind) {
+ case KIND.ENTITY:
+ return 'Entity';
+ case KIND.UTILITY:
+ case KIND.METHOD:
+ return `Fn: ${input.name}`;
+ case KIND.NUMBER:
+ return 'Number';
+ case KIND.PORT:
+ return 'Port';
+ case KIND.STRING:
+ return 'String';
+ case KIND.TARGET:
+ let ret = [];
+ if (input.next) {
+ ret.push($filter('dslParamLabel')(input.next), '@');
+ }
+ ret.push(`Ref: ${input.params[0].name}`);
+ return ret.join(' ');
+ default:
+ return input.toString();
+ }
+ }
+ return input;
+ }
+}
+
+export const graphicalEditDslState = {
+ name: 'main.graphical.edit.dsl',
+ url: '/dsl/:for/:index?levels',
+ params: {
+ index: {
+ value: '',
+ squash: true
+ }
+ },
+ template: template,
+ controller: ['$scope', '$state', '$stateParams', 'objectCache', 'state', EditDslController],
+ controllerAs: 'vm',
+ resolve: {
+ state: ['$state', '$stateParams', 'entity', 'brSnackbar', 'objectCache', ($state, $stateParams, entity, brSnackbar, objectCache) => {
+ let definition = entity.miscData.get('config').find(config => config.name === $stateParams.for);
+ if (!definition) {
+ brSnackbar.create(`Config key ${$stateParams.for} does not exist.`);
+ }
+
+ let rootDsl = objectCache.get(`${definition.name}.dsl`);
+ if (!rootDsl) {
+ let config = entity.config.get(definition.name);
+ if ($stateParams.index) {
+ config = config[$stateParams.index];
+ }
+ rootDsl = config instanceof Dsl
+ ? config.clone()
+ : new Dsl(KIND.STRING, '');
+ objectCache.put(`${definition.name}.dsl`, rootDsl);
+ }
+
+ let view = objectCache.get(`${definition.name}.view`);
+ if (!view) {
+ view = {
+ name: $state.current.name,
+ params: $state.params
+ };
+ objectCache.put(`${definition.name}.view`, view);
+ }
+
+ let state = {
+ entity: entity,
+ levels: $stateParams.levels ? $stateParams.levels.split(',').map(num => parseInt(num)) : [],
+ rootDsl: rootDsl,
+ view: view,
+ index: $stateParams.index
+ };
+
+ state.dsl = state.levels.length > 0
+ ? state.levels.reduce((dsl, level) => (dsl.params[parseInt(level) + 1]), state.rootDsl)
+ : state.rootDsl;
+
+ state.definition = Object.assign({}, definition);
+ if (state.levels.length > 0 || $stateParams.index) {
+ state.definition.type = '.*';
+ }
+
+ return state;
+ }]
+ }
+};
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/dsl/edit.dsl.less
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/dsl/edit.dsl.less b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/dsl/edit.dsl.less
new file mode 100644
index 0000000..2294ac5
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/dsl/edit.dsl.less
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+.spec-dsl {
+ .breadcrumb {
+ overflow-x: scroll;
+ white-space: nowrap;
+ padding: 1em 1em 0.5em 1em;
+ border-radius: 0;
+
+ &::-webkit-scrollbar {
+ height: 0.5em;
+ }
+ &::-webkit-scrollbar-track {
+ background: @breadcrumb-bg;
+ }
+ &::-webkit-scrollbar-thumb {
+ background: @gray-lighter;
+ }
+ &::-webkit-scrollbar-thumb:hover {
+ background: @gray-light;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/dsl/edit.dsl.template.html
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/dsl/edit.dsl.template.html b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/dsl/edit.dsl.template.html
new file mode 100644
index 0000000..a17536e
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/dsl/edit.dsl.template.html
@@ -0,0 +1,34 @@
+<!--
+ 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.
+-->
+<section class="spec-parent">
+ <a ui-sref="{{state.view.name}}({{state.view.params | json}})">{{(state.entity | entityName) || 'New application'}}</a>
+</section>
+
+<section class="spec-dsl">
+ <ol class="breadcrumb">
+ <li>Editing DSL for: <span ng-if="state.index"><code>{{state.index}}</code> in </span><code>{{state.definition.name}}</code></li>
+ <li ng-repeat="breadcrumb in breadcrumbs track by $index" ng-class="{'active': $last}">
+ <a ui-sref="{{breadcrumb.view.name}}({{breadcrumb.view.params | json}})">
+ formatString(<span ng-repeat="(paramIndex, param) in breadcrumb.dsl.params track by param._id" ><code ng-if="breadcrumb.index === paramIndex">{{param | dslParamLabel}}</code><span ng-if="breadcrumb.index !== paramIndex">{{param | dslParamLabel}}</span><span ng-if="!$last">, </span></span>)
+ </a>
+ </li>
+ </ol>
+
+ <dsl-editor definition="state.definition" entity="state.entity" dsl="state.dsl"></dsl-editor>
+</section>
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/edit.controller.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/edit.controller.js b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/edit.controller.js
new file mode 100644
index 0000000..96aa299
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/edit.controller.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+import {HIDE_INTERSTITIAL_SPINNER_EVENT} from 'brooklyn-ui-utils/interstitial-spinner/interstitial-spinner';
+
+export function GraphicalEditController($scope, entity) {
+ $scope.$emit(HIDE_INTERSTITIAL_SPINNER_EVENT);
+ $scope.entity = entity;
+}
+
+export const graphicalEditState = {
+ abstract: true,
+ name: 'main.graphical.edit',
+ url: '/:entityId',
+ template: '<ui-view></ui-view>',
+ controller: ['$scope', 'entity', GraphicalEditController],
+ controllerAs: 'vm',
+ resolve: {
+ entity: ['$q', '$stateParams', 'blueprintService', function ($q, $stateParams, blueprintService) {
+ let defer = $q.defer();
+ let entity = blueprintService.find($stateParams.entityId);
+ if (entity) {
+ defer.resolve(entity);
+ } else {
+ defer.reject('No entity with id [' + $stateParams.entityId + '] found');
+ }
+ return defer.promise;
+ }]
+ }
+};
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/edit.less
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/edit.less b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/edit.less
new file mode 100644
index 0000000..7b547f7
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/edit.less
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+.container-edit {
+ width: 100vw;
+ height: 100vh;
+ background-color: #fff;
+ padding: 15px;
+
+ .container-edit-actions {
+ padding: 15px 0 15px 0;
+ border-top: 1px solid @gray-lighter;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/enricher/edit.enricher.controller.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/enricher/edit.enricher.controller.js b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/enricher/edit.enricher.controller.js
new file mode 100644
index 0000000..8739ef9
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/enricher/edit.enricher.controller.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+import template from './edit.enricher.template.html';
+
+export function EditEnricherController($scope, enricher) {
+ $scope.enricher = enricher;
+}
+
+export const graphicalEditEnricherState = {
+ name: 'main.graphical.edit.enricher',
+ url: '/enricher/:enricherId',
+ template: template,
+ controller: ['$scope', 'enricher', EditEnricherController],
+ controllerAs: 'vm',
+ resolve: {
+ enricher: ['$stateParams', 'entity', function($stateParams, entity) {
+ return entity.enrichers.get($stateParams.enricherId);
+ }]
+ }
+};
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/enricher/edit.enricher.template.html
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/enricher/edit.enricher.template.html b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/enricher/edit.enricher.template.html
new file mode 100644
index 0000000..7160dcc
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/enricher/edit.enricher.template.html
@@ -0,0 +1,23 @@
+<!--
+ 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.
+-->
+<section class="spec-parent">
+ <a ui-sref="main.graphical.edit.entity({entityId: enricher.parent._id})">{{(enricher.parent | entityName) || 'New application'}}</a>
+</section>
+
+<spec-editor model="enricher"></spec-editor>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/entity/edit.entity.controller.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/entity/edit.entity.controller.js b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/entity/edit.entity.controller.js
new file mode 100644
index 0000000..793e1a9
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/entity/edit.entity.controller.js
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+import template from './edit.entity.template.html';
+
+export const graphicalEditEntityState = {
+ name: 'main.graphical.edit.entity',
+ url: '/entity',
+ template: template,
+};
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/entity/edit.entity.template.html
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/entity/edit.entity.template.html b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/entity/edit.entity.template.html
new file mode 100644
index 0000000..1115c26
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/entity/edit.entity.template.html
@@ -0,0 +1,19 @@
+<!--
+ 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.
+-->
+<spec-editor model="entity"></spec-editor>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/policy/edit.policy.controller.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/policy/edit.policy.controller.js b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/policy/edit.policy.controller.js
new file mode 100644
index 0000000..aaad7fe
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/policy/edit.policy.controller.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+import template from './edit.policy.template.html';
+
+export function EditPolicyController($scope, policy) {
+ $scope.policy = policy;
+}
+
+export const graphicalEditPolicyState = {
+ name: 'main.graphical.edit.policy',
+ url: '/policy/:policyId',
+ template: template,
+ controller: ['$scope', 'policy', EditPolicyController],
+ controllerAs: 'vm',
+ resolve: {
+ policy: ['$stateParams', 'entity', function($stateParams, entity) {
+ return entity.policies.get($stateParams.policyId);
+ }]
+ }
+};
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/policy/edit.policy.template.html
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/policy/edit.policy.template.html b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/policy/edit.policy.template.html
new file mode 100644
index 0000000..d7d163a
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/policy/edit.policy.template.html
@@ -0,0 +1,23 @@
+<!--
+ 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.
+-->
+<section class="spec-parent">
+ <a ui-sref="main.graphical.edit.entity({entityId: policy.parent._id})">{{(policy.parent | entityName) || 'New application'}}</a>
+</section>
+
+<spec-editor model="policy"></spec-editor>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/spec/edit.spec.controller.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/spec/edit.spec.controller.js b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/spec/edit.spec.controller.js
new file mode 100644
index 0000000..fc9ef02
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/spec/edit.spec.controller.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+import template from './edit.spec.template.html';
+
+export function EditSpecController($scope, spec) {
+ $scope.spec = spec;
+}
+
+export const graphicalEditSpecState = {
+ name: 'main.graphical.edit.spec',
+ url: '/spec/:specId',
+ template: template,
+ controller: ['$scope', 'spec', EditSpecController],
+ controllerAs: 'vm',
+ resolve: {
+ spec: ['$stateParams', 'entity', function($stateParams, entity) {
+ return entity.getClusterMemberspecEntity((config, entity)=>(entity._id === $stateParams.specId));
+ }]
+ }
+};
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/spec/edit.spec.template.html
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/spec/edit.spec.template.html b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/spec/edit.spec.template.html
new file mode 100644
index 0000000..d98981a
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/edit/spec/edit.spec.template.html
@@ -0,0 +1,23 @@
+<!--
+ 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.
+-->
+<section class="spec-parent">
+ <a ui-sref="main.graphical.edit.entity({entityId: spec.parent._id})">{{(spec.parent | entityName) || 'New application'}}</a>
+</section>
+
+<spec-editor model="spec"></spec-editor>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.html
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.html b/new/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.html
new file mode 100644
index 0000000..b87c38c
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.html
@@ -0,0 +1,52 @@
+<!--
+ 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.
+-->
+<designer></designer>
+
+<div class="left-panel">
+ <ui-view>
+ <br-collapsible state="true">
+ <heading>
+ Entities
+ </heading>
+ <catalog-selector family="EntityFamily.ENTITY" on-select="onTypeSelected(item)" items-per-page="catalogItemsPerPage"></catalog-selector>
+ </br-collapsible>
+
+ <br-collapsible>
+ <heading>
+ Policies
+ </heading>
+ <catalog-selector family="EntityFamily.POLICY" on-select="onTypeSelected(item)" items-per-page="catalogItemsPerPage"></catalog-selector>
+ </br-collapsible>
+
+ <br-collapsible>
+ <heading>
+ Enrichers
+ </heading>
+ <catalog-selector family="EntityFamily.ENRICHER" on-select="onTypeSelected(item)" items-per-page="catalogItemsPerPage"></catalog-selector>
+ </br-collapsible>
+
+ <br-collapsible>
+ <heading>
+ Locations
+ </heading>
+ <catalog-selector family="EntityFamily.LOCATION" on-select="onTypeSelected(item)" items-per-page="catalogItemsPerPage"></catalog-selector>
+ </br-collapsible>
+ </ui-view>
+</div>
+
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.js b/new/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.js
new file mode 100644
index 0000000..00e8180
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.js
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+import {graphicalEditEntityState} from './edit/entity/edit.entity.controller';
+import {graphicalEditPolicyState} from './edit/policy/edit.policy.controller';
+import {graphicalEditEnricherState} from './edit/enricher/edit.enricher.controller';
+import {Entity, EntityFamily} from '../../../components/util/model/entity.model';
+import template from './graphical.state.html';
+
+export const graphicalState = {
+ name: 'main.graphical',
+ url: 'graphical',
+ template: template,
+ controller: ['$scope', '$state', 'blueprintService', graphicalController],
+ data: {
+ label: 'Graphical Designer'
+ }
+};
+
+function graphicalController($scope, $state, blueprintService) {
+ $scope.EntityFamily = EntityFamily;
+ $scope.catalogItemsPerPage = 24;
+
+ $scope.onTypeSelected = (selectedType)=> {
+ let rootEntity = blueprintService.get();
+
+ if (selectedType.supertypes.includes(EntityFamily.ENTITY.superType)) {
+ let newEntity = blueprintService.populateEntityFromApi(new Entity(), selectedType);
+ rootEntity.addChild(newEntity);
+ blueprintService.refreshEntityMetadata(newEntity, EntityFamily.ENTITY).then(() => {
+ $state.go(graphicalEditEntityState, {entityId: newEntity._id});
+ })
+ }
+ else if (selectedType.supertypes.includes(EntityFamily.POLICY.superType)) {
+ let newPolicy = blueprintService.populateEntityFromApi(new Entity(), selectedType);
+ rootEntity.addPolicy(newPolicy);
+ blueprintService.refreshEntityMetadata(newPolicy, EntityFamily.POLICY).then(() => {
+ $state.go(graphicalEditPolicyState, {entityId: rootEntity._id, policyId: newPolicy._id});
+ });
+ }
+ else if (selectedType.supertypes.includes(EntityFamily.ENRICHER.superType)) {
+ let newEnricher = blueprintService.populateEntityFromApi(new Entity(), selectedType);
+ rootEntity.addEnricher(newEnricher);
+ blueprintService.refreshEntityMetadata(newEnricher, EntityFamily.ENRICHER).then(() => {
+ $state.go(graphicalEditEnricherState, {entityId: rootEntity._id, enricherId: newEnricher._id});
+ });
+ }
+ else if (selectedType.supertypes.includes(EntityFamily.LOCATION.superType)) {
+ blueprintService.populateLocationFromApi(rootEntity, selectedType);
+ $state.go(graphicalEditEntityState, {entityId: rootEntity._id});
+ }
+ };
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.less
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.less b/new/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.less
new file mode 100644
index 0000000..0288439
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.less
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+.left-panel {
+ display: block;
+ position: absolute;
+ left: 20px;
+ top: 20px;
+ width: 440px;
+ padding-top: 6px;
+ z-index: 200;
+ overflow-y: scroll;
+ height: calc(~"100vh - 95px");
+ box-shadow: 0 0 rgba(0, 0, 0, 0.2), 0 1px 18px 1px rgba(0, 0, 0, 0.11);
+ background-color: #fff;
+ border: 1px solid @navbar-default-border;
+
+ .container-fluid {
+ padding: 0;
+ }
+
+ .spec-parent {
+ margin-top: -6px;
+ a {
+ background-color: @gray-lighter;
+ padding: 15px 45px 15px 15px;
+ position: relative;
+ color: @gray-light;
+ font-style: italic;
+ display: block;
+ transition: color 0.3s ease;
+ .text-overflow();
+
+ &:after{
+ content: '\f112';
+ font-family: FontAwesome;
+ position: absolute;
+ right: 15px;
+ color: @gray-light;
+ transition: color 0.3s ease;
+ }
+ &:hover {
+ color: @gray;
+ &:after {
+ color: @gray;
+ }
+ }
+ }
+ }
+
+ // panel classes are added by use of accordion toggle in palette
+ // we also use these classes for spec editor and others
+ // (would be nice to refactor so we use our own classes instead)
+ .panel-group {
+ margin-bottom: 0;
+ .panel {
+ border-bottom: 1px solid @gray-lighter;
+ margin: 0 12px;
+ border-radius: 0;
+ box-shadow: none;
+ .panel-heading {
+ padding: 15px 3px 15px 3px;
+ }
+ .panel-title {
+ font-size: 16px;
+ font-weight: 400;
+ }
+ .panel-body {
+ padding: 0;
+ border: none !important;
+ margin-bottom: 24px;
+ }
+ }
+ .panel-title > a,
+ .panel-title > a:hover,
+ .panel-title > a:focus:hover {
+ background: none;
+ color: @gray-light;
+
+ .collapsible-action {
+ padding-left: 2px;
+ padding-right: 6px;
+ margin-top: 1px;
+ }
+ .collapsible-action, a.collapsible-action {
+ color: @gray-light;
+ }
+ .collapsible-action:active, a.collapsible-action:active,
+ .collapsible-action:hover, a.collapsible-action:hover,
+ .collapsible-action:focus, a.collapsible-action:focus {
+ color: @gray;
+ }
+ }
+ }
+
+ br-collapsible catalog-selector {
+ margin-top: 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/main.controller.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/main.controller.js b/new/ui-modules/blueprint-composer/app/views/main/main.controller.js
new file mode 100644
index 0000000..401b8f6
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/main.controller.js
@@ -0,0 +1,270 @@
+/*
+ * 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.
+ */
+import {HIDE_INTERSTITIAL_SPINNER_EVENT} from 'brooklyn-ui-utils/interstitial-spinner/interstitial-spinner';
+import template from './main.template.html';
+import {EntityFamily} from '../../components/util/model/entity.model';
+import {graphicalState} from './graphical/graphical.state';
+import {yamlState} from './yaml/yaml.state';
+import {graphicalEditEntityState} from './graphical/edit/entity/edit.entity.controller';
+import {graphicalEditPolicyState} from './graphical/edit/policy/edit.policy.controller';
+import {graphicalEditEnricherState} from './graphical/edit/enricher/edit.enricher.controller';
+import {graphicalEditSpecState} from './graphical/edit/spec/edit.spec.controller';
+import bottomSheetTemplate from './bottom-sheet.template.html';
+import {ISSUE_LEVEL} from '../../components/util/model/issue.model';
+
+const layers = [
+ {
+ id: 'locations',
+ label: 'Locations',
+ selector: '.node-location',
+ active: true
+ },
+ {
+ id: 'adjuncts',
+ label: 'Adjuncts',
+ selector: '.node-adjuncts',
+ active: true
+ },
+ {
+ id: 'memberspecs',
+ label: 'Member specs',
+ selector: '.spec-node-group',
+ active: true
+ },
+ {
+ id: 'relationships',
+ label: 'Relationships',
+ selector: '.relation-group',
+ active: true
+ }
+];
+const layerCacheKey = 'blueprint-composer.layers';
+
+export function MainController($scope, $log, $state, $stateParams, brBrandInfo, blueprintService, actionService, catalogApi, applicationApi, brSnackbar, brBottomSheet, edit, yaml) {
+ $scope.$emit(HIDE_INTERSTITIAL_SPINNER_EVENT);
+ let vm = this;
+
+ if (edit && yaml) {
+ throw 'Cannot supply both YAML source and a catalog item to edit';
+ }
+
+ vm.mode = $state.current;
+ $scope.$on('$stateChangeSuccess', (event, toState)=>{
+ vm.mode = toState;
+ });
+
+ vm.layers = localStorage && localStorage.getItem(layerCacheKey) !== null ?
+ JSON.parse(localStorage.getItem(layerCacheKey)) :
+ layers;
+ $scope.$watch('vm.layers', ()=> {
+ vm.layers.forEach(layer => {
+ document.querySelectorAll(layer.selector).forEach(node => {
+ angular.element(node).css('display', layer.active ? 'block' : 'none');
+ });
+ });
+ if (localStorage) {
+ try {
+ localStorage.setItem(layerCacheKey, JSON.stringify(vm.layers));
+ } catch (ex) {
+ $log.error('Cannot save layers preferences: ' + ex.message);
+ }
+ }
+ }, true);
+
+ vm.parseError = false;
+ $scope.$on('yaml.lint', (event, error)=>{
+ $scope.$applyAsync(()=> {
+ vm.parseError = error;
+ });
+ });
+
+ $scope.$on('blueprint.reset', () => {
+ vm.saveToCatalogConfig = {};
+ blueprintService.reset();
+ $state.go($state.includes(yamlState) ? yamlState : graphicalState, {}, {inherit: false, reload: true});
+ });
+ $scope.$on('blueprint.deploy', () => {
+ vm.deployApplication();
+ });
+
+ vm.saveToCatalogConfig = {};
+ if (edit) {
+ vm.saveToCatalogConfig = Object.assign(vm.saveToCatalogConfig, {
+ bundle: edit.bundle.symbolicName.replace(/^catalog-bom-/, ''),
+ version: edit.type.version,
+ symbolicName: edit.type.symbolicName,
+ itemType: edit.type.template ? 'template' : 'entity',
+ name: edit.type.displayName,
+ description: edit.type.description,
+ iconUrl: edit.type.iconUrl,
+ versions: edit.versions,
+ });
+ yaml = edit.type.plan.data;
+ }
+
+ if (yaml) {
+ blueprintService.setFromYaml(yaml);
+ } else {
+ blueprintService.reset();
+ }
+
+ vm.deployApplication = function () {
+ if (blueprintService.hasIssues()) {
+ displayIssues();
+ return;
+ }
+
+ deployApplication();
+ };
+
+ vm.isGraphicalMode = () => {
+ return $state.includes(graphicalState.name);
+ };
+
+ vm.getAllActions = () => {
+ return actionService.getActions();
+ }
+
+ function displayIssues() {
+ let isOnlyWarnings = blueprintService.getIssues().length === blueprintService.getIssues().filter(issue => issue.level === ISSUE_LEVEL.WARN).length;
+ let message = '';
+ let options = {};
+ if (isOnlyWarnings) {
+ message = 'Blueprint has some warnings, deployment might fail. Do you wish to proceed anyway?';
+ options = {
+ label: 'Deploy',
+ callback: deployApplication
+ }
+ } else {
+ message = 'Blueprint is not valid: there ' + (
+ blueprintService.getIssues().filter(issue => issue.level === ISSUE_LEVEL.ERROR).length > 1 ?
+ 'are ' + blueprintService.getIssues().filter(issue => issue.level === ISSUE_LEVEL.ERROR).length + ' problems' :
+ 'is 1 problem'
+ ) + ' to fix';
+ }
+
+ brSnackbar.create(message, options);
+
+ let firstEntityWithIssue = blueprintService.getIssues().filter(issue => {
+ if (isOnlyWarnings) {
+ return issue.level === ISSUE_LEVEL.WARN;
+ } else {
+ return issue.level === ISSUE_LEVEL.ERROR;
+ }
+ })[0].entity;
+ switch (firstEntityWithIssue.family) {
+ case EntityFamily.ENTITY:
+ $state.go(graphicalEditEntityState, {entityId: firstEntityWithIssue._id});
+ return;
+ case EntityFamily.POLICY:
+ $state.go(graphicalEditPolicyState, {entityId: firstEntityWithIssue.parent._id, policyId: firstEntityWithIssue._id});
+ return;
+ case EntityFamily.ENRICHER:
+ $state.go(graphicalEditEnricherState, {entityId: firstEntityWithIssue.parent._id, enricherId: firstEntityWithIssue._id});
+ return;
+ case EntityFamily.SPEC:
+ $state.go(graphicalEditSpecState, {entityId: firstEntityWithIssue.parent._id, specId: firstEntityWithIssue._id});
+ return;
+ }
+ }
+
+ function deployApplication() {
+ let bottomSheetOpts = {
+ controller: ['$log', 'brBrandInfo', 'brBottomSheetInstance', 'blueprintService', 'applicationApi', bottomSheetController],
+ controllerAs: 'ctrl',
+ template: bottomSheetTemplate
+ };
+
+ brBottomSheet.open(bottomSheetOpts);
+
+ function bottomSheetController($log, brBrandInfo, brBottomSheetInstance, blueprintService, applicationApi) {
+ this.loading = true;
+ this.vendors = brBrandInfo.getVendorPackages();
+
+ this.close = ()=> {
+ brBottomSheetInstance.close('Closing deployment error reporting');
+ };
+ this.investigate = ()=> {
+ brBottomSheetInstance.updateMode('inset');
+ };
+ this.onClipboardSuccess = (e)=> {
+ angular.element(e.trigger).triggerHandler('copied');
+ e.clearSelection();
+ };
+ this.onClipboardError = (e)=> {
+ let message = '';
+ let actionKey = e.action === 'cut' ? 'X' : 'C';
+ if(/iPhone|iPad/i.test(navigator.userAgent)) {
+ message = 'No support :(';
+ }
+ else if(/Mac/i.test(navigator.userAgent)) {
+ message = 'Press ⌘-' + actionKey + ' to ' + e.action;
+ }
+ else {
+ message = 'Press Ctrl-' + actionKey + ' to ' + e.action;
+ }
+ brSnackbar.create(message);
+ };
+
+ let applicationToDeploy = blueprintService.getAsYaml();
+ applicationApi.createApplication(applicationToDeploy).then((success)=> {
+ $log.info('Application deployment ... success', success);
+ window.location.href = brBrandInfo.getAppDeployedUrl(success.entityId, success.entityId);
+ }).catch((error)=> {
+ $log.error('Application deployment ... failed', error);
+ this.error = {
+ title: 'Application deployment failed',
+ message: error.error.message,
+ details: error.error.details
+ };
+ }).finally(()=> {
+ this.loading = false;
+ });
+ }
+ }
+}
+
+export const mainState = {
+ name: 'main',
+ url: '/?bundleSymbolicName&bundleVersion&typeSymbolicName&typeVersion&yaml',
+ abstract: true,
+ template: template,
+ controller: ['$scope', '$log', '$state', '$stateParams', 'brBrandInfo', 'blueprintService', 'actionService', 'catalogApi', 'applicationApi', 'brSnackbar', 'brBottomSheet', 'edit', 'yaml', MainController],
+ controllerAs: 'vm',
+ resolve: {
+ edit: ['$stateParams', '$q', 'paletteApi', ($stateParams, $q, paletteApi) => {
+ let deferred = $q.defer();
+ if (!($stateParams.bundleSymbolicName && $stateParams.bundleVersion && $stateParams.typeSymbolicName && $stateParams.typeVersion)) {
+ deferred.resolve(null);
+ } else if ($stateParams.bundleSymbolicName && $stateParams.bundleVersion && $stateParams.typeSymbolicName && $stateParams.typeVersion) {
+ $q.all([
+ paletteApi.getBundle($stateParams.bundleSymbolicName, $stateParams.bundleVersion),
+ paletteApi.getBundleType($stateParams.bundleSymbolicName, $stateParams.bundleVersion, $stateParams.typeSymbolicName, $stateParams.typeVersion),
+ paletteApi.getTypeVersions($stateParams.typeSymbolicName)
+ ]).then(responses => {
+ deferred.resolve({bundle: responses[0], type: responses[1], versions: responses[2].map(item => item.version)});
+ }).catch(response => deferred.reject(response.error.message));
+ } else {
+ deferred.reject('Both bundle and type information must be supplied');
+ }
+ return deferred.promise;
+ }],
+ yaml: ['$stateParams', $stateParams => $stateParams.yaml]
+ }
+};
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/main.less
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/main.less b/new/ui-modules/blueprint-composer/app/views/main/main.less
new file mode 100644
index 0000000..fdba549
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/main.less
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+@import "./bottom-sheet.less";
+
+.page-main-area {
+ position: relative;
+
+ .modes {
+ position: absolute;
+ top: 20px;
+ right: 20px;
+ z-index: 100;
+ .btn-primary {
+ border: 1px solid transparent;
+ }
+ a[disabled] {
+ pointer-events: none;
+ }
+ }
+ .layer a {
+ cursor: pointer;
+ color: @gray-lighter;
+ transition: color 0.3s ease;
+ &:hover {
+ color: @gray-light;
+ }
+ }
+ .layer.active a {
+ color: @brand-primary;
+ &:hover {
+ color: @brand-primary;
+ }
+ }
+ .tab-content {
+ width: 100%;
+ background: transparent;
+ border: none;
+ margin: 0;
+
+ .tab-pane {
+ padding: 0;
+ }
+ }
+ .actions {
+ position: absolute;
+ bottom: 20px;
+ right: 20px;
+ z-index: 100;
+ custom-action {
+ margin-left: 5px;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/main.template.html
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/main.template.html b/new/ui-modules/blueprint-composer/app/views/main/main.template.html
new file mode 100644
index 0000000..d9c894e
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/main.template.html
@@ -0,0 +1,54 @@
+<!--
+ 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.
+-->
+<div class="btn-group modes" role="group" aria-label="...">
+ <div class="btn-group" uib-dropdown keyboard-nav auto-close="outsideClick">
+ <button type="button" class="btn btn-default disabled">
+ {{vm.mode.data.label}}
+ </button>
+ <button type="button" class="btn btn-success dropdown-toggle" ng-disabled="!vm.isGraphicalMode()" uib-dropdown-toggle aria-haspopup="true" aria-expanded="false">
+ <span class="caret"></span>
+ <span class="sr-only">Toggle layers selection</span>
+ </button>
+ <ul class="dropdown-menu dropdown-menu-right" uib-dropdown-menu role="menu">
+ <li ng-if="vm.isGraphicalMode()" class="dropdown-header">Layers</li>
+ <li role="menuitem" class="layer"
+ ng-if="vm.isGraphicalMode()"
+ ng-repeat="layer in vm.layers track by layer.id"
+ ng-class="{'active': layer.active}">
+ <a ng-click="layer.active = !layer.active"><i class="fa fa-fw fa-circle"></i> {{layer.label}}</a>
+ </li>
+ </ul>
+ </div>
+ <a ui-sref="main.graphical" ng-if="!vm.isGraphicalMode()" class="btn btn-primary" ng-disabled="vm.parseError">
+ <i class="fa fa-fw fa-exchange"></i>
+ <span class="sr-only">Switch to Graphical Designer</span>
+ </a>
+ <a ui-sref="main.yaml" ng-if="vm.isGraphicalMode()" class="btn btn-primary">
+ <i class="fa fa-fw fa-exchange"></i>
+ <span class="sr-only">Switch to YAML Editor</span>
+ </a>
+</div>
+
+<ui-view></ui-view>
+
+
+<div class="actions">
+ <custom-action ng-repeat="(id, action) in vm.getAllActions() track by id" action="action"></custom-action>
+ <blueprint-data-manager></blueprint-data-manager>
+</div>
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/yaml/yaml.less
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/yaml/yaml.less b/new/ui-modules/blueprint-composer/app/views/main/yaml/yaml.less
new file mode 100644
index 0000000..8a78b17
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/yaml/yaml.less
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+br-yaml-editor {
+ .CodeMirror {
+ height: calc(~"100vh - 55px");
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/app/views/main/yaml/yaml.state.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/app/views/main/yaml/yaml.state.js b/new/ui-modules/blueprint-composer/app/views/main/yaml/yaml.state.js
new file mode 100644
index 0000000..e6cbea1
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/app/views/main/yaml/yaml.state.js
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+import CodeMirror from 'codemirror';
+import {YAMLException} from 'js-yaml';
+
+export const yamlState = {
+ name: 'main.yaml',
+ url: 'yaml',
+ template: '<br-yaml-editor value="vm.yaml" type="blueprint"></br-yaml-editor>',
+ controller: ['$scope', '$rootScope', '$timeout', 'blueprintService', 'brSnackbar', yamlStateController],
+ controllerAs: 'vm',
+ data: {
+ label: 'YAML Editor'
+ }
+};
+
+function yamlStateController($scope, $rootScope, $timeout, blueprintService, brSnackbar) {
+ let vm = this;
+
+ try {
+ vm.yaml = blueprintService.getAsYaml();
+ } catch (ex) {
+ brSnackbar.create(`Cannot load blueprint: ${ex.message}`);
+ vm.yaml = '';
+ }
+
+ if (!CodeMirror.lint.hasOwnProperty('yaml-composer')) {
+ CodeMirror.registerGlobalHelper('lint', 'yaml-composer', mode => mode.name === 'yaml', (text, options, cm) => {
+ let issues = [];
+
+ try {
+ blueprintService.setFromYaml(cm.getValue(), true);
+ } catch (err) {
+ if (!(err instanceof YAMLException)) {
+ issues.push({
+ from: CodeMirror.Pos(0, 0),
+ to: CodeMirror.Pos(0, 0),
+ message: err.message
+ });
+ }
+ }
+
+ return issues;
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/config/build/webpack.config.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/config/build/webpack.config.js b/new/ui-modules/blueprint-composer/config/build/webpack.config.js
new file mode 100644
index 0000000..a050fa9
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/config/build/webpack.config.js
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+eval(require('fs').readFileSync('../shared/config/build/webpack.config.js')+'');
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/blueprint-composer/config/server.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/blueprint-composer/config/server.js b/new/ui-modules/blueprint-composer/config/server.js
new file mode 100644
index 0000000..dfba7dc
--- /dev/null
+++ b/new/ui-modules/blueprint-composer/config/server.js
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+eval(require('fs').readFileSync('../shared/config/server.js')+'');