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;
