add an "Open in Composer" button to quick launch

the effect is to open the template's definition in composer
diff --git a/ui-modules/home/app/views/main/deploy/deploy.controller.js b/ui-modules/home/app/views/main/deploy/deploy.controller.js
index 7055d01..896ec7e 100644
--- a/ui-modules/home/app/views/main/deploy/deploy.controller.js
+++ b/ui-modules/home/app/views/main/deploy/deploy.controller.js
@@ -81,7 +81,8 @@
     function modalController($scope, $location, entitySpec, locations) {
         $scope.app = entitySpec;
         $scope.locations = locations;
-        $scope.args = $location.search();
+        // can optionally add: { noEditButton: true, noComposerButton: true }, or pass in URL
+        $scope.args = angular.extend({}, $location.search());
     }
 }
 
diff --git a/ui-modules/utils/quick-launch/quick-launch.html b/ui-modules/utils/quick-launch/quick-launch.html
index 52b0b13..99f4d5e 100644
--- a/ui-modules/utils/quick-launch/quick-launch.html
+++ b/ui-modules/utils/quick-launch/quick-launch.html
@@ -136,7 +136,8 @@
 
 <div class="quick-launch-actions">
     <button class="btn btn-lg btn-default" ng-if="yamlViewDisplayed && appHasWizard" ng-disabled="deploying" ng-click="hideEditor()">Back</button>
-    <button class="btn btn-lg btn-default" ng-if="!yamlViewDisplayed" ng-disabled="deploying" ng-click="showEditor()">Open in Editor</button>
+    <button class="btn btn-lg btn-default" ng-if="!yamlViewDisplayed && !args.noEditButton" ng-disabled="deploying" ng-click="showEditor()">YAML</button>
+    <button class="btn btn-lg btn-default" ng-if="!args.noComposerButton" ng-disabled="deploying" ng-click="openComposer()">Open in Composer</button>
     <button class="btn btn-lg btn-success pull-right" ng-disabled="(deploy.$invalid || deploying) && !yamlViewDisplayed" ng-click="deployApp()">{{deploying ? 'Deploying&hellip;' : 'Deploy'}}</button>
 </div>
 
diff --git a/ui-modules/utils/quick-launch/quick-launch.js b/ui-modules/utils/quick-launch/quick-launch.js
index 645caf4..4d53cc3 100644
--- a/ui-modules/utils/quick-launch/quick-launch.js
+++ b/ui-modules/utils/quick-launch/quick-launch.js
@@ -39,17 +39,18 @@
             app: '=',
             locations: '=',
             args: '=?',
-            callback: '=?'
+            callback: '=?',
         },
-        controller: ['$scope', '$http', 'brSnackbar', controller]
+        controller: ['$scope', '$http', '$location', 'brSnackbar', controller]
     };
 
-    function controller($scope, $http, brSnackbar) {
+    function controller($scope, $http, $location, brSnackbar) {
         $scope.deploying = false;
         $scope.model = {
             newConfigFormOpen: false
         };
-        if ($scope.args && $scope.args.location) {
+        $scope.args = $scope.args || {};
+        if ($scope.args.location) {
             $scope.model.location = $scope.args.location;
         }
         $scope.toggleNewConfigForm = toggleNewConfigForm;
@@ -57,6 +58,7 @@
         $scope.deleteConfigField = deleteConfigField;
         $scope.deployApp = deployApp;
         $scope.showEditor = showEditor;
+        $scope.openComposer = openComposer;
         $scope.hideEditor = hideEditor;
         $scope.clearError = clearError;
 
@@ -169,6 +171,19 @@
             return yaml.safeDump(newApp);
         }
 
+        function buildComposerYaml() {
+            let newApp = {
+                name: $scope.model.name || $scope.app.displayName,
+            };
+            if ($scope.model.location) {
+                newApp.location = $scope.model.location;
+            }
+            if ($scope.entityToDeploy[BROOKLYN_CONFIG]) {
+                newApp[BROOKLYN_CONFIG] = $scope.entityToDeploy[BROOKLYN_CONFIG]
+            }
+            return yaml.safeDump(newApp) + "\n" + $scope.app.plan.data;
+        }
+
         function showEditor() {
             $scope.editorYaml = buildYaml();
             $scope.yamlViewDisplayed = true;
@@ -178,6 +193,11 @@
             $scope.yamlViewDisplayed = false;
         }
 
+        function openComposer() {
+            window.location.href = '/brooklyn-ui-blueprint-composer/#!/graphical?'+
+                'yaml='+encodeURIComponent(buildComposerYaml());
+        }
+
         function clearError() {
             delete $scope.model.deployError;
         }
diff --git a/ui-modules/utils/quick-launch/quick-launch.less b/ui-modules/utils/quick-launch/quick-launch.less
index 22f3bbe..634fb1c 100644
--- a/ui-modules/utils/quick-launch/quick-launch.less
+++ b/ui-modules/utils/quick-launch/quick-launch.less
@@ -97,6 +97,7 @@
 
   .quick-launch-actions {
     border-top: 1px solid @gray-lighter;
+    min-height: 90px;  // needed if only floating buttons are shown (eg pull-right success)
   }
 }