brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From henev...@apache.org
Subject [09/28] brooklyn-ui git commit: This adds the contributed brooklyn-ui-angular code in the folder new/.
Date Thu, 26 Jul 2018 10:50:26 GMT
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/home/pom.xml
----------------------------------------------------------------------
diff --git a/new/ui-modules/home/pom.xml b/new/ui-modules/home/pom.xml
new file mode 100644
index 0000000..5831ee3
--- /dev/null
+++ b/new/ui-modules/home/pom.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+         
+    <parent>
+        <artifactId>brooklyn-ui-modules-parent</artifactId>
+        <groupId>org.apache.brooklyn.ui.modules</groupId>
+        <version>${revision}</version>
+    </parent>
+    
+    <artifactId>brooklyn-ui-home</artifactId>
+    <packaging>war</packaging>
+    <name>Brooklyn UI :: Modules - Home</name>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <artifactId>maven-clean-plugin</artifactId>
+                <configuration>
+                    <filesets>
+                        <fileset>
+                            <directory>dist</directory>
+                            <followSymlinks>false</followSymlinks>
+                        </fileset>
+                    </filesets>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.github.eirslett</groupId>
+                <artifactId>frontend-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-resources</id>
+                        <!-- here the phase you need -->
+                        <phase>compile</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>
+                                ${project.build.directory}/${project.artifactId}-${project.version}
+                            </outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${project.basedir}/dist</directory>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-war-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <!-- configure plugin to generate MANIFEST.MF
+                     adapted from http://blog.knowhowlab.org/2010/06/osgi-tutorial-from-project-structure-to.html -->
+                <executions>
+                    <execution>
+                        <id>bundle-manifest</id>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>manifest</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <supportedProjectTypes>
+                        <supportedProjectType>war</supportedProjectType>
+                        <supportedProjectType>jar</supportedProjectType>
+                        <supportedProjectType>bundle</supportedProjectType>
+                    </supportedProjectTypes>
+                    <instructions>
+                        <Bundle-ManifestVersion>${project.version}</Bundle-ManifestVersion>
+                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+                        <Import-Package>
+                            org.apache.brooklyn.ui.modularity.module.api,
+                            org.eclipse.jetty.servlets,
+                            *
+                        </Import-Package>
+                        <Export-Package>
+                            !*
+                        </Export-Package>
+                        <Web-ContextPath>/</Web-ContextPath>
+                        <_wab>app</_wab>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/home/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/new/ui-modules/home/src/main/webapp/WEB-INF/web.xml b/new/ui-modules/home/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..992d1f3
--- /dev/null
+++ b/new/ui-modules/home/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,58 @@
+<!--
+  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.
+-->
+<web-app version="2.4"
+         xmlns="http://java.sun.com/xml/ns/j2ee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
+                             http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+    <description>Brooklyn Home</description>
+    <display-name>Brooklyn Home</display-name>
+    <welcome-file-list>
+        <welcome-file>index.html</welcome-file>
+    </welcome-file-list>
+
+    <!--FILTERS :: START-->
+    <filter>
+        <filter-name>ui-module-filter</filter-name>
+        <filter-class>org.apache.brooklyn.ui.modularity.module.api.UiModuleFilter</filter-class>
+        <init-param>
+            <param-name>Cache-Control</param-name>
+            <param-value>public, max-age=604800</param-value><!--Cache static content for 1 week-->
+        </init-param>
+    </filter>
+    <filter>
+        <filter-name>GzipFilter</filter-name>
+        <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
+        <init-param>
+            <param-name>mimeTypes</param-name>
+            <param-value>text/html,text/plain,text/xml,application/xhtml+xml,text/css,application/javascript,image/svg+xml</param-value>
+        </init-param>
+    </filter>
+
+    <filter-mapping>
+        <filter-name>ui-module-filter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+    <filter-mapping>
+        <filter-name>GzipFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+    <!--FILTERS :: END-->
+</web-app>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/.babelrc
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/.babelrc b/new/ui-modules/location-manager/.babelrc
new file mode 100644
index 0000000..222c2ba
--- /dev/null
+++ b/new/ui-modules/location-manager/.babelrc
@@ -0,0 +1,6 @@
+{
+  "presets": [
+    "env",
+    "stage-0"
+  ]
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/.eslintrc.json
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/.eslintrc.json b/new/ui-modules/location-manager/.eslintrc.json
new file mode 100644
index 0000000..c4fe470
--- /dev/null
+++ b/new/ui-modules/location-manager/.eslintrc.json
@@ -0,0 +1,52 @@
+{
+  "__license__": [
+    "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."
+  ],
+  "extends": "google",
+  "rules": {
+    "indent": [
+      "error",
+      4
+    ],
+    "max-len": [
+      "warn",
+      120
+    ],
+    "space-before-function-paren": [
+      "error",
+      "always"
+    ],
+    "sort-imports": [
+      "error",
+      {
+        "ignoreCase": false,
+        "ignoreMemberSort": false,
+        "memberSyntaxSortOrder": [
+          "none",
+          "all",
+          "multiple",
+          "single"
+        ]
+      }
+    ],
+    "quotes": [
+      "error",
+      "single"
+    ]
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/.npmrc
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/.npmrc b/new/ui-modules/location-manager/.npmrc
new file mode 100644
index 0000000..c595d19
--- /dev/null
+++ b/new/ui-modules/location-manager/.npmrc
@@ -0,0 +1,18 @@
+#
+# 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.
+package-lock=false
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/Makefile
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/Makefile b/new/ui-modules/location-manager/Makefile
new file mode 100644
index 0000000..c7cb424
--- /dev/null
+++ b/new/ui-modules/location-manager/Makefile
@@ -0,0 +1,49 @@
+#
+# 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.
+default: dev
+
+build:
+	@echo "Building production bundle..."
+	NODE_ENV="production" npm run build
+
+clean:
+	@echo "Cleaning modules..."
+	@rm -rf ./node_modules
+
+dev:
+	@echo "Starting dev web server..."
+	@npm start
+
+server: build
+	@echo "Starting api proxy server..."
+	NODE_ENV="production" npm start
+
+install:
+	@echo "Installing npm modules..."
+	@npm install
+
+test:
+	@echo "Running tests..."
+	@npm test
+
+setup: clean install
+
+war:
+	@mvn clean install
+
+.PHONY: build clean deploy dev install server setup test war

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/components/dynamic-config/dynamic-config.html
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/components/dynamic-config/dynamic-config.html b/new/ui-modules/location-manager/app/components/dynamic-config/dynamic-config.html
new file mode 100644
index 0000000..8745c78
--- /dev/null
+++ b/new/ui-modules/location-manager/app/components/dynamic-config/dynamic-config.html
@@ -0,0 +1,73 @@
+<!--
+  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="dynamic-config-fields">
+    <div class="form-group" ng-class="locationConfig[key].type" ng-repeat="(key, value) in model track by key" ng-switch="locationConfig[key].type">
+        <div ng-switch-when="select">
+            <label class="control-label">{{key}} <i ng-click="onDeleteDynamicConfig(key)" class="fa fa-trash control-delete"></i></label>
+            <select class="form-control" ng-model="model[key]" auto-focus>
+                <option ng-repeat="(optionKey, optionLabel) in locationConfig[key].options" ng-value="optionKey">{{optionLabel}}</option>
+            </select>
+        </div>
+        <div ng-switch-when="textarea">
+            <label class="control-label">{{key}} <i ng-click="onDeleteDynamicConfig(key)" class="fa fa-trash control-delete"></i></label>
+            <textarea ng-model="model[key]" class="form-control" auto-focus>{{value}}</textarea>
+        </div>
+        <div ng-switch-when="checkbox">
+            <label class="control-label">
+                <input ng-model="model[key]" type="checkbox" class="checkbox" auto-focus />
+                {{key}} <i ng-click="onDeleteDynamicConfig(key)" class="fa fa-trash control-delete"></i>
+            </label>
+        </div>
+        <div ng-switch-default>
+            <label class="control-label">{{key}} <i ng-click="onDeleteDynamicConfig(key)" class="fa fa-trash control-delete"></i></label>
+            <div ng-class="{'input-group': locationConfig[key].unit}">
+                <input ng-model="model[key]" type="{{locationConfig[key].type || 'text'}}" placeholder="{{locationConfig[key].description}}" class="form-control" auto-focus />
+                <span class="input-group-addon" ng-if="locationConfig[key].unit">Unit: <code>{{locationConfig[key].unit}}</code></span>
+            </div>
+        </div>
+    </div>
+</div>
+
+<form name="dynamicConfigForm" ng-submit="onSubmitDynamicConfigForm()" ng-show="showDynamicConfigForm" novalidate>
+    <div class="form-group" ng-class="{'has-error': dynamicConfigForm.newDynamicKey.$invalid && dynamicConfigForm.newDynamicKey.$touched}">
+        <label class="control-label">Enter new {{type}} key</label>
+        <input ng-model="newDynamicKey" type="text" class="form-control" name="newDynamicKey" required
+               autocomplete="off"
+               uib-typeahead="suggestion.name for suggestion in suggestions | filter:$viewValue"
+               typeahead-template-url="SuggestionItemTemplate.html"
+               typeahead-show-hint="true"
+               typeahead-min-length="0"
+               auto-focus="showDynamicConfigForm" />
+        <p class="help-block" ng-show="dynamicConfigForm.$submitted || dynamicConfigForm.newDynamicKey.$touched">
+            <small ng-show="dynamicConfigForm.newDynamicKey.$error.required">You need to specify a {{type}} key first.</small>
+            <small ng-show="dynamicConfigForm.newDynamicKey.$error.used">This key is already used, please choose another one.</small>
+        </p>
+    </div>
+
+    <input type="submit" value="submit" class="hidden" />
+</form>
+
+<p ng-click="toggleDynamicConfigForm()" class="toggle-link" ng-class="{'add': !showDynamicConfigForm, 'remove': showDynamicConfigForm}">{{showDynamicConfigForm ? 'Remove ' : 'Add'}} new {{type}}</p>
+
+<script type="text/ng-template" id="SuggestionItemTemplate.html">
+    <div class="dropdown-item">
+        <h4 class="dropdown-item-heading" ng-bind-html="match.model.name | uibTypeaheadHighlight:query"></h4>
+        <p class="dropdown-item-subheading">{{match.model.description}}</p>
+    </div>
+</script>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/components/dynamic-config/dynamic-config.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/components/dynamic-config/dynamic-config.js b/new/ui-modules/location-manager/app/components/dynamic-config/dynamic-config.js
new file mode 100644
index 0000000..2190298
--- /dev/null
+++ b/new/ui-modules/location-manager/app/components/dynamic-config/dynamic-config.js
@@ -0,0 +1,73 @@
+/*
+ * 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 locationUtils from '../location-utils/location-utils';
+import dynamicConfigTemplate from './dynamic-config.html';
+
+const MODULE_NAME = 'brooklyn.components.dynamic-config';
+
+angular.module(MODULE_NAME, [locationUtils])
+    .directive('dynamicConfig', dynamicConfigDirective);
+
+export default MODULE_NAME;
+
+export function dynamicConfigDirective() {
+    return {
+        restrict: 'E',
+        template: dynamicConfigTemplate,
+        scope: {
+            model: '=',
+            type: '@'
+        },
+        controller: ['$scope', '$timeout', 'locationConfig', controller]
+    };
+
+    function controller($scope, $timeout, locationConfig) {
+        $scope.showDynamicConfigForm = false;
+        $scope.locationConfig = locationConfig;
+        $scope.suggestions = Object.keys(locationConfig).map(function (key) {
+            return {
+                name: key,
+                description: locationConfig[key].description
+            };
+        });
+
+        $scope.toggleDynamicConfigForm = function () {
+            $scope.showDynamicConfigForm = !$scope.showDynamicConfigForm;
+            $timeout(function () {
+                $scope.newDynamicKey = '';
+                $scope.dynamicConfigForm.$setPristine();
+                $scope.dynamicConfigForm.$setUntouched();
+            });
+        };
+
+        $scope.onSubmitDynamicConfigForm = function () {
+            if ($scope.newDynamicKey) {
+                $scope.model[$scope.newDynamicKey] = locationConfig[$scope.newDynamicKey] && locationConfig[$scope.newDynamicKey].type === 'checkbox' ? false : '';
+                $scope.newDynamicKey = '';
+                $scope.showDynamicConfigForm = false;
+            }
+        };
+
+        $scope.onDeleteDynamicConfig = function (key) {
+            if ($scope.model.hasOwnProperty(key)) {
+                delete $scope.model[key];
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/components/dynamic-config/dynamic-config.less
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/components/dynamic-config/dynamic-config.less b/new/ui-modules/location-manager/app/components/dynamic-config/dynamic-config.less
new file mode 100644
index 0000000..64be5c1
--- /dev/null
+++ b/new/ui-modules/location-manager/app/components/dynamic-config/dynamic-config.less
@@ -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.
+ */
+dynamic-config {
+  .toggle-link {
+    color: @gray-light;
+    text-transform: uppercase;
+    text-decoration: none;
+    margin-top: 20px;
+    cursor: pointer;
+
+    &:hover {
+      text-decoration: none;
+    }
+    &.add:before {
+      content: "\f067";
+      font-family: FontAwesome;
+      color: @brand-success;
+      padding-right: 10px;
+    }
+
+    &.remove:before {
+      content: "\f068";
+      font-family: FontAwesome;
+      color: @brand-success;
+      padding-right: 10px;
+    }
+  }
+
+  .control-delete {
+    margin-left: 5px;
+    transition: 0.3s ease color;
+    &:hover {
+      color: @brand-danger;
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/components/location-utils/location-utils.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/components/location-utils/location-utils.js b/new/ui-modules/location-manager/app/components/location-utils/location-utils.js
new file mode 100644
index 0000000..a8468fd
--- /dev/null
+++ b/new/ui-modules/location-manager/app/components/location-utils/location-utils.js
@@ -0,0 +1,222 @@
+/*
+ * 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';
+
+const MODULE_NAME = 'br.utils.location-utils';
+
+angular.module(MODULE_NAME, [])
+    .provider('locationConfig', locationConfigProvider)
+    .provider('locationSpec', locationSpecProvider)
+    .filter('locationIcon', ['locationSpec', locationIconFilter])
+    .filter('locationName', locationNameFilter)
+    .filter('locationProviderUrl', ['locationSpec', locationProviderUrlFilter]);
+
+export default MODULE_NAME;
+
+export function locationConfigProvider() {
+    return {
+        $get: [LocationConfigFactory]
+    };
+
+    function LocationConfigFactory() {
+        return {
+            'minCore': {
+                description: 'Minimum number of core for the generated VM',
+                type: 'number'
+            },
+            'minRam': {
+                description: 'Minimum amount of RAM for the generated VM',
+                type: 'number',
+                unit: 'Mb'
+            },
+            'osFamily': {
+                description: 'Operating system to use for the generated VM',
+                type: 'select',
+                options: {
+                    'ubuntu': 'Ubuntu',
+                    'centos': 'CentOS',
+                    'redhat': 'Red Hat'
+                }
+            },
+            'osVersionRegex': {
+                description: 'Operating system\'s version to use for the generated VM',
+                type: 'text'
+            },
+            'os64Bit': {
+                description: 'Use a 64 bits operating system',
+                type: 'checkbox'
+            },
+            'imageId': {
+                description: 'Image ID to use for the generated VM',
+                type: 'text'
+            },
+            'imageNameRegex': {
+                description: 'Regular expression to choose an image for the generated VM',
+                type: 'text'
+            },
+            'hardwareId': {
+                description: 'Hardware ID to use for the generated VM',
+                type: 'text'
+            },
+            'inboundPorts': {
+                description: 'Ports to open for inbound connections, separated by a coma',
+                type: 'text'
+            },
+            'securityGroups': {
+                description: 'Security groups to use the generated VM, separated by a coma',
+                type: 'text'
+            },
+            'domainName': {
+                description: 'Domain name to use for the generated VM',
+                type: 'text'
+            },
+            'userMetadata': {
+                description: 'Metadatas to set on the generated VM',
+                type: 'text'
+            },
+            'machineCreateAttempts': {
+                description: 'Number of retry to create a VM',
+                type: 'number'
+            },
+            'destroyOnFailure': {
+                description: 'Whether or not to destroy the VM if the provisioning fails',
+                type: 'checkbox'
+            },
+            'user': {
+                description: 'Operating user created on provisioned VM',
+                type: 'text'
+            },
+            'password': {
+                description: 'Operating user\'s password created on provisioned VM',
+                type: 'password'
+            },
+            'loginUser': {
+                description: 'Initial user to log in as',
+                type: 'text'
+            },
+            'privateKeyFile': {
+                description: 'Path to private key to use to connect to the provisioned VM',
+                type: 'text'
+            },
+            'privateKeyPassphrase': {
+                description: 'Passphrase to open the SSH key, used to connect to the provisioned VM',
+                type: 'text'
+            },
+            'publicKeyFile': {
+                description: 'Path to public key to use to connect to the provisioned VM',
+                type: 'text'
+            },
+            'openIptables': {
+                description: 'Whether or not automatically configure iptables',
+                type: 'checkbox'
+            },
+            'installDevUrandom': {
+                description: 'Whether or not install urandom',
+                type: 'checkbox'
+            },
+            'useJcloudsSshInit': {
+                description: 'Whether or not disable the native jclouds support for initial commands executed on the VM',
+                type: 'checkbox'
+            }
+        };
+    }
+}
+
+export function locationSpecProvider() {
+    return {
+        $get: [LocationSpecFactory]
+    };
+
+    function LocationSpecFactory() {
+        return {
+            'jclouds:aws-ec2': {
+                name: 'Amazon EC2',
+                url: 'https://aws.amazon.com/console/',
+                icon: require('../../img/location-icons/aws.png')
+            },
+            'jclouds:softlayer': {
+                name: 'Softlayer',
+                url: 'https://control.softlayer.com/',
+                icon: require('../../img/location-icons/softlayer.png')
+            },
+            'jclouds:google-compute-engine': {
+                name: 'Google Compute Engine',
+                url: 'https://console.cloud.google.com/start',
+                icon: require('../../img/location-icons/jclouds-google-compute-engine.png')
+            },
+            'jclouds:openstack-nova': {
+                name: 'Openstack Nova',
+                icon: require('../../img/location-icons/jclouds-openstack-nova.png')
+            },
+            'jclouds:openstack-mitaka-nova': {
+                name: 'Openstack Mitaka',
+                icon: require('../../img/location-icons/jclouds-openstack-nova.png')
+            },
+            'jclouds:azurecompute-arm': {
+                name: 'Microsoft Azure ARM',
+                url: 'https://portal.azure.com/',
+                icon: require('../../img/location-icons/azurecompute-arm.png')
+            },
+            'jclouds:azurecompute': {
+                name: 'Microsoft Azure Classic (Deprecated)',
+                url: 'https://portal.azure.com/',
+                icon: require('../../img/location-icons/azurecompute.png')
+            },
+            'localhost': {
+                name: 'Localhost',
+                url: 'https://localhost/',
+                icon: require('../../img/location-icons/localhost.png')
+            },
+            'byon': {
+                name: 'BYON',
+                icon: require('../../img/location-icons/byon.png')
+            }
+        }
+    }
+}
+
+export function locationIconFilter(locationSpecProvider) {
+    return function (input) {
+        if (input.iconUrl) {
+            return input.iconUrl;
+        }
+        if (locationSpecProvider.hasOwnProperty(input.spec) && locationSpecProvider[input.spec].icon) {
+            return locationSpecProvider[input.spec].icon;
+        }
+        return require('../../img/location-icons/cloud.png');
+    }
+}
+
+export function locationNameFilter() {
+    return function(input) {
+        if (!input) {
+            return null;
+        }
+        if (input.config && input.config.hasOwnProperty('name')) {
+            return input.config.name;
+        }
+        return input.name ? input.name : input.symbolicName;
+    }
+}
+
+export function locationProviderUrlFilter(locationSpecProvider) {
+    return function(input) {
+        return locationSpecProvider.hasOwnProperty(input.spec) ? locationSpecProvider[input.spec].url : '#';
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/components/transformers/locations.transformer.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/components/transformers/locations.transformer.js b/new/ui-modules/location-manager/app/components/transformers/locations.transformer.js
new file mode 100644
index 0000000..195c5e9
--- /dev/null
+++ b/new/ui-modules/location-manager/app/components/transformers/locations.transformer.js
@@ -0,0 +1,58 @@
+/*
+ * 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 jsyaml from 'js-yaml';
+
+export function oldToCatalogLocation(oldLocation) {
+    return {
+        symbolicName: oldLocation.name,
+        name: oldLocation.config ? (oldLocation.config.displayName || oldLocation.config.name) : oldLocation.name,
+        config: oldLocation.config,
+        deprecated: oldLocation.config ? oldLocation.config.deprecated : false,
+        id: oldLocation.id,
+        type: oldLocation.id,
+        spec: oldLocation.spec,
+        readOnly: true
+    };
+}
+
+export function transformResponse(data, headersGetter, status) {
+    let json = angular.fromJson(data);
+    if (status === 200) {
+        if (angular.isArray(json)) {
+            return json.map((value, key) => {
+                return parseAndExtractYamlConfig(value);
+            });
+        } else if (angular.isObject(json)) {
+            return parseAndExtractYamlConfig(json);
+        }
+    }
+    return json;
+}
+
+export function parseAndExtractYamlConfig(json) {
+    try {
+        let doc = jsyaml.safeLoad(json.planYaml);
+        json.spec = doc['brooklyn.locations'][0].type;
+        json.config = doc['brooklyn.locations'][0]['brooklyn.config'];
+        return json;
+    } catch(ex) {
+        return json;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/img/location-icons/aws.png
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/img/location-icons/aws.png b/new/ui-modules/location-manager/app/img/location-icons/aws.png
new file mode 100644
index 0000000..127ba60
Binary files /dev/null and b/new/ui-modules/location-manager/app/img/location-icons/aws.png differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/img/location-icons/azurecompute-arm.png
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/img/location-icons/azurecompute-arm.png b/new/ui-modules/location-manager/app/img/location-icons/azurecompute-arm.png
new file mode 100644
index 0000000..fccf596
Binary files /dev/null and b/new/ui-modules/location-manager/app/img/location-icons/azurecompute-arm.png differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/img/location-icons/azurecompute.png
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/img/location-icons/azurecompute.png b/new/ui-modules/location-manager/app/img/location-icons/azurecompute.png
new file mode 100644
index 0000000..792772d
Binary files /dev/null and b/new/ui-modules/location-manager/app/img/location-icons/azurecompute.png differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/img/location-icons/byon.png
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/img/location-icons/byon.png b/new/ui-modules/location-manager/app/img/location-icons/byon.png
new file mode 100644
index 0000000..5b8e87c
Binary files /dev/null and b/new/ui-modules/location-manager/app/img/location-icons/byon.png differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/img/location-icons/cloud.png
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/img/location-icons/cloud.png b/new/ui-modules/location-manager/app/img/location-icons/cloud.png
new file mode 100644
index 0000000..a637139
Binary files /dev/null and b/new/ui-modules/location-manager/app/img/location-icons/cloud.png differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/img/location-icons/jclouds-google-compute-engine.png
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/img/location-icons/jclouds-google-compute-engine.png b/new/ui-modules/location-manager/app/img/location-icons/jclouds-google-compute-engine.png
new file mode 100644
index 0000000..16f568c
Binary files /dev/null and b/new/ui-modules/location-manager/app/img/location-icons/jclouds-google-compute-engine.png differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/img/location-icons/jclouds-openstack-nova.png
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/img/location-icons/jclouds-openstack-nova.png b/new/ui-modules/location-manager/app/img/location-icons/jclouds-openstack-nova.png
new file mode 100644
index 0000000..d35de6a
Binary files /dev/null and b/new/ui-modules/location-manager/app/img/location-icons/jclouds-openstack-nova.png differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/img/location-icons/localhost.png
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/img/location-icons/localhost.png b/new/ui-modules/location-manager/app/img/location-icons/localhost.png
new file mode 100644
index 0000000..c69cf16
Binary files /dev/null and b/new/ui-modules/location-manager/app/img/location-icons/localhost.png differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/img/location-icons/softlayer.png
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/img/location-icons/softlayer.png b/new/ui-modules/location-manager/app/img/location-icons/softlayer.png
new file mode 100644
index 0000000..e106339
Binary files /dev/null and b/new/ui-modules/location-manager/app/img/location-icons/softlayer.png differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/index.e2e-spec.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/index.e2e-spec.js b/new/ui-modules/location-manager/app/index.e2e-spec.js
new file mode 100644
index 0000000..8077599
--- /dev/null
+++ b/new/ui-modules/location-manager/app/index.e2e-spec.js
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+const request = require('request');
+
+const APP_NAME = 'Location manager';
+
+describe('App Shell', ()=> {
+    browser.get('./');
+    browser.waitForAngular();
+
+    describe('metadata', ()=> {
+        it('should have the correct title', ()=> {
+            expect(browser.getTitle()).toEqual('Brooklyn - ' + APP_NAME);
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/index.html
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/index.html b/new/ui-modules/location-manager/app/index.html
new file mode 100644
index 0000000..f2bdf4c
--- /dev/null
+++ b/new/ui-modules/location-manager/app/index.html
@@ -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.
+-->
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8"/>
+        <meta http-equiv="x-ua-compatible" content="ie=edge"/>
+        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"/>
+        <link rel="icon" type="image/png" href="${require('!!file-loader!<%= brand.product.favicon %>')}"/>
+        <title><%= getBrandedText('product.name') %> - <%= app.appname %></title>
+    </head>
+    <body ng-app="app" br-server-status ng-strict-di>
+        ${require('ejs-html!brooklyn-shared/partials/header.html')}
+
+        <main class="page-main-area" id="main-content" ui-view ng-cloak></main>
+
+        ${require('ejs-html!brooklyn-shared/partials/footer.html')}
+
+        <br-interstitial-spinner event-count="1">
+            ${require('ejs-html!brooklyn-shared/partials/interstitial.html')}
+        </br-interstitial-spinner>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/index.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/index.js b/new/ui-modules/location-manager/app/index.js
new file mode 100644
index 0000000..429f9a4
--- /dev/null
+++ b/new/ui-modules/location-manager/app/index.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 angular from 'angular';
+import ngAnimate from 'angular-animate';
+import ngCookies from 'angular-cookies';
+import uiRouter from 'angular-ui-router';
+
+import brCore from 'brooklyn-ui-utils/br-core/br-core';
+
+import brServerStatus from 'brooklyn-ui-utils/server-status/server-status';
+import brAutoFocus from 'brooklyn-ui-utils/autofocus/autofocus';
+import brInterstitialSpinner from 'brooklyn-ui-utils/interstitial-spinner/interstitial-spinner';
+import brooklynModuleLinks from 'brooklyn-ui-utils/module-links/module-links';
+import brSensitiveField from 'brooklyn-ui-utils/sensitive-field/sensitive-field';
+import brooklynUserManagement from 'brooklyn-ui-utils/user-management/user-management';
+import brooklynApi from 'brooklyn-ui-utils/brooklyn.api/brooklyn.api';
+
+import locationsState from 'views/locations/locations.controller';
+import detailState from 'views/detail/detail.controller';
+import wizardState from 'views/wizard/wizard.controller';
+import wizardAdvancedState from 'views/wizard/advanced/advanced.controller';
+import wizardByonState from 'views/wizard/byon/byon.controller';
+import wizardCloudState from 'views/wizard/cloud/cloud.controller';
+
+angular.module('app', [ngAnimate, ngCookies, uiRouter, brCore, brServerStatus, brAutoFocus, brInterstitialSpinner, brooklynModuleLinks, brSensitiveField, brooklynUserManagement, brooklynApi, locationsState, detailState, wizardState, wizardAdvancedState, wizardByonState, wizardCloudState])
+    .config(['$urlRouterProvider', '$logProvider', applicationConfig])
+    .run(['$rootScope', '$state', 'brSnackbar', errorHandler])
+    .run(['$http', httpConfig]);
+
+function applicationConfig($urlRouterProvider, $logProvider) {
+    $logProvider.debugEnabled(false);
+    $urlRouterProvider.otherwise('/');
+}
+
+function errorHandler($rootScope, $state, brSnackbar) {
+    $rootScope.$on('$stateChangeError', (event, toState, toParams, fromState, fromParams, error)=> {
+        if (toState.name === 'detail') {
+            brSnackbar.create('Could not locate location [' + toParams.symbolicName + ']');
+        }
+        $state.go('locations');
+    });
+}
+
+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/location-manager/app/index.less
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/index.less b/new/ui-modules/location-manager/app/index.less
new file mode 100644
index 0000000..75c7f0b
--- /dev/null
+++ b/new/ui-modules/location-manager/app/index.less
@@ -0,0 +1,30 @@
+/*
+ * 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/sensitive-field/sensitive-field.less';
+
+// Add project less files here
+@import 'views/locations/locations.less';
+@import 'views/detail/detail.less';
+@import 'views/wizard/wizard.less';
+@import 'components/dynamic-config/dynamic-config';
+
+// 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/location-manager/app/index.spec.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/index.spec.js b/new/ui-modules/location-manager/app/index.spec.js
new file mode 100644
index 0000000..a814932
--- /dev/null
+++ b/new/ui-modules/location-manager/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('Location manager 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/location-manager/app/views/detail/detail.controller.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/views/detail/detail.controller.js b/new/ui-modules/location-manager/app/views/detail/detail.controller.js
new file mode 100644
index 0000000..426c1a9
--- /dev/null
+++ b/new/ui-modules/location-manager/app/views/detail/detail.controller.js
@@ -0,0 +1,106 @@
+/*
+ * 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 uiRouter from 'angular-ui-router';
+import brooklynApi from 'brooklyn-ui-utils/brooklyn.api/brooklyn.api';
+import {HIDE_INTERSTITIAL_SPINNER_EVENT} from 'brooklyn-ui-utils/interstitial-spinner/interstitial-spinner';
+import dynamicConfig from '../../components/dynamic-config/dynamic-config';
+import locationUtils from '../../components/location-utils/location-utils';
+import {oldToCatalogLocation, transformResponse} from '../../components/transformers/locations.transformer';
+import template from './detail.template.html';
+
+const MODULE_NAME = 'state.detail';
+
+angular.module(MODULE_NAME, [uiRouter, brooklynApi, dynamicConfig, locationUtils])
+    .config(['$stateProvider', detailStateConfig]);
+
+export default MODULE_NAME;
+
+export const detailState = {
+    name: 'detail',
+    url: '/location?symbolicName&version',
+    params: {
+        version: {value: null},
+        symbolicName: {value: null}
+    },
+    controller: ['$scope', '$filter', '$state', '$stateParams', 'brSnackbar', 'catalogApi', 'location', detailController],
+    controllerAs: 'vm',
+    template: template,
+    resolve: {
+        location: ['catalogApi', 'locationApi', '$q', '$stateParams', function (catalogApi, locationApi, $q, $stateParams) {
+            if ($stateParams.version !== null) {
+                // If there is a version, it means we are asking for a catalog location
+                return $q.all([
+                    catalogApi.getLocation($stateParams.symbolicName, $stateParams.version, {cache: null, transformResponse: transformResponse}),
+                    catalogApi.getLocations({
+                        fragment: $stateParams.symbolicName,
+                        allVersions: 'true'
+                    }, {cache: null, transformResponse: transformResponse})
+                ]).then(function (result) {
+                    // result[0] is the current location we want to display
+                    // result[1] are all location with the same symbolicName. This is to get a list of available versions
+                    result[0].versions = result[1].filter((location) => {
+                        return location.symbolicName === $stateParams.symbolicName && location.version !== $stateParams.version
+                    }).map((location) => {
+                        return location.version;
+                    });
+                    return result[0];
+                });
+            } else {
+                // Otherwise, let's hit the old API
+                return locationApi.getLocation($stateParams.symbolicName).then(function (location) {
+                    return oldToCatalogLocation(location);
+                });
+            }
+        }]
+    }
+};
+
+export function detailStateConfig($stateProvider) {
+    $stateProvider.state(detailState);
+}
+
+export function detailController($scope, $filter, $state, $stateParams, brSnackbar, catalogApi, location) {
+    $scope.$emit(HIDE_INTERSTITIAL_SPINNER_EVENT);
+
+    let vm = this;
+    vm.location = angular.copy(location);
+    vm.deleteLocation = function () {
+        catalogApi.deleteLocation(vm.location.symbolicName, vm.location.version).then(data => {
+            $state.go('locations');
+            brSnackbar.create('Location "' + $filter('locationName')(vm.location) + '" deleted successfully');
+        }).catch(error => {
+            brSnackbar.create('Could not delete this location: ' + error.message);
+        });
+    };
+    vm.editLocation = function () {
+        if (vm.location['spec'].indexOf('byon') >= 0) {
+            $state.go('wizard.byon', {symbolicName: $stateParams.symbolicName, version: $stateParams.version});
+        }
+        else if (vm.location['spec'].indexOf('jclouds') >= 0) {
+            $state.go('wizard.cloud', {symbolicName: $stateParams.symbolicName, version: $stateParams.version});
+        }
+        else {
+            $state.go('wizard.advanced', {symbolicName: $stateParams.symbolicName, version: $stateParams.version});
+        }
+    };
+    vm.hasLocationConfig = function () {
+        return vm.location && vm.location.config && Object.keys(vm.location.config).length > 0;
+    };
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/views/detail/detail.less
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/views/detail/detail.less b/new/ui-modules/location-manager/app/views/detail/detail.less
new file mode 100644
index 0000000..7fe6438
--- /dev/null
+++ b/new/ui-modules/location-manager/app/views/detail/detail.less
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+.location-detail {
+    .media-heading {
+        font-size: 25px;
+        color: #3C5588;
+        margin-right: 5px;
+        margin-top: 10px;
+    }
+
+    .media-object {
+        width: 64px;
+        height: 64px;
+    }
+
+    .media-body {
+        overflow: visible;
+    }
+
+    .location-id {
+        margin-top: 10px;
+        color: @gray-light;
+        -webkit-font-smoothing: antialiased;
+    }
+
+    .location-detail-description {
+        color: rgba(0, 0, 0, 0.5);
+        font-weight: 300;
+        font-size: 90%;
+        margin-top: 2px;
+    }
+
+    .message-read-only {
+        color: grey;
+        -webkit-font-smoothing: antialiased;
+    }
+
+    .location-config {
+        border-top: 1px solid @gray-lighter;
+        margin-top: 15px;
+        padding-top: 15px;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/views/detail/detail.template.html
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/views/detail/detail.template.html b/new/ui-modules/location-manager/app/views/detail/detail.template.html
new file mode 100644
index 0000000..600f02b
--- /dev/null
+++ b/new/ui-modules/location-manager/app/views/detail/detail.template.html
@@ -0,0 +1,83 @@
+<!--
+  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="container">
+    <div class="row">
+        <div class="col-md-12">
+            <br-card class="location-detail {{vm.location.readOnly ? 'read-only' : ''}}" nf-if="vm.location !== null">
+                <br-card-content>
+                    <div class="media">
+                        <div class="media-left">
+                            <a ng-href="{{vm.location | locationProviderUrl}}">
+                                <img class="media-object" ng-src="{{vm.location | locationIcon}}"
+                                     alt="{{vm.location | locationName}}'s icon">
+                            </a>
+                        </div>
+                        <div class="media-body">
+                            <h4 class="media-heading location-name">
+                                {{vm.location | locationName}}
+                                <div class="btn-group" uib-dropdown ng-if="vm.location.version">
+                                    <button uib-dropdown-toggle ng-disabled="vm.location.versions.length === 0" id="versions-dropdown" type="button" class="btn btn-sm btn-default"><i class="fa fa-code-fork"></i> {{vm.location.version}} <span class="caret"></span></button>
+                                    <ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="versions-dropdown">
+                                        <li role="menuitem" ng-repeat="version in vm.location.versions track by version">
+                                            <a ui-sref="detail({symbolicName: vm.location.symbolicName, version: version})"><i class="fa fa-code-fork"></i> {{version}}</a>
+                                        </li>
+                                    </ul>
+                                </div>
+                            </h4>
+                            <p class="location-detail-description">
+                                {{vm.location.spec}} &bull;
+                                <i class="fa fa-hdd-o"></i> {{vm.location.symbolicName}}
+                            </p>
+                        </div>
+                        <div class="media-right">
+                            <br-button type="btn-primary" on-click="vm.editLocation()" ng-if="!vm.location.readOnly">Edit location</br-button>
+                        </div>
+
+                        <div ng-if="vm.hasLocationConfig()" class="location-config">
+                            <h4>Current configuration</h4>
+                            <div class="table-responsive">
+                                <table class="table table-bordered">
+                                    <thead>
+                                    <tr>
+                                        <th>Name</th>
+                                        <th>Value</th>
+                                    </tr>
+                                    </thead>
+                                    <tbody>
+                                    <tr ng-repeat="(key,value) in vm.location.config track by key">
+                                        <td>{{key}}</td>
+                                        <td sensitive-field field-name="{{key}}">{{value}}</td>
+                                    </tr>
+                                    </tbody>
+                                </table>
+                            </div>
+                        </div>
+                    </div>
+                </br-card-content>
+                <br-card-actions>
+                    <br-button type="btn-danger" on-click="vm.deleteLocation()" ng-if="!vm.location.readOnly">Delete</br-button>
+                    <div class="message-read-only" ng-if="vm.location.readOnly">This location can not be edited or deleted.</div>
+                </br-card-actions>
+            </br-card>
+            <br-card ng-if="vm.location === null">
+                <br-card-content><i class="fa fa-spin fa-spinner"></i></br-card-content>
+            </br-card>
+        </div>
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/views/locations/locations.controller.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/views/locations/locations.controller.js b/new/ui-modules/location-manager/app/views/locations/locations.controller.js
new file mode 100644
index 0000000..5465b32
--- /dev/null
+++ b/new/ui-modules/location-manager/app/views/locations/locations.controller.js
@@ -0,0 +1,100 @@
+/*
+ * 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 uiRouter from 'angular-ui-router';
+import brooklynApi from 'brooklyn-ui-utils/brooklyn.api/brooklyn.api';
+import {HIDE_INTERSTITIAL_SPINNER_EVENT} from 'brooklyn-ui-utils/interstitial-spinner/interstitial-spinner';
+import locationUtils from '../../components/location-utils/location-utils';
+import {oldToCatalogLocation, transformResponse} from '../../components/transformers/locations.transformer';
+import template from './locations.template.html';
+
+const MODULE_NAME = 'state.locations';
+
+angular.module(MODULE_NAME, [uiRouter, brooklynApi, locationUtils])
+    .config(['$stateProvider', locationsStateConfig]);
+
+export default MODULE_NAME;
+
+export const locationsState = {
+    name: 'locations',
+    url: '/',
+    controller: ['$scope', 'locations', locationsStateController],
+    controllerAs: 'vm',
+    template: template,
+    resolve: {
+        locations: ['catalogApi', 'locationApi', '$q', '$filter', function (catalogApi, locationApi, $q, $filter) {
+            return $q.all([locationApi.getLocations(), catalogApi.getLocations({allVersions: 'true'}, {cache: null, transformResponse: transformResponse})]).then(function (result) {
+                // result[0] are all locations coming from the old api. It includes the catalog locations.
+                // result[1] are catalog locations
+                let seenLocations = new Map();
+
+                // This filters out the catalog locations
+                return result[0].filter((oldLocation) => {
+                    return !oldLocation.hasOwnProperty('catalog');
+                })
+                // Then we transform our old location into the same format as catalog locations
+                    .map(oldToCatalogLocation)
+                    // Then we concat the result with the catalog locations
+                    .concat(result[1].filter((newLocation) => {
+                        let prevLocation;
+
+                        // Have we seen this location before?
+                        if (seenLocations.has(newLocation.symbolicName)) {
+                            // Yes, grab it and add this data to it
+                            prevLocation = seenLocations.get(newLocation.symbolicName);
+                            prevLocation.versions.push(newLocation.version);
+                            // Don't keep this entry, we've merged it into the previous one
+                            return false;
+                        }
+
+                        if (!Array.isArray(newLocation.versions)) {
+                            newLocation.versions = [];
+                        }
+
+                        // Remember that we've seen it
+                        seenLocations.set(newLocation.symbolicName, newLocation);
+
+                        // Keep this one, we'll merge any others that match into it
+                        return true;
+                    }))
+                    // Finally, we sort by name
+                    .sort((a, b) => {
+                        let nameA = $filter('locationName')(a);
+                        let nameB = $filter('locationName')(b);
+                        if (nameA < nameB) {
+                            return -1;
+                        }
+                        if (nameA > nameB) {
+                            return 1;
+                        }
+                        return 0;
+                    })
+            });
+        }]
+    }
+};
+
+export function locationsStateConfig($stateProvider) {
+    $stateProvider.state(locationsState);
+}
+
+export function locationsStateController($scope, locations) {
+    $scope.$emit(HIDE_INTERSTITIAL_SPINNER_EVENT);
+    $scope.locations = locations;
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/views/locations/locations.less
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/views/locations/locations.less b/new/ui-modules/location-manager/app/views/locations/locations.less
new file mode 100644
index 0000000..bd7b8ce
--- /dev/null
+++ b/new/ui-modules/location-manager/app/views/locations/locations.less
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+.location-icon {
+  width: 60px;
+  height: 60px;
+  fill: @gray-light;
+}
+
+.no-location {
+  -webkit-font-smoothing: antialiased;
+  margin: 20px;
+  margin-top: 50px;
+  margin-bottom: 50px;
+  color: #747F86;
+  text-align: center;
+  font-size: 20px;
+
+  h4 {
+    font-size: 20px;
+  }
+  p {
+    font-size: 16px;
+  }
+}
+
+ul.card-list-view li {
+  position: relative;
+  .blueprints-list-item { // to get higher importance over utils/
+    &.read-only {
+      background: #f5f5f5;
+    }
+  }
+
+  .id, .version {
+    color: @gray-light;
+    -webkit-font-smoothing: antialiased;
+  }
+
+  .version {
+    position: absolute;
+    bottom: 0;
+    right: 0;
+    padding: 5px 20px 5px 20px;
+    border-top: 1px solid #E1E1E1;
+    border-left: 1px solid #E1E1E1;
+  }
+}
+
+.read-only {
+  .location-name:after{
+    content: '\f023 read-only';
+    font-family: "myriad-pro-1", Helvetica, Arial, sans-serif, FontAwesome;
+    color: grey;
+    font-size: 14px;
+    margin-left: 10px;
+  }
+}
+
+.btn-primary { // Move to utils/
+  -webkit-font-smoothing: antialiased;
+}
+
+.page-heading {
+  .btn.btn-md {
+    margin-top: -7px;
+    margin-left: 10px;
+  }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/views/locations/locations.template.html
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/views/locations/locations.template.html b/new/ui-modules/location-manager/app/views/locations/locations.template.html
new file mode 100644
index 0000000..8b0511f
--- /dev/null
+++ b/new/ui-modules/location-manager/app/views/locations/locations.template.html
@@ -0,0 +1,77 @@
+<!--
+  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="container">
+    <header class="row">
+        <div class="col-sm-9">
+            <h2 class="page-heading">Registered locations <a
+                    ng-if="results.length > 0"
+                    class="btn btn-md btn-primary"
+                    ui-sref="wizard">
+                <i class="fa fa-plus" aria-hidden="true"></i> Add new
+                </a></h2>
+            <p class="page-subheading">All registered target locations</p>
+        </div>
+        <div class="col-sm-3">
+            <div class="action-area">
+                <fieldset>
+                    <div class="form-group has-feedback">
+                        <input ng-model="search" type="text" class="form-control" id="inputSuccess2" aria-describedby="inputSuccess2Status" placeholder="Filter locations">
+                        <span class="form-control-feedback" aria-hidden="true">
+                            <i class="fa fa-search"></i>
+                        </span>
+                    </div>
+                </fieldset>
+            </div>
+        </div>
+    </header>
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="brooklyn-home-card">
+                <ul class="card-list-view">
+                    <li ng-repeat="location in locations | filter:search as results">
+                        <a ui-sref="detail({symbolicName: location.readOnly ? location.id : location.symbolicName, version: location.version})">
+                            <div class="blueprints-list-item" ng-class="{'read-only': location.readOnly}">
+                                <div class="id float-right">
+                                    <i class="fa fa-hdd-o"></i> {{location.symbolicName}}
+                                </div>
+                                <div class="float-left">
+                                    <img ng-src="{{location | locationIcon}}" alt="{{location | locationName}}'s icon" class="location-icon" />
+                                </div>
+                                <div class="details">
+                                    <span class="repo-name location-name">{{location | locationName}}</span>
+                                    <span class="description">{{location.spec}}</span>
+                                </div>
+                            </div>
+                            <div class="version" ng-if="location.version">
+                                <i class="fa fa-code-fork"></i> {{location.version}} <span class="label label-default" ng-if="location.versions.length > 0">+ {{location.versions.length}}</span>
+                            </div>
+                        </a>
+                    </li>
+                    <li ng-if="results.length === 0">
+                        <div class="no-location">
+                            <h4>No locations defined yet.</h4>
+                            <a type="btn-primary" class="btn btn-md btn-primary" ui-sref="wizard">Add location</a>
+                        </div>
+                    </li>
+                </ul>
+            </div>
+        </div>
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/views/wizard/advanced/advanced.controller.js
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/views/wizard/advanced/advanced.controller.js b/new/ui-modules/location-manager/app/views/wizard/advanced/advanced.controller.js
new file mode 100644
index 0000000..975d9c3
--- /dev/null
+++ b/new/ui-modules/location-manager/app/views/wizard/advanced/advanced.controller.js
@@ -0,0 +1,98 @@
+/*
+ * 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 uiRouter from 'angular-ui-router';
+import brooklynApi from 'brooklyn-ui-utils/brooklyn.api/brooklyn.api';
+import {transformResponse} from '../../../components/transformers/locations.transformer';
+import template from './advanced.template.html';
+
+const MODULE_NAME = 'state.wizard.advanced';
+
+angular.module(MODULE_NAME, [uiRouter, brooklynApi])
+    .config(['$stateProvider', wizardAdvancedStateConfig]);
+
+export default MODULE_NAME;
+
+export const wizardAdvancedState = {
+    name: 'wizard.advanced',
+    url: '/advanced?symbolicName&version',
+    params: {
+        version: {value: null},
+        symbolicName: {value: null}
+    }, controller: ['$element', '$state', 'brSnackbar', 'location', 'catalogApi', wizardAdvancedController],
+    controllerAs: 'vm',
+    template: template,
+    resolve: {
+        location: ['catalogApi', '$q', '$stateParams', (catalogApi, $q, $stateParams) => {
+            if ($stateParams.symbolicName !== null) {
+                return catalogApi.getLocation($stateParams.symbolicName, $stateParams.version, {cache: null, transformResponse: transformResponse});
+            }
+            return;
+        }]
+    }
+};
+
+export function wizardAdvancedStateConfig($stateProvider) {
+    $stateProvider.state(wizardAdvancedState);
+}
+
+export function wizardAdvancedController($element, $state, brSnackbar, location, catalogApi) {
+    $element.find('input')[0].focus();
+
+    let vm = this;
+    mapLocation();
+    vm.save = () => {
+        let payload = {
+            'brooklyn.catalog': {
+                bundle: `catalog-bom-${vm.id}`,
+                version: vm.version,
+                items: [
+                    {
+                        itemType: 'location',
+                        item: {
+                            id: vm.id,
+                            name: vm.name,
+                            type: vm.parent,
+                            'brooklyn.config': angular.copy(vm.config)
+                        }
+                    }
+                ]
+            }
+        };
+        catalogApi.create(payload).then(data => {
+            $state.go('detail', {symbolicName: vm.id, version: vm.version});
+        }).catch(error => {
+            brSnackbar.create('Could not save location: ' + error.data.message ? error.data.message : error.data);
+        });
+    };
+
+    function mapLocation() {
+        if (location) {
+            vm.id = location.symbolicName;
+            vm.name = location.name;
+            vm.version = location.version;
+            vm.parent = location.spec;
+            vm.config = location.config;
+        } else {
+            vm.config = {};
+            vm.version = '0.0.0.SNAPSHOT';
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/29927b73/new/ui-modules/location-manager/app/views/wizard/advanced/advanced.template.html
----------------------------------------------------------------------
diff --git a/new/ui-modules/location-manager/app/views/wizard/advanced/advanced.template.html b/new/ui-modules/location-manager/app/views/wizard/advanced/advanced.template.html
new file mode 100644
index 0000000..b41f481
--- /dev/null
+++ b/new/ui-modules/location-manager/app/views/wizard/advanced/advanced.template.html
@@ -0,0 +1,63 @@
+<!--
+  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="row">
+    <div class="col-md-12">
+        <p class="page-subheading">Enter the details of your new advanced location</p>
+        <div class="brooklyn-home-card">
+            <div class="title">
+                <form novalidate name="form">
+                    <div class="form-group" ng-class="{'has-error': form.id.$invalid && form.id.$touched}">
+                        <label class="control-label" for="id">Location ID*</label>
+                        <input ng-model="vm.id" type="text" class="form-control" id="id" name="id" required placeholder="A label to identify this location in YAML. Typically this is lower case using hyphens and no spaces">
+                        <p class="help-block" ng-show="form.$submitted || form.id.$touched">
+                            <span ng-show="form.id.$error.required">You must specify a location ID</span>
+                        </p>
+                    </div>
+                    <div class="form-group" ng-class="{'has-error': form.version.$invalid && form.version.$touched}">
+                        <label class="control-label" for="id">Location version*</label>
+                        <input ng-model="vm.version" type="text" class="form-control" id="version" name="version" required placeholder="A version number to identify this location">
+                        <p class="help-block" ng-show="form.$submitted || form.version.$touched">
+                            <span ng-show="form.id.$error.required">You must specify a location version</span>
+                        </p>
+                    </div>
+                    <div class="form-group" ng-class="{'has-error': form.name.$invalid && form.name.$touched}">
+                        <label class="control-label" for="name">Location name</label>
+                        <input ng-model="vm.name" type="text" class="form-control" id="name" name="name" placeholder="A display name to present this location to a user (optional)">
+                    </div>
+                    <div class="form-group" ng-class="{'has-error': form.parent.$invalid && form.parent.$touched}">
+                        <label class="control-label" for="parent">Parent location*</label>
+                        <input ng-model="vm.parent" type="text" class="form-control" id="parent" name="parent" placeholder="The identity or spec of the location which this location should extend" required />
+                        <p class="help-block" ng-show="form.$submitted || form.id.$touched">
+                            <span ng-show="form.parent.$error.required">You must specify a parent location</span>
+                        </p>
+                    </div>
+                </form>
+
+                <section>
+                    <h3>Additional configuration</h3>
+                    <dynamic-config model="vm.config" type="configuration"></dynamic-config>
+                </section>
+
+                <div class="col-md-12 text-right">
+                    <button class="btn btn-primary btn-lg" ng-disabled="form.$invalid" ng-click="vm.save()">Save</button>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>


Mime
View raw message