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 4bdc4716 catalog saver adjustments for default field values
new a8c8c9c8 Merge remote-tracking branch
'jathanasiou/fix/catalog-saver-defaults'
4bdc4716 is described below
commit 4bdc47167d8f78ff169d3258d5e08d918f3b8928
Author: John Athanasiou <[email protected]>
AuthorDate: Tue Dec 6 09:43:37 2022 +0000
catalog saver adjustments for default field values
---
.../catalog-saver/catalog-saver.directive.js | 127 ++++++++++++++-------
.../catalog-saver.modal.template.html | 20 ++--
.../app/views/main/main.controller.js | 38 ++++--
3 files changed, 119 insertions(+), 66 deletions(-)
diff --git
a/ui-modules/blueprint-composer/app/components/catalog-saver/catalog-saver.directive.js
b/ui-modules/blueprint-composer/app/components/catalog-saver/catalog-saver.directive.js
index 3018f325..8575d988 100644
---
a/ui-modules/blueprint-composer/app/components/catalog-saver/catalog-saver.directive.js
+++
b/ui-modules/blueprint-composer/app/components/catalog-saver/catalog-saver.directive.js
@@ -66,49 +66,84 @@ export function saveToCatalogModalDirective($rootScope,
$uibModal, $injector, $f
link: link
};
+ /*
+ * Categories of data stored in 'config':
+ *
+ * original: what the catalog has
+ * default: what should be shown as a placeholder if blank
+ * initial: what current should be initalized as (not to show a
placeholder)
+ *
+ * local.default: as above, but locally computed (not remembered)
+ * current: what is being edited (ng model)
+ *
+ * Subfields:
+ * {name,descriptiopn,version,bundle,symbolicName,itemType,iconUrl}
+ *
+ * Of the above, `local` and `current` are cleared each time the modal
runs.
+ * If the modal saves, then `initial` is replaced with the value of
`current` so it is available next time.
+ */
+
// TODO We might need to refactor the controller and directive around this
to structure it better
function updateBundleConfig(entity, metadata, config) {
// the name or can be inherited if root node is a known application
type we are editing
// (normally in those cases $scope.config will already be set by
caller, but maybe not always)
- if (!config.name && entity.hasName()) {
- config.name = entity.name;
- }
- // the ID can be set in the UI or can be inherited if root node is a
known application type we are editing
- // (normally in those cases $scope.config will already be set by
caller, but maybe not always)
- if (!config.symbolicName && (entity.hasId() || metadata.has('id'))) {
- config.symbolicName = entity.id || metadata.get('id');
- }
- if (!config.version && (entity.hasVersion() ||
metadata.has('version'))) {
- config.version = entity.version || metadata.get('version');
- }
- config.bundle = config.bundle || config.symbolicName;
+
+ config.current.name = config.current.name || config.initial.name ||
config.local.default.name || entity.name
+
+ // if user clears the current name, the placeholder could show the
default or entity name
+ // (rather than the last saved name); BUT this is subtle, maybe too
much so;
+ // also we don't support default values on name in the UI, nor in
bundlizing, so actually better
+ // not to set this
+ // config.local.default.name = config.local.default.name ||
entity.name || config.original.name;
+
+ config.current.version = config.initial.version ||
config.local.default.version || entity.version || metadata.get('version');
+
+ // we do NOT set symbolic name from any entity metadata anymore; that
ID is mostly used _internally_ eg might be 'root',
+ // so it is not necessarily an appropriate symbolic name for the item
in the bundle.
+ //
+ // if we DID want to do this then we would need to change bundlize to
have the same logic
+ // (or put this logic there instead)
+ //
+ // normally it make it a little bit simpler we just set the _current_
for symbolicName and bundle,
+ // or we allow it to use bundlize to infer from the name
}
- function link($scope, $element) {
- if (!$scope.config.original) {
- // original if provided contains the original metadata, e.g. for
use if coming from a template and switching between template and non-template
- $scope.config.original = {}
- }
- $scope.isNewFromTemplate = () => ($scope.config.itemType !==
'template' && $scope.config.original.itemType === 'template');
- $scope.isUpdate = () => !$scope.isNewFromTemplate() &&
Object.keys($scope.config.original).length>0 && $scope.config.bundle ===
$scope.config.original.bundle;
+ function initOurConfig($scope) {
+ $scope.config.original = $scope.config.original || {}
+ $scope.config.initial = $scope.config.initial || {}
+ $scope.config.default = $scope.config.default || {}
+ $scope.config.current = {};
+ $scope.config.local = { default: {} };
+
+ Object.assign($scope.config.local.default, $scope.config.default);
+ Object.assign($scope.config.current, $scope.config.initial);
+
+ $scope.isNewFromTemplate = () => ($scope.config.initial.itemType !==
'template' && $scope.config.original.itemType === 'template');
+ $scope.isUpdate = () => !$scope.isNewFromTemplate() &&
Object.keys($scope.config.original).length>0 && $scope.config.initial.bundle
=== $scope.config.original.bundle;
$scope.buttonTextFn = () => {
- const name = $scope.config.label || ($scope.isUpdate() &&
($scope.config.name || $scope.config.original.name ||
$scope.config.symbolicName || $scope.config.original.symbolicName));
+ const name = $scope.config.label || ($scope.isUpdate() &&
($scope.config.initial.name || $scope.config.original.name ||
$scope.config.initial.symbolicName || $scope.config.original.symbolicName));
return !!name ? 'Update ' + name : 'Add to catalog';
}
$scope.buttonText = $scope.buttonTextFn();
+ }
+
+ function link($scope, $element) {
+ initOurConfig($scope);
$scope.activateModal = () => {
let entity = blueprintService.get();
let metadata = blueprintService.entityHasMetadata(entity) ?
blueprintService.getEntityMetadata(entity) : new Map();
- if (!$scope.config.itemType) {
+ initOurConfig($scope);
+
+ if (!$scope.config.current.itemType) {
// This is the default item type
- $scope.config.itemType = 'application';
+ $scope.config.current.itemType =
$scope.config.local.default.itemType || 'application';
}
// Set various properties from the blueprint entity data if not
already set
- if (!$scope.config.iconUrl && (entity.hasIcon() ||
metadata.has('iconUrl'))) {
- $scope.config.iconUrl = entity.icon || metadata.get('iconUrl');
+ if (!$scope.config.current.iconUrl &&
($scope.config.initial.iconUrl || entity.hasIcon() || metadata.has('iconUrl')))
{
+ $scope.config.current.iconUrl = $scope.config.initial.iconUrl
|| entity.icon || metadata.get('iconUrl');
}
if (!$scope.isNewFromTemplate()) {
// (these should only be set if not making something new from
a template, as the entity items will refer to the template)
@@ -118,7 +153,7 @@ export function saveToCatalogModalDirective($rootScope,
$uibModal, $injector, $f
// Override this callback to update configuration data elsewhere
$scope.config = (composerOverrides.updateCatalogConfig ||
((config, $element) => config))($scope.config, $element);
- const { bundle, symbolicName } = ($scope.config || {});
+ const { bundle, symbolicName } = ($scope.config.initial || {});
// Show advanced tab initially if bundle or symbolic name does not
match the naming pattern.
$scope.showAdvanced = (bundle && symbolicName)
@@ -162,11 +197,13 @@ export function CatalogItemModalController($scope,
$filter, blueprintService, pa
};
/* Derived properties & calculators, will be updated whenever
$scope.state.view changes */
$scope.getTitle = () => {
+ // expect we should always have current or default name, possibly
don't need symbolicName or `blueprint` defaults
+ const name = $scope.config.current.name ||
$scope.config.local.default.name || $scope.config.current.symbolicName ||
$scope.config.local.default.symbolicName;
switch ($scope.state.view) {
case VIEWS.form:
- return $scope.isUpdate() ? `Update ${$scope.config.name ||
$scope.config.symbolicName || 'blueprint'}` : 'Add to catalog';
+ return $scope.isUpdate() ? `Update ${name || 'blueprint'}` :
'Add to catalog';
case VIEWS.saved:
- return `${$scope.config.name || $scope.config.symbolicName ||
'Blueprint'} ${$scope.isUpdate() ? 'updated' : 'saved'}`;
+ return `${name || 'Blueprint'} ${$scope.isUpdate() ? 'updated'
: 'saved'}`;
}
};
@@ -175,6 +212,7 @@ export function CatalogItemModalController($scope, $filter,
blueprintService, pa
case VIEWS.form:
return '';
case VIEWS.saved:
+ // TODO where do these come from
return
`/brooklyn-ui-catalog/#!/bundles/${$scope.config.catalogBundleId}/${$scope.config.version}/types/${$scope.config.catalogBundleSymbolicName}/${$scope.config.version}`;
}
};
@@ -228,7 +266,7 @@ export function CatalogItemModalController($scope, $filter,
blueprintService, pa
});
// Watch for bundle name and display warning if bundle exists already.
- $scope.$watchGroup(['config.bundle', 'defaultBundle'], () => {
+ $scope.$watchGroup(['config.current.bundle',
'config.local.default.bundle'], () => {
checkIfBundleExists();
});
}
@@ -281,12 +319,13 @@ export function CatalogItemModalController($scope,
$filter, blueprintService, pa
// Now, try to save.
let bom = createBom();
+ $scope.config.initial = $scope.config.current;
paletteApi.create(bom, {forceUpdate: $scope.state.force})
.then((savedItem) => {
if (!angular.isArray($scope.config.versions)) {
$scope.config.versions = [];
}
- $scope.config.versions.push($scope.config.version);
+ $scope.config.versions.push($scope.config.current.version);
$scope.state.view = VIEWS.saved;
})
.catch(error => {
@@ -298,7 +337,7 @@ export function CatalogItemModalController($scope, $filter,
blueprintService, pa
};
function getBundleBase() {
- return $scope.config.bundle || $scope.defaultBundle;
+ return $scope.config.current.bundle ||
$scope.config.local.default.bundle;
}
function getBundleId() {
@@ -306,7 +345,7 @@ export function CatalogItemModalController($scope, $filter,
blueprintService, pa
}
function getSymbolicName() {
- return $scope.config.symbolicName || $scope.defaultSymbolicName;
+ return $scope.config.current.symbolicName ||
$scope.config.local.default.symbolicName;
}
function createBom() {
@@ -320,7 +359,7 @@ export function CatalogItemModalController($scope, $filter,
blueprintService, pa
let bomItem = {
id: bundleSymbolicName,
- itemType: $scope.config.itemType,
+ itemType: $scope.config.current.itemType,
item: blueprint
};
// tags can now be added to a blueprint created in the YAML Editor
@@ -336,22 +375,22 @@ export function CatalogItemModalController($scope,
$filter, blueprintService, pa
const bundleId = getBundleId();
let bomCatalogYaml = {
bundle: bundleId,
- version: $scope.config.version,
+ version: $scope.config.current.version,
items: [ bomItem ]
};
if(tags) {
bomCatalogYaml.tags = tags
}
- let bundleName = $scope.config.name || $scope.defaultName;
+ let bundleName = $scope.config.current.name ||
$scope.config.local.default.name;
if (brUtilsGeneral.isNonEmpty(bundleName)) {
bomItem.name = bundleName;
}
- if (brUtilsGeneral.isNonEmpty($scope.config.description)) {
- bomItem.description = $scope.config.description;
+ if (brUtilsGeneral.isNonEmpty($scope.config.current.description)) {
+ bomItem.description = $scope.config.current.description;
}
- if (brUtilsGeneral.isNonEmpty($scope.config.iconUrl)) {
- bomItem.iconUrl = $scope.config.iconUrl;
+ if (brUtilsGeneral.isNonEmpty($scope.config.current.iconUrl)) {
+ bomItem.iconUrl = $scope.config.current.iconUrl;
}
$scope.config.catalogBundleId = bundleId;
$scope.config.catalogBundleSymbolicName = bundleSymbolicName;
@@ -360,11 +399,11 @@ export function CatalogItemModalController($scope,
$filter, blueprintService, pa
let bundlize = $filter('bundlize');
$scope.updateDefaults = (newName) => {
- $scope.defaultName = ($scope.config.itemType==='template' &&
$scope.config.original.name) || null;
- $scope.defaultSymbolicName = ($scope.config.itemType==='template' &&
$scope.config.original.symbolicName) || bundlize(newName) || null;
- $scope.defaultBundle = ($scope.config.itemType==='template' &&
$scope.config.original.bundle) || bundlize(newName) || null;
+ if (!newName) newName = $scope.config.local.default.name;
+ $scope.config.local.default.symbolicName =
$scope.config.default.symbolicName ||
($scope.config.current.itemType==='template' &&
$scope.config.original.symbolicName) || bundlize(newName) || null;
+ $scope.config.local.default.bundle = $scope.config.default.bundle ||
($scope.config.current.itemType==='template' && $scope.config.original.bundle)
|| bundlize(newName) || null;
};
- $scope.$watchGroup(['config.name', 'config.itemType', 'config.bundle',
'config.symbolicName'], (newVals) => {
+ $scope.$watchGroup(['config.current.name', 'config.current.itemType',
'config.current.bundle', 'config.current.symbolicName'], (newVals) => {
$scope.updateDefaults(newVals[0]);
$scope.form.name.$validate();
$scope.buttonText = $scope.buttonTextFn();
@@ -383,11 +422,11 @@ function composerBlueprintNameValidatorDirective() {
return true;
}
// if not set, we need a bundle and symbolic name
- if (scope.config.bundle && scope.config.symbolicName) {
+ if (scope.config.current.bundle &&
scope.config.current.symbolicName) {
return true;
}
// or if we have defaults for bundle and symbolic name we
don't need this name
- if (scope.defaultBundle && scope.defaultSymbolicName) {
+ if (scope.config.local.default.bundle &&
scope.config.local.default.symbolicName) {
return true;
}
return false;
diff --git
a/ui-modules/blueprint-composer/app/components/catalog-saver/catalog-saver.modal.template.html
b/ui-modules/blueprint-composer/app/components/catalog-saver/catalog-saver.modal.template.html
index 0bdfbcb0..2a17dd67 100644
---
a/ui-modules/blueprint-composer/app/components/catalog-saver/catalog-saver.modal.template.html
+++
b/ui-modules/blueprint-composer/app/components/catalog-saver/catalog-saver.modal.template.html
@@ -26,7 +26,7 @@
<div class="form-group" ng-class="{'has-error': form.name.$invalid}">
<label class="control-label">Blueprint display name</label>
- <input ng-model="config.name" ng-disabled="state.saving"
class="form-control" name="name" type="text" placeholder="{{ defaultName }}"
composer-blueprint-name-validator/>
+ <input ng-model="config.current.name" ng-disabled="state.saving"
class="form-control" name="name" type="text" placeholder="{{
config.local.default.name }}" composer-blueprint-name-validator/>
<p class="help-block" ng-show="form.name.$invalid">
<span ng-if="form.name.$invalid">You must specify a name for
this item or supply explicit bundle ID and blueprint symbolic name</span>
</p>
@@ -34,13 +34,13 @@
<div class="form-group">
<label class="control-label">Blueprint description</label>
- <textarea ng-model="config.description" ng-disabled="state.saving"
class="form-control" name="description" rows="3"></textarea>
+ <textarea ng-model="config.current.description"
ng-disabled="state.saving" class="form-control" name="description"
rows="3"></textarea>
</div>
<div class="form-group" ng-class="{'has-error':
form.version.$invalid}">
<label class="control-label">Version</label>
<div class="input-group">
- <input ng-model="config.version" ng-disabled="state.saving"
class="form-control" placeholder="E.g. 1.0.0-SNAPSHOT" name="version"
type="text" required catalog-version="config.versions"
catalog-version-force="state.force" ng-pattern="state.pattern" />
+ <input ng-model="config.current.version"
ng-disabled="state.saving" class="form-control" placeholder="E.g.
1.0.0-SNAPSHOT" name="version" type="text" required
catalog-version="config.versions" catalog-version-force="state.force"
ng-pattern="state.pattern" />
<span class="input-group-btn">
<button class="btn btn-default" ng-class="{'btn-primary
active': state.force}" ng-click="state.force = !state.force"
uib-tooltip="Force override of existing bundle at
this version." tooltip-placement="top-right">
@@ -59,7 +59,7 @@
<label class="control-label">Bundle ID</label>
<div class="input-group">
<span class="input-group-addon">{{catalogBomPrefix}}</span>
- <input ng-model="config.bundle" ng-disabled="state.saving"
class="form-control" name="bundle" ng-pattern="state.pattern" autofocus
placeholder="{{ defaultBundle || 'E.g. my-bundle-id' }}"/>
+ <input ng-model="config.current.bundle"
ng-disabled="state.saving" class="form-control" name="bundle"
ng-pattern="state.pattern" autofocus placeholder="{{
config.local.default.bundle || 'E.g. my-bundle-id' }}"/>
</div>
<p class="help-block" ng-show="form.bundle.$invalid">
<span ng-if="form.bundle.$error.pattern">The bundle ID can
contain only letters, numbers as well as the following characters:
<code>.</code>, <code>-</code> and <code>_</code></span>
@@ -68,7 +68,7 @@
<div class="form-group" ng-class="{'has-error':
form.symbolicName.$invalid}">
<label class="control-label">Blueprint symbolic name</label>
- <input ng-model="config.symbolicName"
ng-disabled="state.saving" class="form-control" name="symbolicName"
ng-pattern="state.pattern" autofocus placeholder="{{ defaultSymbolicName ||
'E.g. my-catalog-id' }}"/>
+ <input ng-model="config.current.symbolicName"
ng-disabled="state.saving" class="form-control" name="symbolicName"
ng-pattern="state.pattern" autofocus placeholder="{{
config.local.default.symbolicName || 'E.g. my-catalog-id' }}"/>
<p class="help-block" ng-show="form.symbolicName.$invalid">
<span ng-if="form.symbolicName.$error.pattern">The
blueprint symbolic name can contain only letters, numbers as well as the
following characters: <code>.</code>, <code>-</code> and <code>_</code></span>
</p>
@@ -78,7 +78,7 @@
<label class="control-label">Blueprint type</label>
<div class="checkbox">
<label>
- <input ng-model="config.itemType"
ng-disabled="state.saving" name="itemType" type="radio" value="application" />
+ <input ng-model="config.current.itemType"
ng-disabled="state.saving" name="itemType" type="radio" value="application" />
Application entity
<i class="fa fa-fw fa-info-circle"
popover-trigger="'mouseenter'"
uib-popover="Save as an application entity which
can be deployed on its own, or configured and used in blueprints but only
config and sensors declared at the root are accessible in the Composer
('application' item type)"></i>
@@ -86,7 +86,7 @@
</div>
<div class="checkbox">
<label>
- <input ng-model="config.itemType"
ng-disabled="state.saving" name="itemType" type="radio" value="template" />
+ <input ng-model="config.current.itemType"
ng-disabled="state.saving" name="itemType" type="radio" value="template" />
Application template
<i class="fa fa-fw fa-info-circle"
popover-trigger="'mouseenter'"
uib-popover="Save as a blueprint template which can
be used as an editable starting point for blueprints or used as an application
entity, and in some contexts this prioritizes the blueprint for inclusion in
quick-selection views ('template' item type)"></i>
@@ -94,7 +94,7 @@
</div>
<div class="checkbox">
<label>
- <input ng-model="config.itemType"
ng-disabled="state.saving" name="itemType" type="radio" value="entity" />
+ <input ng-model="config.current.itemType"
ng-disabled="state.saving" name="itemType" type="radio" value="entity" />
Extended entity
<i class="fa fa-fw fa-info-circle"
popover-trigger="'mouseenter'"
uib-popover="Save as an entity which can be
configured and used in blueprints, exposing the config and adjuncts it inherits
('entity' item type)"></i>
@@ -104,7 +104,7 @@
<div class="form-group">
<label class="control-label">Blueprint icon URL</label>
- <input ng-model="config.iconUrl" ng-disabled="state.saving"
class="form-control" name="iconUrl" type="text" />
+ <input ng-model="config.current.iconUrl"
ng-disabled="state.saving" class="form-control" name="iconUrl" type="text" />
</div>
</br-collapsible>
</form>
@@ -122,7 +122,7 @@
<button class="btn btn-default btn-block"
ng-click="$close(REASONS.continue)">Continue to edit this blueprint</button>
<button class="btn btn-info btn-block"
ng-click="$close(REASONS.new)">Create a new blueprint</button>
<a class="btn btn-primary btn-block" ng-href="{{catalogURL}}">View
in catalog</a>
- <button ng-if="['template', 'entity'].indexOf(config.itemType) >
-1" class="btn btn-link btn-block" ng-click="$close(REASONS.deploy)">Or
deploy</button>
+ <button ng-if="['template',
'entity'].indexOf(config.current.itemType) > -1" class="btn btn-link btn-block"
ng-click="$close(REASONS.deploy)">Or deploy</button>
</div>
</div>
diff --git a/ui-modules/blueprint-composer/app/views/main/main.controller.js
b/ui-modules/blueprint-composer/app/views/main/main.controller.js
index 5fb43772..d568709b 100644
--- a/ui-modules/blueprint-composer/app/views/main/main.controller.js
+++ b/ui-modules/blueprint-composer/app/views/main/main.controller.js
@@ -168,28 +168,42 @@ export function MainController($scope, $element, $log,
$state, $stateParams, brB
vm.saveToCatalogConfig = {};
if (edit) {
+ // 'edit' is the details of an existing blueprint from catalog being
edited, which via state parameters are loaded and passed to controller
+ // it might be a template in which case we take the values SUGGESTED
BY the template and make them _current_
+ // or it might be an existing bundle (non-template), in which case we
take the values OF the item being edited
+ console.log("EDIT TYPE", edit.type);
+ console.log("VERSIONS", edit.versions);
+ console.log("EDIT", edit);
vm.saveToCatalogConfig = Object.assign(vm.saveToCatalogConfig, {
- version: edit.type.version,
- template: edit.type.template || false,
- itemType: edit.type.template || !edit.type.superTypes ||
edit.type.superTypes.contains("org.apache.brooklyn.api.entity.Application")
- ? 'application'
- : 'entity',
- description: edit.type.description,
- iconUrl: edit.type.iconUrlSource || edit.type.iconUrl,
+ initial: {
+ version: edit.type.version,
+ description: edit.type.description,
+ iconUrl: edit.type.iconUrlSource || edit.type.iconUrl,
+ },
original: {
bundle: edit.bundle.symbolicName.replace(/^catalog-bom-/, ''),
symbolicName: edit.type.symbolicName,
name: edit.type.displayName,
- versions: edit.versions,
- itemType: edit.type.template ? 'template'
+ itemType: edit.type.template ? 'template'
: !edit.type.superTypes ||
edit.type.superTypes.contains("org.apache.brooklyn.api.entity.Application") ?
'application'
: 'entity',
- }
+ },
+ default: {},
});
+
if (!edit.type.template) {
- // if loading a templates, do NOT set name, bundle, symbolicName,
versions
+ // set name, bundle, symbolicName, and itemType unless we are a
template
// or in other words, for other items, DO set these
- vm.saveToCatalogConfig = Object.assign(vm.saveToCatalogConfig,
vm.saveToCatalogConfig.original);
+ vm.saveToCatalogConfig.initial.template = false;
+ ['itemType','bundle','symbolicName','name'].forEach(key =>
vm.saveToCatalogConfig.initial[key] = vm.saveToCatalogConfig.original[key]);
+ // no defaults supplied by this view
+ // [].forEach(key => vm.saveToCatalogConfig.default[key] =
vm.saveToCatalogConfig.original[key]);
+ vm.saveToCatalogConfig.versions = edit.versions; // only set if
not a template
+
+ } else {
+ // if we are from a template the name etc should be blank (could
use a placeholder)
+ vm.saveToCatalogConfig.initial.template = edit.type.template;
+ vm.saveToCatalogConfig.initial.itemType = 'application';
}
$scope.initialYamlFormat = $stateParams.format;