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
The following commit(s) were added to refs/heads/master by this push:
new 8b6fc802 improve quick launch dropdowns
8b6fc802 is described below
commit 8b6fc802a95f5bf472d11f00a4c04dc4b371d4e6
Author: Alex Heneveld <[email protected]>
AuthorDate: Wed Feb 5 23:40:06 2025 +0000
improve quick launch dropdowns
- always show entry if pinned or required
- only show dropdown if >1 option or if json
- improve json detection and messages and behavior
- include hoist as a dropdown, but only use it if it is pure camp yaml
---
ui-modules/utils/quick-launch/quick-launch.html | 2 +-
ui-modules/utils/quick-launch/quick-launch.js | 83 ++++++++++++++++---------
2 files changed, 55 insertions(+), 30 deletions(-)
diff --git a/ui-modules/utils/quick-launch/quick-launch.html
b/ui-modules/utils/quick-launch/quick-launch.html
index 6ce304c8..abd3e0ec 100644
--- a/ui-modules/utils/quick-launch/quick-launch.html
+++ b/ui-modules/utils/quick-launch/quick-launch.html
@@ -101,7 +101,7 @@
<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="entityToDeployConfigJson[key]"
ng-required="isRequired(configMap[key])" disabled auto-focus="focus === key" />
<small class="help-block">
- <span>This complex value can only be edited in
composer.</span>
+ <span>This complex value can only be edited in
Composer or as YAML.</span>
</small>
</div>
<div class="form-group" ng-class="{'has-error':
deploy[key].$invalid && deploy[key].$touched}" ng-switch-when="defaults">
diff --git a/ui-modules/utils/quick-launch/quick-launch.js
b/ui-modules/utils/quick-launch/quick-launch.js
index de3df92d..e692c3ea 100644
--- a/ui-modules/utils/quick-launch/quick-launch.js
+++ b/ui-modules/utils/quick-launch/quick-launch.js
@@ -115,22 +115,23 @@ export function quickLaunchDirective() {
const defaults = configMap[key].defaults;
options.push({
value: null,
- description: 'Use '+defaults[0].source+':
'+(defaults[0].jsonString || defaults[0].value),
+ description: (defaults[0].jsonString || defaults[0].value) + '
('+defaults[0].source+')',
});
- options.push({
- value: defaults[0].value,
- description: 'Copy '+defaults[0].source,
- });
- for (let i=1; i<defaults.length; i++) {
+ for (let i=0; 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),
+ isJson: defaults[i].isJson,
+ description: 'Use ' + defaults[i].source + ': ' +
(defaults[i].jsonString || defaults[i].value),
});
}
}
+ options.push({
+ value: '',
+ description: 'Use new value',
+ });
return options;
}
quickLaunch.onDefaultsDropdown = (key, configMap, v) => {
@@ -140,7 +141,8 @@ export function quickLaunchDirective() {
for (let opt of configMap[key].defaults) {
if (angular.equals(opt.value, v)) {
if (opt.isJson) {
- $scope.entityToDeployConfigJson[v] = opt.jsonString;
+ $scope.entityToDeployConfigJson[key] = opt.jsonString;
+ configMap[key].json = true;
}
return;
}
@@ -181,8 +183,10 @@ export function quickLaunchDirective() {
$scope.editorFormat = quickLaunch.getOriginalPlanFormat();
let campPlanYaml;
+ let campPlanModified = false;
try {
campPlanYaml = (await
quickLaunch.convertPlanFromOriginalFormat($scope.app.plan)).data;
+ campPlanModified = $scope.app.plan.data != campPlanYaml;
} catch (error) {
console.warn("Unable to restore CAMP format", error,
$scope.app.plan);
campPlanYaml = $scope.app.plan.data;
@@ -190,7 +194,9 @@ export function quickLaunchDirective() {
let parsedPlan = null;
try {
parsedPlan = yaml.safeLoad(campPlanYaml);
- } catch (e) { /*console.log('Failed to parse YAML', e)*/ }
+ } catch (e) {
+ console.log('Failed to parse YAML', e)
+ }
// enable wizard if it's parseble and doesn't specify a location
// (if it's not parseable, or it specifies a location, then the
YAML view is displayed)
@@ -209,46 +215,65 @@ export function quickLaunchDirective() {
$scope.setServiceName = true;
}
if ($scope.app.config) {
+ const singleServiceConfig = parsedPlan.services &&
parsedPlan.services.length === 1 && parsedPlan.services[0][BROOKLYN_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) {
- configValue = (parsedPlan.services[0] &&
parsedPlan.services[0][BROOKLYN_CONFIG] || {})[config.name];
+ let configValueOuter = (parsedPlan[BROOKLYN_CONFIG] ||
{})[config.name];
+ const hasTemplateValueOuter = typeof configValueOuter !==
'undefined';
+ if (hasTemplateValueOuter) {
+ result[config.name].defaults.push({
+ source: 'template default',
+ value: configValueOuter,
+ });
}
- if (typeof configValue !== 'undefined') {
+
+ const hasTemplateValueInner = !campPlanModified &&
singleServiceConfig && (typeof singleServiceConfig[config.name] != 'undefined');
+ if (hasTemplateValueInner) {
result[config.name].defaults.push({
- source: 'default from template',
- value: configValue,
+ source: 'template inner default',
+ value: singleServiceConfig[config.name],
});
- showWithDefaultsDropdown = true;
}
- if (typeof config.defaultValue !== 'undefined') {
+ const hasParameterDefault = typeof config.defaultValue !==
'undefined';
+ if (hasParameterDefault) {
result[config.name].defaults.push({
- source: 'default from parameter',
+ source: 'parameter default',
value: config.defaultValue,
});
- showWithDefaultsDropdown = showWithDefaultsDropdown ||
config.pinned || (isRequired(config) && (typeof config.defaultValue !==
'undefined'));
}
+ let atLeastOneJsonValue = false;
result[config.name].defaults.forEach(d => {
- let jsonString =
getJsonOfConfigValue($scope.entityToDeploy[BROOKLYN_CONFIG][config.name]);
+ let jsonString = getJsonOfConfigValue(d.value);
if (jsonString != null) {
- // TODO do we need this?
- result[config.name].json = true;
-
d.isJson = true;
d.jsonString = jsonString;
+
+ // don't set this yet; it gets set once/if user
picks to copy a json value
+ // result[config.name].json = true;
+
+ // force dropdown so user knows what they are
getting into
+ atLeastOneJsonValue = true;
}
});
-
- if (result[config.name].defaults.length) {
- result[config.name].defaultsForDropdown =
quickLaunch.getDefaultsDropdown(config.name, result);
- if (showWithDefaultsDropdown) {
-
$scope.entityToDeploy[BROOKLYN_CONFIG][config.name] = null;
+ // was (isRequired && hasTemplateDefault) -- but that
doesn't make sense (rarely matters as root items are always pinned)
+ const showPossiblyWithDefaultsDropdown =
hasTemplateValueOuter || hasTemplateValueInner || atLeastOneJsonValue ||
config.pinned || isRequired(config);
+
+ if (showPossiblyWithDefaultsDropdown) {
+ // initialize this field so it displays explicitly;
null is a good choice because it allows either dropdown or blank if no dropdown
+ $scope.entityToDeploy[BROOKLYN_CONFIG][config.name] =
null;
+
+ // compute dropdowns to show, and if there is exactly
one default value (removing duplicates), and if it is editable (not json),
+ // then don't use the dropdown, set that as the
editable value
+ if (result[config.name].defaults.length) {
+ result[config.name].defaultsForDropdown =
quickLaunch.getDefaultsDropdown(config.name, result);
+ if
(result[config.name].defaultsForDropdown.length-2==1 && !atLeastOneJsonValue) {
+ // if just one value, and not json then use it
+
$scope.entityToDeploy[BROOKLYN_CONFIG][config.name] =
result[config.name].defaults[0].value;
+ }
}
}