@dualbox/editor 1.0.58 → 1.0.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -43595,6 +43595,7 @@ class GraphNode {
|
|
|
43595
43595
|
return this.setAttributeValue(name, val);
|
|
43596
43596
|
}
|
|
43597
43597
|
}
|
|
43598
|
+
this.m.save();
|
|
43598
43599
|
}
|
|
43599
43600
|
|
|
43600
43601
|
deleteVal(srcType, name) {
|
|
@@ -43603,6 +43604,7 @@ class GraphNode {
|
|
|
43603
43604
|
} else if (srcType === "attr" && this.def.attr) {
|
|
43604
43605
|
delete this.def.attr[name];
|
|
43605
43606
|
}
|
|
43607
|
+
this.m.save();
|
|
43606
43608
|
}
|
|
43607
43609
|
|
|
43608
43610
|
getValueType(srcType, name) {
|
|
@@ -45035,8 +45037,7 @@ class AppManager {
|
|
|
45035
45037
|
load(cb) {
|
|
45036
45038
|
if (this.loaded) {
|
|
45037
45039
|
cb();
|
|
45038
|
-
}
|
|
45039
|
-
else {
|
|
45040
|
+
} else {
|
|
45040
45041
|
/* todo: load dynamically .js ressources from the app */
|
|
45041
45042
|
this.loaded = true;
|
|
45042
45043
|
cb();
|
|
@@ -45060,10 +45061,9 @@ class AppManager {
|
|
|
45060
45061
|
options.options.debug.record = options.options.debug.record || false;
|
|
45061
45062
|
options.ressources = window.DualBoxRessources || {};
|
|
45062
45063
|
|
|
45063
|
-
this.app = window.DualBox.start(options);
|
|
45064
|
+
this.app = window.app = window.DualBox.start(options);
|
|
45064
45065
|
this.app.start(cb);
|
|
45065
|
-
}
|
|
45066
|
-
else {
|
|
45066
|
+
} else {
|
|
45067
45067
|
setTimeout(this.run.bind(this, json, options, cb), 1000);
|
|
45068
45068
|
}
|
|
45069
45069
|
}
|
|
@@ -63619,7 +63619,7 @@ var script$8 = {
|
|
|
63619
63619
|
else if( resolvedType.startsWith("map") ) {
|
|
63620
63620
|
templateType = "map";
|
|
63621
63621
|
this.deserializedValue = window.DualBox.Type.deserialize(this.v || {
|
|
63622
|
-
"metadata":{
|
|
63622
|
+
"metadata":{
|
|
63623
63623
|
"type":"Map<String,"+ this.firstLetterUppercase( this.getEmbeddedType(resolvedType) )+">"
|
|
63624
63624
|
},
|
|
63625
63625
|
"data": {}
|
|
@@ -63762,7 +63762,7 @@ var script$8 = {
|
|
|
63762
63762
|
firstLetterUppercase: function(s) {
|
|
63763
63763
|
return s.charAt(0).toUpperCase() + s.slice(1)
|
|
63764
63764
|
},
|
|
63765
|
-
|
|
63765
|
+
|
|
63766
63766
|
selectIndex: function(index) {
|
|
63767
63767
|
if( this.selectedIndex !== index ) {
|
|
63768
63768
|
this.selectedIndex = index;
|
|
@@ -64068,7 +64068,7 @@ var __vue_render__$8 = function() {
|
|
|
64068
64068
|
_vm.selectedIndex !== null
|
|
64069
64069
|
? _c("edit-value", {
|
|
64070
64070
|
attrs: {
|
|
64071
|
-
cIndex: _vm.
|
|
64071
|
+
cIndex: _vm.index,
|
|
64072
64072
|
type: _vm.embeddedType,
|
|
64073
64073
|
v: _vm.getElement(_vm.selectedIndex)
|
|
64074
64074
|
},
|
|
@@ -64133,11 +64133,11 @@ __vue_render__$8._withStripped = true;
|
|
|
64133
64133
|
/* style */
|
|
64134
64134
|
const __vue_inject_styles__$8 = function (inject) {
|
|
64135
64135
|
if (!inject) return
|
|
64136
|
-
inject("data-v-19f6a0fe_0", { source: "\n.template-value-container[data-v-19f6a0fe], .field-editor[data-v-19f6a0fe] {\n margin-bottom: 10px;\n}\n.template-value-message[data-v-19f6a0fe] {\n text-align: center;\n margin-top: 30px;\n margin-bottom: 30px;\n width: 100%;\n opacity: 0.5;\n}\n", map: {"version":3,"sources":["/home/seb/dev/dualbox/editor/js/src/v/templates/editValue.vue"],"names":[],"mappings":";AACA;IACA,mBAAA;AACA;AAEA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;IACA,WAAA;IACA,YAAA;AACA","file":"editValue.vue","sourcesContent":["<style scoped>\n .template-value-container, .field-editor {\n margin-bottom: 10px;\n }\n\n .template-value-message {\n text-align: center;\n margin-top: 30px;\n margin-bottom: 30px;\n width: 100%;\n opacity: 0.5;\n }\n</style>\n\n<template>\n <div class=\"w-100\">\n <p style=\"display: none;\">{{cIndex}}</p>\n <template v-if=\"isBasicDataType()\">\n <template v-if=\"dataType === 'string'\">\n <input class=\"edit-value-input\" type=\"text\" @keyup.enter=\"setStringValue\" @keyup.esc=\"setStringValue\" :value=\"v\" @focus=\"$event.target.select()\"></input>\n </template>\n <template v-else-if=\"dataType === 'boolean'\">\n <select class=\"edit-value-input\" @change=\"setBoolValue\">\n <option value=\"true\" :selected=\"v == true\">True</option>\n <option value=\"false\" :selected=\"v == false\">False</option>\n </select>\n </template>\n <template v-else-if=\"dataType === 'number'\">\n <input class=\"edit-value-input\" type=\"number\" @keyup.enter=\"setNumberValue\" @blur=\"setNumberValue\" :value=\"v\" @focus=\"$event.target.select()\" style=\"width: 40px;\"></input>\n </template>\n </template>\n <template v-else>\n <!-- we already are in a modal, don't instanciate another one -->\n <template v-if=\"isTemplateType()\">\n <div class=\"container template-value-container\" style=\"border: 1px solid rgba(0, 0, 0, 0.125);\">\n <div v-if=\"isArrayType()\" class=\"row\" style=\"background-color: rgba(0,0,0,.125);\">Array Editor</div>\n <div v-else-if=\"isMapType()\" class=\"row\" style=\"background-color: rgba(0,0,0,.125);\">Map Editor</div>\n <div class=\"row\" style=\"1px solid rgba(0,0,0,.125);\">\n <div class=\"col list-group-flush\" :class=\"{ 'col-1' : isArrayType(), 'col-2' : isMapType()}\" style=\"padding: 0; background-color: white; overflow-y: auto; border-right: 1px solid rgba(0, 0, 0, 0.125);\">\n <button v-for=\"index in deserializedValue.keys()\" :key=\"index\" :data-key=\"index\" type=\"button\" class=\"list-group-item list-group-item-action\" :class=\"{ active: isSelectedIndex(index) }\" style=\"text-align: center;\" @click=\"selectIndex(index)\">{{index}}</button>\n <button type=\"button\" @click=\"addItem\" class=\"list-group-item list-group-item-action add-item\" style=\"text-align: center;\"><i class=\"fas fa-plus-circle\"></i></button>\n </div>\n <div class=\"col\" style=\"padding: 10px\">\n <edit-value v-if=\"selectedIndex !== undefined && selectedIndex !== null\" :cIndex=\"edit-value\" :type=\"embeddedType\" :v=\"getElement(selectedIndex)\" @edited=\"onSubValueEdited(selectedIndex, $event)\"></edit-value>\n <p v-else class=\"template-value-message\">Select an element to edit.</p>\n </div>\n </div>\n </div>\n </template>\n <template v-else>\n <div class=\"field-editor\" :data-value=\"hash()\"></div>\n </template>\n </template>\n\n <!-- set null and delete buttons -->\n <div class=\"d-inline-block float-right\">\n <button class=\"btn btn-secondary btn-sm btn-xs\" title=\"set Null\" @click=\"setNullValue\">null</button>\n <button class=\"btn btn-danger btn-sm btn-xs\" title=\"delete value\" @click=\"deleteValue\" style=\"margin-left: 0px;\"><i class=\"fas fa-trash\"></i></button>\n </div>\n </div>\n\n</template>\n\n<script>\nimport _ from 'lodash';\nimport swal from 'sweetalert2';\nimport JSONEditor from '@dualbox/dualbox-lib-jsoneditor';\n\nString.prototype.hashCode = function() {\n var hash = 0, i, chr;\n if (this.length === 0) return hash;\n for (i = 0; i < this.length; i++) {\n chr = this.charCodeAt(i);\n hash = ((hash << 5) - hash) + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash;\n};\n\nexport default {\n name : \"edit-value\",\n props: [\n // required\n \"v\", // the value\n \"type\", // the dualbox type of the value\n\n // specific properties (for recursivity)\n \"cIndex\" // index for reference when in an array\n ],\n data: function () {\n return {\n \"dataType\": null, // the real javascript dataType of this.v\n \"deserializedValue\": null,\n\n // if type is a collection (dataType==\"map\" or dataType==\"array\")\n \"embeddedType\": null, // the embedded type of this templated collection\n \"selectedIndex\": null, // the current index of the element we are editing\n };\n },\n created: function() {\n this.view = window.dualboxEditor.v;\n this.editor = null;\n this.initData();\n },\n mounted: function() {\n var self = this;\n\n this.updateEditor();\n\n $(this.$el).find('.edit-value-input').focus(); // focus on the edit element\n },\n beforeUpdate: function() {\n this.updateData();\n },\n updated: function() {\n if( this.autochange ) {\n // change triggered by ourself, skip\n this.autochange = false;\n }\n else {\n this.updateEditor();\n }\n },\n methods: {\n hash: function() {\n var str = new String(this.v).toString();\n return str.split('').reduce((prevHash, currVal) => (((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0);\n },\n\n updateEditor: function() {\n if( this.dataType === \"object\" ) {\n if( !this.editor && $(this.$el).find('.field-editor')[0] !== undefined ) {\n // bind the json editor\n this.editor = new JSONEditor(\n $(this.$el).find('.field-editor')[0], {\n modes: ['tree', 'code', 'text' ],\n onChange: () => {\n try {\n var json = this.editor.get();\n this.autochange = true;\n this.$emit('edited', json);\n }\n catch(e) {}\n }\n });\n }\n\n if( this.editor ) {\n this.editor.set(this.v || {});\n }\n }\n },\n resolveDatatype() {\n // determine datatype of the value\n var resolvedType = this.type ? this.type.toLowerCase() : typeof this.v;\n\n // If \"*\", resolve the type by detecting it dynamically from value\n if( resolvedType.indexOf(\"*\") !== -1 ) {\n resolvedType = window.DualBox.Type.detectType(this.v).toLowerCase();\n }\n\n // Check if we have a template type. If so, determine current index and embedded type\n var templateType = null;\n if( resolvedType.startsWith(\"array\") ) {\n templateType = \"array\";\n this.deserializedValue = this.v || [];\n }\n else if( resolvedType.startsWith(\"map\") ) {\n templateType = \"map\";\n this.deserializedValue = window.DualBox.Type.deserialize(this.v || {\n \"metadata\":{ \n \"type\":\"Map<String,\"+ this.firstLetterUppercase( this.getEmbeddedType(resolvedType) )+\">\"\n },\n \"data\": {}\n });\n }\n\n if( templateType ) {\n this.dataType = templateType;\n this.embeddedType = this.getEmbeddedType(resolvedType);\n if( this.selectedIndex == null ) {\n var firstKey = this.deserializedValue.keys().next();\n if( firstKey && firstKey.value ) {\n this.selectedIndex = firstKey.value;\n }\n }\n }\n else {\n this.dataType = resolvedType;\n }\n\n // Finally, transform to object if not a basic value\n if( [\"string\", \"number\", \"boolean\", \"array\", \"map\"].indexOf(this.dataType) == -1 ) {\n this.dataType = \"object\";\n }\n\n console.log(`Type: ${this.type}, Datatype: ${this.dataType}, embeddedType: ${this.embeddedType}`);\n },\n\n initData: function() {\n this.v = this.v;\n this.resolveDatatype();\n this.selectNextIndex();\n },\n\n updateData: function() {\n this.resolveDatatype();\n },\n\n isBasicDataType() {\n return this.dataType == \"string\" ||\n this.dataType == \"number\" ||\n this.dataType == \"boolean\";\n },\n\n serialize( value ) {\n if( this.isTemplateType() ) {\n if( this.isArrayType() ) {\n return value; // we store arrays as is\n }\n else if( this.isMapType() ) {\n return window.DualBox.Type.serialize(value);\n }\n }\n else {\n return value;\n }\n },\n\n saveChanges: function() {\n this.$forceUpdate();\n\n if( this.isTemplateType() ) {\n this.$emit(\"edited\", this.serialize(this.deserializedValue));\n }\n else if( this.isObjectType() ) {\n // emit the result to the parent Vue\n this.$emit(\"edited\", this.editor.get());\n }\n },\n\n setStringValue: function(e) {\n var val = $(e.target).val();\n this.$emit(\"edited\", val);\n },\n\n setBoolValue: function(e) {\n var val = $(e.target).val() == \"true\";\n this.$emit(\"edited\", val);\n },\n\n setNumberValue: function(e) {\n var val = parseFloat($(e.target).val());\n this.$emit(\"edited\", val);\n },\n\n setNullValue: function() {\n this.$forceUpdate();\n\n // emit the result to the parent Vue\n this.$emit(\"edited\", null);\n },\n\n selectNextIndex: function() {\n if( this.isArrayType() ) {\n this.selectedIndex = this.deserializedValue.length > 0 ? 0 : null;\n }\n else if( this.isMapType() ) {\n var keys = this.deserializedValue.keys();\n var next = keys.next();\n this.selectedIndex = next ? next.value : null;\n }\n },\n\n deleteValue: function(e) {\n this.selectNextIndex();\n this.$forceUpdate();\n\n // emit the result to the parent Vue\n this.$emit(\"edited\", undefined);\n },\n\n isArrayType: function() {\n return this.dataType == \"array\";\n },\n\n isMapType: function() {\n return this.dataType == \"map\";\n },\n\n isObjectType: function() {\n return this.dataType == \"object\";\n },\n\n isTemplateType: function() {\n return this.isArrayType() || this.isMapType();\n },\n\n getEmbeddedType: function(type) {\n var start = type.indexOf('<') + 1;\n var end = type.lastIndexOf('>');\n if( type.toLowerCase().startsWith('array') ) {\n return type.substr(start, end - start).trim().toLowerCase();\n }\n else if( type.toLowerCase().startsWith('map') ) {\n var sub = type.substr(start, end - start);\n return sub.substr(sub.indexOf(',') + 1).trim().toLowerCase();\n }\n },\n\n firstLetterUppercase: function(s) {\n return s.charAt(0).toUpperCase() + s.slice(1)\n },\n \n selectIndex: function(index) {\n if( this.selectedIndex !== index ) {\n this.selectedIndex = index;\n this.$forceUpdate();\n }\n },\n\n isSelectedIndex: function(index) {\n return index == this.selectedIndex;\n },\n\n getElement: function(i) {\n if( Array.isArray(this.v) ) {\n return this.deserializedValue[i];\n }\n else {\n return this.deserializedValue.get(i);\n }\n },\n\n onSubValueEdited: function(index, newValue) {\n console.log(`Edited at index ${index}: ${JSON.stringify(newValue)}`);\n if( this.isArrayType() ) {\n if( newValue === undefined ) {\n // we just remove this value\n this.deserializedValue.splice(index, 1);\n }\n else {\n this.deserializedValue[index] = newValue;\n }\n }\n else if ( this.isMapType() ) {\n if( newValue === undefined ) {\n this.deserializedValue.delete(index);\n }\n else {\n this.deserializedValue.set(index, newValue);\n }\n }\n this.saveChanges();\n this.$forceUpdate();\n },\n\n addItem: function() {\n if( this.isArrayType() ) {\n this.deserializedValue[ this.deserializedValue.length ] = null;\n this.selectedIndex = this.deserializedValue.length - 1;\n this.saveChanges();\n this.$forceUpdate();\n }\n else if( this.isMapType() ) {\n this.swalFixBootstrapModal();\n swal({\n input: 'text',\n title: 'Enter map key',\n }).then((result) => {\n this.swalRestoreBootstrapModal();\n if( result && result.value ) {\n this.selectedIndex = result.value;\n this.deserializedValue.set(result.value, null);\n this.saveChanges();\n this.$forceUpdate();\n }\n });\n }\n },\n\n // call this before showing SweetAlert:\n swalFixBootstrapModal() {\n var modal = $(\"body\").find('.modal[tabindex=\"-1\"]');\n if (!modal) return;\n modal.removeAttr('tabindex');\n modal.addClass('js-swal-fixed');\n },\n\n // call this before hiding SweetAlert (inside done callback):\n swalRestoreBootstrapModal() {\n var modal = $(\"body\").find('.modal.js-swal-fixed');\n if (!modal) return;\n modal.attr('tabindex', '-1');\n modal.removeClass('js-swal-fixed');\n }\n }\n}\n</script>\n"]}, media: undefined });
|
|
64136
|
+
inject("data-v-18e3a1d2_0", { source: "\n.template-value-container[data-v-18e3a1d2], .field-editor[data-v-18e3a1d2] {\n margin-bottom: 10px;\n}\n.template-value-message[data-v-18e3a1d2] {\n text-align: center;\n margin-top: 30px;\n margin-bottom: 30px;\n width: 100%;\n opacity: 0.5;\n}\n", map: {"version":3,"sources":["/home/seb/dev/dualbox/editor/js/src/v/templates/editValue.vue"],"names":[],"mappings":";AACA;IACA,mBAAA;AACA;AAEA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;IACA,WAAA;IACA,YAAA;AACA","file":"editValue.vue","sourcesContent":["<style scoped>\n .template-value-container, .field-editor {\n margin-bottom: 10px;\n }\n\n .template-value-message {\n text-align: center;\n margin-top: 30px;\n margin-bottom: 30px;\n width: 100%;\n opacity: 0.5;\n }\n</style>\n\n<template>\n <div class=\"w-100\">\n <p style=\"display: none;\">{{cIndex}}</p>\n <template v-if=\"isBasicDataType()\">\n <template v-if=\"dataType === 'string'\">\n <input class=\"edit-value-input\" type=\"text\" @keyup.enter=\"setStringValue\" @keyup.esc=\"setStringValue\" :value=\"v\" @focus=\"$event.target.select()\"></input>\n </template>\n <template v-else-if=\"dataType === 'boolean'\">\n <select class=\"edit-value-input\" @change=\"setBoolValue\">\n <option value=\"true\" :selected=\"v == true\">True</option>\n <option value=\"false\" :selected=\"v == false\">False</option>\n </select>\n </template>\n <template v-else-if=\"dataType === 'number'\">\n <input class=\"edit-value-input\" type=\"number\" @keyup.enter=\"setNumberValue\" @blur=\"setNumberValue\" :value=\"v\" @focus=\"$event.target.select()\" style=\"width: 40px;\"></input>\n </template>\n </template>\n <template v-else>\n <!-- we already are in a modal, don't instanciate another one -->\n <template v-if=\"isTemplateType()\">\n <div class=\"container template-value-container\" style=\"border: 1px solid rgba(0, 0, 0, 0.125);\">\n <div v-if=\"isArrayType()\" class=\"row\" style=\"background-color: rgba(0,0,0,.125);\">Array Editor</div>\n <div v-else-if=\"isMapType()\" class=\"row\" style=\"background-color: rgba(0,0,0,.125);\">Map Editor</div>\n <div class=\"row\" style=\"1px solid rgba(0,0,0,.125);\">\n <div class=\"col list-group-flush\" :class=\"{ 'col-1' : isArrayType(), 'col-2' : isMapType()}\" style=\"padding: 0; background-color: white; overflow-y: auto; border-right: 1px solid rgba(0, 0, 0, 0.125);\">\n <button v-for=\"index in deserializedValue.keys()\" :key=\"index\" :data-key=\"index\" type=\"button\" class=\"list-group-item list-group-item-action\" :class=\"{ active: isSelectedIndex(index) }\" style=\"text-align: center;\" @click=\"selectIndex(index)\">{{index}}</button>\n <button type=\"button\" @click=\"addItem\" class=\"list-group-item list-group-item-action add-item\" style=\"text-align: center;\"><i class=\"fas fa-plus-circle\"></i></button>\n </div>\n <div class=\"col\" style=\"padding: 10px\">\n <edit-value v-if=\"selectedIndex !== undefined && selectedIndex !== null\" :cIndex=\"index\" :type=\"embeddedType\" :v=\"getElement(selectedIndex)\" @edited=\"onSubValueEdited(selectedIndex, $event)\"></edit-value>\n <p v-else class=\"template-value-message\">Select an element to edit.</p>\n </div>\n </div>\n </div>\n </template>\n <template v-else>\n <div class=\"field-editor\" :data-value=\"hash()\"></div>\n </template>\n </template>\n\n <!-- set null and delete buttons -->\n <div class=\"d-inline-block float-right\">\n <button class=\"btn btn-secondary btn-sm btn-xs\" title=\"set Null\" @click=\"setNullValue\">null</button>\n <button class=\"btn btn-danger btn-sm btn-xs\" title=\"delete value\" @click=\"deleteValue\" style=\"margin-left: 0px;\"><i class=\"fas fa-trash\"></i></button>\n </div>\n </div>\n\n</template>\n\n<script>\nimport _ from 'lodash';\nimport swal from 'sweetalert2';\nimport JSONEditor from '@dualbox/dualbox-lib-jsoneditor';\n\nString.prototype.hashCode = function() {\n var hash = 0, i, chr;\n if (this.length === 0) return hash;\n for (i = 0; i < this.length; i++) {\n chr = this.charCodeAt(i);\n hash = ((hash << 5) - hash) + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash;\n};\n\nexport default {\n name : \"edit-value\",\n props: [\n // required\n \"v\", // the value\n \"type\", // the dualbox type of the value\n\n // specific properties (for recursivity)\n \"cIndex\" // index for reference when in an array\n ],\n data: function () {\n return {\n \"dataType\": null, // the real javascript dataType of this.v\n \"deserializedValue\": null,\n\n // if type is a collection (dataType==\"map\" or dataType==\"array\")\n \"embeddedType\": null, // the embedded type of this templated collection\n \"selectedIndex\": null, // the current index of the element we are editing\n };\n },\n created: function() {\n this.view = window.dualboxEditor.v;\n this.editor = null;\n this.initData();\n },\n mounted: function() {\n var self = this;\n\n this.updateEditor();\n\n $(this.$el).find('.edit-value-input').focus(); // focus on the edit element\n },\n beforeUpdate: function() {\n this.updateData();\n },\n updated: function() {\n if( this.autochange ) {\n // change triggered by ourself, skip\n this.autochange = false;\n }\n else {\n this.updateEditor();\n }\n },\n methods: {\n hash: function() {\n var str = new String(this.v).toString();\n return str.split('').reduce((prevHash, currVal) => (((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0);\n },\n\n updateEditor: function() {\n if( this.dataType === \"object\" ) {\n if( !this.editor && $(this.$el).find('.field-editor')[0] !== undefined ) {\n // bind the json editor\n this.editor = new JSONEditor(\n $(this.$el).find('.field-editor')[0], {\n modes: ['tree', 'code', 'text' ],\n onChange: () => {\n try {\n var json = this.editor.get();\n this.autochange = true;\n this.$emit('edited', json);\n }\n catch(e) {}\n }\n });\n }\n\n if( this.editor ) {\n this.editor.set(this.v || {});\n }\n }\n },\n resolveDatatype() {\n // determine datatype of the value\n var resolvedType = this.type ? this.type.toLowerCase() : typeof this.v;\n\n // If \"*\", resolve the type by detecting it dynamically from value\n if( resolvedType.indexOf(\"*\") !== -1 ) {\n resolvedType = window.DualBox.Type.detectType(this.v).toLowerCase();\n }\n\n // Check if we have a template type. If so, determine current index and embedded type\n var templateType = null;\n if( resolvedType.startsWith(\"array\") ) {\n templateType = \"array\";\n this.deserializedValue = this.v || [];\n }\n else if( resolvedType.startsWith(\"map\") ) {\n templateType = \"map\";\n this.deserializedValue = window.DualBox.Type.deserialize(this.v || {\n \"metadata\":{\n \"type\":\"Map<String,\"+ this.firstLetterUppercase( this.getEmbeddedType(resolvedType) )+\">\"\n },\n \"data\": {}\n });\n }\n\n if( templateType ) {\n this.dataType = templateType;\n this.embeddedType = this.getEmbeddedType(resolvedType);\n if( this.selectedIndex == null ) {\n var firstKey = this.deserializedValue.keys().next();\n if( firstKey && firstKey.value ) {\n this.selectedIndex = firstKey.value;\n }\n }\n }\n else {\n this.dataType = resolvedType;\n }\n\n // Finally, transform to object if not a basic value\n if( [\"string\", \"number\", \"boolean\", \"array\", \"map\"].indexOf(this.dataType) == -1 ) {\n this.dataType = \"object\";\n }\n\n console.log(`Type: ${this.type}, Datatype: ${this.dataType}, embeddedType: ${this.embeddedType}`);\n },\n\n initData: function() {\n this.v = this.v;\n this.resolveDatatype();\n this.selectNextIndex();\n },\n\n updateData: function() {\n this.resolveDatatype();\n },\n\n isBasicDataType() {\n return this.dataType == \"string\" ||\n this.dataType == \"number\" ||\n this.dataType == \"boolean\";\n },\n\n serialize( value ) {\n if( this.isTemplateType() ) {\n if( this.isArrayType() ) {\n return value; // we store arrays as is\n }\n else if( this.isMapType() ) {\n return window.DualBox.Type.serialize(value);\n }\n }\n else {\n return value;\n }\n },\n\n saveChanges: function() {\n this.$forceUpdate();\n\n if( this.isTemplateType() ) {\n this.$emit(\"edited\", this.serialize(this.deserializedValue));\n }\n else if( this.isObjectType() ) {\n // emit the result to the parent Vue\n this.$emit(\"edited\", this.editor.get());\n }\n },\n\n setStringValue: function(e) {\n var val = $(e.target).val();\n this.$emit(\"edited\", val);\n },\n\n setBoolValue: function(e) {\n var val = $(e.target).val() == \"true\";\n this.$emit(\"edited\", val);\n },\n\n setNumberValue: function(e) {\n var val = parseFloat($(e.target).val());\n this.$emit(\"edited\", val);\n },\n\n setNullValue: function() {\n this.$forceUpdate();\n\n // emit the result to the parent Vue\n this.$emit(\"edited\", null);\n },\n\n selectNextIndex: function() {\n if( this.isArrayType() ) {\n this.selectedIndex = this.deserializedValue.length > 0 ? 0 : null;\n }\n else if( this.isMapType() ) {\n var keys = this.deserializedValue.keys();\n var next = keys.next();\n this.selectedIndex = next ? next.value : null;\n }\n },\n\n deleteValue: function(e) {\n this.selectNextIndex();\n this.$forceUpdate();\n\n // emit the result to the parent Vue\n this.$emit(\"edited\", undefined);\n },\n\n isArrayType: function() {\n return this.dataType == \"array\";\n },\n\n isMapType: function() {\n return this.dataType == \"map\";\n },\n\n isObjectType: function() {\n return this.dataType == \"object\";\n },\n\n isTemplateType: function() {\n return this.isArrayType() || this.isMapType();\n },\n\n getEmbeddedType: function(type) {\n var start = type.indexOf('<') + 1;\n var end = type.lastIndexOf('>');\n if( type.toLowerCase().startsWith('array') ) {\n return type.substr(start, end - start).trim().toLowerCase();\n }\n else if( type.toLowerCase().startsWith('map') ) {\n var sub = type.substr(start, end - start);\n return sub.substr(sub.indexOf(',') + 1).trim().toLowerCase();\n }\n },\n\n firstLetterUppercase: function(s) {\n return s.charAt(0).toUpperCase() + s.slice(1)\n },\n\n selectIndex: function(index) {\n if( this.selectedIndex !== index ) {\n this.selectedIndex = index;\n this.$forceUpdate();\n }\n },\n\n isSelectedIndex: function(index) {\n return index == this.selectedIndex;\n },\n\n getElement: function(i) {\n if( Array.isArray(this.v) ) {\n return this.deserializedValue[i];\n }\n else {\n return this.deserializedValue.get(i);\n }\n },\n\n onSubValueEdited: function(index, newValue) {\n console.log(`Edited at index ${index}: ${JSON.stringify(newValue)}`);\n if( this.isArrayType() ) {\n if( newValue === undefined ) {\n // we just remove this value\n this.deserializedValue.splice(index, 1);\n }\n else {\n this.deserializedValue[index] = newValue;\n }\n }\n else if ( this.isMapType() ) {\n if( newValue === undefined ) {\n this.deserializedValue.delete(index);\n }\n else {\n this.deserializedValue.set(index, newValue);\n }\n }\n this.saveChanges();\n this.$forceUpdate();\n },\n\n addItem: function() {\n if( this.isArrayType() ) {\n this.deserializedValue[ this.deserializedValue.length ] = null;\n this.selectedIndex = this.deserializedValue.length - 1;\n this.saveChanges();\n this.$forceUpdate();\n }\n else if( this.isMapType() ) {\n this.swalFixBootstrapModal();\n swal({\n input: 'text',\n title: 'Enter map key',\n }).then((result) => {\n this.swalRestoreBootstrapModal();\n if( result && result.value ) {\n this.selectedIndex = result.value;\n this.deserializedValue.set(result.value, null);\n this.saveChanges();\n this.$forceUpdate();\n }\n });\n }\n },\n\n // call this before showing SweetAlert:\n swalFixBootstrapModal() {\n var modal = $(\"body\").find('.modal[tabindex=\"-1\"]');\n if (!modal) return;\n modal.removeAttr('tabindex');\n modal.addClass('js-swal-fixed');\n },\n\n // call this before hiding SweetAlert (inside done callback):\n swalRestoreBootstrapModal() {\n var modal = $(\"body\").find('.modal.js-swal-fixed');\n if (!modal) return;\n modal.attr('tabindex', '-1');\n modal.removeClass('js-swal-fixed');\n }\n }\n}\n</script>\n"]}, media: undefined });
|
|
64137
64137
|
|
|
64138
64138
|
};
|
|
64139
64139
|
/* scoped */
|
|
64140
|
-
const __vue_scope_id__$8 = "data-v-
|
|
64140
|
+
const __vue_scope_id__$8 = "data-v-18e3a1d2";
|
|
64141
64141
|
/* module identifier */
|
|
64142
64142
|
const __vue_module_identifier__$8 = undefined;
|
|
64143
64143
|
/* functional template */
|
package/js/src/m/GraphModel.js
CHANGED
|
@@ -993,6 +993,7 @@ class GraphNode {
|
|
|
993
993
|
return this.setAttributeValue(name, val);
|
|
994
994
|
}
|
|
995
995
|
}
|
|
996
|
+
this.m.save();
|
|
996
997
|
}
|
|
997
998
|
|
|
998
999
|
deleteVal(srcType, name) {
|
|
@@ -1001,6 +1002,7 @@ class GraphNode {
|
|
|
1001
1002
|
} else if (srcType === "attr" && this.def.attr) {
|
|
1002
1003
|
delete this.def.attr[name];
|
|
1003
1004
|
}
|
|
1005
|
+
this.m.save();
|
|
1004
1006
|
}
|
|
1005
1007
|
|
|
1006
1008
|
getValueType(srcType, name) {
|
package/js/src/v/AppManager.js
CHANGED
|
@@ -21,8 +21,7 @@ class AppManager {
|
|
|
21
21
|
load(cb) {
|
|
22
22
|
if (this.loaded) {
|
|
23
23
|
cb();
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
24
|
+
} else {
|
|
26
25
|
/* todo: load dynamically .js ressources from the app */
|
|
27
26
|
this.loaded = true;
|
|
28
27
|
cb();
|
|
@@ -46,10 +45,9 @@ class AppManager {
|
|
|
46
45
|
options.options.debug.record = options.options.debug.record || false;
|
|
47
46
|
options.ressources = window.DualBoxRessources || {};
|
|
48
47
|
|
|
49
|
-
this.app = window.DualBox.start(options);
|
|
48
|
+
this.app = window.app = window.DualBox.start(options);
|
|
50
49
|
this.app.start(cb);
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
50
|
+
} else {
|
|
53
51
|
setTimeout(this.run.bind(this, json, options, cb), 1000);
|
|
54
52
|
}
|
|
55
53
|
}
|
|
@@ -59,4 +57,4 @@ class AppManager {
|
|
|
59
57
|
}
|
|
60
58
|
}
|
|
61
59
|
|
|
62
|
-
export default AppManager;
|
|
60
|
+
export default AppManager;
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
<button type="button" @click="addItem" class="list-group-item list-group-item-action add-item" style="text-align: center;"><i class="fas fa-plus-circle"></i></button>
|
|
42
42
|
</div>
|
|
43
43
|
<div class="col" style="padding: 10px">
|
|
44
|
-
<edit-value v-if="selectedIndex !== undefined && selectedIndex !== null" :cIndex="
|
|
44
|
+
<edit-value v-if="selectedIndex !== undefined && selectedIndex !== null" :cIndex="index" :type="embeddedType" :v="getElement(selectedIndex)" @edited="onSubValueEdited(selectedIndex, $event)"></edit-value>
|
|
45
45
|
<p v-else class="template-value-message">Select an element to edit.</p>
|
|
46
46
|
</div>
|
|
47
47
|
</div>
|
|
@@ -168,7 +168,7 @@ export default {
|
|
|
168
168
|
else if( resolvedType.startsWith("map") ) {
|
|
169
169
|
templateType = "map";
|
|
170
170
|
this.deserializedValue = window.DualBox.Type.deserialize(this.v || {
|
|
171
|
-
"metadata":{
|
|
171
|
+
"metadata":{
|
|
172
172
|
"type":"Map<String,"+ this.firstLetterUppercase( this.getEmbeddedType(resolvedType) )+">"
|
|
173
173
|
},
|
|
174
174
|
"data": {}
|
|
@@ -311,7 +311,7 @@ export default {
|
|
|
311
311
|
firstLetterUppercase: function(s) {
|
|
312
312
|
return s.charAt(0).toUpperCase() + s.slice(1)
|
|
313
313
|
},
|
|
314
|
-
|
|
314
|
+
|
|
315
315
|
selectIndex: function(index) {
|
|
316
316
|
if( this.selectedIndex !== index ) {
|
|
317
317
|
this.selectedIndex = index;
|