This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-ui.git

commit ed0a439be9a92ec6ada55bf97a56ff45656ecc05
Author: Alex Heneveld <[email protected]>
AuthorDate: Wed Sep 11 16:11:21 2024 +0100

    UI for QuickLaunch - if there are multiple possible defaults, give an option
---
 ui-modules/utils/quick-launch/quick-launch.html | 13 +++-
 ui-modules/utils/quick-launch/quick-launch.js   | 97 ++++++++++++++++++++++---
 2 files changed, 98 insertions(+), 12 deletions(-)

diff --git a/ui-modules/utils/quick-launch/quick-launch.html 
b/ui-modules/utils/quick-launch/quick-launch.html
index 4733fbf0..6ce304c8 100644
--- a/ui-modules/utils/quick-launch/quick-launch.html
+++ b/ui-modules/utils/quick-launch/quick-launch.html
@@ -67,7 +67,7 @@
         <section class="quick-launch-section quick-launch-configuration">
             <h3 class="quick-launch-section-title">Configuration</h3>
             <div class="quick-launch-section-content">
-                <div ng-repeat="(key,value) in 
entityToDeploy['brooklyn.config'] track by key" ng-switch="configMap[key].json 
? 'json' : configMap[key].type">
+                <div ng-repeat="(key,value) in 
entityToDeploy['brooklyn.config'] track by key" 
ng-switch="vm.getWidgetKind(key, configMap, 
entityToDeploy['brooklyn.config'][key])">
                     <div class="checkbox" ng-class="{'has-error': 
deploy[key].$invalid && deploy[key].$touched}" 
ng-switch-when="java.lang.Boolean">
                         <label>
                             <input type="checkbox" 
ng-model="entityToDeploy['brooklyn.config'][key]" ng-disabled="deploying" 
auto-focus="focus === key" />
@@ -104,6 +104,17 @@
                             <span>This complex value can only be edited in 
composer.</span>
                         </small>
                     </div>
+                    <div class="form-group" ng-class="{'has-error': 
deploy[key].$invalid && deploy[key].$touched}" ng-switch-when="defaults">
+                        <label for="{{key}}">{{key}} <i 
ng-click="deleteConfigField(key)" class="fa fa-trash form-delete"></i></label>
+                        <select class="form-control" id="{{key}}" 
name="{{key}}"
+                                ng-options="s.value as s.description for s in 
configMap[key].defaultsForDropdown"
+                                
ng-model="entityToDeploy['brooklyn.config'][key]"
+                                ng-change="vm.onDefaultsDropdown(key, 
configMap, entityToDeploy['brooklyn.config'][key])"
+                                ng-required="isRequired(configMap[key])"
+                                ng-disabled="deploying"
+                                auto-focus="focus === key">
+                        </select>
+                    </div>
                     <div class="form-group" ng-class="{'has-error': 
deploy[key].$invalid && deploy[key].$touched}" ng-switch-default>
                         <label for="{{key}}">{{key}} <i 
ng-click="deleteConfigField(key)" class="fa fa-trash form-delete"></i></label>
                         <input type="text" id="{{key}}" name="{{key}}" 
class="form-control" ng-model="entityToDeploy['brooklyn.config'][key]" 
ng-required="isRequired(configMap[key])" ng-disabled="deploying" 
auto-focus="focus === key" />
diff --git a/ui-modules/utils/quick-launch/quick-launch.js 
b/ui-modules/utils/quick-launch/quick-launch.js
index f3b1568d..de3df92d 100644
--- a/ui-modules/utils/quick-launch/quick-launch.js
+++ b/ui-modules/utils/quick-launch/quick-launch.js
@@ -87,6 +87,7 @@ export function quickLaunchDirective() {
             };
 
         quickLaunch.convertPlanToPreferredFormat = 
convertPlanToPreferredFormat;
+        quickLaunch.convertPlanFromOriginalFormat = 
convertPlanFromOriginalFormat;
         quickLaunch.getComposerHref = getComposerHref;
         quickLaunch.getPlanObject = getPlanObject;
         quickLaunch.getCampPlanObjectFromForm = getCampPlanObjectFromForm;
@@ -103,6 +104,49 @@ export function quickLaunchDirective() {
                 // model.location = locations[0].id; // predefined/uploaded 
Location objects, ID prop is sufficient
             }
         };
+        quickLaunch.getWidgetKind = (key, configMap, v) => {
+            if (!configMap || !configMap[key]) return undefined;  // ad hoc 
config?
+            if (configMap[key].json) return 'json';
+            if (v==null && configMap[key].defaults && 
configMap[key].defaults.length) return 'defaults';
+            return configMap[key].type;
+        }
+        quickLaunch.getDefaultsDropdown = (key, configMap) => {
+            const options = [];
+            const defaults = configMap[key].defaults;
+            options.push({
+                value: null,
+                description: 'Use '+defaults[0].source+': 
'+(defaults[0].jsonString || defaults[0].value),
+            });
+            options.push({
+                value: defaults[0].value,
+                description: 'Copy '+defaults[0].source,
+            });
+            for (let i=1; i<defaults.length; i++) {
+                if (options.find(x => angular.equals(x.value, 
defaults[i].value))) {
+                    // skip
+                } else {
+                    options.push({
+                        value: defaults[i].value,
+                        description: 'Copy ' + defaults[i].source + ': ' + 
(defaults[i].jsonString || defaults[i].value),
+                    });
+                }
+            }
+            return options;
+        }
+        quickLaunch.onDefaultsDropdown = (key, configMap, v) => {
+            if (v==null) return; //nothing to do
+
+            $scope.entityToDeploy['brooklyn.config'][key] = v;  // already 
done, if coming from dropdown, but no harm
+            for (let opt of configMap[key].defaults) {
+                if (angular.equals(opt.value, v)) {
+                    if (opt.isJson) {
+                        $scope.entityToDeployConfigJson[v] = opt.jsonString;
+                    }
+                    return;
+                }
+            }
+            // odd, nothing matched; just ignore
+        }
 
         $scope.formEnabled = true;
         $scope.editorEnabled = !$scope.args.noEditButton;
@@ -130,15 +174,22 @@ export function quickLaunchDirective() {
         $scope.clearError = () => { delete $scope.model.deployError; };
         $scope.transitionsShown = () => $scope.editorEnabled && 
$scope.formEnabled && !$scope.forceFormOnly;
 
-        $scope.$watch('app', () => {
+        $scope.$watch('app', async () => {
             quickLaunch.loadLocation($scope);
             $scope.clearError();
             $scope.editorYaml = $scope.app.plan.data;
             $scope.editorFormat = quickLaunch.getOriginalPlanFormat();
 
+            let campPlanYaml;
+            try {
+                campPlanYaml = (await 
quickLaunch.convertPlanFromOriginalFormat($scope.app.plan)).data;
+            } catch (error) {
+                console.warn("Unable to restore CAMP format", error, 
$scope.app.plan);
+                campPlanYaml = $scope.app.plan.data;
+            }
             let parsedPlan = null;
             try {
-                parsedPlan = yaml.safeLoad($scope.editorYaml);
+                parsedPlan = yaml.safeLoad(campPlanYaml);
             } catch (e) { /*console.log('Failed to parse YAML', e)*/ }
 
             // enable wizard if it's parseble and doesn't specify a location
@@ -160,22 +211,45 @@ export function quickLaunchDirective() {
             if ($scope.app.config) {
                 $scope.configMap = $scope.app.config.reduce((result, config) 
=> {
                     result[config.name] = config;
+                    result[config.name].defaults = [];
+                    let showWithDefaultsDropdown = false;
 
                     let configValue = (parsedPlan[BROOKLYN_CONFIG] || 
{})[config.name];
-                    if (typeof configValue === 'undefined' &&  
parsedPlan.services && parsedPlan.services.length === 1) {
+                    if (typeof configValue === 'undefined' && 
parsedPlan.services && parsedPlan.services.length === 1) {
                         configValue = (parsedPlan.services[0] && 
parsedPlan.services[0][BROOKLYN_CONFIG] || {})[config.name];
                     }
-
                     if (typeof configValue !== 'undefined') {
-                        $scope.entityToDeploy[BROOKLYN_CONFIG][config.name] = 
configValue;
-                    } else if (config.pinned || (isRequired(config) && (typeof 
config.defaultValue !== 'undefined'))) {
-                        $scope.entityToDeploy[BROOKLYN_CONFIG][config.name] = 
get(config, 'defaultValue', null);
+                        result[config.name].defaults.push({
+                            source: 'default from template',
+                            value: configValue,
+                        });
+                        showWithDefaultsDropdown = true;
+                    }
+
+                    if (typeof config.defaultValue !== 'undefined') {
+                        result[config.name].defaults.push({
+                            source: 'default from parameter',
+                            value: config.defaultValue,
+                        });
+                        showWithDefaultsDropdown = showWithDefaultsDropdown || 
config.pinned || (isRequired(config) && (typeof config.defaultValue !== 
'undefined'));
                     }
 
-                    let json = 
getJsonOfConfigValue($scope.entityToDeploy[BROOKLYN_CONFIG][config.name]);
-                    if (json!=null) {
-                        $scope.entityToDeployConfigJson[config.name] = json;
-                        result[config.name].json = true;
+                    result[config.name].defaults.forEach(d => {
+                        let jsonString = 
getJsonOfConfigValue($scope.entityToDeploy[BROOKLYN_CONFIG][config.name]);
+                        if (jsonString != null) {
+                            // TODO do we need this?
+                            result[config.name].json = true;
+
+                            d.isJson = true;
+                            d.jsonString = jsonString;
+                        }
+                    });
+
+                    if (result[config.name].defaults.length) {
+                        result[config.name].defaultsForDropdown = 
quickLaunch.getDefaultsDropdown(config.name, result);
+                        if (showWithDefaultsDropdown) {
+                            
$scope.entityToDeploy[BROOKLYN_CONFIG][config.name] = null;
+                        }
                     }
 
                     return result;
@@ -461,6 +535,7 @@ export function quickLaunchDirective() {
         }
 
         function convertPlanToPreferredFormat(plan) { return plan; }
+        function convertPlanFromOriginalFormat(plan) { return plan; }
 
         function getOriginalPlanFormat(scope) {
             scope = scope || $scope;

Reply via email to