You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2022/08/22 20:37:14 UTC

[brooklyn-ui] branch master updated (ca85f4c4 -> 467978ed)

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

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


    from ca85f4c4 skip the maven-karaf-verify goal as that interferes with subsequent builds
     new f111229b handle `null` values for config better, and bogus port range match
     new e8fc8083 allow priority to be set on parameter, and used for config even if locally set
     new f87fba3d better validation and handling of complex types
     new 201229d8 use yaml instead of json for complex fields in spec editor
     new 467978ed filter out null (unset) config when building yaml

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../spec-editor/spec-editor.directive.js           | 119 ++++++++++++++-------
 .../app/components/spec-editor/spec-editor.less    |   9 ++
 .../spec-editor/spec-editor.template.html          |  13 +++
 .../app/components/util/model/dsl.model.js         |   4 +-
 .../app/components/util/model/entity.model.js      |  20 ++--
 ui-modules/utils/quick-launch/quick-launch.js      |  13 ++-
 .../addon/schemas/blueprint-entity.json            |   4 +-
 .../utils/yaml-editor/addon/schemas/blueprint.json |  44 ++++++++
 8 files changed, 177 insertions(+), 49 deletions(-)


[brooklyn-ui] 02/05: allow priority to be set on parameter, and used for config even if locally set

Posted by he...@apache.org.
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 e8fc8083c85d6463b9e8541f900a0a56914bcf61
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Mon Aug 22 15:58:28 2022 +0100

    allow priority to be set on parameter, and used for config even if locally set
---
 .../app/components/spec-editor/spec-editor.directive.js     |  4 ++--
 .../app/components/spec-editor/spec-editor.less             |  6 ++++++
 .../app/components/spec-editor/spec-editor.template.html    | 13 +++++++++++++
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
index a83970f5..adc1dbfb 100644
--- a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
+++ b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
@@ -55,9 +55,9 @@ export const CONFIG_FILTERS = [
         id: 'suggested',
         label: 'Suggested',
         icon: 'plus-circle',
-        hoverText: 'Show config keys that marked as pinned or priority',
+        hoverText: 'Show config keys that are marked as pinned or priority',
         filter: (item)=> {
-            return item.pinned && item.priority > -1;
+            return item.pinned && (!item.priority || item.priority > -1);
         }
     },
     {
diff --git a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.less b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.less
index 9fba5889..b19d94bf 100644
--- a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.less
+++ b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.less
@@ -643,6 +643,12 @@ spec-editor {
     .input-group .btn {
       padding: 3px 6px 2px 6px;
     }
+    .input-group input[type='checkbox'] {
+      height: 17px;
+      width: min-content;
+      margin: 5px 0px;
+      box-shadow: none;
+    }
     .form-control {
       padding: 3px 6px;
       height: 27px;
diff --git a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
index a60f6d1f..cdc5a811 100644
--- a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
+++ b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
@@ -272,6 +272,19 @@
                                     </textarea>
                                 </span>
                             </div>
+                            <div class="param-field"> <span class="param-field-label">Pinned
+                                <i class="fa fa-fw fa-info-circle" popover-trigger="'mouseenter'"
+                                   uib-popover="Optional flag that this parameter should be pinned as a suggested parameter in the UI"
+                                   x-popover-class="spec-editor-popover"
+                                   popover-placement="top-left" popover-append-to-body="true"></i>
+                              </span>
+                              <span class="param-field-value">
+                                <input type="checkbox" ng-model="filteredParams[$index].pinned" class="form-control rounded-edge" id="pinned-{{item.name}}"
+                                          ng-focus="specEditor.recordParameterFocus(item)"
+                                          on-enter="specEditor.advanceOutToFormGroupInPanel">
+                                </input>
+                              </span>
+                            </div>
                             <div class="param-field"> <span class="param-field-label">Constraints
                                     <i class="fa fa-fw fa-info-circle" popover-trigger="'mouseenter'"
                                            uib-popover="Constraints such as &quot;required&quot; or &quot;forbiddenUnless(otherKey)&quot;, expressed as a JSON list (wrapped in square brackets and double quotes)"


[brooklyn-ui] 05/05: filter out null (unset) config when building yaml

Posted by he...@apache.org.
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 467978ed9a69f665216124868551bf112b392550
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Mon Aug 22 21:34:33 2022 +0100

    filter out null (unset) config when building yaml
---
 ui-modules/utils/quick-launch/quick-launch.js | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/ui-modules/utils/quick-launch/quick-launch.js b/ui-modules/utils/quick-launch/quick-launch.js
index 224c28e7..0d0ea086 100644
--- a/ui-modules/utils/quick-launch/quick-launch.js
+++ b/ui-modules/utils/quick-launch/quick-launch.js
@@ -51,11 +51,22 @@ export function quickLaunchDirective() {
 
         let quickLaunch = this;
 
+        function removeNullConfig(obj) {
+            if (obj && obj[BROOKLYN_CONFIG]) {
+                for (const key in obj[BROOKLYN_CONFIG]) {
+                    const val = obj[BROOKLYN_CONFIG][key];
+                    if (val==null || typeof val === 'undefined') {
+                        delete obj[BROOKLYN_CONFIG][key];
+                    }
+                }
+            }
+            return obj;
+        }
         quickLaunch.buildNewApp = () => ({
             name: $scope.model.name || $scope.app.displayName,
             location: $scope.model.location || '<REPLACE>',
             services: [
-                angular.copy($scope.entityToDeploy)
+                removeNullConfig(angular.copy($scope.entityToDeploy))
             ],
         });
         quickLaunch.getOriginalPlanFormat = getOriginalPlanFormat;


[brooklyn-ui] 03/05: better validation and handling of complex types

Posted by he...@apache.org.
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 f87fba3df704666c13e664500652da1e45275ab7
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Mon Aug 22 20:14:17 2022 +0100

    better validation and handling of complex types
---
 .../spec-editor/spec-editor.directive.js           | 66 +++++++++++++---------
 .../addon/schemas/blueprint-entity.json            |  4 +-
 .../utils/yaml-editor/addon/schemas/blueprint.json | 44 +++++++++++++++
 3 files changed, 86 insertions(+), 28 deletions(-)

diff --git a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
index adc1dbfb..1b74dafd 100644
--- a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
+++ b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
@@ -591,6 +591,7 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
                     if (!Array.isArray(val)) return type + '-manual';  // causes default string editor
                 }
             }
+
             if (scope.state.config.codeModeActive[item.name]) {
                 // code mode forces manual editor
                 return type + '-manual';
@@ -991,27 +992,33 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
 
             try {
                 if (definition.widgetMode === 'array') {
-                    return value.map(item => {
-                        if (item instanceof Dsl) {
-                            return item.toString();
-                        } else if (item instanceof Array || item instanceof Object) {
-                            throw 'not simple json in array';
-                        } else {
-                            return item;
-                        }
-                    });
+                    if (Array.isArray(value)) {
+                        return value.map(item => {
+                            if (item instanceof Dsl) {
+                                return item.toString();
+                            } else if (item instanceof Array || item instanceof Object) {
+                                throw 'not simple json in array';
+                            } else {
+                                return item;
+                            }
+                        });
+                    }
+                    // fall through to return toString below
                 } else if (definition.widgetMode === 'map') {
-                    let object = {};
-                    for (let keyObject in value) {
-                        if (value[keyObject] instanceof Dsl) {
-                            object[keyObject] = value[keyObject].toString();
-                        } else if (value[keyObject] instanceof Array || value[keyObject] instanceof Object) {
-                            throw 'not simple json in map';
-                        } else {
-                            object[keyObject] = value[keyObject];
+                    if (typeof value === "object") {
+                        let object = {};
+                        for (let keyObject in value) {
+                            if (value[keyObject] instanceof Dsl) {
+                                object[keyObject] = value[keyObject].toString();
+                            } else if (value[keyObject] instanceof Array || value[keyObject] instanceof Object) {
+                                throw 'not simple json in map';
+                            } else {
+                                object[keyObject] = value[keyObject];
+                            }
                         }
+                        return object;
                     }
-                    return object;
+                    // fall through to return toString below
                 } else if (!(value instanceof Dsl) && (value instanceof Object || value instanceof Array)) {
                     throw 'must use code editor';
                 }
@@ -1065,6 +1072,7 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
                 if (angular.isUndefined(localConfig[keyRef]) || localConfig[keyRef] === null || localConfig[keyRef].length < 1) {
                     continue;
                 }
+
                 if (localConfig[keyRef].hasOwnProperty(REPLACED_DSL_ENTITYSPEC)) {
                     result[keyRef] = {};
                     result[keyRef][DSL_ENTITY_SPEC] = localConfig[keyRef][REPLACED_DSL_ENTITYSPEC];
@@ -1077,11 +1085,13 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
                     scope.getConfigWidgetMode(definition, localConfig[keyRef])
                 }
 
+                let v = localConfig[keyRef];
+
                 // if JSON mode then parse
                 scope.state.config.codeModeError[keyRef] = null;
                 if (scope.state.config.codeModeActive && scope.state.config.codeModeActive[keyRef]) {
                     try {
-                        result[keyRef] = JSON.parse(localConfig[keyRef]);
+                        result[keyRef] = JSON.parse(v);
                     } catch (ex) {
                         scope.state.config.codeModeError[keyRef] = "Invalid JSON";
                         result[keyRef] = localConfig[keyRef];
@@ -1092,18 +1102,22 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
                 // else return as is, or introspect for array/map
 
                 if (definition.widgetMode === 'array') {
-                    result[keyRef] = localConfig[keyRef].map(getModelValueFromString);
-                    continue;
+                    if (Array.isArray(v)) {
+                        result[keyRef] = v.map(getModelValueFromString);
+                        continue;
+                    }
                 }
                 if (definition.widgetMode === 'map') {
-                    result[keyRef] = {};
-                    for (let keyObject in localConfig[keyRef]) {
-                        result[keyRef][keyObject] = getModelValueFromString(localConfig[keyRef][keyObject]);
+                    if (typeof v === "object") {
+                        result[keyRef] = {};
+                        for (let keyObject in v) {
+                            result[keyRef][keyObject] = getModelValueFromString(v[keyObject]);
+                        }
+                        continue;
                     }
-                    continue;
                 }
 
-                result[keyRef] = getModelValueFromString(localConfig[keyRef]);
+                result[keyRef] = getModelValueFromString(v);
             }
 
             scope.model.setConfigFromJson(result);
diff --git a/ui-modules/utils/yaml-editor/addon/schemas/blueprint-entity.json b/ui-modules/utils/yaml-editor/addon/schemas/blueprint-entity.json
index 811d1d8d..c0df9a28 100644
--- a/ui-modules/utils/yaml-editor/addon/schemas/blueprint-entity.json
+++ b/ui-modules/utils/yaml-editor/addon/schemas/blueprint-entity.json
@@ -120,9 +120,9 @@
         },
         "type": {
           "title": "Parameter type",
-          "description": "The type of the parameter, one of string, boolean, integer, long, float, double, timestamp, duration, port, or a fully qualified Java type name; the default is string",
+          "description": "The type of the parameter, one of string, boolean, integer, long, float, double, timestamp, duration, port, or a registered type name; the default is string",
           "type": "string",
-          "pattern": "^(string|boolean|integer|long|float|double|timestamp|duration|port|[a-z]+(\\.[a-zA-Z]+)+)$"
+          "pattern": "^(string|[^ ]+)$"
         },
         "default": {
           "title": "Parameter default value",
diff --git a/ui-modules/utils/yaml-editor/addon/schemas/blueprint.json b/ui-modules/utils/yaml-editor/addon/schemas/blueprint.json
index fcc8ebc3..b5688436 100644
--- a/ui-modules/utils/yaml-editor/addon/schemas/blueprint.json
+++ b/ui-modules/utils/yaml-editor/addon/schemas/blueprint.json
@@ -39,6 +39,50 @@
     },
     "location": {
       "$ref": "/Blueprint/Location"
+    },
+    "brooklyn.config": {
+      "title": "Entity configuration",
+      "description": "Configuration key-value pairs passed to the service entity being created",
+      "type": "object"
+    },
+    "brooklyn.policies": {
+      "title": "Policies",
+      "description": "A list of policies, each as a map described with their type and their brooklyn.config as keys",
+      "type": "array",
+      "items": {
+        "title": "Policy",
+        "$ref": "/Blueprint/Entity"
+      },
+      "minItems": 1
+    },
+    "brooklyn.enrichers": {
+      "title": "Enrichers",
+      "description": "A list of enrichers, each as a map described with their type and their brooklyn.config as keys",
+      "type": "array",
+      "items": {
+        "title": "Enricher",
+        "$ref": "/Blueprint/Entity"
+      },
+      "minItems": 1
+    },
+    "brooklyn.initializers": {
+      "title": "Initializers",
+      "description": "A list of initializers instances to be constructed and run against the entity, each as a map described with their type and their brooklyn.config as keys",
+      "type": "array",
+      "items": {
+        "title": "Initializer",
+        "$ref": "/Blueprint/Entity"
+      },
+      "minItems": 1
+    },
+    "brooklyn.parameters": {
+      "title": "Parameters",
+      "description": "A list of typed parameters the entity accepts",
+      "type": "array",
+      "items": {
+        "$ref": "/Blueprint/Entity#/definitions/brooklynParameter"
+      },
+      "minItems": 1
     }
   }
 }
\ No newline at end of file


[brooklyn-ui] 04/05: use yaml instead of json for complex fields in spec editor

Posted by he...@apache.org.
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 201229d897f6746d37071d3271a2ef434b8f37c6
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Mon Aug 22 20:50:01 2022 +0100

    use yaml instead of json for complex fields in spec editor
    
    easily controllable with CODE_MODE="YAML" or "JSON"
---
 .../spec-editor/spec-editor.directive.js           | 51 +++++++++++++++++-----
 .../app/components/spec-editor/spec-editor.less    |  3 ++
 2 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
index 1b74dafd..ab6df27e 100644
--- a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
+++ b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
@@ -30,6 +30,7 @@ import template from './spec-editor.template.html';
 import {isSensitiveFieldName} from 'brooklyn-ui-utils/sensitive-field/sensitive-field';
 import {computeQuickFixesForIssue} from '../quick-fix/quick-fix';
 import scriptTagDecorator from 'brooklyn-ui-utils/script-tag-non-overwrite/script-tag-non-overwrite';
+import jsYaml from "js-yaml";
 
 const MODULE_NAME = 'brooklyn.components.spec-editor';
 const REPLACED_DSL_ENTITYSPEC = '___brooklyn:entitySpec';
@@ -38,6 +39,8 @@ const SUBSECTION = {
     PARAMETERS: 'parameters'
 }
 
+const CODE_MODE = "YAML";
+
 export const SUBSECTION_TEMPLATE_OTHERS_URL = 'blueprint-composer/component/spec-editor/section-others.html';
 
 angular.module(MODULE_NAME, [onEnter, autoGrow, blurOnEnter, brooklynDslEditor, brooklynDslViewer, scriptTagDecorator])
@@ -640,7 +643,8 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
             if (!specEditor.defined(val)) return false;
             if (typeof val === 'string') {
                 try {
-                    // a YAML parse would be nicer, but JSON is simpler, and sufficient
+                    // a YAML parse would be nicer, but JSON is easier to detect its presence, and sufficient;
+                    // for convenience, we allow yaml to be _entered_
                     // (esp as we export a JSON stringify; preferable would be to export the exact YAML from model,
                     // including comments, but again lower priority)
                     let parsed = JSON.parse(val);
@@ -680,7 +684,7 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
                     try {
                         // if it's a parseable string, then parse it
                         if (typeof value === 'string' && value.length) {
-                            value = JSON.parse(value);
+                            value = parseYamlOrJson(value);
                             if (value instanceof Array || value instanceof Object) {
                                 // if result is not a primitive then don't allow user to leave code mode
                                 // (if type is known as a map/list then likely we should allow leaving code mode,
@@ -716,7 +720,7 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
                         }
                     } catch (notJson) {
                         // if not parseable or not a string, then convert to json
-                        value = JSON.stringify(value);
+                        value = toCode(value);
                     }
                 }
                 if (value !== null) {
@@ -767,7 +771,7 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
                     } catch (notJson) {
                         // if not parseable or not a string, then convert to json
                         // (as with other stringify, this loses any comments etc)
-                        value = JSON.stringify(value, null, "  ");
+                        value = toCode(value, true);
                     }
                     if (value !== null) {
                         scope.state.parameters.edit.json = value;
@@ -975,7 +979,7 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
                 // also supporting yaml and comments, but that is a bigger task!)
                 if (scope.config && typeof scope.config[key] === 'string') {
                     try {
-                        if (JSON.stringify(JSON.parse(scope.config[key])) === JSON.stringify(value)) {
+                        if (JSON.stringify(parseYamlOrJson(scope.config[key])) === JSON.stringify(value)) {
                             return scope.config[key];
                         }
                     } catch (ignoredError) {
@@ -985,7 +989,7 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
                 // otherwise pretty print it, so they get decent multiline on first load and
                 // if they click off the entity then back on to the entity and this field
                 // (we'd like to respect what they actually typed but that needs the parse tree, as above)
-                return JSON.stringify(value, null, "  ");
+                return toCode(value, true);
             }
 
             // else treat as value, with array/map special
@@ -1026,6 +1030,8 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
                 // any map/array with complex json inside, or other value of complex json,
                 // will force the code editor
                 // (previously we did stringify on entries then tried to parse, but that was inconsistent)
+                console.log("Forcing code mode on ", key, "because", hasComplexJson);
+
                 scope.state.config.codeModeActive[key] = true;
                 // and the widget mode updated to be 'manual'
                 scope.getConfigWidgetMode(definition, value);
@@ -1090,13 +1096,15 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
                 // if JSON mode then parse
                 scope.state.config.codeModeError[keyRef] = null;
                 if (scope.state.config.codeModeActive && scope.state.config.codeModeActive[keyRef]) {
+                    // first try a yaml parse
                     try {
-                        result[keyRef] = JSON.parse(v);
+                        result[keyRef] = parseYamlOrJson(v);
+                        continue;
                     } catch (ex) {
                         scope.state.config.codeModeError[keyRef] = "Invalid JSON";
                         result[keyRef] = localConfig[keyRef];
+                        continue;
                     }
-                    continue;
                 }
 
                 // else return as is, or introspect for array/map
@@ -1147,7 +1155,7 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
                     model.addIssue(Issue.builder().group('config').ref(key).message('<code>' + $sanitize(value) + '</code> is not a number').build());
                 }
                 if (scope.state.config.codeModeError[key]) {
-                    model.addIssue(Issue.builder().group('config').ref(key).message('<code>' + $sanitize(value) + '</code> is not valid JSON').build());
+                    model.addIssue(Issue.builder().group('config').ref(key).message('Content is not valid '+(CODE_MODE)).build());
                 }
             });
         }
@@ -1207,7 +1215,7 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
                 scope.state.parameters.edit.errors = [];
                 if (scope.state.parameters.codeModeActive[item.name]) {
                     try {
-                        let parsed = JSON.parse(scope.state.parameters.edit.json);
+                        let parsed = parseYamlOrJson(scope.state.parameters.edit.json);
                         checkNameChange(item.name, parsed.name);
                         if (JSON.stringify(item)==JSON.stringify(parsed)) {
                             // no change; don't change else we get a digest cycle
@@ -1349,3 +1357,26 @@ export function specEditorTypeFilter() {
 function templateCache($templateCache) {
     $templateCache.put(TEMPLATE_URL, template);
 }
+
+function parseYamlOrJson(v) {
+    // YAML mode experimental; if not working switch back to JSON
+    let error = null;
+    if (CODE_MODE=="YAML") {
+        try {
+            return jsYaml.safeLoad(v);
+        } catch (ex) {
+            error = ex;
+        }
+    }
+    try {
+        return JSON.parse(v);
+    } catch (ex) {
+        if (CODE_MODE=="YAML" && error) throw error;
+        throw ex;
+    }
+}
+
+function toCode(obj, pretty) {
+    if (CODE_MODE=="YAML") return jsYaml.dump(obj).trim();
+    return pretty ? JSON.stringify(obj, null, "  ") : JSON.stringify(obj);
+}
diff --git a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.less b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.less
index b19d94bf..e02a3d61 100644
--- a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.less
+++ b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.less
@@ -946,6 +946,9 @@ spec-editor {
 .version-selection {
   margin: 1em 0px;
 
+  button {
+    text-align: left;
+  }
   .dropdown {
     // preventing LESS from incorrectly parsing the calc expression
     // using 30px offset for the icon


[brooklyn-ui] 01/05: handle `null` values for config better, and bogus port range match

Posted by he...@apache.org.
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 f111229bf6e2d394160ec694905cbbb525204b6d
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Mon Aug 22 12:55:51 2022 +0100

    handle `null` values for config better, and bogus port range match
---
 .../app/components/util/model/dsl.model.js           |  4 ++--
 .../app/components/util/model/entity.model.js        | 20 +++++++++++++-------
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/ui-modules/blueprint-composer/app/components/util/model/dsl.model.js b/ui-modules/blueprint-composer/app/components/util/model/dsl.model.js
index 7617af6d..a05365d5 100644
--- a/ui-modules/blueprint-composer/app/components/util/model/dsl.model.js
+++ b/ui-modules/blueprint-composer/app/components/util/model/dsl.model.js
@@ -87,7 +87,7 @@ export class Dsl {
         ID.set(this, Math.random().toString(36).slice(2));
         PARAMS.set(this, new Array());
         KINDS.set(this, kind);
-        NAME.set(this, name === undefined ? ID.get(this).toString() : name.toString());
+        NAME.set(this, name === undefined || name === null ? ID.get(this).toString() : name.toString());
         RELATIONSHIPS.set(this, new Array());
         ISSUES.set(this, new Array());
     }
@@ -1026,7 +1026,7 @@ export class Tokenizer {
      * @return {boolean}
      */
     peekPortRange() {
-        return this.s.search(portRangeRegex) >= 0;
+        return this.s.search("^"+portRangeRegex) >= 0;
     }
 
     /**
diff --git a/ui-modules/blueprint-composer/app/components/util/model/entity.model.js b/ui-modules/blueprint-composer/app/components/util/model/entity.model.js
index 22e9d4a7..faa260a0 100644
--- a/ui-modules/blueprint-composer/app/components/util/model/entity.model.js
+++ b/ui-modules/blueprint-composer/app/components/util/model/entity.model.js
@@ -676,7 +676,7 @@ export const PREDICATE_MEMBERSPEC = (config, entity)=> {
  */
 function addConfig(key, value) {
     try {
-        if (value.hasOwnProperty(DSL.ENTITY_SPEC)) {
+        if (value && value.hasOwnProperty(DSL.ENTITY_SPEC)) {
             if (value[DSL.ENTITY_SPEC] instanceof Entity) {
                 value[DSL.ENTITY_SPEC].family = EntityFamily.SPEC.id;
                 value[DSL.ENTITY_SPEC].parent = this;
@@ -694,7 +694,7 @@ function addConfig(key, value) {
             let entity = null;
             if (value instanceof Entity) {
                 entity = value;
-            } else if (value['type']) {
+            } else if (value && value['type']) {
                 entity = new Entity().setEntityFromJson(value);
             }
             if (entity) {
@@ -927,8 +927,11 @@ function getClusterMemberspecEntities() {
         .filter((config)=>isPossiblyEntitySpec(baseType(config.type)))
         .reduce((acc, config)=> {
             if (CONFIG.get(this).has(config.name)) {
-                const val = CONFIG.get(this).get(config.name)[DSL.ENTITY_SPEC];
-                if (val) acc[config.name] = val;
+                const v0 = CONFIG.get(this).get(config.name);
+                if (v0) {
+                    const val = v0[DSL.ENTITY_SPEC];
+                    if (val) acc[config.name] = val;
+                }
             }
             return acc;
         }, {});
@@ -949,9 +952,12 @@ function getClusterMemberspecEntity(predicate = ()=>(true)) {
         .filter((config)=>isPossiblyEntitySpec(baseType(config.type)))
         .reduce((acc, config)=> {
             if (CONFIG.get(this).has(config.name)) {
-                let entityV = CONFIG.get(this).get(config.name)[DSL.ENTITY_SPEC];
-                if (entityV && predicate(config, entityV)) {
-                    return entityV;
+                const v0 = CONFIG.get(this).get(config.name);
+                if (v0) {
+                    let entityV = v0[DSL.ENTITY_SPEC];
+                    if (entityV && predicate(config, entityV)) {
+                        return entityV;
+                    }
                 }
             }
             return acc;