@dualbox/editor 1.0.80 → 1.0.82
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.
- package/js/dist/GraphEditor.js +53 -21
- package/js/dist/GraphEditor.min.js +52 -20
- package/js/src/m/DualboxUtils.js +9 -2
- package/js/src/m/GraphModel.js +17 -1
- package/js/src/v/templates/editMainSettings.vue +5 -0
- package/js/src/v/templates/editValue.vue +17 -14
- package/js/src/v/templates/main.vue +1 -1
- package/package.json +1 -1
|
@@ -40660,6 +40660,14 @@ class DualboxUtils {
|
|
|
40660
40660
|
return packageName.indexOf('dualbox-module-') !== -1 ||
|
|
40661
40661
|
packageName.indexOf('dualbox-core-') !== -1;
|
|
40662
40662
|
}
|
|
40663
|
+
|
|
40664
|
+
isLibrary(packageName) {
|
|
40665
|
+
return packageName === "@dualbox/dualbox" || packageName.indexOf('dualbox-lib-') !== -1;
|
|
40666
|
+
}
|
|
40667
|
+
|
|
40668
|
+
isType(packageName) {
|
|
40669
|
+
return packageName.indexOf('dualbox-type-') !== -1;
|
|
40670
|
+
}
|
|
40663
40671
|
}
|
|
40664
40672
|
|
|
40665
40673
|
var utils = new DualboxUtils();
|
|
@@ -43911,6 +43919,20 @@ class GraphModel {
|
|
|
43911
43919
|
return instances;
|
|
43912
43920
|
}
|
|
43913
43921
|
|
|
43922
|
+
// add pkg dependencies (lib, types, etc) to app graph
|
|
43923
|
+
addDependencies(pkg) {
|
|
43924
|
+
lodash.each(pkg.dependencies, async (dependencyVersion, dependencyName) => {
|
|
43925
|
+
if (utils.isLibrary(dependencyName) || utils.isType(dependencyName)) {
|
|
43926
|
+
console.log('[*] Adding dependency: ' + dependencyName);
|
|
43927
|
+
// await this.e.loadPackage(dependencyName, dependencyVersion); // Is this better ?
|
|
43928
|
+
await this.e.loadPackage(dependencyName); // or should we just load the last version ?
|
|
43929
|
+
let pkg = this.e.packages[dependencyName];
|
|
43930
|
+
this.data.root.libs[pkg.name] = pkg.version;
|
|
43931
|
+
await this.addDependencies(pkg);
|
|
43932
|
+
}
|
|
43933
|
+
});
|
|
43934
|
+
}
|
|
43935
|
+
|
|
43914
43936
|
addNode(id, pkg) {
|
|
43915
43937
|
console.log('adding node: ' + id);
|
|
43916
43938
|
|
|
@@ -43926,6 +43948,7 @@ class GraphModel {
|
|
|
43926
43948
|
return false;
|
|
43927
43949
|
}
|
|
43928
43950
|
var node = this.getCurrentMetanode().modules[id] = desc;
|
|
43951
|
+
this.addDependencies(pkg); // async but no pb
|
|
43929
43952
|
} else if (utils.isUI(pkg.name)) {
|
|
43930
43953
|
this.ensure('ui');
|
|
43931
43954
|
if (this.getCurrentMetanode().ui[id]) {
|
|
@@ -43933,6 +43956,7 @@ class GraphModel {
|
|
|
43933
43956
|
return false;
|
|
43934
43957
|
}
|
|
43935
43958
|
var node = this.getCurrentMetanode().ui[id] = desc;
|
|
43959
|
+
this.addDependencies(pkg); // async but no pb
|
|
43936
43960
|
} else {
|
|
43937
43961
|
// may be a metanode
|
|
43938
43962
|
var nodeDef = idx_1(this.getCurrentMetanode(), o => o.metanodes[pkg.name]);
|
|
@@ -45191,7 +45215,7 @@ class GraphNode {
|
|
|
45191
45215
|
|
|
45192
45216
|
// return true if the node is in a metanode
|
|
45193
45217
|
isInMetanode() {
|
|
45194
|
-
return this.m.getCurrentMetanodeName() !=
|
|
45218
|
+
return this.m.getCurrentMetanodeName() != this.m.data.windows[0][0];
|
|
45195
45219
|
}
|
|
45196
45220
|
|
|
45197
45221
|
// Works only is this.isInMetanode() == true
|
|
@@ -65020,21 +65044,23 @@ var script$8 = {
|
|
|
65020
65044
|
var templateType = null;
|
|
65021
65045
|
if (resolvedType.startsWith("array")) {
|
|
65022
65046
|
templateType = "array";
|
|
65023
|
-
this.deserializedValue = this.v || [];
|
|
65047
|
+
this.deserializedValue = lodash.clone(this.v || []);
|
|
65024
65048
|
} else if (resolvedType.startsWith("map")) {
|
|
65025
65049
|
templateType = "map";
|
|
65026
|
-
this.deserializedValue =
|
|
65027
|
-
|
|
65028
|
-
|
|
65029
|
-
|
|
65030
|
-
|
|
65031
|
-
|
|
65032
|
-
this.
|
|
65033
|
-
|
|
65034
|
-
|
|
65035
|
-
|
|
65036
|
-
|
|
65037
|
-
|
|
65050
|
+
this.deserializedValue = lodash.clone(
|
|
65051
|
+
window.DualBox.Type.deserialize(
|
|
65052
|
+
this.v || {
|
|
65053
|
+
metadata: {
|
|
65054
|
+
type:
|
|
65055
|
+
"Map<String," +
|
|
65056
|
+
this.firstLetterUppercase(
|
|
65057
|
+
this.getEmbeddedType(resolvedType)
|
|
65058
|
+
) +
|
|
65059
|
+
">"
|
|
65060
|
+
},
|
|
65061
|
+
data: {}
|
|
65062
|
+
}
|
|
65063
|
+
)
|
|
65038
65064
|
);
|
|
65039
65065
|
}
|
|
65040
65066
|
|
|
@@ -65101,7 +65127,8 @@ var script$8 = {
|
|
|
65101
65127
|
this.$forceUpdate();
|
|
65102
65128
|
|
|
65103
65129
|
if (this.isTemplateType()) {
|
|
65104
|
-
|
|
65130
|
+
let value = lodash.clone(this.deserializedValue);
|
|
65131
|
+
this.emit(this.serialize(value));
|
|
65105
65132
|
this.emitted = true;
|
|
65106
65133
|
} else if (this.isObjectType()) {
|
|
65107
65134
|
// emit the result to the parent Vue
|
|
@@ -65659,11 +65686,11 @@ __vue_render__$8._withStripped = true;
|
|
|
65659
65686
|
/* style */
|
|
65660
65687
|
const __vue_inject_styles__$8 = function (inject) {
|
|
65661
65688
|
if (!inject) return
|
|
65662
|
-
inject("data-v-7a46f3f8_0", { source: "\n.template-value-container[data-v-7a46f3f8],\r\n.field-editor[data-v-7a46f3f8] {\r\n margin-bottom: 10px;\n}\n.template-value-message[data-v-7a46f3f8] {\r\n text-align: center;\r\n margin-top: 30px;\r\n margin-bottom: 30px;\r\n width: 100%;\r\n opacity: 0.5;\n}\n.dragOver[data-v-7a46f3f8] {\r\n border-bottom: 2px solid blue;\n}\r\n", map: {"version":3,"sources":["C:\\Users\\maxim\\Projects\\dualbox\\editor\\js\\src\\v\\templates\\editValue.vue"],"names":[],"mappings":";AACA;;IAEA,mBAAA;AACA;AAEA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,6BAAA;AACA","file":"editValue.vue","sourcesContent":["<style scoped>\r\n.template-value-container,\r\n.field-editor {\r\n margin-bottom: 10px;\r\n}\r\n\r\n.template-value-message {\r\n text-align: center;\r\n margin-top: 30px;\r\n margin-bottom: 30px;\r\n width: 100%;\r\n opacity: 0.5;\r\n}\r\n\r\n.dragOver {\r\n border-bottom: 2px solid blue;\r\n}\r\n</style>\r\n\r\n<template>\r\n <div class=\"w-100\">\r\n <p style=\"display: none;\">{{cIndex}}</p>\r\n <template v-if=\"isBasicDataType()\">\r\n <template v-if=\"dataType === 'string'\">\r\n <input class=\"edit-value-input\" type=\"text\" @keyup.enter=\"setStringValue\" @keyup.esc=\"setStringValue\" @blur=\"setStringValueFromBlur\" :value=\"v\" @focus=\"$event.target.select()\" />\r\n </template>\r\n\r\n <template v-else-if=\"dataType === 'boolean'\">\r\n <select class=\"edit-value-input\" @change=\"setBoolValue\">\r\n <option value=\"true\" :selected=\"v == true\">True</option>\r\n <option value=\"false\" :selected=\"v == false\">False</option>\r\n </select>\r\n </template>\r\n\r\n <template v-else-if=\"dataType === 'number'\">\r\n <input class=\"edit-value-input\" type=\"number\" @keyup.enter=\"setNumberValue\" @blur=\"setNumberValueFromBlur\" :value=\"v\" @focus=\"$event.target.select()\" style=\"width: 40px;\" />\r\n </template>\r\n </template>\r\n\r\n <template v-else>\r\n <!-- we already are in a modal, don't instanciate another one -->\r\n <template v-if=\"isTemplateType()\">\r\n <div class=\"container template-value-container\" style=\"border: 1px solid rgba(0, 0, 0, 0.125);\">\r\n <div v-if=\"isArrayType()\" class=\"row\" style=\"background-color: rgba(0,0,0,.125);\">Array Editor</div>\r\n <div v-else-if=\"isMapType()\" class=\"row\" style=\"background-color: rgba(0,0,0,.125);\">Map Editor</div>\r\n <div class=\"row\" style=\"1px solid rgba(0,0,0,.125);\">\r\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);\">\r\n <button v-for=\"index in deserializedValue.keys()\" :draggable=\"isArrayType()\" @dragstart=\"arrayIndexDragStart(index, $event)\" @dragover.prevent @dragenter=\"arrayIndexDragEnter\" @dragleave=\"arrayIndexDragLeave\" @drop=\"arrayIndexDrop(index, $event)\" :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>\r\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>\r\n </div>\r\n <div class=\"col\" style=\"padding: 10px\">\r\n <edit-value v-if=\"selectedIndex !== undefined && selectedIndex !== null\" :key=\"selectedIndex\" ref=\"subValueEditor\" :cIndex=\"selectedIndex\" :type=\"embeddedType\" :v=\"getElement(selectedIndex)\" @edited=\"onSubValueEdited\"></edit-value>\r\n <p v-else class=\"template-value-message\">Select an element to edit.</p>\r\n </div>\r\n </div>\r\n </div>\r\n </template>\r\n <template v-else>\r\n <span v-if=\"isNull()\" @click=\"setEmptyJsonValue\" class=\"d-inline-block data-display data-value\" style=\"word-break: break-all;\" title=\"set value here\" data-toggle=\"tooltip\" data-trigger=\"hover\" data-placement=\"top\">\r\n <i class=\"fas fa-pen\"></i> null\r\n </span>\r\n <div v-else class=\"field-editor\" :data-value=\"hash()\"></div>\r\n </template>\r\n </template>\r\n\r\n <!-- set null and delete buttons -->\r\n <div class=\"d-inline-block float-right\">\r\n <button class=\"btn btn-secondary btn-sm btn-xs\" title=\"set null\" @click=\"setNullValue\">null</button>\r\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>\r\n </div>\r\n </div>\r\n\r\n</template>\r\n\r\n<script>\r\nimport _ from \"lodash-es\";\r\nimport swal from \"sweetalert2\";\r\nimport JSONEditor from \"@dualbox/dualbox-lib-jsoneditor\";\r\n\r\nString.prototype.hashCode = function() {\r\n var hash = 0,\r\n i,\r\n chr;\r\n if (this.length === 0) return hash;\r\n for (i = 0; i < this.length; i++) {\r\n chr = this.charCodeAt(i);\r\n hash = (hash << 5) - hash + chr;\r\n hash |= 0; // Convert to 32bit integer\r\n }\r\n return hash;\r\n};\r\n\r\nexport default {\r\n name: \"edit-value\",\r\n props: [\r\n // required\r\n \"v\", // the value\r\n \"type\", // the dualbox type of the value\r\n\r\n // specific properties (for recursivity)\r\n \"cIndex\" // index for reference when in an array\r\n ],\r\n data: function() {\r\n return {\r\n dataType: null, // the real javascript dataType of this.v\r\n deserializedValue: null,\r\n\r\n // if type is a collection (dataType==\"map\" or dataType==\"array\")\r\n embeddedType: null, // the embedded type of this templated collection\r\n selectedIndex: null // the current index of the element we are editing\r\n };\r\n },\r\n created: function() {\r\n this.view = window.dualboxEditor.v;\r\n this.editor = null;\r\n this.edited = false;\r\n this.initData();\r\n this.saveOnDestroy = true;\r\n\r\n // create a debounced json emit\r\n this.jsonEmit = () => {\r\n try {\r\n var json = this.editor.get();\r\n this.autochange = true;\r\n this.emit(json);\r\n } catch (e) {}\r\n };\r\n this.debouncedJsonEmit = _.debounce(this.jsonEmit, 5000); // 5 second save debounce\r\n this.debouncedSetStringValue = _.debounce(this.setStringValue, 250); // thoses are to be used with the blur event, so it's cancellable if\r\n this.debouncedSetNumberValue = _.debounce(this.setNumberValue, 250); // the user clicked on \"null\" or \"remove\" instead or changing the string/num value\r\n },\r\n mounted: function() {\r\n var self = this;\r\n\r\n this.updateEditor();\r\n\r\n $(this.$el)\r\n .find(\".edit-value-input\")\r\n .focus(); // focus on the edit element\r\n },\r\n beforeUpdate: function() {\r\n this.updateData();\r\n },\r\n updated: function() {\r\n if (this.autochange) {\r\n // change triggered by ourself, skip\r\n this.autochange = false;\r\n } else {\r\n this.updateEditor();\r\n }\r\n },\r\n beforeDestroy: function() {\r\n if (this.saveOnDestroy) {\r\n // if some debounced json edition was going on, do it now\r\n this.debouncedJsonEmit.flush();\r\n\r\n // make sure the value was set\r\n if (!this.emitted) {\r\n if (this.isBasicDataType()) {\r\n var elt = $(this.$el).find(\".edit-value-input\");\r\n var val = elt.val();\r\n this.$emit(\"edited\", val);\r\n } else {\r\n this.saveChanges();\r\n }\r\n }\r\n }\r\n },\r\n methods: {\r\n hash: function() {\r\n var str = new String(this.v).toString();\r\n return str\r\n .split(\"\")\r\n .reduce(\r\n (prevHash, currVal) =>\r\n ((prevHash << 5) - prevHash + currVal.charCodeAt(0)) |\r\n 0,\r\n 0\r\n );\r\n },\r\n\r\n updateEditor: function() {\r\n if (this.dataType === \"object\" && !this.isNull()) {\r\n if (\r\n !this.editor &&\r\n $(this.$el).find(\".field-editor\")[0] !== undefined\r\n ) {\r\n // bind the json editor\r\n this.editor = new JSONEditor(\r\n $(this.$el).find(\".field-editor\")[0],\r\n {\r\n modes: [\"tree\", \"code\", \"text\"],\r\n onChange: this.debouncedJsonEmit\r\n }\r\n );\r\n }\r\n\r\n if (this.editor) {\r\n this.editor.set(this.v || {});\r\n }\r\n }\r\n },\r\n resolveDatatype() {\r\n // determine datatype of the value\r\n var resolvedType = this.type\r\n ? this.type.toLowerCase()\r\n : typeof this.v;\r\n\r\n // If \"*\", resolve the type by detecting it dynamically from value\r\n if (resolvedType.indexOf(\"*\") !== -1) {\r\n resolvedType = window.DualBox.Type.detectType(\r\n this.v\r\n ).toLowerCase();\r\n }\r\n\r\n // Check if we have a template type. If so, determine current index and embedded type\r\n var templateType = null;\r\n if (resolvedType.startsWith(\"array\")) {\r\n templateType = \"array\";\r\n this.deserializedValue = this.v || [];\r\n } else if (resolvedType.startsWith(\"map\")) {\r\n templateType = \"map\";\r\n this.deserializedValue = window.DualBox.Type.deserialize(\r\n this.v || {\r\n metadata: {\r\n type:\r\n \"Map<String,\" +\r\n this.firstLetterUppercase(\r\n this.getEmbeddedType(resolvedType)\r\n ) +\r\n \">\"\r\n },\r\n data: {}\r\n }\r\n );\r\n }\r\n\r\n if (templateType) {\r\n this.dataType = templateType;\r\n this.embeddedType = this.getEmbeddedType(resolvedType);\r\n if (this.selectedIndex == null) {\r\n var firstKey = this.deserializedValue.keys().next();\r\n if (firstKey && firstKey.value) {\r\n this.selectedIndex = firstKey.value;\r\n }\r\n }\r\n } else {\r\n this.dataType = resolvedType;\r\n }\r\n\r\n // Finally, transform to object if not a basic value\r\n if (\r\n [\"string\", \"number\", \"boolean\", \"array\", \"map\"].indexOf(\r\n this.dataType\r\n ) == -1\r\n ) {\r\n this.dataType = \"object\";\r\n }\r\n //console.log(`Type: ${this.type}, Datatype: ${this.dataType}, embeddedType: ${this.embeddedType}`);\r\n },\r\n\r\n initData: function() {\r\n this.v = this.v;\r\n this.resolveDatatype();\r\n this.selectNextIndex();\r\n },\r\n\r\n updateData: function() {\r\n this.resolveDatatype();\r\n },\r\n\r\n isBasicDataType() {\r\n return (\r\n this.dataType == \"string\" ||\r\n this.dataType == \"number\" ||\r\n this.dataType == \"boolean\"\r\n );\r\n },\r\n\r\n serialize(value) {\r\n if (this.isTemplateType()) {\r\n if (this.isArrayType()) {\r\n return value; // we store arrays as is\r\n } else if (this.isMapType()) {\r\n return window.DualBox.Type.serialize(value);\r\n }\r\n } else {\r\n return value;\r\n }\r\n },\r\n\r\n emit(val) {\r\n this.$emit(\"edited\", val, this.cIndex);\r\n this.emitted = true;\r\n },\r\n\r\n saveChanges: function() {\r\n this.$forceUpdate();\r\n\r\n if (this.isTemplateType()) {\r\n this.emit(this.serialize(this.deserializedValue));\r\n this.emitted = true;\r\n } else if (this.isObjectType()) {\r\n // emit the result to the parent Vue\r\n this.emit(this.editor.get());\r\n this.emitted = true;\r\n }\r\n },\r\n\r\n setStringValue: function(e) {\r\n var val = $(e.target).val();\r\n this.emit(val);\r\n this.emitted = true;\r\n },\r\n\r\n // debounce the function to allow user to click on null or remove\r\n setStringValueFromBlur: function(e) {\r\n this.debouncedSetStringValue(e);\r\n },\r\n\r\n setBoolValue: function(e) {\r\n var val = $(e.target).val() == \"true\";\r\n this.emit(val);\r\n this.emitted = true;\r\n },\r\n\r\n setNumberValue: function(e) {\r\n var val = parseFloat($(e.target).val());\r\n if (isNaN(val)) {\r\n this.deleteValue(e);\r\n } else {\r\n this.emit(val);\r\n this.emitted = true;\r\n }\r\n },\r\n\r\n // debounce the function to allow user to click on null or remove\r\n setNumberValueFromBlur: function(e) {\r\n this.debouncedSetNumberValue(e);\r\n },\r\n\r\n cancelBlurDebounced: function() {\r\n this.debouncedSetStringValue.cancel();\r\n this.debouncedSetNumberValue.cancel();\r\n },\r\n\r\n setNullValue: function() {\r\n this.cancelBlurDebounced(); // kill incoming debounced setStringFromBlur or setNumberFromBlur\r\n\r\n this.$forceUpdate();\r\n\r\n // emit the result to the parent Vue\r\n this.emit(null);\r\n },\r\n\r\n setEmptyJsonValue: function() {\r\n // TODO: check this.type and create an empty object of this type\r\n this.emit({});\r\n },\r\n\r\n selectNextIndex: function() {\r\n if (this.isArrayType()) {\r\n this.selectedIndex =\r\n this.deserializedValue.length > 0 ? 0 : null;\r\n } else if (this.isMapType()) {\r\n var keys = this.deserializedValue.keys();\r\n var next = keys.next();\r\n this.selectedIndex = next ? next.value : null;\r\n }\r\n },\r\n\r\n deleteValue: function(e) {\r\n this.cancelBlurDebounced(); // kill incoming debounced setStringFromBlur or setNumberFromBlur\r\n this.selectNextIndex();\r\n this.$forceUpdate();\r\n\r\n // emit the result to the parent Vue\r\n this.emit(undefined);\r\n this.emitted = true;\r\n },\r\n\r\n isArrayType: function() {\r\n return this.dataType == \"array\";\r\n },\r\n\r\n isMapType: function() {\r\n return this.dataType == \"map\";\r\n },\r\n\r\n isObjectType: function() {\r\n return this.dataType == \"object\";\r\n },\r\n\r\n isTemplateType: function() {\r\n return this.isArrayType() || this.isMapType();\r\n },\r\n\r\n isNull: function() {\r\n return this.v === null;\r\n },\r\n\r\n getEmbeddedType: function(type) {\r\n var start = type.indexOf(\"<\") + 1;\r\n var end = type.lastIndexOf(\">\");\r\n if (type.toLowerCase().startsWith(\"array\")) {\r\n return type\r\n .substr(start, end - start)\r\n .trim()\r\n .toLowerCase();\r\n } else if (type.toLowerCase().startsWith(\"map\")) {\r\n var sub = type.substr(start, end - start);\r\n return sub\r\n .substr(sub.indexOf(\",\") + 1)\r\n .trim()\r\n .toLowerCase();\r\n }\r\n },\r\n\r\n firstLetterUppercase: function(s) {\r\n return s.charAt(0).toUpperCase() + s.slice(1);\r\n },\r\n\r\n selectIndex: function(index) {\r\n if (this.selectedIndex !== index) {\r\n this.selectedIndex = index;\r\n this.$forceUpdate();\r\n }\r\n },\r\n\r\n isSelectedIndex: function(index) {\r\n return index == this.selectedIndex;\r\n },\r\n\r\n getElement: function(i) {\r\n if (Array.isArray(this.v)) {\r\n return this.deserializedValue[i];\r\n } else {\r\n return this.deserializedValue.get(i);\r\n }\r\n },\r\n\r\n onSubValueEdited: function(newValue, index) {\r\n console.log(\r\n `Edited at index ${index}: ${JSON.stringify(newValue)}`\r\n );\r\n if (this.isArrayType()) {\r\n if (newValue === undefined) {\r\n // we just remove this value\r\n this.deserializedValue.splice(index, 1);\r\n } else {\r\n this.deserializedValue[index] = newValue;\r\n }\r\n } else if (this.isMapType()) {\r\n if (newValue === undefined) {\r\n this.deserializedValue.delete(index);\r\n } else {\r\n this.deserializedValue.set(index, newValue);\r\n }\r\n }\r\n this.saveChanges();\r\n this.$forceUpdate();\r\n },\r\n\r\n addItem: function() {\r\n if (this.isArrayType()) {\r\n this.deserializedValue[this.deserializedValue.length] = null;\r\n this.selectedIndex = this.deserializedValue.length - 1;\r\n this.saveChanges();\r\n this.$forceUpdate();\r\n } else if (this.isMapType()) {\r\n this.swalFixBootstrapModal();\r\n swal({\r\n input: \"text\",\r\n title: \"Enter map key\"\r\n }).then(result => {\r\n this.swalRestoreBootstrapModal();\r\n if (result && result.value) {\r\n this.selectedIndex = result.value;\r\n this.deserializedValue.set(result.value, null);\r\n this.saveChanges();\r\n this.$forceUpdate();\r\n }\r\n });\r\n }\r\n },\r\n\r\n // call this before showing SweetAlert:\r\n swalFixBootstrapModal() {\r\n var modal = $(\"body\").find('.modal[tabindex=\"-1\"]');\r\n if (!modal) return;\r\n modal.removeAttr(\"tabindex\");\r\n modal.addClass(\"js-swal-fixed\");\r\n },\r\n\r\n // call this before hiding SweetAlert (inside done callback):\r\n swalRestoreBootstrapModal() {\r\n var modal = $(\"body\").find(\".modal.js-swal-fixed\");\r\n if (!modal) return;\r\n modal.attr(\"tabindex\", \"-1\");\r\n modal.removeClass(\"js-swal-fixed\");\r\n },\r\n\r\n arrayIndexDragStart(which, e) {\r\n if (this.isArrayType()) {\r\n this.dragging = which;\r\n }\r\n this.selectedIndex = to;\r\n this.$forceUpdate();\r\n },\r\n\r\n arrayIndexDrop(to, e) {\r\n if (this.isArrayType()) {\r\n $(e.target).removeClass(\"dragOver\");\r\n let from = this.dragging;\r\n\r\n if (from === this.selectedIndex) {\r\n // we will have to ignore next destroy\r\n this.$refs.subValueEditor.saveOnDestroy = false;\r\n }\r\n\r\n // remove from for our indices and insert it after \"to\"\r\n var elem = this.deserializedValue.splice(from, 1)[0];\r\n this.deserializedValue.splice(to, 0, elem);\r\n\r\n this.selectedIndex = to;\r\n this.saveChanges();\r\n this.$forceUpdate();\r\n }\r\n },\r\n\r\n arrayIndexDragEnter(e) {\r\n $(e.target).addClass(\"dragOver\");\r\n },\r\n\r\n arrayIndexDragLeave(e) {\r\n $(e.target).removeClass(\"dragOver\");\r\n }\r\n }\r\n};\r\n</script>\r\n"]}, media: undefined });
|
|
65689
|
+
inject("data-v-bcbe186e_0", { source: "\n.template-value-container[data-v-bcbe186e],\r\n.field-editor[data-v-bcbe186e] {\r\n margin-bottom: 10px;\n}\n.template-value-message[data-v-bcbe186e] {\r\n text-align: center;\r\n margin-top: 30px;\r\n margin-bottom: 30px;\r\n width: 100%;\r\n opacity: 0.5;\n}\n.dragOver[data-v-bcbe186e] {\r\n border-bottom: 2px solid blue;\n}\r\n", map: {"version":3,"sources":["C:\\Users\\maxim\\Projects\\dualbox\\editor\\js\\src\\v\\templates\\editValue.vue"],"names":[],"mappings":";AACA;;IAEA,mBAAA;AACA;AAEA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,6BAAA;AACA","file":"editValue.vue","sourcesContent":["<style scoped>\r\n.template-value-container,\r\n.field-editor {\r\n margin-bottom: 10px;\r\n}\r\n\r\n.template-value-message {\r\n text-align: center;\r\n margin-top: 30px;\r\n margin-bottom: 30px;\r\n width: 100%;\r\n opacity: 0.5;\r\n}\r\n\r\n.dragOver {\r\n border-bottom: 2px solid blue;\r\n}\r\n</style>\r\n\r\n<template>\r\n <div class=\"w-100\">\r\n <p style=\"display: none;\">{{cIndex}}</p>\r\n <template v-if=\"isBasicDataType()\">\r\n <template v-if=\"dataType === 'string'\">\r\n <input class=\"edit-value-input\" type=\"text\" @keyup.enter=\"setStringValue\" @keyup.esc=\"setStringValue\" @blur=\"setStringValueFromBlur\" :value=\"v\" @focus=\"$event.target.select()\" />\r\n </template>\r\n\r\n <template v-else-if=\"dataType === 'boolean'\">\r\n <select class=\"edit-value-input\" @change=\"setBoolValue\">\r\n <option value=\"true\" :selected=\"v == true\">True</option>\r\n <option value=\"false\" :selected=\"v == false\">False</option>\r\n </select>\r\n </template>\r\n\r\n <template v-else-if=\"dataType === 'number'\">\r\n <input class=\"edit-value-input\" type=\"number\" @keyup.enter=\"setNumberValue\" @blur=\"setNumberValueFromBlur\" :value=\"v\" @focus=\"$event.target.select()\" style=\"width: 40px;\" />\r\n </template>\r\n </template>\r\n\r\n <template v-else>\r\n <!-- we already are in a modal, don't instanciate another one -->\r\n <template v-if=\"isTemplateType()\">\r\n <div class=\"container template-value-container\" style=\"border: 1px solid rgba(0, 0, 0, 0.125);\">\r\n <div v-if=\"isArrayType()\" class=\"row\" style=\"background-color: rgba(0,0,0,.125);\">Array Editor</div>\r\n <div v-else-if=\"isMapType()\" class=\"row\" style=\"background-color: rgba(0,0,0,.125);\">Map Editor</div>\r\n <div class=\"row\" style=\"1px solid rgba(0,0,0,.125);\">\r\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);\">\r\n <button v-for=\"index in deserializedValue.keys()\" :draggable=\"isArrayType()\" @dragstart=\"arrayIndexDragStart(index, $event)\" @dragover.prevent @dragenter=\"arrayIndexDragEnter\" @dragleave=\"arrayIndexDragLeave\" @drop=\"arrayIndexDrop(index, $event)\" :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>\r\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>\r\n </div>\r\n <div class=\"col\" style=\"padding: 10px\">\r\n <edit-value v-if=\"selectedIndex !== undefined && selectedIndex !== null\" :key=\"selectedIndex\" ref=\"subValueEditor\" :cIndex=\"selectedIndex\" :type=\"embeddedType\" :v=\"getElement(selectedIndex)\" @edited=\"onSubValueEdited\"></edit-value>\r\n <p v-else class=\"template-value-message\">Select an element to edit.</p>\r\n </div>\r\n </div>\r\n </div>\r\n </template>\r\n <template v-else>\r\n <span v-if=\"isNull()\" @click=\"setEmptyJsonValue\" class=\"d-inline-block data-display data-value\" style=\"word-break: break-all;\" title=\"set value here\" data-toggle=\"tooltip\" data-trigger=\"hover\" data-placement=\"top\">\r\n <i class=\"fas fa-pen\"></i> null\r\n </span>\r\n <div v-else class=\"field-editor\" :data-value=\"hash()\"></div>\r\n </template>\r\n </template>\r\n\r\n <!-- set null and delete buttons -->\r\n <div class=\"d-inline-block float-right\">\r\n <button class=\"btn btn-secondary btn-sm btn-xs\" title=\"set null\" @click=\"setNullValue\">null</button>\r\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>\r\n </div>\r\n </div>\r\n\r\n</template>\r\n\r\n<script>\r\nimport _ from \"lodash-es\";\r\nimport swal from \"sweetalert2\";\r\nimport JSONEditor from \"@dualbox/dualbox-lib-jsoneditor\";\r\n\r\nString.prototype.hashCode = function() {\r\n var hash = 0,\r\n i,\r\n chr;\r\n if (this.length === 0) return hash;\r\n for (i = 0; i < this.length; i++) {\r\n chr = this.charCodeAt(i);\r\n hash = (hash << 5) - hash + chr;\r\n hash |= 0; // Convert to 32bit integer\r\n }\r\n return hash;\r\n};\r\n\r\nexport default {\r\n name: \"edit-value\",\r\n props: [\r\n // required\r\n \"v\", // the value\r\n \"type\", // the dualbox type of the value\r\n\r\n // specific properties (for recursivity)\r\n \"cIndex\" // index for reference when in an array\r\n ],\r\n data: function() {\r\n return {\r\n dataType: null, // the real javascript dataType of this.v\r\n deserializedValue: null,\r\n\r\n // if type is a collection (dataType==\"map\" or dataType==\"array\")\r\n embeddedType: null, // the embedded type of this templated collection\r\n selectedIndex: null // the current index of the element we are editing\r\n };\r\n },\r\n created: function() {\r\n this.view = window.dualboxEditor.v;\r\n this.editor = null;\r\n this.edited = false;\r\n this.initData();\r\n this.saveOnDestroy = true;\r\n\r\n // create a debounced json emit\r\n this.jsonEmit = () => {\r\n try {\r\n var json = this.editor.get();\r\n this.autochange = true;\r\n this.emit(json);\r\n } catch (e) {}\r\n };\r\n this.debouncedJsonEmit = _.debounce(this.jsonEmit, 5000); // 5 second save debounce\r\n this.debouncedSetStringValue = _.debounce(this.setStringValue, 250); // thoses are to be used with the blur event, so it's cancellable if\r\n this.debouncedSetNumberValue = _.debounce(this.setNumberValue, 250); // the user clicked on \"null\" or \"remove\" instead or changing the string/num value\r\n },\r\n mounted: function() {\r\n var self = this;\r\n\r\n this.updateEditor();\r\n\r\n $(this.$el)\r\n .find(\".edit-value-input\")\r\n .focus(); // focus on the edit element\r\n },\r\n beforeUpdate: function() {\r\n this.updateData();\r\n },\r\n updated: function() {\r\n if (this.autochange) {\r\n // change triggered by ourself, skip\r\n this.autochange = false;\r\n } else {\r\n this.updateEditor();\r\n }\r\n },\r\n beforeDestroy: function() {\r\n if (this.saveOnDestroy) {\r\n // if some debounced json edition was going on, do it now\r\n this.debouncedJsonEmit.flush();\r\n\r\n // make sure the value was set\r\n if (!this.emitted) {\r\n if (this.isBasicDataType()) {\r\n var elt = $(this.$el).find(\".edit-value-input\");\r\n var val = elt.val();\r\n this.$emit(\"edited\", val);\r\n } else {\r\n this.saveChanges();\r\n }\r\n }\r\n }\r\n },\r\n methods: {\r\n hash: function() {\r\n var str = new String(this.v).toString();\r\n return str\r\n .split(\"\")\r\n .reduce(\r\n (prevHash, currVal) =>\r\n ((prevHash << 5) - prevHash + currVal.charCodeAt(0)) |\r\n 0,\r\n 0\r\n );\r\n },\r\n\r\n updateEditor: function() {\r\n if (this.dataType === \"object\" && !this.isNull()) {\r\n if (\r\n !this.editor &&\r\n $(this.$el).find(\".field-editor\")[0] !== undefined\r\n ) {\r\n // bind the json editor\r\n this.editor = new JSONEditor(\r\n $(this.$el).find(\".field-editor\")[0],\r\n {\r\n modes: [\"tree\", \"code\", \"text\"],\r\n onChange: this.debouncedJsonEmit\r\n }\r\n );\r\n }\r\n\r\n if (this.editor) {\r\n this.editor.set(this.v || {});\r\n }\r\n }\r\n },\r\n resolveDatatype() {\r\n // determine datatype of the value\r\n var resolvedType = this.type\r\n ? this.type.toLowerCase()\r\n : typeof this.v;\r\n\r\n // If \"*\", resolve the type by detecting it dynamically from value\r\n if (resolvedType.indexOf(\"*\") !== -1) {\r\n resolvedType = window.DualBox.Type.detectType(\r\n this.v\r\n ).toLowerCase();\r\n }\r\n\r\n // Check if we have a template type. If so, determine current index and embedded type\r\n var templateType = null;\r\n if (resolvedType.startsWith(\"array\")) {\r\n templateType = \"array\";\r\n this.deserializedValue = _.clone(this.v || []);\r\n } else if (resolvedType.startsWith(\"map\")) {\r\n templateType = \"map\";\r\n this.deserializedValue = _.clone(\r\n window.DualBox.Type.deserialize(\r\n this.v || {\r\n metadata: {\r\n type:\r\n \"Map<String,\" +\r\n this.firstLetterUppercase(\r\n this.getEmbeddedType(resolvedType)\r\n ) +\r\n \">\"\r\n },\r\n data: {}\r\n }\r\n )\r\n );\r\n }\r\n\r\n if (templateType) {\r\n this.dataType = templateType;\r\n this.embeddedType = this.getEmbeddedType(resolvedType);\r\n if (this.selectedIndex == null) {\r\n var firstKey = this.deserializedValue.keys().next();\r\n if (firstKey && firstKey.value) {\r\n this.selectedIndex = firstKey.value;\r\n }\r\n }\r\n } else {\r\n this.dataType = resolvedType;\r\n }\r\n\r\n // Finally, transform to object if not a basic value\r\n if (\r\n [\"string\", \"number\", \"boolean\", \"array\", \"map\"].indexOf(\r\n this.dataType\r\n ) == -1\r\n ) {\r\n this.dataType = \"object\";\r\n }\r\n //console.log(`Type: ${this.type}, Datatype: ${this.dataType}, embeddedType: ${this.embeddedType}`);\r\n },\r\n\r\n initData: function() {\r\n this.v = this.v;\r\n this.resolveDatatype();\r\n this.selectNextIndex();\r\n },\r\n\r\n updateData: function() {\r\n this.resolveDatatype();\r\n },\r\n\r\n isBasicDataType() {\r\n return (\r\n this.dataType == \"string\" ||\r\n this.dataType == \"number\" ||\r\n this.dataType == \"boolean\"\r\n );\r\n },\r\n\r\n serialize(value) {\r\n if (this.isTemplateType()) {\r\n if (this.isArrayType()) {\r\n return value; // we store arrays as is\r\n } else if (this.isMapType()) {\r\n return window.DualBox.Type.serialize(value);\r\n }\r\n } else {\r\n return value;\r\n }\r\n },\r\n\r\n emit(val) {\r\n this.$emit(\"edited\", val, this.cIndex);\r\n this.emitted = true;\r\n },\r\n\r\n saveChanges: function() {\r\n this.$forceUpdate();\r\n\r\n if (this.isTemplateType()) {\r\n let value = _.clone(this.deserializedValue);\r\n this.emit(this.serialize(value));\r\n this.emitted = true;\r\n } else if (this.isObjectType()) {\r\n // emit the result to the parent Vue\r\n this.emit(this.editor.get());\r\n this.emitted = true;\r\n }\r\n },\r\n\r\n setStringValue: function(e) {\r\n var val = $(e.target).val();\r\n this.emit(val);\r\n this.emitted = true;\r\n },\r\n\r\n // debounce the function to allow user to click on null or remove\r\n setStringValueFromBlur: function(e) {\r\n this.debouncedSetStringValue(e);\r\n },\r\n\r\n setBoolValue: function(e) {\r\n var val = $(e.target).val() == \"true\";\r\n this.emit(val);\r\n this.emitted = true;\r\n },\r\n\r\n setNumberValue: function(e) {\r\n var val = parseFloat($(e.target).val());\r\n if (isNaN(val)) {\r\n this.deleteValue(e);\r\n } else {\r\n this.emit(val);\r\n this.emitted = true;\r\n }\r\n },\r\n\r\n // debounce the function to allow user to click on null or remove\r\n setNumberValueFromBlur: function(e) {\r\n this.debouncedSetNumberValue(e);\r\n },\r\n\r\n cancelBlurDebounced: function() {\r\n this.debouncedSetStringValue.cancel();\r\n this.debouncedSetNumberValue.cancel();\r\n },\r\n\r\n setNullValue: function() {\r\n this.cancelBlurDebounced(); // kill incoming debounced setStringFromBlur or setNumberFromBlur\r\n\r\n this.$forceUpdate();\r\n\r\n // emit the result to the parent Vue\r\n this.emit(null);\r\n },\r\n\r\n setEmptyJsonValue: function() {\r\n // TODO: check this.type and create an empty object of this type\r\n this.emit({});\r\n },\r\n\r\n selectNextIndex: function() {\r\n if (this.isArrayType()) {\r\n this.selectedIndex =\r\n this.deserializedValue.length > 0 ? 0 : null;\r\n } else if (this.isMapType()) {\r\n var keys = this.deserializedValue.keys();\r\n var next = keys.next();\r\n this.selectedIndex = next ? next.value : null;\r\n }\r\n },\r\n\r\n deleteValue: function(e) {\r\n this.cancelBlurDebounced(); // kill incoming debounced setStringFromBlur or setNumberFromBlur\r\n this.selectNextIndex();\r\n this.$forceUpdate();\r\n\r\n // emit the result to the parent Vue\r\n this.emit(undefined);\r\n this.emitted = true;\r\n },\r\n\r\n isArrayType: function() {\r\n return this.dataType == \"array\";\r\n },\r\n\r\n isMapType: function() {\r\n return this.dataType == \"map\";\r\n },\r\n\r\n isObjectType: function() {\r\n return this.dataType == \"object\";\r\n },\r\n\r\n isTemplateType: function() {\r\n return this.isArrayType() || this.isMapType();\r\n },\r\n\r\n isNull: function() {\r\n return this.v === null;\r\n },\r\n\r\n getEmbeddedType: function(type) {\r\n var start = type.indexOf(\"<\") + 1;\r\n var end = type.lastIndexOf(\">\");\r\n if (type.toLowerCase().startsWith(\"array\")) {\r\n return type\r\n .substr(start, end - start)\r\n .trim()\r\n .toLowerCase();\r\n } else if (type.toLowerCase().startsWith(\"map\")) {\r\n var sub = type.substr(start, end - start);\r\n return sub\r\n .substr(sub.indexOf(\",\") + 1)\r\n .trim()\r\n .toLowerCase();\r\n }\r\n },\r\n\r\n firstLetterUppercase: function(s) {\r\n return s.charAt(0).toUpperCase() + s.slice(1);\r\n },\r\n\r\n selectIndex: function(index) {\r\n if (this.selectedIndex !== index) {\r\n this.selectedIndex = index;\r\n this.$forceUpdate();\r\n }\r\n },\r\n\r\n isSelectedIndex: function(index) {\r\n return index == this.selectedIndex;\r\n },\r\n\r\n getElement: function(i) {\r\n if (Array.isArray(this.v)) {\r\n return this.deserializedValue[i];\r\n } else {\r\n return this.deserializedValue.get(i);\r\n }\r\n },\r\n\r\n onSubValueEdited: function(newValue, index) {\r\n console.log(\r\n `Edited at index ${index}: ${JSON.stringify(newValue)}`\r\n );\r\n if (this.isArrayType()) {\r\n if (newValue === undefined) {\r\n // we just remove this value\r\n this.deserializedValue.splice(index, 1);\r\n } else {\r\n this.deserializedValue[index] = newValue;\r\n }\r\n } else if (this.isMapType()) {\r\n if (newValue === undefined) {\r\n this.deserializedValue.delete(index);\r\n } else {\r\n this.deserializedValue.set(index, newValue);\r\n }\r\n }\r\n this.saveChanges();\r\n this.$forceUpdate();\r\n },\r\n\r\n addItem: function() {\r\n if (this.isArrayType()) {\r\n this.deserializedValue[this.deserializedValue.length] = null;\r\n this.selectedIndex = this.deserializedValue.length - 1;\r\n this.saveChanges();\r\n this.$forceUpdate();\r\n } else if (this.isMapType()) {\r\n this.swalFixBootstrapModal();\r\n swal({\r\n input: \"text\",\r\n title: \"Enter map key\"\r\n }).then(result => {\r\n this.swalRestoreBootstrapModal();\r\n if (result && result.value) {\r\n this.selectedIndex = result.value;\r\n this.deserializedValue.set(result.value, null);\r\n this.saveChanges();\r\n this.$forceUpdate();\r\n }\r\n });\r\n }\r\n },\r\n\r\n // call this before showing SweetAlert:\r\n swalFixBootstrapModal() {\r\n var modal = $(\"body\").find('.modal[tabindex=\"-1\"]');\r\n if (!modal) return;\r\n modal.removeAttr(\"tabindex\");\r\n modal.addClass(\"js-swal-fixed\");\r\n },\r\n\r\n // call this before hiding SweetAlert (inside done callback):\r\n swalRestoreBootstrapModal() {\r\n var modal = $(\"body\").find(\".modal.js-swal-fixed\");\r\n if (!modal) return;\r\n modal.attr(\"tabindex\", \"-1\");\r\n modal.removeClass(\"js-swal-fixed\");\r\n },\r\n\r\n arrayIndexDragStart(which, e) {\r\n if (this.isArrayType()) {\r\n this.dragging = which;\r\n }\r\n this.selectedIndex = to;\r\n this.$forceUpdate();\r\n },\r\n\r\n arrayIndexDrop(to, e) {\r\n if (this.isArrayType()) {\r\n $(e.target).removeClass(\"dragOver\");\r\n let from = this.dragging;\r\n\r\n if (from === this.selectedIndex) {\r\n // we will have to ignore next destroy\r\n this.$refs.subValueEditor.saveOnDestroy = false;\r\n }\r\n\r\n // remove from for our indices and insert it after \"to\"\r\n var elem = this.deserializedValue.splice(from, 1)[0];\r\n this.deserializedValue.splice(to, 0, elem);\r\n\r\n this.selectedIndex = to;\r\n this.saveChanges();\r\n this.$forceUpdate();\r\n }\r\n },\r\n\r\n arrayIndexDragEnter(e) {\r\n $(e.target).addClass(\"dragOver\");\r\n },\r\n\r\n arrayIndexDragLeave(e) {\r\n $(e.target).removeClass(\"dragOver\");\r\n }\r\n }\r\n};\r\n</script>\r\n"]}, media: undefined });
|
|
65663
65690
|
|
|
65664
65691
|
};
|
|
65665
65692
|
/* scoped */
|
|
65666
|
-
const __vue_scope_id__$8 = "data-v-
|
|
65693
|
+
const __vue_scope_id__$8 = "data-v-bcbe186e";
|
|
65667
65694
|
/* module identifier */
|
|
65668
65695
|
const __vue_module_identifier__$8 = undefined;
|
|
65669
65696
|
/* functional template */
|
|
@@ -66088,7 +66115,12 @@ var script$a = {
|
|
|
66088
66115
|
});
|
|
66089
66116
|
|
|
66090
66117
|
var index = parseInt($(e.target).attr('data-index'));
|
|
66118
|
+
|
|
66119
|
+
// set event target
|
|
66091
66120
|
this.view.c.setEventTarget( "#application-" + $(e.target).attr('dualbox-target') + '-' + $(e.target).attr('data-event'), index, target);
|
|
66121
|
+
|
|
66122
|
+
// also set event name, to ensure we don't have a set event that doesn't exist on this node
|
|
66123
|
+
this.view.c.setEventName( "#application-" + $(e.target).attr('dualbox-target') + '-' + $(e.target).attr('data-event'), index, targetEvents[0]);
|
|
66092
66124
|
this.onEdited();
|
|
66093
66125
|
},
|
|
66094
66126
|
|
|
@@ -67333,7 +67365,7 @@ __vue_render__$a._withStripped = true;
|
|
|
67333
67365
|
/* style */
|
|
67334
67366
|
const __vue_inject_styles__$a = function (inject) {
|
|
67335
67367
|
if (!inject) return
|
|
67336
|
-
inject("data-v-6f37b981_0", { source: "\n.card-settings .card-body {\r\n font-size: 12px;\r\n padding-left: 5px;\r\n padding-right: 5px;\n}\n.fa {\r\n pointer-events: none;\n}\n.table-desc {\r\n width: 100%;\n}\n.table-desc > thead > th > td {\r\n margin-right: 6px;\n}\n.table-desc > tbody > tr > td {\r\n margin-right: 6px;\r\n padding-top: 8px;\r\n padding-bottom: 8px;\r\n height: 40px;\n}\n.application-description {\r\n margin-top: 20px;\r\n text-align: left;\r\n font-size: 12px;\n}\n.card-header[data-toggle=\"collapse\"] {\r\n cursor: pointer;\n}\n.card-header[data-toggle=\"collapse\"] h5 {\r\n user-select: none;\n}\n.card-header[data-toggle=\"collapse\"]:hover .btn-link {\r\n text-decoration: none;\n}\n.text-value, .number-value, .boolean-value {\r\n max-width: 140px;\n}\n.select-event-target, .select-event-name, .event-if, .event-data {\r\n font-size: 12px;\n}\n.edit-body {\r\n overflow-y: hidden;\r\n overflow-x: hidden;\r\n max-height: calc(100% - 90px);\n}\r\n\r\n/* remove bs4 transition on collapsing */\n.edit-main-panel .collapsing {\r\n -webkit-transition: none!important;\r\n transition: none!important;\r\n display: none!important;\n}\n.table-events .event-rooting {\r\n margin-top: 10px;\n}\n.table-events thead {\r\n border-bottom: 1px solid #ddd;\n}\n.table-events .tr-event-condition td {\r\n padding-left: 10px;\n}\n.table-events .tr-event-data td {\r\n padding-left: 10px;\n}\n.tr-event-condition td, .tr-event-data td {\r\n height: 20px!important;\n}\n.tr-event-condition, .tr-event-condition td, .tr-event-data, .tr-event-data td {\r\n padding-top: 1px!important;\r\n padding-bottom: 1px!important;\n}\n.table-events tr + .event-rooting {\r\n /* border-top: 1px solid #ddd; */\n}\n.event-rooting td {\r\n padding-top: 8px!important;\r\n padding-bottom: 4px!important;\n}\n.event-data-type {\r\n font-size: 75%;\r\n border-radius: 5px;\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-top: 2px;\r\n padding-bottom: 2px;\n}\n.event-data-display {\r\n font-size: 75%;\r\n border-radius: 5px;\r\n border: 1px solid #ddd;\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-top: 2px;\r\n padding-bottom: 2px;\n}\n.event-if {\r\n font-size: 75%;\r\n border-radius: 5px;\r\n border: 1px solid #ddd;\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-top: 2px;\r\n padding-bottom: 2px;\n}\ni.fa, i.fas, i.far {\r\n pointer-events: none;\n}\n.h100 {\r\n height: 100%;\n}\n.card-app-event > .card-header {\r\n padding: 6px 12px;\n}\n.card-main-settings {\r\n border: 1px solid rgba(0,0,0,.125);\n}\n.card-main-settings > .card-header {\r\n padding-top: 6px;\r\n padding-bottom: 6px;\r\n padding-left: 12px;\r\n padding-right: 12px;\n}\n.card-main-settings > .card-header > h5 {\r\n font-size: 20px;\n}\r\n", map: {"version":3,"sources":["C:\\Users\\maxim\\Projects\\dualbox\\editor\\js\\src\\v\\templates\\editMainSettings.vue"],"names":[],"mappings":";AACA;IACA,eAAA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,oBAAA;AACA;AAEA;IACA,WAAA;AACA;AAEA;IACA,iBAAA;AACA;AAEA;IACA,iBAAA;IACA,gBAAA;IACA,mBAAA;IACA,YAAA;AACA;AAEA;IACA,gBAAA;IACA,gBAAA;IACA,eAAA;AACA;AAEA;IACA,eAAA;AACA;AAEA;IACA,iBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,eAAA;AACA;AAEA;IACA,kBAAA;IACA,kBAAA;IACA,6BAAA;AACA;;AAEA,wCAAA;AACA;IACA,kCAAA;IACA,0BAAA;IACA,uBAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,6BAAA;AACA;AAEA;IACA,kBAAA;AACA;AAEA;IACA,kBAAA;AACA;AAEA;IACA,sBAAA;AACA;AAEA;IACA,0BAAA;IACA,6BAAA;AACA;AAEA;IACA,gCAAA;AACA;AAEA;IACA,0BAAA;IACA,6BAAA;AACA;AAEA;IACA,cAAA;IACA,kBAAA;IACA,iBAAA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;AACA;AAEA;IACA,cAAA;IACA,kBAAA;IACA,sBAAA;IACA,iBAAA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;AACA;AAEA;IACA,cAAA;IACA,kBAAA;IACA,sBAAA;IACA,iBAAA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;AACA;AAEA;IACA,oBAAA;AACA;AAEA;IACA,YAAA;AACA;AAEA;IACA,iBAAA;AACA;AAEA;IACA,kCAAA;AACA;AAEA;IACA,gBAAA;IACA,mBAAA;IACA,kBAAA;IACA,mBAAA;AACA;AAEA;IACA,eAAA;AACA","file":"editMainSettings.vue","sourcesContent":["<style>\r\n.card-settings .card-body {\r\n font-size: 12px;\r\n padding-left: 5px;\r\n padding-right: 5px;\r\n}\r\n\r\n.fa {\r\n pointer-events: none;\r\n}\r\n\r\n.table-desc {\r\n width: 100%;\r\n}\r\n\r\n.table-desc > thead > th > td {\r\n margin-right: 6px;\r\n}\r\n\r\n.table-desc > tbody > tr > td {\r\n margin-right: 6px;\r\n padding-top: 8px;\r\n padding-bottom: 8px;\r\n height: 40px;\r\n}\r\n\r\n.application-description {\r\n margin-top: 20px;\r\n text-align: left;\r\n font-size: 12px;\r\n}\r\n\r\n.card-header[data-toggle=\"collapse\"] {\r\n cursor: pointer;\r\n}\r\n\r\n.card-header[data-toggle=\"collapse\"] h5 {\r\n user-select: none;\r\n}\r\n\r\n.card-header[data-toggle=\"collapse\"]:hover .btn-link {\r\n text-decoration: none;\r\n}\r\n\r\n.text-value, .number-value, .boolean-value {\r\n max-width: 140px;\r\n}\r\n\r\n.select-event-target, .select-event-name, .event-if, .event-data {\r\n font-size: 12px;\r\n}\r\n\r\n.edit-body {\r\n overflow-y: hidden;\r\n overflow-x: hidden;\r\n max-height: calc(100% - 90px);\r\n}\r\n\r\n/* remove bs4 transition on collapsing */\r\n.edit-main-panel .collapsing {\r\n -webkit-transition: none!important;\r\n transition: none!important;\r\n display: none!important;\r\n}\r\n\r\n.table-events .event-rooting {\r\n margin-top: 10px;\r\n}\r\n\r\n.table-events thead {\r\n border-bottom: 1px solid #ddd;\r\n}\r\n\r\n.table-events .tr-event-condition td {\r\n padding-left: 10px;\r\n}\r\n\r\n.table-events .tr-event-data td {\r\n padding-left: 10px;\r\n}\r\n\r\n.tr-event-condition td, .tr-event-data td {\r\n height: 20px!important;\r\n}\r\n\r\n.tr-event-condition, .tr-event-condition td, .tr-event-data, .tr-event-data td {\r\n padding-top: 1px!important;\r\n padding-bottom: 1px!important;\r\n}\r\n\r\n.table-events tr + .event-rooting {\r\n /* border-top: 1px solid #ddd; */\r\n}\r\n\r\n.event-rooting td {\r\n padding-top: 8px!important;\r\n padding-bottom: 4px!important;\r\n}\r\n\r\n.event-data-type {\r\n font-size: 75%;\r\n border-radius: 5px;\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-top: 2px;\r\n padding-bottom: 2px;\r\n}\r\n\r\n.event-data-display {\r\n font-size: 75%;\r\n border-radius: 5px;\r\n border: 1px solid #ddd;\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-top: 2px;\r\n padding-bottom: 2px;\r\n}\r\n\r\n.event-if {\r\n font-size: 75%;\r\n border-radius: 5px;\r\n border: 1px solid #ddd;\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-top: 2px;\r\n padding-bottom: 2px;\r\n}\r\n\r\ni.fa, i.fas, i.far {\r\n pointer-events: none;\r\n}\r\n\r\n.h100 {\r\n height: 100%;\r\n}\r\n\r\n.card-app-event > .card-header {\r\n padding: 6px 12px;\r\n}\r\n\r\n.card-main-settings {\r\n border: 1px solid rgba(0,0,0,.125);\r\n}\r\n\r\n.card-main-settings > .card-header {\r\n padding-top: 6px;\r\n padding-bottom: 6px;\r\n padding-left: 12px;\r\n padding-right: 12px;\r\n}\r\n\r\n.card-main-settings > .card-header > h5 {\r\n font-size: 20px;\r\n}\r\n</style>\r\n\r\n<template>\r\n\r\n<div class=\"edit-main-panel h100\" id=\"edit-main-panel\">\r\n <div class=\"edit-main-presentation\" style=\"padding-left: 10px; padding-top: 10px; padding-right: 10px; padding-bottom 10px;\">\r\n <h2 class=\"edit-dualbox-app\" style=\"margin-bottom: none;\">\r\n <div class=\"dualbox-node-name\">\r\n <span class=\"text-truncate d-inline-block\" style=\"width: 290px\">Application</span>\r\n </div>\r\n </h2>\r\n </div>\r\n\r\n <div class=\"edit-body h100\">\r\n <!--\r\n <div class=\"card-main-settings\">\r\n <div class=\"card-header\" id=\"dualbox-main-desc\" data-toggle=\"collapse\" data-target=\"#dualbox-main-desc-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-main-desc-collapse\">\r\n <h5 class=\"mb-0 btn-link\">Description</h5>\r\n </div>\r\n\r\n\r\n <div id=\"dualbox-main-desc-collapse\" class=\"collapse show\" aria-labelledby=\"dualbox-main-desc\" data-parent=\"#edit-main-panel\">\r\n <div class=\"card-body\">\r\n <p class=\"application-description\">{{ app.getDescription() || \"[No description available]\" }} <button class=\"btn btn-editor-xs btn-light btn-edit-app-description\" @click=\"editAppDescription\"><i class=\"fa fa-edit\"></i></button></p>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n -->\r\n <div class=\"card-main-settings\">\r\n <div class=\"card-header\" id=\"dualbox-main-events\" data-toggle=\"collapse\" data-target=\"#dualbox-main-events-collapse\" aria-expanded=\"true\" aria-controls=\"dualbox-main-events-collapse\">\r\n <h5 class=\"mb-0 btn-link\">Events</h5>\r\n </div>\r\n\r\n <div id=\"dualbox-main-events-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-main-events\" data-parent=\"#edit-main-panel\">\r\n <div class=\"card-body\" style=\"padding-left: 4px; padding-right: 4px;\">\r\n <button class=\"btn btn-success btn-sm btn-add-app-event mb-3\" @click=\"addAppEvent\">Add application event</button>\r\n <div v-for=\"key in app.getEventsNames()\" class=\"card card-app-event\" :key=\"'app-event-' + key\">\r\n <div class=\"card-header\" :id=\"'dualbox-event-' + key\" data-toggle=\"collapse\" :data-target=\"'#dualbox-event-' + key + '-collapse'\" aria-expanded=\"false\" aria-controls=\"'dualbox-event-' + key + '-collapse'\">\r\n <h5 class=\"mb-0 btn-link\" style=\"font-size: 16px; font-weight: normal;\">\r\n {{key}}\r\n <div class=\"float-right d-inline-block\">\r\n <button class=\"btn btn-light btn-editor-xs btn-rename-app-event\" :data-event=\"key\" @click=\"renameAppEvent\">\r\n <i class=\"fa fa-edit\"></i>\r\n </button>\r\n <button class=\"btn btn-danger btn-editor-xs btn-remove-app-event\" :data-event=\"key\" @click=\"removeAppEvent\">\r\n <i class=\"fa fa-minus\"></i>\r\n </button>\r\n </div>\r\n </h5>\r\n </div>\r\n\r\n <div :id=\"'dualbox-event-'+ key + '-collapse'\" class=\"collapse\" :aria-labelledby=\"'dualbox-event-' + key\" data-parent=\"#dualbox-main-events\">\r\n <div class=\"card-body\" style=\"padding-left: 4px; padding-right: 4px;\">\r\n <h5 style=\"font-size: 16px; text-decoration: underline; font-weight: normal;\">Description</h5>\r\n <p>{{ app.getEventDescription(key) || \"[no description available]\" }} <button class=\"btn btn-editor-xs btn-light btn-edit-event-description\" :data-event=\"key\" @click=\"editEventDescription\"><i class=\"fa fa-edit\"></i></button></p>\r\n <h5 class=\"mt-3\" style=\"font-size: 16px; text-decoration: underline; font-weight: normal;\">Triggers</h5>\r\n\r\n <table class=\"table-events table-desc\" style=\"font-size: 12px!important;\">\r\n <thead class=\"thead-dark\">\r\n <th>Target</th>\r\n <th>Event</th>\r\n <!--<th>If</th>-->\r\n <!--<th>Data</th>-->\r\n <th>Action</th>\r\n </thead>\r\n <tbody>\r\n <template v-for=\"(evt,index) in app.getEventIn(key)\" :data-index=\"index\">\r\n <tr class=\"event-rooting\">\r\n <td>\r\n <select v-if=\"evt.node !== undefined\" class=\"form-control form-control-sm select-event-target\" dualbox-target=\"events-in\" :data-event=\"key\" :data-index=\"index\" @change=\"selectEventTarget\">\r\n <option v-for=\"node in getNodesWithInEvents()\" :value=\"node.getGraphId()\" :selected=\"node.getGraphId()==evt.node\" :key=\"'event-in-target-' + node.getGraphId()\">{{node.getGraphId()}}</option>\r\n </select>\r\n <span v-else>{{evt.selector}}</span>\r\n </td>\r\n <td>\r\n <select class=\"form-control form-control-sm select-event-name\" dualbox-target=\"events-in\" :data-event=\"key\" :data-index=\"index\" @change=\"selectEventName\" >\r\n <template v-if=\"evt.node\">\r\n <option v-for=\"te in getNodeInEvents(evt.node)\" :value=\"te\" :selected=\"te == evt.event\" :key=\"'app-event-in-target-' + evt.node + '-' + te\">{{te}}</option>\r\n </template>\r\n <template v-else>\r\n <option value=\"hide\">hide</option>\r\n <option value=\"show\">show</option>\r\n </template>\r\n </select>\r\n </td>\r\n <td style=\"min-width: 58px;\">\r\n <button class=\"btn btn-secondary btn-editor-xs\" :data-event=\"key\" :data-index=\"index\" @click=\"toggleAdvancedAppEventSettings\" style=\"margin-left: 10px;\" title=\"Toggle advanced event settings\" >\r\n <i class=\"fas fa-cog\"></i>\r\n </button>\r\n <button class=\"btn btn-danger btn-editor-xs\" :data-event=\"key\" :data-index=\"index\" @click=\"removeInEvent\" >\r\n <i class=\"fas fa-minus\"></i>\r\n </button>\r\n </td>\r\n </tr>\r\n <tr v-if=\"evt.if || expanded[key+'##'+index]\" class=\"tr-event-condition\">\r\n <td colspan=\"3\">\r\n <span style=\"width: 60px; display: inline-block;\"><i class=\"fas fa-caret-right\"></i> Occur if:</span>\r\n\r\n <input style=\"max-width: 340px; width: 340px;\" class=\"form-control form-control-sm event-if d-inline-block\" type=\"text\" dualbox-target=\"events-in\" :data-event=\"key\" :data-index=\"index\" :value=\"evt.if\" @change=\"setEventIf\" />\r\n </td>\r\n </tr>\r\n <tr v-if=\"evt.data || evt.datatype || expanded[key+'##'+index]\" class=\"tr-event-data\" colspan=\"3\">\r\n <td colspan=\"3\">\r\n <span style=\"width: 53px; display: inline-block;\"><i class=\"fas fa-caret-right\"></i> Data:</span>\r\n <span style=\"width: 350px;\">\r\n <display-type :type=\"getDataType(evt)\" @edited=\"onEditEventInDataType(key, index, $event)\"></display-type>\r\n <display-value :v=\"evt.data\" :type=\"getDataType(evt)\" cssWidth=\"auto\" @edited=\"onEditEventInData(key, index, $event)\"></display-value>\r\n </span>\r\n </td>\r\n </tr>\r\n </template>\r\n <tr>\r\n <td colspan=\"5\" style=\"padding-top: 0px; padding-bottom: 0px;\">\r\n <button class=\"btn btn-secondary btn-sm btn-add-subevent\" style=\"width: 100%;\" @click=\"addSubEvent(key)\">Add a subevent</button>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <h5 class=\"mt-3\" style=\"font-size: 16px; text-decoration: underline; font-weight: normal;\">Callback</h5>\r\n\r\n <table class=\"table-desc table-striped\" style=\"font-size: 12px!important;\">\r\n <thead class=\"thead-dark\">\r\n <th>Target</th>\r\n <th>Event</th>\r\n <th>Action</th>\r\n </thead>\r\n <tbody>\r\n <tr v-if=\"app.getEventOut(key) !== undefined\">\r\n <td>\r\n <select class=\"form-control form-control-sm select-event-target select-callback-target\" dualbox-target=\"events-out\" @change=\"setCallback(key)\">\r\n <option v-for=\"node in getNodesWithOutEvents()\" :value=\"node.getGraphId()\" :selected=\"node.getGraphId()===app.getEventOut(key).node\" :key=\"'app-event-out-target-' + node.getGraphId()\">{{ node.getGraphId() }}</option>\r\n </select>\r\n </td>\r\n <td>\r\n <select class=\"form-control form-control-sm select-event-name select-callback-event\" dualbox-target=\"events-out\">\r\n <template v-if=\"app.getEventOut(key).node\" @change=\"setCallback(key)\">\r\n <option v-for=\"(te, index) in getNodeOutEvents(app.getEventOut(key).node)\" :value=\"te\" :selected=\"te == app.getEventOut(key).event\" :key=\"'app-event-out-' + index\">{{te}}</option>\r\n </template>\r\n </select>\r\n </td>\r\n <td>\r\n <button class=\"btn btn-danger btn-editor-xs btn-remove-out-event\" :data-event=\"key\" @click=\"removeOutEvent\">\r\n <i class=\"fa fa-minus\"></i>\r\n </button>\r\n </td>\r\n </tr>\r\n <tr v-else>\r\n <td colspan=\"3\" style=\"padding-top: 0px; padding-bottom: 0px;\">\r\n <button class=\"btn btn-sm btn-add-callback\" style=\"width: 100%;\" @click=\"addCallback(key)\">Add a callback</button>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"modal edit-value-modal\" tabindex=\"-1\" role=\"dialog\">\r\n <div class=\"modal-dialog\" role=\"document\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h5 class=\"modal-title\">Edit value</h5>\r\n <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\">×</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div>\r\n <div class=\"form-check\">\r\n <input type=\"radio\" class=\"form-check-input set-value unset-value\" id=\"unset-value\" name=\"set-value\" value=\"unset-value\" checked>\r\n <label class=\"form-check-label\" for=\"unset-value\">\r\n don't set a value\r\n </label>\r\n </div>\r\n <div class=\"form-check\">\r\n <input type=\"radio\" class=\"form-check-input set-value set-value-null\" id=\"set-value-null\" name=\"set-value\" value=\"set-value-null\">\r\n <label class=\"form-check-label\" for=\"set-value-null\">\r\n set null\r\n </label>\r\n </div>\r\n <div class=\"form-check\">\r\n <input type=\"radio\" class=\"form-check-input set-value set-value-type\" id=\"set-value-type\" name=\"set-value\" value=\"set-value-type\" aria-label=\"Set a value of type\">\r\n <div class=\"form-inline form-check-label\" style=\"height: 24px;\">\r\n <label for=\"set-value-type\">\r\n set a value of type:\r\n <select class=\"form-control choose-value-type d-inline-block form-control-sm ml-2\">\r\n <option value=\"string\">String</option>\r\n <option value=\"number\">Number</option>\r\n <option value=\"boolean\">Boolean</option>\r\n <option value=\"object\">Object</option>\r\n </select>\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"has-value\" style=\"display: none;\">\r\n <hr/>\r\n <div class=\"define-value define-boolean\" style=\"display: none;\">\r\n <div class=\"form-inline\">\r\n <label>Value: </label>\r\n <select class=\"form-control form-control-sm bool-value d-inline-block ml-2\">\r\n <option value=true>True</option>\r\n <option value=false>False</option>\r\n </select>\r\n </div>\r\n </div>\r\n <div class=\"define-value define-number\" style=\"display: none;\">\r\n <div class=\"form-inline\">\r\n <label>Value: </label>\r\n <input type=\"number\" class=\"form-control form-control-sm number-value ml-2\"/>\r\n </div>\r\n </div>\r\n <div class=\"define-value define-string\" style=\"display: none;\">\r\n <div class=\"form-inline\">\r\n <label>Value: </label>\r\n <input type=\"text\" class=\"form-control form-control-sm text-value ml-2\"/>\r\n </div>\r\n </div>\r\n <div class=\"define-value define-object\" style=\"display: none;\">\r\n <label>Value: </label>\r\n <div class=\"json-editor\" style=\"height: 400px;\"></div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-primary btn-save\">Save changes</button>\r\n <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Close</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n</template>\r\n\r\n<script>\r\nimport _ from 'lodash-es';\r\nimport swal from 'sweetalert2';\r\nimport DisplayTypeVue from './displayType.vue';\r\nimport DisplayValueVue from './displayValue.vue';\r\n\r\nexport default {\r\n props: [\r\n \"app\"\r\n ],\r\n components: {\r\n \"display-type\" : DisplayTypeVue,\r\n \"display-value\" : DisplayValueVue,\r\n },\r\n data: function () {\r\n return {\r\n expanded: {} // expanded app events (advanced settings)\r\n };\r\n },\r\n created: function() {\r\n this.view = window.dualboxEditor.v;\r\n },\r\n mounted: function() {\r\n // bind tooltips\r\n $(this.$el).find('button[data-toggle=\"tooltip\"]').tooltip();\r\n this.fixMaxHeightForCategories();\r\n },\r\n updated: function() {\r\n this.fixMaxHeightForCategories();\r\n },\r\n methods: {\r\n // setup a max height for each menu, so a scroll appears if there's too much item in it\r\n fixMaxHeightForCategories : function() {\r\n let nbActiveCategories = $(this.$el).find('.edit-body > .card').length;\r\n let headerHeight = $(this.$el).find('.edit-body > .card > .card-header').outerHeight();\r\n let panelHeight = $(this.$el).height() - $(this.$el).find('.edit-main-presentation').outerHeight();\r\n let maxCategoryHeight = panelHeight - nbActiveCategories * headerHeight;\r\n $(this.$el).find('.edit-body').css('height', panelHeight);\r\n $(this.$el).find('.edit-body > .card > .collapse > .card-body').css('max-height', maxCategoryHeight + \"px\");\r\n },\r\n\r\n onEdited: function() {\r\n this.view.repaint();\r\n },\r\n\r\n getNodesWithInEvents: function() {\r\n var l = [];\r\n var nodes = this.view.m.getNodes(\"ui\");\r\n _.each(nodes, (n) => {\r\n if( n.getInEventsNames().length > 0 ) {\r\n l.push(n);\r\n }\r\n });\r\n return l;\r\n },\r\n\r\n getNodesWithOutEvents: function() {\r\n var l = [];\r\n var nodes = this.view.m.getNodes(\"ui\");\r\n _.each(nodes, (n) => {\r\n if( n.getOutEventsNames().length > 0 ) {\r\n l.push(n);\r\n }\r\n });\r\n return l;\r\n },\r\n\r\n getNodeEvents: function( nodeId ) {\r\n var node = this.view.m.getNode(nodeId);\r\n return node.getEventsNames();\r\n },\r\n\r\n getNodeInEvents: function( nodeId ) {\r\n var node = this.view.m.getNode(nodeId);\r\n return node.getInEventsNames();\r\n },\r\n\r\n getNodeOutEvents: function( nodeId ) {\r\n var node = this.view.m.getNode(nodeId);\r\n return node.getOutEventsNames();\r\n },\r\n\r\n editAppDescription: function() {\r\n swal({\r\n input: 'text',\r\n title: 'Enter the description',\r\n }).then((result) => {\r\n this.view.c.setAppDescription(result.value);\r\n });\r\n },\r\n\r\n editEventDescription: function(e) {\r\n var eventName = $(e.target).attr('data-event');\r\n\r\n swal({\r\n input: 'text',\r\n title: 'Enter the description',\r\n }).then((result) => {\r\n this.view.c.setAppEventDescription(eventName, result.value);\r\n });\r\n },\r\n\r\n removeAppEvent: function(e) {\r\n var name = $(e.target).attr('data-event');\r\n this.view.c.removeAppEvent(name);\r\n this.onEdited();\r\n },\r\n\r\n renameAppEvent: function(e) {\r\n var name = $(e.target).attr('data-event');\r\n swal({\r\n input: 'text',\r\n title: 'Enter the new event name',\r\n }).then((result) => {\r\n if( result.value ) {\r\n this.view.c.renameAppEvent(name, result.value);\r\n this.onEdited();\r\n }\r\n });\r\n },\r\n\r\n setEventIf: function(e) {\r\n var index = parseInt($(e.target).attr('data-index'));\r\n var val = $(e.target).val();\r\n this.view.c.setEventIf( \"#application-\" + $(e.target).attr('dualbox-target') + '-' + $(e.target).attr('data-event'), index, val);\r\n this.onEdited();\r\n },\r\n\r\n setEventData: function(e) {\r\n var index = parseInt($(e.target).attr('data-index'));\r\n var val = $(e.target).val();\r\n this.view.c.setEventData( \"#application-\" + $(e.target).attr('dualbox-target') + '-' + $(e.target).attr('data-event'), index, val);\r\n this.onEdited();\r\n },\r\n\r\n selectEventTarget: function(e) {\r\n var target = $(e.target).val();\r\n\r\n // change options of closest .select-event-name according to this new target\r\n var targetNode = this.view.m.getNode(target);\r\n var targetEvents = targetNode.getEventsNames();\r\n var select = $(e.target).closest('tr').find('.select-event-name');\r\n select.html('');\r\n _.each(targetEvents, (eventName) => {\r\n select.append( $('<option/>', {\r\n value: eventName\r\n }).append(eventName));\r\n });\r\n\r\n var index = parseInt($(e.target).attr('data-index'));\r\n this.view.c.setEventTarget( \"#application-\" + $(e.target).attr('dualbox-target') + '-' + $(e.target).attr('data-event'), index, target);\r\n this.onEdited();\r\n },\r\n\r\n selectEventName: function(e) {\r\n var index = parseInt($(e.target).attr('data-index'));\r\n var val = $(e.target).val();\r\n this.view.c.setEventName( \"#application-\" + $(e.target).attr('dualbox-target') + '-' + $(e.target).attr('data-event'), index, val );\r\n this.onEdited();\r\n },\r\n\r\n addCallback: function(appEventName) {\r\n var nodesWithOutEvents = this.getNodesWithOutEvents();\r\n if( nodesWithOutEvents.length > 0 ) {\r\n var firstNode = nodesWithOutEvents[0];\r\n var firstEvent = firstNode.getOutEventsNames()[0];\r\n this.setCallback(appEventName, firstNode, firstEvent);\r\n }\r\n else {\r\n swal({\r\n title: \"You can not add an API callback here\",\r\n text: \"None of the UIs of the application does have an OUT event, usable for API callbacks\",\r\n type: \"error\"\r\n })\r\n }\r\n },\r\n\r\n setCallback: function(appEventName, e) {\r\n var targetNodeId = $(this.$el).find('.select-callback-target').val();\r\n var targetNodeEvent = $(this.$el).find('.select-callback-event').val();\r\n this.view.c.setCallback(appEventName, targetNodeId, targetNodeEvent);\r\n this.onEdited();\r\n },\r\n\r\n addAppEvent: function(e) {\r\n swal({\r\n input: 'text',\r\n title: 'Enter the event name',\r\n }).then(async (result) => {\r\n await this.view.c.addAppEvent(result.value);\r\n this.onEdited();\r\n });\r\n },\r\n\r\n removeInEvent: function(e) {\r\n var eventName = $(e.target).attr('data-event');\r\n var index = parseInt($(e.target).attr('data-index'));\r\n this.view.c.removeAppInEvent(eventName, index);\r\n this.onEdited();\r\n },\r\n\r\n removeOutEvent: function(e) {\r\n var eventName = $(e.target).attr('data-event');\r\n this.view.c.removeAppOutEvent(eventName);\r\n this.onEdited();\r\n },\r\n\r\n addSubEvent: function(eventName) {\r\n this.view.c.addSubEvent(eventName);\r\n this.onEdited();\r\n },\r\n\r\n getDataType: function(evt) {\r\n if( evt.datatype ) {\r\n return evt.datatype;\r\n }\r\n else if( evt.data ) {\r\n return window.DualBox.Type.detectType(evt.data);\r\n }\r\n else {\r\n return undefined;\r\n }\r\n },\r\n\r\n toggleAdvancedAppEventSettings: function(e) {\r\n var key = $(e.target).data('event');\r\n var index = $(e.target).data('index');\r\n var k=key+'##'+index;\r\n this.expanded[k] = this.expanded[k] ? false : true;\r\n this.$forceUpdate();\r\n },\r\n\r\n onEditEventInData(key, index, val) {\r\n this.view.c.setEventData( \"#application-events-in-\" + key, index, val);\r\n this.$emit('edited');\r\n },\r\n\r\n onEditEventInDataType(key, index, type) {\r\n this.view.c.setEventDataType( \"#application-events-in-\" + key, index, type);\r\n\r\n // check that the set value still match the new type\r\n // delete it otherwise\r\n var val = this.app.getEventIn(key)[index].data;\r\n try {\r\n // TODO: ensure type is already loaded (after dualbox) and remove the try/catch\r\n if( !window.DualBox.Type.check(type, val) ) {\r\n // delete data (== set undefined)\r\n this.view.c.setEventData( \"#application-events-in-\" + key, index, undefined);\r\n }\r\n }\r\n catch(e) {\r\n this.view.c.setEventData( \"#application-events-in-\" + key, index, undefined);\r\n }\r\n\r\n this.$emit('edited');\r\n },\r\n }\r\n}\r\n</script>\r\n"]}, media: undefined });
|
|
67368
|
+
inject("data-v-3d749219_0", { source: "\n.card-settings .card-body {\r\n font-size: 12px;\r\n padding-left: 5px;\r\n padding-right: 5px;\n}\n.fa {\r\n pointer-events: none;\n}\n.table-desc {\r\n width: 100%;\n}\n.table-desc > thead > th > td {\r\n margin-right: 6px;\n}\n.table-desc > tbody > tr > td {\r\n margin-right: 6px;\r\n padding-top: 8px;\r\n padding-bottom: 8px;\r\n height: 40px;\n}\n.application-description {\r\n margin-top: 20px;\r\n text-align: left;\r\n font-size: 12px;\n}\n.card-header[data-toggle=\"collapse\"] {\r\n cursor: pointer;\n}\n.card-header[data-toggle=\"collapse\"] h5 {\r\n user-select: none;\n}\n.card-header[data-toggle=\"collapse\"]:hover .btn-link {\r\n text-decoration: none;\n}\n.text-value, .number-value, .boolean-value {\r\n max-width: 140px;\n}\n.select-event-target, .select-event-name, .event-if, .event-data {\r\n font-size: 12px;\n}\n.edit-body {\r\n overflow-y: hidden;\r\n overflow-x: hidden;\r\n max-height: calc(100% - 90px);\n}\r\n\r\n/* remove bs4 transition on collapsing */\n.edit-main-panel .collapsing {\r\n -webkit-transition: none!important;\r\n transition: none!important;\r\n display: none!important;\n}\n.table-events .event-rooting {\r\n margin-top: 10px;\n}\n.table-events thead {\r\n border-bottom: 1px solid #ddd;\n}\n.table-events .tr-event-condition td {\r\n padding-left: 10px;\n}\n.table-events .tr-event-data td {\r\n padding-left: 10px;\n}\n.tr-event-condition td, .tr-event-data td {\r\n height: 20px!important;\n}\n.tr-event-condition, .tr-event-condition td, .tr-event-data, .tr-event-data td {\r\n padding-top: 1px!important;\r\n padding-bottom: 1px!important;\n}\n.table-events tr + .event-rooting {\r\n /* border-top: 1px solid #ddd; */\n}\n.event-rooting td {\r\n padding-top: 8px!important;\r\n padding-bottom: 4px!important;\n}\n.event-data-type {\r\n font-size: 75%;\r\n border-radius: 5px;\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-top: 2px;\r\n padding-bottom: 2px;\n}\n.event-data-display {\r\n font-size: 75%;\r\n border-radius: 5px;\r\n border: 1px solid #ddd;\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-top: 2px;\r\n padding-bottom: 2px;\n}\n.event-if {\r\n font-size: 75%;\r\n border-radius: 5px;\r\n border: 1px solid #ddd;\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-top: 2px;\r\n padding-bottom: 2px;\n}\ni.fa, i.fas, i.far {\r\n pointer-events: none;\n}\n.h100 {\r\n height: 100%;\n}\n.card-app-event > .card-header {\r\n padding: 6px 12px;\n}\n.card-main-settings {\r\n border: 1px solid rgba(0,0,0,.125);\n}\n.card-main-settings > .card-header {\r\n padding-top: 6px;\r\n padding-bottom: 6px;\r\n padding-left: 12px;\r\n padding-right: 12px;\n}\n.card-main-settings > .card-header > h5 {\r\n font-size: 20px;\n}\r\n", map: {"version":3,"sources":["C:\\Users\\maxim\\Projects\\dualbox\\editor\\js\\src\\v\\templates\\editMainSettings.vue"],"names":[],"mappings":";AACA;IACA,eAAA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,oBAAA;AACA;AAEA;IACA,WAAA;AACA;AAEA;IACA,iBAAA;AACA;AAEA;IACA,iBAAA;IACA,gBAAA;IACA,mBAAA;IACA,YAAA;AACA;AAEA;IACA,gBAAA;IACA,gBAAA;IACA,eAAA;AACA;AAEA;IACA,eAAA;AACA;AAEA;IACA,iBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,eAAA;AACA;AAEA;IACA,kBAAA;IACA,kBAAA;IACA,6BAAA;AACA;;AAEA,wCAAA;AACA;IACA,kCAAA;IACA,0BAAA;IACA,uBAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,6BAAA;AACA;AAEA;IACA,kBAAA;AACA;AAEA;IACA,kBAAA;AACA;AAEA;IACA,sBAAA;AACA;AAEA;IACA,0BAAA;IACA,6BAAA;AACA;AAEA;IACA,gCAAA;AACA;AAEA;IACA,0BAAA;IACA,6BAAA;AACA;AAEA;IACA,cAAA;IACA,kBAAA;IACA,iBAAA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;AACA;AAEA;IACA,cAAA;IACA,kBAAA;IACA,sBAAA;IACA,iBAAA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;AACA;AAEA;IACA,cAAA;IACA,kBAAA;IACA,sBAAA;IACA,iBAAA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;AACA;AAEA;IACA,oBAAA;AACA;AAEA;IACA,YAAA;AACA;AAEA;IACA,iBAAA;AACA;AAEA;IACA,kCAAA;AACA;AAEA;IACA,gBAAA;IACA,mBAAA;IACA,kBAAA;IACA,mBAAA;AACA;AAEA;IACA,eAAA;AACA","file":"editMainSettings.vue","sourcesContent":["<style>\r\n.card-settings .card-body {\r\n font-size: 12px;\r\n padding-left: 5px;\r\n padding-right: 5px;\r\n}\r\n\r\n.fa {\r\n pointer-events: none;\r\n}\r\n\r\n.table-desc {\r\n width: 100%;\r\n}\r\n\r\n.table-desc > thead > th > td {\r\n margin-right: 6px;\r\n}\r\n\r\n.table-desc > tbody > tr > td {\r\n margin-right: 6px;\r\n padding-top: 8px;\r\n padding-bottom: 8px;\r\n height: 40px;\r\n}\r\n\r\n.application-description {\r\n margin-top: 20px;\r\n text-align: left;\r\n font-size: 12px;\r\n}\r\n\r\n.card-header[data-toggle=\"collapse\"] {\r\n cursor: pointer;\r\n}\r\n\r\n.card-header[data-toggle=\"collapse\"] h5 {\r\n user-select: none;\r\n}\r\n\r\n.card-header[data-toggle=\"collapse\"]:hover .btn-link {\r\n text-decoration: none;\r\n}\r\n\r\n.text-value, .number-value, .boolean-value {\r\n max-width: 140px;\r\n}\r\n\r\n.select-event-target, .select-event-name, .event-if, .event-data {\r\n font-size: 12px;\r\n}\r\n\r\n.edit-body {\r\n overflow-y: hidden;\r\n overflow-x: hidden;\r\n max-height: calc(100% - 90px);\r\n}\r\n\r\n/* remove bs4 transition on collapsing */\r\n.edit-main-panel .collapsing {\r\n -webkit-transition: none!important;\r\n transition: none!important;\r\n display: none!important;\r\n}\r\n\r\n.table-events .event-rooting {\r\n margin-top: 10px;\r\n}\r\n\r\n.table-events thead {\r\n border-bottom: 1px solid #ddd;\r\n}\r\n\r\n.table-events .tr-event-condition td {\r\n padding-left: 10px;\r\n}\r\n\r\n.table-events .tr-event-data td {\r\n padding-left: 10px;\r\n}\r\n\r\n.tr-event-condition td, .tr-event-data td {\r\n height: 20px!important;\r\n}\r\n\r\n.tr-event-condition, .tr-event-condition td, .tr-event-data, .tr-event-data td {\r\n padding-top: 1px!important;\r\n padding-bottom: 1px!important;\r\n}\r\n\r\n.table-events tr + .event-rooting {\r\n /* border-top: 1px solid #ddd; */\r\n}\r\n\r\n.event-rooting td {\r\n padding-top: 8px!important;\r\n padding-bottom: 4px!important;\r\n}\r\n\r\n.event-data-type {\r\n font-size: 75%;\r\n border-radius: 5px;\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-top: 2px;\r\n padding-bottom: 2px;\r\n}\r\n\r\n.event-data-display {\r\n font-size: 75%;\r\n border-radius: 5px;\r\n border: 1px solid #ddd;\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-top: 2px;\r\n padding-bottom: 2px;\r\n}\r\n\r\n.event-if {\r\n font-size: 75%;\r\n border-radius: 5px;\r\n border: 1px solid #ddd;\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-top: 2px;\r\n padding-bottom: 2px;\r\n}\r\n\r\ni.fa, i.fas, i.far {\r\n pointer-events: none;\r\n}\r\n\r\n.h100 {\r\n height: 100%;\r\n}\r\n\r\n.card-app-event > .card-header {\r\n padding: 6px 12px;\r\n}\r\n\r\n.card-main-settings {\r\n border: 1px solid rgba(0,0,0,.125);\r\n}\r\n\r\n.card-main-settings > .card-header {\r\n padding-top: 6px;\r\n padding-bottom: 6px;\r\n padding-left: 12px;\r\n padding-right: 12px;\r\n}\r\n\r\n.card-main-settings > .card-header > h5 {\r\n font-size: 20px;\r\n}\r\n</style>\r\n\r\n<template>\r\n\r\n<div class=\"edit-main-panel h100\" id=\"edit-main-panel\">\r\n <div class=\"edit-main-presentation\" style=\"padding-left: 10px; padding-top: 10px; padding-right: 10px; padding-bottom 10px;\">\r\n <h2 class=\"edit-dualbox-app\" style=\"margin-bottom: none;\">\r\n <div class=\"dualbox-node-name\">\r\n <span class=\"text-truncate d-inline-block\" style=\"width: 290px\">Application</span>\r\n </div>\r\n </h2>\r\n </div>\r\n\r\n <div class=\"edit-body h100\">\r\n <!--\r\n <div class=\"card-main-settings\">\r\n <div class=\"card-header\" id=\"dualbox-main-desc\" data-toggle=\"collapse\" data-target=\"#dualbox-main-desc-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-main-desc-collapse\">\r\n <h5 class=\"mb-0 btn-link\">Description</h5>\r\n </div>\r\n\r\n\r\n <div id=\"dualbox-main-desc-collapse\" class=\"collapse show\" aria-labelledby=\"dualbox-main-desc\" data-parent=\"#edit-main-panel\">\r\n <div class=\"card-body\">\r\n <p class=\"application-description\">{{ app.getDescription() || \"[No description available]\" }} <button class=\"btn btn-editor-xs btn-light btn-edit-app-description\" @click=\"editAppDescription\"><i class=\"fa fa-edit\"></i></button></p>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n -->\r\n <div class=\"card-main-settings\">\r\n <div class=\"card-header\" id=\"dualbox-main-events\" data-toggle=\"collapse\" data-target=\"#dualbox-main-events-collapse\" aria-expanded=\"true\" aria-controls=\"dualbox-main-events-collapse\">\r\n <h5 class=\"mb-0 btn-link\">Events</h5>\r\n </div>\r\n\r\n <div id=\"dualbox-main-events-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-main-events\" data-parent=\"#edit-main-panel\">\r\n <div class=\"card-body\" style=\"padding-left: 4px; padding-right: 4px;\">\r\n <button class=\"btn btn-success btn-sm btn-add-app-event mb-3\" @click=\"addAppEvent\">Add application event</button>\r\n <div v-for=\"key in app.getEventsNames()\" class=\"card card-app-event\" :key=\"'app-event-' + key\">\r\n <div class=\"card-header\" :id=\"'dualbox-event-' + key\" data-toggle=\"collapse\" :data-target=\"'#dualbox-event-' + key + '-collapse'\" aria-expanded=\"false\" aria-controls=\"'dualbox-event-' + key + '-collapse'\">\r\n <h5 class=\"mb-0 btn-link\" style=\"font-size: 16px; font-weight: normal;\">\r\n {{key}}\r\n <div class=\"float-right d-inline-block\">\r\n <button class=\"btn btn-light btn-editor-xs btn-rename-app-event\" :data-event=\"key\" @click=\"renameAppEvent\">\r\n <i class=\"fa fa-edit\"></i>\r\n </button>\r\n <button class=\"btn btn-danger btn-editor-xs btn-remove-app-event\" :data-event=\"key\" @click=\"removeAppEvent\">\r\n <i class=\"fa fa-minus\"></i>\r\n </button>\r\n </div>\r\n </h5>\r\n </div>\r\n\r\n <div :id=\"'dualbox-event-'+ key + '-collapse'\" class=\"collapse\" :aria-labelledby=\"'dualbox-event-' + key\" data-parent=\"#dualbox-main-events\">\r\n <div class=\"card-body\" style=\"padding-left: 4px; padding-right: 4px;\">\r\n <h5 style=\"font-size: 16px; text-decoration: underline; font-weight: normal;\">Description</h5>\r\n <p>{{ app.getEventDescription(key) || \"[no description available]\" }} <button class=\"btn btn-editor-xs btn-light btn-edit-event-description\" :data-event=\"key\" @click=\"editEventDescription\"><i class=\"fa fa-edit\"></i></button></p>\r\n <h5 class=\"mt-3\" style=\"font-size: 16px; text-decoration: underline; font-weight: normal;\">Triggers</h5>\r\n\r\n <table class=\"table-events table-desc\" style=\"font-size: 12px!important;\">\r\n <thead class=\"thead-dark\">\r\n <th>Target</th>\r\n <th>Event</th>\r\n <!--<th>If</th>-->\r\n <!--<th>Data</th>-->\r\n <th>Action</th>\r\n </thead>\r\n <tbody>\r\n <template v-for=\"(evt,index) in app.getEventIn(key)\" :data-index=\"index\">\r\n <tr class=\"event-rooting\">\r\n <td>\r\n <select v-if=\"evt.node !== undefined\" class=\"form-control form-control-sm select-event-target\" dualbox-target=\"events-in\" :data-event=\"key\" :data-index=\"index\" @change=\"selectEventTarget\">\r\n <option v-for=\"node in getNodesWithInEvents()\" :value=\"node.getGraphId()\" :selected=\"node.getGraphId()==evt.node\" :key=\"'event-in-target-' + node.getGraphId()\">{{node.getGraphId()}}</option>\r\n </select>\r\n <span v-else>{{evt.selector}}</span>\r\n </td>\r\n <td>\r\n <select class=\"form-control form-control-sm select-event-name\" dualbox-target=\"events-in\" :data-event=\"key\" :data-index=\"index\" @change=\"selectEventName\" >\r\n <template v-if=\"evt.node\">\r\n <option v-for=\"te in getNodeInEvents(evt.node)\" :value=\"te\" :selected=\"te == evt.event\" :key=\"'app-event-in-target-' + evt.node + '-' + te\">{{te}}</option>\r\n </template>\r\n <template v-else>\r\n <option value=\"hide\">hide</option>\r\n <option value=\"show\">show</option>\r\n </template>\r\n </select>\r\n </td>\r\n <td style=\"min-width: 58px;\">\r\n <button class=\"btn btn-secondary btn-editor-xs\" :data-event=\"key\" :data-index=\"index\" @click=\"toggleAdvancedAppEventSettings\" style=\"margin-left: 10px;\" title=\"Toggle advanced event settings\" >\r\n <i class=\"fas fa-cog\"></i>\r\n </button>\r\n <button class=\"btn btn-danger btn-editor-xs\" :data-event=\"key\" :data-index=\"index\" @click=\"removeInEvent\" >\r\n <i class=\"fas fa-minus\"></i>\r\n </button>\r\n </td>\r\n </tr>\r\n <tr v-if=\"evt.if || expanded[key+'##'+index]\" class=\"tr-event-condition\">\r\n <td colspan=\"3\">\r\n <span style=\"width: 60px; display: inline-block;\"><i class=\"fas fa-caret-right\"></i> Occur if:</span>\r\n\r\n <input style=\"max-width: 340px; width: 340px;\" class=\"form-control form-control-sm event-if d-inline-block\" type=\"text\" dualbox-target=\"events-in\" :data-event=\"key\" :data-index=\"index\" :value=\"evt.if\" @change=\"setEventIf\" />\r\n </td>\r\n </tr>\r\n <tr v-if=\"evt.data || evt.datatype || expanded[key+'##'+index]\" class=\"tr-event-data\" colspan=\"3\">\r\n <td colspan=\"3\">\r\n <span style=\"width: 53px; display: inline-block;\"><i class=\"fas fa-caret-right\"></i> Data:</span>\r\n <span style=\"width: 350px;\">\r\n <display-type :type=\"getDataType(evt)\" @edited=\"onEditEventInDataType(key, index, $event)\"></display-type>\r\n <display-value :v=\"evt.data\" :type=\"getDataType(evt)\" cssWidth=\"auto\" @edited=\"onEditEventInData(key, index, $event)\"></display-value>\r\n </span>\r\n </td>\r\n </tr>\r\n </template>\r\n <tr>\r\n <td colspan=\"5\" style=\"padding-top: 0px; padding-bottom: 0px;\">\r\n <button class=\"btn btn-secondary btn-sm btn-add-subevent\" style=\"width: 100%;\" @click=\"addSubEvent(key)\">Add a subevent</button>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <h5 class=\"mt-3\" style=\"font-size: 16px; text-decoration: underline; font-weight: normal;\">Callback</h5>\r\n\r\n <table class=\"table-desc table-striped\" style=\"font-size: 12px!important;\">\r\n <thead class=\"thead-dark\">\r\n <th>Target</th>\r\n <th>Event</th>\r\n <th>Action</th>\r\n </thead>\r\n <tbody>\r\n <tr v-if=\"app.getEventOut(key) !== undefined\">\r\n <td>\r\n <select class=\"form-control form-control-sm select-event-target select-callback-target\" dualbox-target=\"events-out\" @change=\"setCallback(key)\">\r\n <option v-for=\"node in getNodesWithOutEvents()\" :value=\"node.getGraphId()\" :selected=\"node.getGraphId()===app.getEventOut(key).node\" :key=\"'app-event-out-target-' + node.getGraphId()\">{{ node.getGraphId() }}</option>\r\n </select>\r\n </td>\r\n <td>\r\n <select class=\"form-control form-control-sm select-event-name select-callback-event\" dualbox-target=\"events-out\">\r\n <template v-if=\"app.getEventOut(key).node\" @change=\"setCallback(key)\">\r\n <option v-for=\"(te, index) in getNodeOutEvents(app.getEventOut(key).node)\" :value=\"te\" :selected=\"te == app.getEventOut(key).event\" :key=\"'app-event-out-' + index\">{{te}}</option>\r\n </template>\r\n </select>\r\n </td>\r\n <td>\r\n <button class=\"btn btn-danger btn-editor-xs btn-remove-out-event\" :data-event=\"key\" @click=\"removeOutEvent\">\r\n <i class=\"fa fa-minus\"></i>\r\n </button>\r\n </td>\r\n </tr>\r\n <tr v-else>\r\n <td colspan=\"3\" style=\"padding-top: 0px; padding-bottom: 0px;\">\r\n <button class=\"btn btn-sm btn-add-callback\" style=\"width: 100%;\" @click=\"addCallback(key)\">Add a callback</button>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"modal edit-value-modal\" tabindex=\"-1\" role=\"dialog\">\r\n <div class=\"modal-dialog\" role=\"document\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h5 class=\"modal-title\">Edit value</h5>\r\n <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\">×</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div>\r\n <div class=\"form-check\">\r\n <input type=\"radio\" class=\"form-check-input set-value unset-value\" id=\"unset-value\" name=\"set-value\" value=\"unset-value\" checked>\r\n <label class=\"form-check-label\" for=\"unset-value\">\r\n don't set a value\r\n </label>\r\n </div>\r\n <div class=\"form-check\">\r\n <input type=\"radio\" class=\"form-check-input set-value set-value-null\" id=\"set-value-null\" name=\"set-value\" value=\"set-value-null\">\r\n <label class=\"form-check-label\" for=\"set-value-null\">\r\n set null\r\n </label>\r\n </div>\r\n <div class=\"form-check\">\r\n <input type=\"radio\" class=\"form-check-input set-value set-value-type\" id=\"set-value-type\" name=\"set-value\" value=\"set-value-type\" aria-label=\"Set a value of type\">\r\n <div class=\"form-inline form-check-label\" style=\"height: 24px;\">\r\n <label for=\"set-value-type\">\r\n set a value of type:\r\n <select class=\"form-control choose-value-type d-inline-block form-control-sm ml-2\">\r\n <option value=\"string\">String</option>\r\n <option value=\"number\">Number</option>\r\n <option value=\"boolean\">Boolean</option>\r\n <option value=\"object\">Object</option>\r\n </select>\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"has-value\" style=\"display: none;\">\r\n <hr/>\r\n <div class=\"define-value define-boolean\" style=\"display: none;\">\r\n <div class=\"form-inline\">\r\n <label>Value: </label>\r\n <select class=\"form-control form-control-sm bool-value d-inline-block ml-2\">\r\n <option value=true>True</option>\r\n <option value=false>False</option>\r\n </select>\r\n </div>\r\n </div>\r\n <div class=\"define-value define-number\" style=\"display: none;\">\r\n <div class=\"form-inline\">\r\n <label>Value: </label>\r\n <input type=\"number\" class=\"form-control form-control-sm number-value ml-2\"/>\r\n </div>\r\n </div>\r\n <div class=\"define-value define-string\" style=\"display: none;\">\r\n <div class=\"form-inline\">\r\n <label>Value: </label>\r\n <input type=\"text\" class=\"form-control form-control-sm text-value ml-2\"/>\r\n </div>\r\n </div>\r\n <div class=\"define-value define-object\" style=\"display: none;\">\r\n <label>Value: </label>\r\n <div class=\"json-editor\" style=\"height: 400px;\"></div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-primary btn-save\">Save changes</button>\r\n <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Close</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n</template>\r\n\r\n<script>\r\nimport _ from 'lodash-es';\r\nimport swal from 'sweetalert2';\r\nimport DisplayTypeVue from './displayType.vue';\r\nimport DisplayValueVue from './displayValue.vue';\r\n\r\nexport default {\r\n props: [\r\n \"app\"\r\n ],\r\n components: {\r\n \"display-type\" : DisplayTypeVue,\r\n \"display-value\" : DisplayValueVue,\r\n },\r\n data: function () {\r\n return {\r\n expanded: {} // expanded app events (advanced settings)\r\n };\r\n },\r\n created: function() {\r\n this.view = window.dualboxEditor.v;\r\n },\r\n mounted: function() {\r\n // bind tooltips\r\n $(this.$el).find('button[data-toggle=\"tooltip\"]').tooltip();\r\n this.fixMaxHeightForCategories();\r\n },\r\n updated: function() {\r\n this.fixMaxHeightForCategories();\r\n },\r\n methods: {\r\n // setup a max height for each menu, so a scroll appears if there's too much item in it\r\n fixMaxHeightForCategories : function() {\r\n let nbActiveCategories = $(this.$el).find('.edit-body > .card').length;\r\n let headerHeight = $(this.$el).find('.edit-body > .card > .card-header').outerHeight();\r\n let panelHeight = $(this.$el).height() - $(this.$el).find('.edit-main-presentation').outerHeight();\r\n let maxCategoryHeight = panelHeight - nbActiveCategories * headerHeight;\r\n $(this.$el).find('.edit-body').css('height', panelHeight);\r\n $(this.$el).find('.edit-body > .card > .collapse > .card-body').css('max-height', maxCategoryHeight + \"px\");\r\n },\r\n\r\n onEdited: function() {\r\n this.view.repaint();\r\n },\r\n\r\n getNodesWithInEvents: function() {\r\n var l = [];\r\n var nodes = this.view.m.getNodes(\"ui\");\r\n _.each(nodes, (n) => {\r\n if( n.getInEventsNames().length > 0 ) {\r\n l.push(n);\r\n }\r\n });\r\n return l;\r\n },\r\n\r\n getNodesWithOutEvents: function() {\r\n var l = [];\r\n var nodes = this.view.m.getNodes(\"ui\");\r\n _.each(nodes, (n) => {\r\n if( n.getOutEventsNames().length > 0 ) {\r\n l.push(n);\r\n }\r\n });\r\n return l;\r\n },\r\n\r\n getNodeEvents: function( nodeId ) {\r\n var node = this.view.m.getNode(nodeId);\r\n return node.getEventsNames();\r\n },\r\n\r\n getNodeInEvents: function( nodeId ) {\r\n var node = this.view.m.getNode(nodeId);\r\n return node.getInEventsNames();\r\n },\r\n\r\n getNodeOutEvents: function( nodeId ) {\r\n var node = this.view.m.getNode(nodeId);\r\n return node.getOutEventsNames();\r\n },\r\n\r\n editAppDescription: function() {\r\n swal({\r\n input: 'text',\r\n title: 'Enter the description',\r\n }).then((result) => {\r\n this.view.c.setAppDescription(result.value);\r\n });\r\n },\r\n\r\n editEventDescription: function(e) {\r\n var eventName = $(e.target).attr('data-event');\r\n\r\n swal({\r\n input: 'text',\r\n title: 'Enter the description',\r\n }).then((result) => {\r\n this.view.c.setAppEventDescription(eventName, result.value);\r\n });\r\n },\r\n\r\n removeAppEvent: function(e) {\r\n var name = $(e.target).attr('data-event');\r\n this.view.c.removeAppEvent(name);\r\n this.onEdited();\r\n },\r\n\r\n renameAppEvent: function(e) {\r\n var name = $(e.target).attr('data-event');\r\n swal({\r\n input: 'text',\r\n title: 'Enter the new event name',\r\n }).then((result) => {\r\n if( result.value ) {\r\n this.view.c.renameAppEvent(name, result.value);\r\n this.onEdited();\r\n }\r\n });\r\n },\r\n\r\n setEventIf: function(e) {\r\n var index = parseInt($(e.target).attr('data-index'));\r\n var val = $(e.target).val();\r\n this.view.c.setEventIf( \"#application-\" + $(e.target).attr('dualbox-target') + '-' + $(e.target).attr('data-event'), index, val);\r\n this.onEdited();\r\n },\r\n\r\n setEventData: function(e) {\r\n var index = parseInt($(e.target).attr('data-index'));\r\n var val = $(e.target).val();\r\n this.view.c.setEventData( \"#application-\" + $(e.target).attr('dualbox-target') + '-' + $(e.target).attr('data-event'), index, val);\r\n this.onEdited();\r\n },\r\n\r\n selectEventTarget: function(e) {\r\n var target = $(e.target).val();\r\n\r\n // change options of closest .select-event-name according to this new target\r\n var targetNode = this.view.m.getNode(target);\r\n var targetEvents = targetNode.getEventsNames();\r\n var select = $(e.target).closest('tr').find('.select-event-name');\r\n select.html('');\r\n _.each(targetEvents, (eventName) => {\r\n select.append( $('<option/>', {\r\n value: eventName\r\n }).append(eventName));\r\n });\r\n\r\n var index = parseInt($(e.target).attr('data-index'));\r\n\r\n // set event target\r\n this.view.c.setEventTarget( \"#application-\" + $(e.target).attr('dualbox-target') + '-' + $(e.target).attr('data-event'), index, target);\r\n\r\n // also set event name, to ensure we don't have a set event that doesn't exist on this node\r\n this.view.c.setEventName( \"#application-\" + $(e.target).attr('dualbox-target') + '-' + $(e.target).attr('data-event'), index, targetEvents[0]);\r\n this.onEdited();\r\n },\r\n\r\n selectEventName: function(e) {\r\n var index = parseInt($(e.target).attr('data-index'));\r\n var val = $(e.target).val();\r\n this.view.c.setEventName( \"#application-\" + $(e.target).attr('dualbox-target') + '-' + $(e.target).attr('data-event'), index, val );\r\n this.onEdited();\r\n },\r\n\r\n addCallback: function(appEventName) {\r\n var nodesWithOutEvents = this.getNodesWithOutEvents();\r\n if( nodesWithOutEvents.length > 0 ) {\r\n var firstNode = nodesWithOutEvents[0];\r\n var firstEvent = firstNode.getOutEventsNames()[0];\r\n this.setCallback(appEventName, firstNode, firstEvent);\r\n }\r\n else {\r\n swal({\r\n title: \"You can not add an API callback here\",\r\n text: \"None of the UIs of the application does have an OUT event, usable for API callbacks\",\r\n type: \"error\"\r\n })\r\n }\r\n },\r\n\r\n setCallback: function(appEventName, e) {\r\n var targetNodeId = $(this.$el).find('.select-callback-target').val();\r\n var targetNodeEvent = $(this.$el).find('.select-callback-event').val();\r\n this.view.c.setCallback(appEventName, targetNodeId, targetNodeEvent);\r\n this.onEdited();\r\n },\r\n\r\n addAppEvent: function(e) {\r\n swal({\r\n input: 'text',\r\n title: 'Enter the event name',\r\n }).then(async (result) => {\r\n await this.view.c.addAppEvent(result.value);\r\n this.onEdited();\r\n });\r\n },\r\n\r\n removeInEvent: function(e) {\r\n var eventName = $(e.target).attr('data-event');\r\n var index = parseInt($(e.target).attr('data-index'));\r\n this.view.c.removeAppInEvent(eventName, index);\r\n this.onEdited();\r\n },\r\n\r\n removeOutEvent: function(e) {\r\n var eventName = $(e.target).attr('data-event');\r\n this.view.c.removeAppOutEvent(eventName);\r\n this.onEdited();\r\n },\r\n\r\n addSubEvent: function(eventName) {\r\n this.view.c.addSubEvent(eventName);\r\n this.onEdited();\r\n },\r\n\r\n getDataType: function(evt) {\r\n if( evt.datatype ) {\r\n return evt.datatype;\r\n }\r\n else if( evt.data ) {\r\n return window.DualBox.Type.detectType(evt.data);\r\n }\r\n else {\r\n return undefined;\r\n }\r\n },\r\n\r\n toggleAdvancedAppEventSettings: function(e) {\r\n var key = $(e.target).data('event');\r\n var index = $(e.target).data('index');\r\n var k=key+'##'+index;\r\n this.expanded[k] = this.expanded[k] ? false : true;\r\n this.$forceUpdate();\r\n },\r\n\r\n onEditEventInData(key, index, val) {\r\n this.view.c.setEventData( \"#application-events-in-\" + key, index, val);\r\n this.$emit('edited');\r\n },\r\n\r\n onEditEventInDataType(key, index, type) {\r\n this.view.c.setEventDataType( \"#application-events-in-\" + key, index, type);\r\n\r\n // check that the set value still match the new type\r\n // delete it otherwise\r\n var val = this.app.getEventIn(key)[index].data;\r\n try {\r\n // TODO: ensure type is already loaded (after dualbox) and remove the try/catch\r\n if( !window.DualBox.Type.check(type, val) ) {\r\n // delete data (== set undefined)\r\n this.view.c.setEventData( \"#application-events-in-\" + key, index, undefined);\r\n }\r\n }\r\n catch(e) {\r\n this.view.c.setEventData( \"#application-events-in-\" + key, index, undefined);\r\n }\r\n\r\n this.$emit('edited');\r\n },\r\n }\r\n}\r\n</script>\r\n"]}, media: undefined });
|
|
67337
67369
|
|
|
67338
67370
|
};
|
|
67339
67371
|
/* scoped */
|
|
@@ -87923,7 +87955,7 @@ var script$d = {
|
|
|
87923
87955
|
"dualbox-container",
|
|
87924
87956
|
"dualbox-container-" + name,
|
|
87925
87957
|
type == "viewer"
|
|
87926
|
-
? "dualbox-viewer"
|
|
87958
|
+
? "dualbox-viewer dualbox-mobile-h60"
|
|
87927
87959
|
: "dualbox-controls",
|
|
87928
87960
|
"dualbox-panel",
|
|
87929
87961
|
cssPositionClass
|
|
@@ -88861,7 +88893,7 @@ __vue_render__$d._withStripped = true;
|
|
|
88861
88893
|
/* style */
|
|
88862
88894
|
const __vue_inject_styles__$d = function (inject) {
|
|
88863
88895
|
if (!inject) return
|
|
88864
|
-
inject("data-v-30c84de8_0", { source: "\n.code-panel {\r\n width: 30%;\r\n height: 100%;\r\n vertical-align: top;\r\n float: left;\n}\n.application-container {\r\n width: calc(70% - 5px);\r\n height: 100%;\r\n display: inline-block;\r\n vertical-align: top;\r\n float: right;\n}\n.code-controls,\r\n.run-options {\r\n width: 100%;\r\n height: 60px;\n}\n.application {\r\n width: 100%;\r\n height: calc(100% - 60px);\r\n background-color: #ccc;\n}\n.dragbar {\r\n height: 100%;\r\n width: 5px;\r\n background-color: #e7e7e7;\r\n display: inline-block;\r\n cursor: col-resize;\n}\n.code-content {\r\n position: relative;\r\n height: calc(100% - 56px);\n}\n.code-html-container {\r\n position: relative;\r\n height: 50%;\r\n border-bottom: 1px solid #e7e7e7;\n}\n.code-css-container {\r\n position: relative;\r\n height: calc(50% - 1px);\r\n overflow: hidden;\n}\n.code-css {\r\n width: 100%;\r\n height: 100%;\n}\n.code-html {\r\n height: calc(100% - 40px);\r\n width: 100%;\n}\n.CodeMirror {\r\n height: 100% !important;\n}\n.code-badge {\r\n position: absolute;\r\n top: 10px;\r\n right: 10px;\r\n padding: 10px;\n}\n.btn-light.focus,\r\n.btn-light:focus {\r\n box-shadow: none !important;\n}\n.button-bar {\r\n width: 60px;\r\n padding: 10px;\r\n border-bottom: 1px solid #e7e7e7;\r\n width: 100%;\r\n background-color: white;\n}\n.noselect {\r\n -webkit-user-select: none;\r\n /* Chrome/Safari */\r\n -moz-user-select: none;\r\n /* Firefox */\r\n -ms-user-select: none;\r\n /* IE10+ */\r\n -o-user-select: none;\r\n user-select: none;\n}\n.btn + .btn {\r\n margin-left: 5px;\n}\n.btn-graph-goto {\r\n box-shadow: none !important;\n}\n.nav-tabs {\r\n border-bottom: none;\n}\n.main-navigation a.nav-link {\r\n color: white;\n}\n.main-navigation a.nav-link.active {\r\n color: #212529;\n}\n.dualbox-editor-body {\r\n width: 100%;\r\n height: 100%;\r\n overflow: hidden;\r\n background-color: rgb(85, 85, 85);\n}\n.dualbox-graph-left-section {\r\n height: 100%;\r\n width: 500px;\r\n float: left;\r\n position: relative;\r\n overflow: hidden;\r\n margin-left: -465px;\r\n transition: margin-left 0.3s ease;\n}\n.dualbox-graph-left-window {\r\n width: calc(100% - 35px);\r\n height: calc(100% - 10px);\r\n margin-top: 10px;\r\n /* background-color: #ECF2F8; */\r\n background-color: #f8f9fa;\r\n /* border: 1px solid grey; */\r\n border-radius: 5px;\r\n position: relative;\r\n float: left;\n}\n.dualbox-graph-left-panel {\r\n width: 100%;\r\n height: 100%;\n}\n.btn-toggle-left-window {\r\n position: absolute;\r\n right: 0;\r\n top: 0;\r\n margin-right: -35px;\r\n z-index: 100;\r\n border-top-left-radius: 0px;\r\n border-bottom-left-radius: 0px;\n}\n.btn-toggle-left-window:hover,\r\n.btn-toggle-right-window:hover,\r\n.btn-toggle-left-window:focus,\r\n.btn-toggle-right-window:focus,\r\n.btn-toggle-left-window:active,\r\n.btn-toggle-right-window:active,\r\n.btn-toggle-left-window:active:hover,\r\n.btn-toggle-right-window:active:hover {\r\n color: #212529 !important;\r\n background-color: #f8f9fa !important;\r\n border-color: #f8f9fa !important;\n}\n.dualbox-graph-right-section {\r\n height: 100%;\r\n width: 500px;\r\n float: right;\r\n position: relative;\r\n overflow: hidden;\r\n margin-right: -465px;\r\n transition: margin-right 0.3s ease;\n}\n.dualbox-graph-right-window {\r\n width: calc(100% - 35px);\r\n height: calc(100% - 20px);\r\n margin-top: 10px;\r\n margin-bottom: 30px;\r\n /* background-color: #ECF2F8; */\r\n background-color: #f8f9fa;\r\n /* border: 1px solid grey; */\r\n border-radius: 5px;\r\n position: relative;\r\n float: right;\n}\n.dualbox-graph-right-panel {\r\n width: 100%;\r\n height: 100%;\n}\n.btn-toggle-right-window {\r\n position: absolute;\r\n left: 0;\r\n top: 0;\r\n margin-left: -35px;\r\n z-index: 100;\r\n border-top-right-radius: 0px;\r\n border-bottom-right-radius: 0px;\n}\n.dualbox-graph-tab {\r\n height: 100%;\r\n width: 100%;\r\n background-color: #555 !important;\n}\n.dualbox-graph-main {\r\n height: 100%;\r\n width: calc(100% - 70px);\r\n float: right;\r\n background-color: #555 !important;\r\n transition: width 0.3s ease;\n}\n.dualbox-graph-main.left-panel-expanded {\r\n width: calc(100% - 535px);\r\n margin-left: -465px;\n}\n.dualbox-graph-main.right-panel-expanded {\r\n width: calc(100% - 535px);\n}\n.dualbox-graph-main.left-panel-expanded.right-panel-expanded {\r\n width: calc(100% - 1000px);\r\n margin-left: -465px;\n}\n.opacity0 {\r\n opacity: 0;\n}\n.btn-editor-xs {\r\n width: 18px;\r\n padding: 3px !important;\r\n line-height: 0.5;\r\n border-radius: 2px;\n}\n.btn-editor-xs > i {\r\n font-size: 10px;\n}\n.btn-outline-discrete {\r\n border-color: rgba(0, 0, 0, 0.05);\r\n border-color: transparent;\r\n color: rgba(0, 0, 0, 0.3);\n}\n.dualbox-app-navigation {\r\n background-color: transparent;\r\n margin-bottom: 0;\r\n vertical-align: middle;\r\n padding-top: 7px;\r\n padding-bottom: 7px;\r\n font-weight: bold;\r\n user-select: none;\n}\n.app-topbar {\r\n border-bottom: none;\r\n padding-left: 15px;\r\n padding-right: 15px;\r\n display: flex;\r\n width: 100%;\r\n height: 58px;\r\n padding-top: 10px;\r\n padding-bottom: 10px;\n}\n.dark,\r\n.graph-tab.active,\r\n.nav-item.active .graph-tab {\r\n color: white !important;\r\n background-color: #555 !important;\n}\n.light {\r\n color: #4d4d4d !important;\r\n background-color: #f8f9fa !important;\n}\n.main-navigation .nav-link,\r\n.main-navigation .nav-link.active,\r\n.nav-item.active .nav-link {\r\n border-bottom: none;\r\n border-left: none;\r\n border-top: none;\r\n border-right: none;\r\n position: relative;\r\n top: 1px;\n}\n.btn:focus,\r\nbutton:focus {\r\n outline: none;\r\n box-shadow: none;\n}\n.btn-transparent,\r\n.btn-transparent:hover,\r\n.btn-transparent:focus {\r\n background-color: transparent;\n}\n.connection-control {\r\n position: absolute;\r\n height: 14px;\r\n width: 14px;\r\n background-color: transparent;\r\n z-index: 19;\r\n cursor: move;\n}\n.connection-control.selected {\r\n border-color: #0066ff;\r\n box-shadow: 1px 1px 10px #0066ff;\n}\n.connection-label {\r\n z-index: 22 !important;\r\n color: #004d00 !important;\r\n background-color: white !important;\r\n padding: 4px 4px;\r\n border: 2px solid #004d00;\r\n font-size: 16px !important;\r\n border-radius: 5px;\n}\n.input-color-tag {\r\n background-color: #f2d600;\n}\n.output-color-tag {\r\n background-color: #ffab4a;\n}\n.ui-color-tag {\r\n background-color: #61bd4f;\n}\n.metanode-color-tag {\r\n background-color: #dddddd;\n}\n.input {\n}\n.output {\n}\n.fileUpload {\r\n position: relative;\r\n overflow: hidden;\r\n margin: 10px;\n}\n.fileUpload input.upload {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n margin: 0;\r\n padding: 0;\r\n font-size: 20px;\r\n cursor: pointer;\r\n opacity: 0;\r\n filter: alpha(opacity=0);\n}\n.module-edit-modal-body .btn + .btn {\r\n margin-bottom: 0;\r\n margin-left: 5px;\n}\n.btn-add-node {\r\n width: 46%;\r\n margin: 1%;\n}\nbutton.close {\r\n position: absolute;\r\n right: 0;\r\n margin-right: 5px !important;\n}\n.CodeMirror {\r\n height: auto;\r\n min-height: 300px;\n}\n.load-app,\r\n.save-app {\r\n margin-left: 5px;\r\n margin-right: 5px;\n}\n.btn-xs {\r\n padding: 0px 4px;\r\n font-size: 12px;\n}\n@media screen and (max-width: 1152px) {\n.code-panel {\r\n display: none;\n}\n.dragbar {\r\n display: none !important;\n}\n.application-container {\r\n width: 100%;\n}\n.run-options {\r\n display: none;\n}\n.application {\r\n height: 100%;\n}\n.navbar-right {\r\n display: none;\n}\n}\r\n", map: {"version":3,"sources":["C:\\Users\\maxim\\Projects\\dualbox\\editor\\js\\src\\v\\templates\\main.vue"],"names":[],"mappings":";AACA;IACA,UAAA;IACA,YAAA;IACA,mBAAA;IACA,WAAA;AACA;AAEA;IACA,sBAAA;IACA,YAAA;IACA,qBAAA;IACA,mBAAA;IACA,YAAA;AACA;AAEA;;IAEA,WAAA;IACA,YAAA;AACA;AAEA;IACA,WAAA;IACA,yBAAA;IACA,sBAAA;AACA;AAEA;IACA,YAAA;IACA,UAAA;IACA,yBAAA;IACA,qBAAA;IACA,kBAAA;AACA;AAEA;IACA,kBAAA;IACA,yBAAA;AACA;AAEA;IACA,kBAAA;IACA,WAAA;IACA,gCAAA;AACA;AAEA;IACA,kBAAA;IACA,uBAAA;IACA,gBAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,yBAAA;IACA,WAAA;AACA;AAEA;IACA,uBAAA;AACA;AAEA;IACA,kBAAA;IACA,SAAA;IACA,WAAA;IACA,aAAA;AACA;AAEA;;IAEA,2BAAA;AACA;AAEA;IACA,WAAA;IACA,aAAA;IACA,gCAAA;IACA,WAAA;IACA,uBAAA;AACA;AAEA;IACA,yBAAA;IACA,kBAAA;IACA,sBAAA;IACA,YAAA;IACA,qBAAA;IACA,UAAA;IACA,oBAAA;IACA,iBAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,2BAAA;AACA;AAEA;IACA,mBAAA;AACA;AAEA;IACA,YAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;IACA,gBAAA;IACA,iCAAA;AACA;AAEA;IACA,YAAA;IACA,YAAA;IACA,WAAA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;IACA,iCAAA;AACA;AAEA;IACA,wBAAA;IACA,yBAAA;IACA,gBAAA;IACA,+BAAA;IACA,yBAAA;IACA,4BAAA;IACA,kBAAA;IACA,kBAAA;IACA,WAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,kBAAA;IACA,QAAA;IACA,MAAA;IACA,mBAAA;IACA,YAAA;IACA,2BAAA;IACA,8BAAA;AACA;AAEA;;;;;;;;IAQA,yBAAA;IACA,oCAAA;IACA,gCAAA;AACA;AAEA;IACA,YAAA;IACA,YAAA;IACA,YAAA;IACA,kBAAA;IACA,gBAAA;IACA,oBAAA;IACA,kCAAA;AACA;AAEA;IACA,wBAAA;IACA,yBAAA;IACA,gBAAA;IACA,mBAAA;IACA,+BAAA;IACA,yBAAA;IACA,4BAAA;IACA,kBAAA;IACA,kBAAA;IACA,YAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,kBAAA;IACA,OAAA;IACA,MAAA;IACA,kBAAA;IACA,YAAA;IACA,4BAAA;IACA,+BAAA;AACA;AAEA;IACA,YAAA;IACA,WAAA;IACA,iCAAA;AACA;AAEA;IACA,YAAA;IACA,wBAAA;IACA,YAAA;IACA,iCAAA;IACA,2BAAA;AACA;AAEA;IACA,yBAAA;IACA,mBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,0BAAA;IACA,mBAAA;AACA;AAEA;IACA,UAAA;AACA;AAEA;IACA,WAAA;IACA,uBAAA;IACA,gBAAA;IACA,kBAAA;AACA;AAEA;IACA,eAAA;AACA;AAEA;IACA,iCAAA;IACA,yBAAA;IACA,yBAAA;AACA;AAEA;IACA,6BAAA;IACA,gBAAA;IACA,sBAAA;IACA,gBAAA;IACA,mBAAA;IACA,iBAAA;IACA,iBAAA;AACA;AAEA;IACA,mBAAA;IACA,kBAAA;IACA,mBAAA;IACA,aAAA;IACA,WAAA;IACA,YAAA;IACA,iBAAA;IACA,oBAAA;AACA;AAEA;;;IAGA,uBAAA;IACA,iCAAA;AACA;AAEA;IACA,yBAAA;IACA,oCAAA;AACA;AAEA;;;IAGA,mBAAA;IACA,iBAAA;IACA,gBAAA;IACA,kBAAA;IACA,kBAAA;IACA,QAAA;AACA;AAEA;;IAEA,aAAA;IACA,gBAAA;AACA;AAEA;;;IAGA,6BAAA;AACA;AAEA;IACA,kBAAA;IACA,YAAA;IACA,WAAA;IACA,6BAAA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,qBAAA;IACA,gCAAA;AACA;AAEA;IACA,sBAAA;IACA,yBAAA;IACA,kCAAA;IACA,gBAAA;IACA,yBAAA;IACA,0BAAA;IACA,kBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;AACA;AAEA;AACA;AAEA;IACA,kBAAA;IACA,gBAAA;IACA,YAAA;AACA;AAEA;IACA,kBAAA;IACA,MAAA;IACA,QAAA;IACA,SAAA;IACA,UAAA;IACA,eAAA;IACA,eAAA;IACA,UAAA;IACA,wBAAA;AACA;AAEA;IACA,gBAAA;IACA,gBAAA;AACA;AAEA;IACA,UAAA;IACA,UAAA;AACA;AAEA;IACA,kBAAA;IACA,QAAA;IACA,4BAAA;AACA;AAEA;IACA,YAAA;IACA,iBAAA;AACA;AAEA;;IAEA,gBAAA;IACA,iBAAA;AACA;AAEA;IACA,gBAAA;IACA,eAAA;AACA;AAEA;AACA;QACA,aAAA;AACA;AAEA;QACA,wBAAA;AACA;AAEA;QACA,WAAA;AACA;AAEA;QACA,aAAA;AACA;AAEA;QACA,YAAA;AACA;AAEA;QACA,aAAA;AACA;AACA","file":"main.vue","sourcesContent":["<style>\r\n.code-panel {\r\n width: 30%;\r\n height: 100%;\r\n vertical-align: top;\r\n float: left;\r\n}\r\n\r\n.application-container {\r\n width: calc(70% - 5px);\r\n height: 100%;\r\n display: inline-block;\r\n vertical-align: top;\r\n float: right;\r\n}\r\n\r\n.code-controls,\r\n.run-options {\r\n width: 100%;\r\n height: 60px;\r\n}\r\n\r\n.application {\r\n width: 100%;\r\n height: calc(100% - 60px);\r\n background-color: #ccc;\r\n}\r\n\r\n.dragbar {\r\n height: 100%;\r\n width: 5px;\r\n background-color: #e7e7e7;\r\n display: inline-block;\r\n cursor: col-resize;\r\n}\r\n\r\n.code-content {\r\n position: relative;\r\n height: calc(100% - 56px);\r\n}\r\n\r\n.code-html-container {\r\n position: relative;\r\n height: 50%;\r\n border-bottom: 1px solid #e7e7e7;\r\n}\r\n\r\n.code-css-container {\r\n position: relative;\r\n height: calc(50% - 1px);\r\n overflow: hidden;\r\n}\r\n\r\n.code-css {\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n.code-html {\r\n height: calc(100% - 40px);\r\n width: 100%;\r\n}\r\n\r\n.CodeMirror {\r\n height: 100% !important;\r\n}\r\n\r\n.code-badge {\r\n position: absolute;\r\n top: 10px;\r\n right: 10px;\r\n padding: 10px;\r\n}\r\n\r\n.btn-light.focus,\r\n.btn-light:focus {\r\n box-shadow: none !important;\r\n}\r\n\r\n.button-bar {\r\n width: 60px;\r\n padding: 10px;\r\n border-bottom: 1px solid #e7e7e7;\r\n width: 100%;\r\n background-color: white;\r\n}\r\n\r\n.noselect {\r\n -webkit-user-select: none;\r\n /* Chrome/Safari */\r\n -moz-user-select: none;\r\n /* Firefox */\r\n -ms-user-select: none;\r\n /* IE10+ */\r\n -o-user-select: none;\r\n user-select: none;\r\n}\r\n\r\n.btn + .btn {\r\n margin-left: 5px;\r\n}\r\n\r\n.btn-graph-goto {\r\n box-shadow: none !important;\r\n}\r\n\r\n.nav-tabs {\r\n border-bottom: none;\r\n}\r\n\r\n.main-navigation a.nav-link {\r\n color: white;\r\n}\r\n\r\n.main-navigation a.nav-link.active {\r\n color: #212529;\r\n}\r\n\r\n.dualbox-editor-body {\r\n width: 100%;\r\n height: 100%;\r\n overflow: hidden;\r\n background-color: rgb(85, 85, 85);\r\n}\r\n\r\n.dualbox-graph-left-section {\r\n height: 100%;\r\n width: 500px;\r\n float: left;\r\n position: relative;\r\n overflow: hidden;\r\n margin-left: -465px;\r\n transition: margin-left 0.3s ease;\r\n}\r\n\r\n.dualbox-graph-left-window {\r\n width: calc(100% - 35px);\r\n height: calc(100% - 10px);\r\n margin-top: 10px;\r\n /* background-color: #ECF2F8; */\r\n background-color: #f8f9fa;\r\n /* border: 1px solid grey; */\r\n border-radius: 5px;\r\n position: relative;\r\n float: left;\r\n}\r\n\r\n.dualbox-graph-left-panel {\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n.btn-toggle-left-window {\r\n position: absolute;\r\n right: 0;\r\n top: 0;\r\n margin-right: -35px;\r\n z-index: 100;\r\n border-top-left-radius: 0px;\r\n border-bottom-left-radius: 0px;\r\n}\r\n\r\n.btn-toggle-left-window:hover,\r\n.btn-toggle-right-window:hover,\r\n.btn-toggle-left-window:focus,\r\n.btn-toggle-right-window:focus,\r\n.btn-toggle-left-window:active,\r\n.btn-toggle-right-window:active,\r\n.btn-toggle-left-window:active:hover,\r\n.btn-toggle-right-window:active:hover {\r\n color: #212529 !important;\r\n background-color: #f8f9fa !important;\r\n border-color: #f8f9fa !important;\r\n}\r\n\r\n.dualbox-graph-right-section {\r\n height: 100%;\r\n width: 500px;\r\n float: right;\r\n position: relative;\r\n overflow: hidden;\r\n margin-right: -465px;\r\n transition: margin-right 0.3s ease;\r\n}\r\n\r\n.dualbox-graph-right-window {\r\n width: calc(100% - 35px);\r\n height: calc(100% - 20px);\r\n margin-top: 10px;\r\n margin-bottom: 30px;\r\n /* background-color: #ECF2F8; */\r\n background-color: #f8f9fa;\r\n /* border: 1px solid grey; */\r\n border-radius: 5px;\r\n position: relative;\r\n float: right;\r\n}\r\n\r\n.dualbox-graph-right-panel {\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n.btn-toggle-right-window {\r\n position: absolute;\r\n left: 0;\r\n top: 0;\r\n margin-left: -35px;\r\n z-index: 100;\r\n border-top-right-radius: 0px;\r\n border-bottom-right-radius: 0px;\r\n}\r\n\r\n.dualbox-graph-tab {\r\n height: 100%;\r\n width: 100%;\r\n background-color: #555 !important;\r\n}\r\n\r\n.dualbox-graph-main {\r\n height: 100%;\r\n width: calc(100% - 70px);\r\n float: right;\r\n background-color: #555 !important;\r\n transition: width 0.3s ease;\r\n}\r\n\r\n.dualbox-graph-main.left-panel-expanded {\r\n width: calc(100% - 535px);\r\n margin-left: -465px;\r\n}\r\n\r\n.dualbox-graph-main.right-panel-expanded {\r\n width: calc(100% - 535px);\r\n}\r\n\r\n.dualbox-graph-main.left-panel-expanded.right-panel-expanded {\r\n width: calc(100% - 1000px);\r\n margin-left: -465px;\r\n}\r\n\r\n.opacity0 {\r\n opacity: 0;\r\n}\r\n\r\n.btn-editor-xs {\r\n width: 18px;\r\n padding: 3px !important;\r\n line-height: 0.5;\r\n border-radius: 2px;\r\n}\r\n\r\n.btn-editor-xs > i {\r\n font-size: 10px;\r\n}\r\n\r\n.btn-outline-discrete {\r\n border-color: rgba(0, 0, 0, 0.05);\r\n border-color: transparent;\r\n color: rgba(0, 0, 0, 0.3);\r\n}\r\n\r\n.dualbox-app-navigation {\r\n background-color: transparent;\r\n margin-bottom: 0;\r\n vertical-align: middle;\r\n padding-top: 7px;\r\n padding-bottom: 7px;\r\n font-weight: bold;\r\n user-select: none;\r\n}\r\n\r\n.app-topbar {\r\n border-bottom: none;\r\n padding-left: 15px;\r\n padding-right: 15px;\r\n display: flex;\r\n width: 100%;\r\n height: 58px;\r\n padding-top: 10px;\r\n padding-bottom: 10px;\r\n}\r\n\r\n.dark,\r\n.graph-tab.active,\r\n.nav-item.active .graph-tab {\r\n color: white !important;\r\n background-color: #555 !important;\r\n}\r\n\r\n.light {\r\n color: #4d4d4d !important;\r\n background-color: #f8f9fa !important;\r\n}\r\n\r\n.main-navigation .nav-link,\r\n.main-navigation .nav-link.active,\r\n.nav-item.active .nav-link {\r\n border-bottom: none;\r\n border-left: none;\r\n border-top: none;\r\n border-right: none;\r\n position: relative;\r\n top: 1px;\r\n}\r\n\r\n.btn:focus,\r\nbutton:focus {\r\n outline: none;\r\n box-shadow: none;\r\n}\r\n\r\n.btn-transparent,\r\n.btn-transparent:hover,\r\n.btn-transparent:focus {\r\n background-color: transparent;\r\n}\r\n\r\n.connection-control {\r\n position: absolute;\r\n height: 14px;\r\n width: 14px;\r\n background-color: transparent;\r\n z-index: 19;\r\n cursor: move;\r\n}\r\n\r\n.connection-control.selected {\r\n border-color: #0066ff;\r\n box-shadow: 1px 1px 10px #0066ff;\r\n}\r\n\r\n.connection-label {\r\n z-index: 22 !important;\r\n color: #004d00 !important;\r\n background-color: white !important;\r\n padding: 4px 4px;\r\n border: 2px solid #004d00;\r\n font-size: 16px !important;\r\n border-radius: 5px;\r\n}\r\n\r\n.input-color-tag {\r\n background-color: #f2d600;\r\n}\r\n\r\n.output-color-tag {\r\n background-color: #ffab4a;\r\n}\r\n\r\n.ui-color-tag {\r\n background-color: #61bd4f;\r\n}\r\n\r\n.metanode-color-tag {\r\n background-color: #dddddd;\r\n}\r\n\r\n.input {\r\n}\r\n\r\n.output {\r\n}\r\n\r\n.fileUpload {\r\n position: relative;\r\n overflow: hidden;\r\n margin: 10px;\r\n}\r\n\r\n.fileUpload input.upload {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n margin: 0;\r\n padding: 0;\r\n font-size: 20px;\r\n cursor: pointer;\r\n opacity: 0;\r\n filter: alpha(opacity=0);\r\n}\r\n\r\n.module-edit-modal-body .btn + .btn {\r\n margin-bottom: 0;\r\n margin-left: 5px;\r\n}\r\n\r\n.btn-add-node {\r\n width: 46%;\r\n margin: 1%;\r\n}\r\n\r\nbutton.close {\r\n position: absolute;\r\n right: 0;\r\n margin-right: 5px !important;\r\n}\r\n\r\n.CodeMirror {\r\n height: auto;\r\n min-height: 300px;\r\n}\r\n\r\n.load-app,\r\n.save-app {\r\n margin-left: 5px;\r\n margin-right: 5px;\r\n}\r\n\r\n.btn-xs {\r\n padding: 0px 4px;\r\n font-size: 12px;\r\n}\r\n\r\n@media screen and (max-width: 1152px) {\r\n .code-panel {\r\n display: none;\r\n }\r\n\r\n .dragbar {\r\n display: none !important;\r\n }\r\n\r\n .application-container {\r\n width: 100%;\r\n }\r\n\r\n .run-options {\r\n display: none;\r\n }\r\n\r\n .application {\r\n height: 100%;\r\n }\r\n\r\n .navbar-right {\r\n display: none;\r\n }\r\n}\r\n</style>\r\n\r\n<template>\r\n <div class=\"dualbox-editor-body\">\r\n <nav class=\"main-navigation navbar navbar-default\" style=\"position: relative; margin-bottom: 0px; padding: 0; padding-top: 5px; background-color: #0B6D80;\">\r\n <ul class=\"nav nav-tabs\">\r\n <li class=\"nav-item active\">\r\n <a class=\"nav-link graph-tab\" href=\"#editor-graph-tab\" data-toggle=\"tab\">Application Graph</a>\r\n </li>\r\n <li class=\"nav-item\">\r\n <a class=\"nav-link interface-tab\" href=\"#editor-interface-tab\" data-toggle=\"tab\">Interface Editor</a>\r\n </li>\r\n </ul>\r\n\r\n <div class=\"nav navbar-right\" style=\"vertical-align: top; margin-top: 5px; margin-right: 10px; margin-bottom: 5px;\">\r\n <div v-if=\"showLoadButton === true\">\r\n <button class=\"load-app btn btn-sm btn-light\" style=\"position: relative; bottom: 3px;\" @click=\"loadApp\">Load App</button>\r\n </div>\r\n <div v-if=\"showSaveButton\">\r\n <button class=\"save-app btn btn-sm btn-light\" style=\"position: relative; bottom: 3px;\" @click=\"saveApp\">Save App</button>\r\n </div>\r\n </div>\r\n </nav>\r\n <div class=\"tab-content dualbox-graph-tab\" style=\"width: 100%; height: calc(100% - 46px);\">\r\n <div class=\"tab-pane active\" id=\"editor-graph-tab\" style=\"width: 100%; height: 100%;\">\r\n <div class=\"dualbox-graph-left-section dark\">\r\n <div class=\"dualbox-graph-left-window\">\r\n <button class=\"btn btn-light btn-toggle-left-window\" @click=\"toggleLeftWindow\" title=\"shrink window\" data-expanded=\"false\"><i class=\"fa fa-angle-double-right\"></i></button>\r\n <div class=\"dualbox-graph-left-panel light\">\r\n <edit-node-settings v-if=\"leftPanelMode == 'node' && selectedNodeId !== null\" :id=\"selectedNodeId\" :key=\"selectedNodeId\"></edit-node-settings>\r\n <edit-main-settings v-else-if=\"leftPanelMode == 'main'\" :app=\"getCurrentApplication()\" @edited=\"onEdited()\"></edit-main-settings>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"dualbox-graph-right-section dark\">\r\n <div class=\"dualbox-graph-right-window\">\r\n <button class=\"btn btn-light btn-toggle-right-window\" @click=\"toggleRightWindow\" title=\"shrink window\" data-expanded=\"false\"><i class=\"fa fa-angle-double-left\"></i></button>\r\n <div class=\"dualbox-graph-right-panel light\">\r\n <debug-node-infos v-if=\"debugNodeId !== null\" :id=\"debugNodeId\"></debug-node-infos>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"container-fluid dualbox-graph-main\" @click=\"setMainMenu\">\r\n <div class=\"row\">\r\n <div class=\"app-topbar dark\">\r\n <div class=\"justify-content-left\">\r\n <div class=\"dropdown\">\r\n <button class=\"btn btn-primary dropdown-toggle d-none\" type=\"button\" id=\"add-node-dropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" style=\"margin-right: 5px;\">\r\n Add\r\n </button>\r\n <div class=\"dropdown-menu\" aria-labelledby=\"add-node-dropdown\">\r\n <a class=\"dropdown-item add-box\" @click=\"addBox\" href=\"#\">Add box</a>\r\n <a class=\"dropdown-item add-metabox\" @click=\"addMetabox\" href=\"#\">Add metabox</a>\r\n <a class=\"dropdown-item add-input\" @click=\"addInput\" href=\"#\">Add input</a>\r\n <a class=\"dropdown-item add-output\" @click=\"addOutput\" href=\"#\">Add output</a>\r\n <a class=\"dropdown-item import-metabox\" @click=\"importMetabox\" href=\"#\">Import metabox</a>\r\n </div>\r\n <button class=\"btn btn-light btn-undo\" title=\"undo (ctrl-z)\" @click=\"undo\"><i class=\"fa fa-undo\"></i></button>\r\n <button class=\"btn btn-light btn-redo\" title=\"redo (ctrl-y)\" @click=\"redo\"><i class=\"fa fa-repeat fa-redo\"></i></button>\r\n <div class=\"form-check d-inline-block ml-2\">\r\n <label class=\"form-check-label\">\r\n <input class=\"form-check-input show-events\" type=\"checkbox\" value=\"false\" @click=\"showEvents\">\r\n <span class=\"noselect\">Show events</span>\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"justify-content-center mx-auto\">\r\n <ol class=\"dualbox-app-navigation breadcrumb\"></ol>\r\n </div>\r\n\r\n <div class=\"justify-content-right\">\r\n <div class=\"dropdown selection-menu\" style=\"display: none;\">\r\n <button class=\"btn btn-primary dropdown-toggle\" type=\"button\" id=\"selection-dropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">\r\n Selection\r\n </button>\r\n <div class=\"dropdown-menu dropdown-menu-right\" aria-labelledby=\"add-node-dropdown\">\r\n <a class=\"dropdown-item dualbox-merge-selection\" @click=\"mergeSelection\" href=\"#\">Merge</a>\r\n <a class=\"dropdown-item dualbox-remove-selection\" @click=\"removeSelection\" href=\"#\" style=\"color: red;\">Delete</a>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row\" style=\"height: calc(100% - 58px);\">\r\n <graph-vue :app=\"app\" ref=\"graph\" :displayEvents=\"displayEvents\"></graph-vue>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"tab-pane\" id=\"editor-interface-tab\" style=\"width 100%; height: 100%; background-color: white;\">\r\n <div class=\"db-editor-main\" style=\"width: 100%; height: 100%; overflow: hidden;\">\r\n <div class=\"code-panel\">\r\n <div class=\"button-bar form-inline code-controls\" style=\"position: relative;\">\r\n <button class=\"btn btn-primary btn-save-interface-element\" @click=\"saveInterfaceElement\">Save changes</button>\r\n </div>\r\n <div class=\"code-content\">\r\n <div class=\"code-html-container\">\r\n <div style=\"padding-top: 5px; padding-bottom: 5px; height: 50px; position: relative;\">\r\n <h3 style=\"position: absolute; top: 0; margin: 5px; font-size: 16px; z-index: 100; display: inline-block; margin-top: 5px;\">HTML</h3>\r\n <div class=\"d-inline-block ml-auto form-inline mr-2 mt-2\" style=\"position: absolute; top: 0; right: 0;\">\r\n <button class=\"btn btn-success btn-sm btn-add-interface\" @click=\"addInterface\"><i class=\"fas fa-plus\"></i></button>\r\n <select class=\"form-control btn-sm app-interface-select\" @change=\"selectInterface\" style=\"width: 150px; height: 32px;\">\r\n <option>Load UI...</option>\r\n <option v-for=\"interfaceName in getInterfacesNames()\" :value=\"interfaceName\">{{interfaceName}}</option>\r\n </select>\r\n <button class=\"btn btn-sm btn-light btn-edit-panel-description\" @click=\"editPanelDescription\"><i class=\"fas fa-info\" style=\"padding-left: 8px; padding-right: 8px;\"></i></button>\r\n <button class=\"btn btn-danger btn-sm btn-remove-interface\" @click=\"removeInterface\"><i class=\"fas fa-minus\"></i></button>\r\n </div>\r\n </div>\r\n <div class=\"code-html-text-container\" style=\"position: relative; height: calc(100% - 50px);\">\r\n <textarea class=\"code-html\" v-html=\"getSelectedInterfaceCode()\"></textarea>\r\n </div>\r\n </div>\r\n <div class=\"code-css-container\">\r\n <div style=\"height: 30px;\">\r\n <h3 style=\"position: absolute; top: 0; margin: 5px; font-size: 16px; z-index: 100;\">CSS</h3>\r\n </div>\r\n <div class=\"colde-css-text-container\" style=\"position: relative; height: calc(100% - 30px);\">\r\n <textarea class=\"code-css\" v-model=\"appCss\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"dragbar\"></div>\r\n <div class=\"application-container\">\r\n <div class=\"button-bar form-inline run-options\" style=\"position: relative;\">\r\n <button class=\"btn btn-success btn-run mr-2\" @click=\"runApp\">Run</button>\r\n\r\n <select class=\"form-control run-loglevel mr-1 ml-2\">\r\n <option>error</option>\r\n <option>warn</option>\r\n <option>info</option>\r\n <option>log</option>\r\n <option>debug</option>\r\n </select>\r\n\r\n <input class=\"form-control run-noversioncheck mr-1 ml-3\" type=\"checkbox\" checked>No version checking</input>\r\n <input class=\"form-control run-removetrycatch mr-1 ml-3\" type=\"checkbox\">Remove Try/catch</input>\r\n <input class=\"form-control run-makesynchrone mr-1 ml-3\" type=\"checkbox\">Make Synchrone</input>\r\n <input class=\"form-control run-ressourcecaching mr-1 ml-3\" type=\"checkbox\">Ressource caching</input>\r\n\r\n <div class=\"ml-auto\">\r\n <input class=\"form-control run-profiler mr-1 ml-3\" type=\"checkbox\">Profiler</input>\r\n <input class=\"form-control run-record mr-1 ml-3\" type=\"checkbox\">Record</input>\r\n <button class=\"btn btn-secondary btn-snapshot\" @click=\"takeAndLoadSnapshot\">Snapshot</button>\r\n </div>\r\n </div>\r\n <div class=\"application capture-left-click capture-right-click\"></div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <add-node-vue :display=\"this.addingBox\" :mousePosition=\"this.newBoxPosition\" @closed=\"onAddBoxClosed\"></add-node-vue>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport _ from \"lodash-es\";\r\nimport swal from \"sweetalert2\";\r\n\r\nimport graphVue from \"./graph.vue\";\r\nimport addNodeVue from \"./addNode.vue\";\r\nimport editMainSettingsVue from \"./editMainSettings.vue\";\r\nimport editNodeSettingsVue from \"./editNodeSettings.vue\";\r\nimport debugNodeInfosVue from \"./debugNodeInfos.vue\";\r\n\r\n// CodeMirror\r\nimport CodeMirror from \"codemirror/lib/codemirror.js\";\r\nimport \"codemirror/mode/xml/xml.js\";\r\nimport \"codemirror/mode/css/css.js\";\r\nimport \"codemirror/mode/javascript/javascript.js\";\r\nimport \"codemirror/mode/htmlmixed/htmlmixed.js\";\r\n\r\nimport htmltool from \"@dualbox/dualbox-lib-htmltool\";\r\n\r\nexport default {\r\n props: [\r\n \"app\", // the app\r\n\r\n // Display configuration (online or offline ?)\r\n \"showLoadButton\",\r\n \"showSaveButton\",\r\n \"saveButtonFunction\",\r\n\r\n // modes\r\n \"eventVisibility\" // are events visible\r\n ],\r\n components: {\r\n \"graph-vue\": graphVue,\r\n \"add-node-vue\": addNodeVue,\r\n \"edit-main-settings\": editMainSettingsVue,\r\n \"edit-node-settings\": editNodeSettingsVue,\r\n \"debug-node-infos\": debugNodeInfosVue\r\n },\r\n data() {\r\n return {\r\n // modes\r\n addingBox: false,\r\n leftPanelMode: \"main\", // 'main' to display main menu, 'node' for a node\r\n selectedNodeId: null, // id of the node to display in left menu\r\n debugNodeId: null, // on a snapshot, id of the node to display debug infos\r\n newBoxPosition: null, // track mouse position relative to the graph when adding a node\r\n displayEvents: false,\r\n selectedInterface: null,\r\n\r\n // the specific app css\r\n appCss: \"\"\r\n };\r\n },\r\n created: function() {\r\n this.view = window.dualboxEditor.v;\r\n // TODO: restore this when all menus are migrated to Vue.js\r\n\r\n this.cssCode = null;\r\n this.htmlCode = null;\r\n },\r\n updated: function() {\r\n //console.log('updating main view with: ' + JSON.stringify(this.app));\r\n this.appCss = (this.app && this.app.css) || \"\";\r\n\r\n // Update html and css code editor\r\n this.updateCode();\r\n },\r\n mounted: function() {\r\n //this.view.setMainMenu();\r\n\r\n $(this.$el).bind(\"expandSettings\", function(e) {\r\n // expand\r\n $(this)\r\n .find(\".dualbox-graph-left-section\")\r\n .css(\"margin-left\", \"0\");\r\n $(this)\r\n .find(\".dualbox-graph-main\")\r\n .addClass(\"left-panel-expanded\");\r\n $(this)\r\n .find(\".btn-toggle-left-window\")\r\n .data(\"expanded\", true)\r\n .find(\"i\")\r\n .removeClass(\"fa-angle-double-right\")\r\n .addClass(\"fa-angle-double-left\")\r\n .attr(\"title\", \"shrink window\");\r\n });\r\n\r\n $(this.$el).bind(\"shrinkSettings\", function(e) {\r\n // shrink\r\n $(this)\r\n .find(\".dualbox-graph-left-section\")\r\n .css(\"margin-left\", \"-465px\");\r\n $(this)\r\n .find(\".dualbox-graph-main\")\r\n .removeClass(\"left-panel-expanded\");\r\n $(this)\r\n .find(\".btn-toggle-left-window\")\r\n .data(\"expanded\", false)\r\n .find(\"i\")\r\n .removeClass(\"fa-angle-double-left\")\r\n .addClass(\"fa-angle-double-right\")\r\n .attr(\"title\", \"expand window\");\r\n });\r\n\r\n $(this.$el).bind(\"expandDebug\", function(e) {\r\n // expand\r\n $(this)\r\n .find(\".dualbox-graph-right-section\")\r\n .css(\"margin-right\", \"0\");\r\n $(this)\r\n .find(\".dualbox-graph-main\")\r\n .addClass(\"right-panel-expanded\");\r\n $(this)\r\n .find(\".btn-toggle-right-window\")\r\n .data(\"expanded\", true)\r\n .find(\"i\")\r\n .removeClass(\"fa-angle-double-left\")\r\n .addClass(\"fa-angle-double-right\")\r\n .attr(\"title\", \"shrink window\");\r\n });\r\n\r\n $(this.$el).bind(\"shrinkDebug\", function(e) {\r\n // shrink\r\n $(this)\r\n .find(\".dualbox-graph-right-section\")\r\n .css(\"margin-right\", \"-465px\");\r\n $(this)\r\n .find(\".dualbox-graph-main\")\r\n .removeClass(\"right-panel-expanded\");\r\n $(this)\r\n .find(\".btn-toggle-right-window\")\r\n .data(\"expanded\", false)\r\n .find(\"i\")\r\n .removeClass(\"fa-angle-double-right\")\r\n .addClass(\"fa-angle-double-left\")\r\n .attr(\"title\", \"expand window\");\r\n });\r\n\r\n // bind tabs\r\n var self = this;\r\n $(this.$el)\r\n .find(\"a[data-toggle='tab']\")\r\n .on(\"shown.bs.tab\", function(e) {\r\n var target = $(e.target).attr(\"href\"); // activated tab\r\n if (target == \"#editor-graph-tab\") {\r\n self.view.killApp();\r\n } else if (target == \"#editor-interface-tab\") {\r\n self.htmlCode.refresh();\r\n self.cssCode.refresh();\r\n self.view.runApp(self.getOptions());\r\n }\r\n });\r\n\r\n $(this.$el)\r\n .find(\"a[data-toggle='tab']\")\r\n .on(\"click\", function(e) {\r\n e.preventDefault();\r\n $(this).tab(\"show\");\r\n });\r\n\r\n // Update html and css code editor\r\n this.updateCode();\r\n\r\n // Resize horizontally\r\n $(this.$el)\r\n .find(\".dragbar\")\r\n .mousedown(function(e) {\r\n e.preventDefault();\r\n $(document).mouseup(function(e) {\r\n $(document).unbind(\"mousemove\");\r\n });\r\n $(document).mousemove(function(e) {\r\n $(\".code-panel\").css(\"width\", e.pageX + \"px\");\r\n $(\".application-container\").css(\r\n \"width\",\r\n $(\".db-editor-main\").width() - e.pageX - 5 + \"px\"\r\n );\r\n });\r\n });\r\n\r\n // prevent default behavior for ctrl+s / cmd+s\r\n $(document).keydown(function(event) {\r\n if ((event.ctrlKey || event.metaKey) && event.which == 83) {\r\n event.preventDefault();\r\n return false;\r\n }\r\n });\r\n },\r\n destroyed: function() {\r\n console.log(\"Graph vue destroyed\");\r\n $(\".ContextMenu\").remove();\r\n },\r\n methods: {\r\n getOptions: function() {\r\n return {\r\n profiler: $(this.$el)\r\n .find(\".run-profiler\")\r\n .is(\":checked\"),\r\n logLevel: $(this.$el)\r\n .find(\".run-loglevel\")\r\n .val(),\r\n options: {\r\n noVersionCheck: $(this.$el)\r\n .find(\".run-noversioncheck\")\r\n .is(\":checked\"),\r\n debug: {\r\n removeTryCatch: $(this.$el)\r\n .find(\".run-removetrycatch\")\r\n .is(\":checked\"),\r\n makeSynchrone: $(this.$el)\r\n .find(\".run-makesynchrone\")\r\n .is(\":checked\"),\r\n record: $(this.$el)\r\n .find(\".run-record\")\r\n .is(\":checked\"),\r\n ressourceCaching: $(this.$el)\r\n .find(\".run-ressourcecaching\")\r\n .is(\":checked\")\r\n }\r\n }\r\n };\r\n },\r\n\r\n updateCode: function() {\r\n // instanciate codemirror for html and css\r\n if (!this.htmlCode) {\r\n this.htmlCode = CodeMirror.fromTextArea(\r\n $(this.$el).find(\".code-html\")[0],\r\n {\r\n lineNumbers: true,\r\n mode: \"htmlmixed\",\r\n lineWrapping: true,\r\n extraKeys: {\r\n \"Ctrl-S\": () => {\r\n this.saveInterfaceElement();\r\n this.runApp();\r\n },\r\n \"Cmd-S\": () => {\r\n this.saveInterfaceElement();\r\n this.runApp();\r\n }\r\n }\r\n }\r\n );\r\n }\r\n if (!this.cssCode) {\r\n this.cssCode = CodeMirror.fromTextArea(\r\n $(this.$el).find(\".code-css\")[0],\r\n {\r\n lineNumbers: true,\r\n mode: \"css\",\r\n lineWrapping: true,\r\n extraKeys: {\r\n \"Ctrl-S\": () => {\r\n // save css code into app\r\n this.view.m.data.root.css = this.cssCode.getValue();\r\n this.view.m.save();\r\n this.runApp();\r\n },\r\n \"Cmd-S\": () => {\r\n // save css code into app\r\n this.view.m.data.root.css = this.cssCode.getValue();\r\n this.view.m.save();\r\n this.runApp();\r\n }\r\n }\r\n }\r\n );\r\n }\r\n\r\n this.htmlCode.setValue(this.getSelectedInterfaceCode());\r\n this.cssCode.setValue(this.view.m.get().css || \"\");\r\n },\r\n\r\n loadApp: function() {\r\n var self = this;\r\n\r\n // create a fake input and click it to select a file\r\n var input = $(\"<input/>\", {\r\n type: \"file\",\r\n class: \"upload\",\r\n accept: \".json\"\r\n });\r\n input.change(function(e) {\r\n // if we're not here, go to 1st tab\r\n $(\"a[data-toggle='tab'][href='#editor-graph-tab']\").click();\r\n\r\n // parse the file JSON and load it\r\n var files = e.target.files; // FileList object\r\n var r = new FileReader();\r\n r.onload = function(e) {\r\n var contents = e.target.result;\r\n var json = JSON.parse(contents);\r\n self.view.e.setApp(json);\r\n };\r\n\r\n r.readAsText(files[0]);\r\n });\r\n input.click();\r\n },\r\n saveApp: function() {\r\n // bind the app load\r\n if (this.saveButtonFunction) {\r\n var saveButtonFunction = e => {\r\n var json = this.view.m.getCleanJson();\r\n return this.saveButtonFunction(json);\r\n };\r\n } else {\r\n var saveButtonFunction = e => {\r\n var app = this.view.m.getCleanJson();\r\n var text = JSON.stringify(app, null, 2);\r\n var blob = new Blob([text], {\r\n type: \"application/octet-stream\"\r\n });\r\n\r\n var a = document.createElement(\"a\");\r\n a.href = window.URL.createObjectURL(blob);\r\n a.download = \"app.json\";\r\n\r\n // simulate a click on the link\r\n if (document.createEvent) {\r\n var event = document.createEvent(\"MouseEvents\");\r\n event.initEvent(\"click\", true, true);\r\n a.dispatchEvent(event);\r\n } else {\r\n a.click();\r\n }\r\n };\r\n }\r\n saveButtonFunction();\r\n },\r\n getCurrentMousePosition: function(e) {\r\n return this.$refs.graph.getCurrentMousePosition(e);\r\n },\r\n addBox: function(e) {\r\n this.addingBox = true;\r\n this.newBoxPosition = this.getCurrentMousePosition(e);\r\n this.$forceUpdate();\r\n },\r\n onAddBoxClosed: function() {\r\n this.addingBox = false;\r\n this.$forceUpdate();\r\n },\r\n addMetabox: function(e) {\r\n var self = this;\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n swal({\r\n input: \"text\",\r\n title: \"Choose a name for the metabox\"\r\n }).then(function(result) {\r\n if (result.value) {\r\n self.view.c.addNewMetabox(result.value);\r\n }\r\n });\r\n },\r\n addInput: function(e) {\r\n this.view.c.createInput();\r\n },\r\n addOutput: function(e) {\r\n this.view.c.createOutput();\r\n },\r\n importMetabox: async function(e) {\r\n var self = this;\r\n\r\n const { value: file } = await swal({\r\n title: \"Select your metabox file\",\r\n input: \"file\",\r\n inputAttributes: {\r\n accept: \"application/json\",\r\n \"aria-label\": \"Select your metabox file\"\r\n }\r\n });\r\n\r\n if (file) {\r\n const reader = new FileReader();\r\n reader.onload = e => {\r\n var json = JSON.parse(e.target.result);\r\n\r\n self.view.e\r\n .loadPackages(json)\r\n .then(async () => {\r\n const { value: name } = await swal({\r\n title: \"Choose a name for your metabox\",\r\n input: \"text\",\r\n showCancelButton: true,\r\n inputValidator: value => {\r\n return (\r\n !value && \"You need to write something!\"\r\n );\r\n }\r\n });\r\n\r\n self.view.c.addNewMetabox(name, json);\r\n })\r\n .catch(err => {\r\n console.error(err);\r\n });\r\n };\r\n reader.readAsText(file);\r\n }\r\n },\r\n\r\n getInterfacesNames: function() {\r\n return _.keys(\r\n _.get(this.view.m, [\"data\", \"root\", \"interface\"]) || {}\r\n );\r\n },\r\n\r\n getInterfaceCode: function(uiName) {\r\n var itf = this.view.m.data.root.interface;\r\n var htmlString = htmltool.json2html(itf[uiName]);\r\n var prettyString = htmltool.htmlPrettyPrint(htmlString);\r\n return prettyString;\r\n },\r\n\r\n getSelectedInterfaceCode: function() {\r\n return this.selectedInterface\r\n ? this.getInterfaceCode(this.selectedInterface)\r\n : \"\";\r\n },\r\n\r\n selectInterface: function(e) {\r\n // Load the interface HTML when selected\r\n var uiName = $(e.target).val();\r\n this.selectedInterface = uiName;\r\n if (uiName !== \"\" && uiName !== \"Load UI...\") {\r\n var prettyString = this.getInterfaceCode(uiName);\r\n this.htmlCode.setValue(prettyString);\r\n } else {\r\n this.htmlCode.setValue(\"\");\r\n }\r\n },\r\n saveInterfaceElement: function(e) {\r\n var currentInterface = $(this.$el)\r\n .find(\".app-interface-select\")\r\n .val();\r\n if (currentInterface !== \"\") {\r\n var currentHTML = this.htmlCode.getValue();\r\n\r\n // save html code into app\r\n this.view.m.data.root.interface[\r\n currentInterface\r\n ] = htmltool.html2json(currentHTML);\r\n }\r\n\r\n // save css code into app\r\n this.view.m.data.root.css = this.cssCode.getValue();\r\n this.view.m.save();\r\n },\r\n addInterface: function(e) {\r\n var self = this;\r\n\r\n swal.mixin({\r\n confirmButtonText: \"Next →\",\r\n showCancelButton: true,\r\n progressSteps: [\"1\", \"2\", \"3\"]\r\n })\r\n .queue([\r\n {\r\n input: \"text\",\r\n title: \"Choose a name\",\r\n text: \"Enter a name for the new interface\"\r\n },\r\n {\r\n input: \"select\",\r\n title: \"Choose the type\",\r\n text: \"Is it a viewer panel or a control panel?\",\r\n inputOptions: {\r\n control: \"A control panel\",\r\n viewer: \"A viewer\"\r\n }\r\n },\r\n {\r\n input: \"select\",\r\n title: \"Choose the position\",\r\n text: \"Where do you want to position your panel?\",\r\n inputOptions: {\r\n \"top-left\": \"At the top-left\",\r\n \"top-center\": \"At the top-center\",\r\n \"top-right\": \"At the top-right\",\r\n \"center-left\": \"At the center-left\",\r\n center: \"At the center\",\r\n \"center-right\": \"At the center-right\",\r\n \"bottom-left\": \"At the bottom-left\",\r\n \"bottom-center\": \"At the bottom-center\",\r\n \"bottom-right\": \"At the bottom-right\",\r\n \"whole-screen\": \"I want my panel in full-screen\"\r\n }\r\n }\r\n ])\r\n .then(result => {\r\n if (result.value) {\r\n var name = result.value[0];\r\n var type = result.value[1];\r\n var position = result.value[2];\r\n\r\n if (name === \"\") {\r\n swal.showInputError(\"the name is empty!\");\r\n return false;\r\n }\r\n\r\n var appInterface = self.view.m.data.root.interface;\r\n if (appInterface[name]) {\r\n swal.showInputError(\r\n \"Interface \" + name + \" already exists!\"\r\n );\r\n return false;\r\n } else {\r\n var style = {};\r\n var cssPositionClass = \"dualbox-panel-\" + position;\r\n\r\n // add a basic control\r\n appInterface[name] = {\r\n type: \"Element\",\r\n tagName: \"div\",\r\n attributes: {\r\n className: [\r\n \"dualbox\",\r\n \"dualbox-container\",\r\n \"dualbox-container-\" + name,\r\n type == \"viewer\"\r\n ? \"dualbox-viewer\"\r\n : \"dualbox-controls\",\r\n \"dualbox-panel\",\r\n cssPositionClass\r\n ]\r\n },\r\n children: []\r\n };\r\n\r\n // add the value to our select, and load it\r\n $(self.$el)\r\n .find(\".app-interface-select\")\r\n .append(\r\n $(\"<option/>\", {\r\n value: name\r\n }).append(name)\r\n );\r\n $(document).ready(() => {\r\n $(self.$el)\r\n .find(\".app-interface-select\")\r\n .val(name)\r\n .change();\r\n\r\n // set it into the editor\r\n var htmlString = htmltool.json2html(\r\n appInterface[name]\r\n );\r\n var prettyString = htmltool.htmlPrettyPrint(\r\n htmlString\r\n );\r\n this.htmlCode.setValue(prettyString);\r\n self.updateCode();\r\n });\r\n\r\n self.view.m.save();\r\n self.view.runApp(self.getOptions());\r\n }\r\n }\r\n });\r\n },\r\n removeInterface: function(e) {\r\n var self = this;\r\n var name = $(\".app-interface-select\").val();\r\n\r\n swal({\r\n title: \"Confirm deleting \" + name + \" ?\",\r\n type: \"warning\",\r\n showCancelButton: true,\r\n confirmButtonColor: \"#DD6B55\",\r\n confirmButtonText: \"Yes, delete it!\",\r\n closeOnConfirm: true,\r\n closeOnCancel: true\r\n }).then(result => {\r\n if (result.value) {\r\n // set the interface back to first value\r\n $(this.$el)\r\n .find(\r\n \".app-interface-select option[value='\" + name + \"']\"\r\n )\r\n .remove();\r\n $(this.$el)\r\n .find(\".app-interface-select\")\r\n .change();\r\n delete self.view.m.data.root.interface[name];\r\n self.htmlCode.setValue(\"\");\r\n self.view.runApp(self.getOptions());\r\n }\r\n });\r\n },\r\n editPanelDescription: function(e) {\r\n var self = this;\r\n var name = $(\".app-interface-select\").val();\r\n\r\n swal({\r\n title: \"Enter a description for this panel!\",\r\n input: \"textarea\",\r\n inputValue:\r\n this.view.m.data.root.interface[name].description || \"\",\r\n showCancelButton: true,\r\n closeOnConfirm: false,\r\n showLoaderOnConfirm: true,\r\n animation: \"slide-from-top\",\r\n inputPlaceholder: \"Write something\"\r\n }).then(result => {\r\n if (result.value === \"\") {\r\n swal.showInputError(\"You need to write something!\");\r\n return false;\r\n } else {\r\n self.view.m.data.root.interface[name].description =\r\n result.value;\r\n }\r\n });\r\n },\r\n toggleLeftWindow: function(e) {\r\n var expanded = $(e.target)\r\n .closest(\"button\")\r\n .data(\"expanded\");\r\n if (expanded) {\r\n $(this.$el).trigger(\"shrinkSettings\");\r\n } else {\r\n $(this.$el).trigger(\"expandSettings\");\r\n }\r\n },\r\n toggleRightWindow: function(e) {\r\n var expanded = $(e.target)\r\n .closest(\"button\")\r\n .data(\"expanded\");\r\n if (expanded) {\r\n $(this.$el).trigger(\"shrinkDebug\");\r\n } else {\r\n $(this.$el).trigger(\"expandDebug\");\r\n }\r\n },\r\n\r\n showEvents: function(e) {\r\n //this.view.setEventsVisibility( $(e.target).is(':checked') );\r\n this.displayEvents = $(e.target).is(\":checked\");\r\n },\r\n\r\n runApp: function(e) {\r\n this.view.runApp(this.getOptions());\r\n },\r\n\r\n takeAndLoadSnapshot: function(e) {\r\n this.view.takeAndLoadSnapshot();\r\n },\r\n\r\n undo: function(e) {\r\n this.view.c.undo();\r\n },\r\n\r\n redo: function(e) {\r\n this.view.c.redo();\r\n },\r\n\r\n removeSelection: function(e) {\r\n this.view.c.deleteSelection();\r\n },\r\n\r\n mergeSelection: function(e) {\r\n this.view.c.mergeSelection();\r\n },\r\n\r\n setMainMenu: async function(e) {\r\n await this.view.setMainMenu();\r\n },\r\n\r\n getCurrentApplication: function(e) {\r\n // trick to make this function reactive to \"app\" field update\r\n if (this.app) {\r\n return this.view.m.getCurrentApp(true);\r\n } else {\r\n throw \"Error: no app found\";\r\n }\r\n },\r\n\r\n onEdited: function(e) {\r\n console.log(\"Something was edited, forcing new render\");\r\n this.$forceUpdate();\r\n },\r\n\r\n ready: function() {\r\n return new Promise(resolve => {\r\n this.$nextTick(() => {\r\n window.requestAnimationFrame(() => {\r\n $(this.$el).ready(resolve);\r\n });\r\n });\r\n });\r\n }\r\n }\r\n};\r\n</script>\r\n"]}, media: undefined });
|
|
88896
|
+
inject("data-v-9e6a4702_0", { source: "\n.code-panel {\r\n width: 30%;\r\n height: 100%;\r\n vertical-align: top;\r\n float: left;\n}\n.application-container {\r\n width: calc(70% - 5px);\r\n height: 100%;\r\n display: inline-block;\r\n vertical-align: top;\r\n float: right;\n}\n.code-controls,\r\n.run-options {\r\n width: 100%;\r\n height: 60px;\n}\n.application {\r\n width: 100%;\r\n height: calc(100% - 60px);\r\n background-color: #ccc;\n}\n.dragbar {\r\n height: 100%;\r\n width: 5px;\r\n background-color: #e7e7e7;\r\n display: inline-block;\r\n cursor: col-resize;\n}\n.code-content {\r\n position: relative;\r\n height: calc(100% - 56px);\n}\n.code-html-container {\r\n position: relative;\r\n height: 50%;\r\n border-bottom: 1px solid #e7e7e7;\n}\n.code-css-container {\r\n position: relative;\r\n height: calc(50% - 1px);\r\n overflow: hidden;\n}\n.code-css {\r\n width: 100%;\r\n height: 100%;\n}\n.code-html {\r\n height: calc(100% - 40px);\r\n width: 100%;\n}\n.CodeMirror {\r\n height: 100% !important;\n}\n.code-badge {\r\n position: absolute;\r\n top: 10px;\r\n right: 10px;\r\n padding: 10px;\n}\n.btn-light.focus,\r\n.btn-light:focus {\r\n box-shadow: none !important;\n}\n.button-bar {\r\n width: 60px;\r\n padding: 10px;\r\n border-bottom: 1px solid #e7e7e7;\r\n width: 100%;\r\n background-color: white;\n}\n.noselect {\r\n -webkit-user-select: none;\r\n /* Chrome/Safari */\r\n -moz-user-select: none;\r\n /* Firefox */\r\n -ms-user-select: none;\r\n /* IE10+ */\r\n -o-user-select: none;\r\n user-select: none;\n}\n.btn + .btn {\r\n margin-left: 5px;\n}\n.btn-graph-goto {\r\n box-shadow: none !important;\n}\n.nav-tabs {\r\n border-bottom: none;\n}\n.main-navigation a.nav-link {\r\n color: white;\n}\n.main-navigation a.nav-link.active {\r\n color: #212529;\n}\n.dualbox-editor-body {\r\n width: 100%;\r\n height: 100%;\r\n overflow: hidden;\r\n background-color: rgb(85, 85, 85);\n}\n.dualbox-graph-left-section {\r\n height: 100%;\r\n width: 500px;\r\n float: left;\r\n position: relative;\r\n overflow: hidden;\r\n margin-left: -465px;\r\n transition: margin-left 0.3s ease;\n}\n.dualbox-graph-left-window {\r\n width: calc(100% - 35px);\r\n height: calc(100% - 10px);\r\n margin-top: 10px;\r\n /* background-color: #ECF2F8; */\r\n background-color: #f8f9fa;\r\n /* border: 1px solid grey; */\r\n border-radius: 5px;\r\n position: relative;\r\n float: left;\n}\n.dualbox-graph-left-panel {\r\n width: 100%;\r\n height: 100%;\n}\n.btn-toggle-left-window {\r\n position: absolute;\r\n right: 0;\r\n top: 0;\r\n margin-right: -35px;\r\n z-index: 100;\r\n border-top-left-radius: 0px;\r\n border-bottom-left-radius: 0px;\n}\n.btn-toggle-left-window:hover,\r\n.btn-toggle-right-window:hover,\r\n.btn-toggle-left-window:focus,\r\n.btn-toggle-right-window:focus,\r\n.btn-toggle-left-window:active,\r\n.btn-toggle-right-window:active,\r\n.btn-toggle-left-window:active:hover,\r\n.btn-toggle-right-window:active:hover {\r\n color: #212529 !important;\r\n background-color: #f8f9fa !important;\r\n border-color: #f8f9fa !important;\n}\n.dualbox-graph-right-section {\r\n height: 100%;\r\n width: 500px;\r\n float: right;\r\n position: relative;\r\n overflow: hidden;\r\n margin-right: -465px;\r\n transition: margin-right 0.3s ease;\n}\n.dualbox-graph-right-window {\r\n width: calc(100% - 35px);\r\n height: calc(100% - 20px);\r\n margin-top: 10px;\r\n margin-bottom: 30px;\r\n /* background-color: #ECF2F8; */\r\n background-color: #f8f9fa;\r\n /* border: 1px solid grey; */\r\n border-radius: 5px;\r\n position: relative;\r\n float: right;\n}\n.dualbox-graph-right-panel {\r\n width: 100%;\r\n height: 100%;\n}\n.btn-toggle-right-window {\r\n position: absolute;\r\n left: 0;\r\n top: 0;\r\n margin-left: -35px;\r\n z-index: 100;\r\n border-top-right-radius: 0px;\r\n border-bottom-right-radius: 0px;\n}\n.dualbox-graph-tab {\r\n height: 100%;\r\n width: 100%;\r\n background-color: #555 !important;\n}\n.dualbox-graph-main {\r\n height: 100%;\r\n width: calc(100% - 70px);\r\n float: right;\r\n background-color: #555 !important;\r\n transition: width 0.3s ease;\n}\n.dualbox-graph-main.left-panel-expanded {\r\n width: calc(100% - 535px);\r\n margin-left: -465px;\n}\n.dualbox-graph-main.right-panel-expanded {\r\n width: calc(100% - 535px);\n}\n.dualbox-graph-main.left-panel-expanded.right-panel-expanded {\r\n width: calc(100% - 1000px);\r\n margin-left: -465px;\n}\n.opacity0 {\r\n opacity: 0;\n}\n.btn-editor-xs {\r\n width: 18px;\r\n padding: 3px !important;\r\n line-height: 0.5;\r\n border-radius: 2px;\n}\n.btn-editor-xs > i {\r\n font-size: 10px;\n}\n.btn-outline-discrete {\r\n border-color: rgba(0, 0, 0, 0.05);\r\n border-color: transparent;\r\n color: rgba(0, 0, 0, 0.3);\n}\n.dualbox-app-navigation {\r\n background-color: transparent;\r\n margin-bottom: 0;\r\n vertical-align: middle;\r\n padding-top: 7px;\r\n padding-bottom: 7px;\r\n font-weight: bold;\r\n user-select: none;\n}\n.app-topbar {\r\n border-bottom: none;\r\n padding-left: 15px;\r\n padding-right: 15px;\r\n display: flex;\r\n width: 100%;\r\n height: 58px;\r\n padding-top: 10px;\r\n padding-bottom: 10px;\n}\n.dark,\r\n.graph-tab.active,\r\n.nav-item.active .graph-tab {\r\n color: white !important;\r\n background-color: #555 !important;\n}\n.light {\r\n color: #4d4d4d !important;\r\n background-color: #f8f9fa !important;\n}\n.main-navigation .nav-link,\r\n.main-navigation .nav-link.active,\r\n.nav-item.active .nav-link {\r\n border-bottom: none;\r\n border-left: none;\r\n border-top: none;\r\n border-right: none;\r\n position: relative;\r\n top: 1px;\n}\n.btn:focus,\r\nbutton:focus {\r\n outline: none;\r\n box-shadow: none;\n}\n.btn-transparent,\r\n.btn-transparent:hover,\r\n.btn-transparent:focus {\r\n background-color: transparent;\n}\n.connection-control {\r\n position: absolute;\r\n height: 14px;\r\n width: 14px;\r\n background-color: transparent;\r\n z-index: 19;\r\n cursor: move;\n}\n.connection-control.selected {\r\n border-color: #0066ff;\r\n box-shadow: 1px 1px 10px #0066ff;\n}\n.connection-label {\r\n z-index: 22 !important;\r\n color: #004d00 !important;\r\n background-color: white !important;\r\n padding: 4px 4px;\r\n border: 2px solid #004d00;\r\n font-size: 16px !important;\r\n border-radius: 5px;\n}\n.input-color-tag {\r\n background-color: #f2d600;\n}\n.output-color-tag {\r\n background-color: #ffab4a;\n}\n.ui-color-tag {\r\n background-color: #61bd4f;\n}\n.metanode-color-tag {\r\n background-color: #dddddd;\n}\n.input {\n}\n.output {\n}\n.fileUpload {\r\n position: relative;\r\n overflow: hidden;\r\n margin: 10px;\n}\n.fileUpload input.upload {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n margin: 0;\r\n padding: 0;\r\n font-size: 20px;\r\n cursor: pointer;\r\n opacity: 0;\r\n filter: alpha(opacity=0);\n}\n.module-edit-modal-body .btn + .btn {\r\n margin-bottom: 0;\r\n margin-left: 5px;\n}\n.btn-add-node {\r\n width: 46%;\r\n margin: 1%;\n}\nbutton.close {\r\n position: absolute;\r\n right: 0;\r\n margin-right: 5px !important;\n}\n.CodeMirror {\r\n height: auto;\r\n min-height: 300px;\n}\n.load-app,\r\n.save-app {\r\n margin-left: 5px;\r\n margin-right: 5px;\n}\n.btn-xs {\r\n padding: 0px 4px;\r\n font-size: 12px;\n}\n@media screen and (max-width: 1152px) {\n.code-panel {\r\n display: none;\n}\n.dragbar {\r\n display: none !important;\n}\n.application-container {\r\n width: 100%;\n}\n.run-options {\r\n display: none;\n}\n.application {\r\n height: 100%;\n}\n.navbar-right {\r\n display: none;\n}\n}\r\n", map: {"version":3,"sources":["C:\\Users\\maxim\\Projects\\dualbox\\editor\\js\\src\\v\\templates\\main.vue"],"names":[],"mappings":";AACA;IACA,UAAA;IACA,YAAA;IACA,mBAAA;IACA,WAAA;AACA;AAEA;IACA,sBAAA;IACA,YAAA;IACA,qBAAA;IACA,mBAAA;IACA,YAAA;AACA;AAEA;;IAEA,WAAA;IACA,YAAA;AACA;AAEA;IACA,WAAA;IACA,yBAAA;IACA,sBAAA;AACA;AAEA;IACA,YAAA;IACA,UAAA;IACA,yBAAA;IACA,qBAAA;IACA,kBAAA;AACA;AAEA;IACA,kBAAA;IACA,yBAAA;AACA;AAEA;IACA,kBAAA;IACA,WAAA;IACA,gCAAA;AACA;AAEA;IACA,kBAAA;IACA,uBAAA;IACA,gBAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,yBAAA;IACA,WAAA;AACA;AAEA;IACA,uBAAA;AACA;AAEA;IACA,kBAAA;IACA,SAAA;IACA,WAAA;IACA,aAAA;AACA;AAEA;;IAEA,2BAAA;AACA;AAEA;IACA,WAAA;IACA,aAAA;IACA,gCAAA;IACA,WAAA;IACA,uBAAA;AACA;AAEA;IACA,yBAAA;IACA,kBAAA;IACA,sBAAA;IACA,YAAA;IACA,qBAAA;IACA,UAAA;IACA,oBAAA;IACA,iBAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,2BAAA;AACA;AAEA;IACA,mBAAA;AACA;AAEA;IACA,YAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;IACA,gBAAA;IACA,iCAAA;AACA;AAEA;IACA,YAAA;IACA,YAAA;IACA,WAAA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;IACA,iCAAA;AACA;AAEA;IACA,wBAAA;IACA,yBAAA;IACA,gBAAA;IACA,+BAAA;IACA,yBAAA;IACA,4BAAA;IACA,kBAAA;IACA,kBAAA;IACA,WAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,kBAAA;IACA,QAAA;IACA,MAAA;IACA,mBAAA;IACA,YAAA;IACA,2BAAA;IACA,8BAAA;AACA;AAEA;;;;;;;;IAQA,yBAAA;IACA,oCAAA;IACA,gCAAA;AACA;AAEA;IACA,YAAA;IACA,YAAA;IACA,YAAA;IACA,kBAAA;IACA,gBAAA;IACA,oBAAA;IACA,kCAAA;AACA;AAEA;IACA,wBAAA;IACA,yBAAA;IACA,gBAAA;IACA,mBAAA;IACA,+BAAA;IACA,yBAAA;IACA,4BAAA;IACA,kBAAA;IACA,kBAAA;IACA,YAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,kBAAA;IACA,OAAA;IACA,MAAA;IACA,kBAAA;IACA,YAAA;IACA,4BAAA;IACA,+BAAA;AACA;AAEA;IACA,YAAA;IACA,WAAA;IACA,iCAAA;AACA;AAEA;IACA,YAAA;IACA,wBAAA;IACA,YAAA;IACA,iCAAA;IACA,2BAAA;AACA;AAEA;IACA,yBAAA;IACA,mBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,0BAAA;IACA,mBAAA;AACA;AAEA;IACA,UAAA;AACA;AAEA;IACA,WAAA;IACA,uBAAA;IACA,gBAAA;IACA,kBAAA;AACA;AAEA;IACA,eAAA;AACA;AAEA;IACA,iCAAA;IACA,yBAAA;IACA,yBAAA;AACA;AAEA;IACA,6BAAA;IACA,gBAAA;IACA,sBAAA;IACA,gBAAA;IACA,mBAAA;IACA,iBAAA;IACA,iBAAA;AACA;AAEA;IACA,mBAAA;IACA,kBAAA;IACA,mBAAA;IACA,aAAA;IACA,WAAA;IACA,YAAA;IACA,iBAAA;IACA,oBAAA;AACA;AAEA;;;IAGA,uBAAA;IACA,iCAAA;AACA;AAEA;IACA,yBAAA;IACA,oCAAA;AACA;AAEA;;;IAGA,mBAAA;IACA,iBAAA;IACA,gBAAA;IACA,kBAAA;IACA,kBAAA;IACA,QAAA;AACA;AAEA;;IAEA,aAAA;IACA,gBAAA;AACA;AAEA;;;IAGA,6BAAA;AACA;AAEA;IACA,kBAAA;IACA,YAAA;IACA,WAAA;IACA,6BAAA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,qBAAA;IACA,gCAAA;AACA;AAEA;IACA,sBAAA;IACA,yBAAA;IACA,kCAAA;IACA,gBAAA;IACA,yBAAA;IACA,0BAAA;IACA,kBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;AACA;AAEA;AACA;AAEA;IACA,kBAAA;IACA,gBAAA;IACA,YAAA;AACA;AAEA;IACA,kBAAA;IACA,MAAA;IACA,QAAA;IACA,SAAA;IACA,UAAA;IACA,eAAA;IACA,eAAA;IACA,UAAA;IACA,wBAAA;AACA;AAEA;IACA,gBAAA;IACA,gBAAA;AACA;AAEA;IACA,UAAA;IACA,UAAA;AACA;AAEA;IACA,kBAAA;IACA,QAAA;IACA,4BAAA;AACA;AAEA;IACA,YAAA;IACA,iBAAA;AACA;AAEA;;IAEA,gBAAA;IACA,iBAAA;AACA;AAEA;IACA,gBAAA;IACA,eAAA;AACA;AAEA;AACA;QACA,aAAA;AACA;AAEA;QACA,wBAAA;AACA;AAEA;QACA,WAAA;AACA;AAEA;QACA,aAAA;AACA;AAEA;QACA,YAAA;AACA;AAEA;QACA,aAAA;AACA;AACA","file":"main.vue","sourcesContent":["<style>\r\n.code-panel {\r\n width: 30%;\r\n height: 100%;\r\n vertical-align: top;\r\n float: left;\r\n}\r\n\r\n.application-container {\r\n width: calc(70% - 5px);\r\n height: 100%;\r\n display: inline-block;\r\n vertical-align: top;\r\n float: right;\r\n}\r\n\r\n.code-controls,\r\n.run-options {\r\n width: 100%;\r\n height: 60px;\r\n}\r\n\r\n.application {\r\n width: 100%;\r\n height: calc(100% - 60px);\r\n background-color: #ccc;\r\n}\r\n\r\n.dragbar {\r\n height: 100%;\r\n width: 5px;\r\n background-color: #e7e7e7;\r\n display: inline-block;\r\n cursor: col-resize;\r\n}\r\n\r\n.code-content {\r\n position: relative;\r\n height: calc(100% - 56px);\r\n}\r\n\r\n.code-html-container {\r\n position: relative;\r\n height: 50%;\r\n border-bottom: 1px solid #e7e7e7;\r\n}\r\n\r\n.code-css-container {\r\n position: relative;\r\n height: calc(50% - 1px);\r\n overflow: hidden;\r\n}\r\n\r\n.code-css {\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n.code-html {\r\n height: calc(100% - 40px);\r\n width: 100%;\r\n}\r\n\r\n.CodeMirror {\r\n height: 100% !important;\r\n}\r\n\r\n.code-badge {\r\n position: absolute;\r\n top: 10px;\r\n right: 10px;\r\n padding: 10px;\r\n}\r\n\r\n.btn-light.focus,\r\n.btn-light:focus {\r\n box-shadow: none !important;\r\n}\r\n\r\n.button-bar {\r\n width: 60px;\r\n padding: 10px;\r\n border-bottom: 1px solid #e7e7e7;\r\n width: 100%;\r\n background-color: white;\r\n}\r\n\r\n.noselect {\r\n -webkit-user-select: none;\r\n /* Chrome/Safari */\r\n -moz-user-select: none;\r\n /* Firefox */\r\n -ms-user-select: none;\r\n /* IE10+ */\r\n -o-user-select: none;\r\n user-select: none;\r\n}\r\n\r\n.btn + .btn {\r\n margin-left: 5px;\r\n}\r\n\r\n.btn-graph-goto {\r\n box-shadow: none !important;\r\n}\r\n\r\n.nav-tabs {\r\n border-bottom: none;\r\n}\r\n\r\n.main-navigation a.nav-link {\r\n color: white;\r\n}\r\n\r\n.main-navigation a.nav-link.active {\r\n color: #212529;\r\n}\r\n\r\n.dualbox-editor-body {\r\n width: 100%;\r\n height: 100%;\r\n overflow: hidden;\r\n background-color: rgb(85, 85, 85);\r\n}\r\n\r\n.dualbox-graph-left-section {\r\n height: 100%;\r\n width: 500px;\r\n float: left;\r\n position: relative;\r\n overflow: hidden;\r\n margin-left: -465px;\r\n transition: margin-left 0.3s ease;\r\n}\r\n\r\n.dualbox-graph-left-window {\r\n width: calc(100% - 35px);\r\n height: calc(100% - 10px);\r\n margin-top: 10px;\r\n /* background-color: #ECF2F8; */\r\n background-color: #f8f9fa;\r\n /* border: 1px solid grey; */\r\n border-radius: 5px;\r\n position: relative;\r\n float: left;\r\n}\r\n\r\n.dualbox-graph-left-panel {\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n.btn-toggle-left-window {\r\n position: absolute;\r\n right: 0;\r\n top: 0;\r\n margin-right: -35px;\r\n z-index: 100;\r\n border-top-left-radius: 0px;\r\n border-bottom-left-radius: 0px;\r\n}\r\n\r\n.btn-toggle-left-window:hover,\r\n.btn-toggle-right-window:hover,\r\n.btn-toggle-left-window:focus,\r\n.btn-toggle-right-window:focus,\r\n.btn-toggle-left-window:active,\r\n.btn-toggle-right-window:active,\r\n.btn-toggle-left-window:active:hover,\r\n.btn-toggle-right-window:active:hover {\r\n color: #212529 !important;\r\n background-color: #f8f9fa !important;\r\n border-color: #f8f9fa !important;\r\n}\r\n\r\n.dualbox-graph-right-section {\r\n height: 100%;\r\n width: 500px;\r\n float: right;\r\n position: relative;\r\n overflow: hidden;\r\n margin-right: -465px;\r\n transition: margin-right 0.3s ease;\r\n}\r\n\r\n.dualbox-graph-right-window {\r\n width: calc(100% - 35px);\r\n height: calc(100% - 20px);\r\n margin-top: 10px;\r\n margin-bottom: 30px;\r\n /* background-color: #ECF2F8; */\r\n background-color: #f8f9fa;\r\n /* border: 1px solid grey; */\r\n border-radius: 5px;\r\n position: relative;\r\n float: right;\r\n}\r\n\r\n.dualbox-graph-right-panel {\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n.btn-toggle-right-window {\r\n position: absolute;\r\n left: 0;\r\n top: 0;\r\n margin-left: -35px;\r\n z-index: 100;\r\n border-top-right-radius: 0px;\r\n border-bottom-right-radius: 0px;\r\n}\r\n\r\n.dualbox-graph-tab {\r\n height: 100%;\r\n width: 100%;\r\n background-color: #555 !important;\r\n}\r\n\r\n.dualbox-graph-main {\r\n height: 100%;\r\n width: calc(100% - 70px);\r\n float: right;\r\n background-color: #555 !important;\r\n transition: width 0.3s ease;\r\n}\r\n\r\n.dualbox-graph-main.left-panel-expanded {\r\n width: calc(100% - 535px);\r\n margin-left: -465px;\r\n}\r\n\r\n.dualbox-graph-main.right-panel-expanded {\r\n width: calc(100% - 535px);\r\n}\r\n\r\n.dualbox-graph-main.left-panel-expanded.right-panel-expanded {\r\n width: calc(100% - 1000px);\r\n margin-left: -465px;\r\n}\r\n\r\n.opacity0 {\r\n opacity: 0;\r\n}\r\n\r\n.btn-editor-xs {\r\n width: 18px;\r\n padding: 3px !important;\r\n line-height: 0.5;\r\n border-radius: 2px;\r\n}\r\n\r\n.btn-editor-xs > i {\r\n font-size: 10px;\r\n}\r\n\r\n.btn-outline-discrete {\r\n border-color: rgba(0, 0, 0, 0.05);\r\n border-color: transparent;\r\n color: rgba(0, 0, 0, 0.3);\r\n}\r\n\r\n.dualbox-app-navigation {\r\n background-color: transparent;\r\n margin-bottom: 0;\r\n vertical-align: middle;\r\n padding-top: 7px;\r\n padding-bottom: 7px;\r\n font-weight: bold;\r\n user-select: none;\r\n}\r\n\r\n.app-topbar {\r\n border-bottom: none;\r\n padding-left: 15px;\r\n padding-right: 15px;\r\n display: flex;\r\n width: 100%;\r\n height: 58px;\r\n padding-top: 10px;\r\n padding-bottom: 10px;\r\n}\r\n\r\n.dark,\r\n.graph-tab.active,\r\n.nav-item.active .graph-tab {\r\n color: white !important;\r\n background-color: #555 !important;\r\n}\r\n\r\n.light {\r\n color: #4d4d4d !important;\r\n background-color: #f8f9fa !important;\r\n}\r\n\r\n.main-navigation .nav-link,\r\n.main-navigation .nav-link.active,\r\n.nav-item.active .nav-link {\r\n border-bottom: none;\r\n border-left: none;\r\n border-top: none;\r\n border-right: none;\r\n position: relative;\r\n top: 1px;\r\n}\r\n\r\n.btn:focus,\r\nbutton:focus {\r\n outline: none;\r\n box-shadow: none;\r\n}\r\n\r\n.btn-transparent,\r\n.btn-transparent:hover,\r\n.btn-transparent:focus {\r\n background-color: transparent;\r\n}\r\n\r\n.connection-control {\r\n position: absolute;\r\n height: 14px;\r\n width: 14px;\r\n background-color: transparent;\r\n z-index: 19;\r\n cursor: move;\r\n}\r\n\r\n.connection-control.selected {\r\n border-color: #0066ff;\r\n box-shadow: 1px 1px 10px #0066ff;\r\n}\r\n\r\n.connection-label {\r\n z-index: 22 !important;\r\n color: #004d00 !important;\r\n background-color: white !important;\r\n padding: 4px 4px;\r\n border: 2px solid #004d00;\r\n font-size: 16px !important;\r\n border-radius: 5px;\r\n}\r\n\r\n.input-color-tag {\r\n background-color: #f2d600;\r\n}\r\n\r\n.output-color-tag {\r\n background-color: #ffab4a;\r\n}\r\n\r\n.ui-color-tag {\r\n background-color: #61bd4f;\r\n}\r\n\r\n.metanode-color-tag {\r\n background-color: #dddddd;\r\n}\r\n\r\n.input {\r\n}\r\n\r\n.output {\r\n}\r\n\r\n.fileUpload {\r\n position: relative;\r\n overflow: hidden;\r\n margin: 10px;\r\n}\r\n\r\n.fileUpload input.upload {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n margin: 0;\r\n padding: 0;\r\n font-size: 20px;\r\n cursor: pointer;\r\n opacity: 0;\r\n filter: alpha(opacity=0);\r\n}\r\n\r\n.module-edit-modal-body .btn + .btn {\r\n margin-bottom: 0;\r\n margin-left: 5px;\r\n}\r\n\r\n.btn-add-node {\r\n width: 46%;\r\n margin: 1%;\r\n}\r\n\r\nbutton.close {\r\n position: absolute;\r\n right: 0;\r\n margin-right: 5px !important;\r\n}\r\n\r\n.CodeMirror {\r\n height: auto;\r\n min-height: 300px;\r\n}\r\n\r\n.load-app,\r\n.save-app {\r\n margin-left: 5px;\r\n margin-right: 5px;\r\n}\r\n\r\n.btn-xs {\r\n padding: 0px 4px;\r\n font-size: 12px;\r\n}\r\n\r\n@media screen and (max-width: 1152px) {\r\n .code-panel {\r\n display: none;\r\n }\r\n\r\n .dragbar {\r\n display: none !important;\r\n }\r\n\r\n .application-container {\r\n width: 100%;\r\n }\r\n\r\n .run-options {\r\n display: none;\r\n }\r\n\r\n .application {\r\n height: 100%;\r\n }\r\n\r\n .navbar-right {\r\n display: none;\r\n }\r\n}\r\n</style>\r\n\r\n<template>\r\n <div class=\"dualbox-editor-body\">\r\n <nav class=\"main-navigation navbar navbar-default\" style=\"position: relative; margin-bottom: 0px; padding: 0; padding-top: 5px; background-color: #0B6D80;\">\r\n <ul class=\"nav nav-tabs\">\r\n <li class=\"nav-item active\">\r\n <a class=\"nav-link graph-tab\" href=\"#editor-graph-tab\" data-toggle=\"tab\">Application Graph</a>\r\n </li>\r\n <li class=\"nav-item\">\r\n <a class=\"nav-link interface-tab\" href=\"#editor-interface-tab\" data-toggle=\"tab\">Interface Editor</a>\r\n </li>\r\n </ul>\r\n\r\n <div class=\"nav navbar-right\" style=\"vertical-align: top; margin-top: 5px; margin-right: 10px; margin-bottom: 5px;\">\r\n <div v-if=\"showLoadButton === true\">\r\n <button class=\"load-app btn btn-sm btn-light\" style=\"position: relative; bottom: 3px;\" @click=\"loadApp\">Load App</button>\r\n </div>\r\n <div v-if=\"showSaveButton\">\r\n <button class=\"save-app btn btn-sm btn-light\" style=\"position: relative; bottom: 3px;\" @click=\"saveApp\">Save App</button>\r\n </div>\r\n </div>\r\n </nav>\r\n <div class=\"tab-content dualbox-graph-tab\" style=\"width: 100%; height: calc(100% - 46px);\">\r\n <div class=\"tab-pane active\" id=\"editor-graph-tab\" style=\"width: 100%; height: 100%;\">\r\n <div class=\"dualbox-graph-left-section dark\">\r\n <div class=\"dualbox-graph-left-window\">\r\n <button class=\"btn btn-light btn-toggle-left-window\" @click=\"toggleLeftWindow\" title=\"shrink window\" data-expanded=\"false\"><i class=\"fa fa-angle-double-right\"></i></button>\r\n <div class=\"dualbox-graph-left-panel light\">\r\n <edit-node-settings v-if=\"leftPanelMode == 'node' && selectedNodeId !== null\" :id=\"selectedNodeId\" :key=\"selectedNodeId\"></edit-node-settings>\r\n <edit-main-settings v-else-if=\"leftPanelMode == 'main'\" :app=\"getCurrentApplication()\" @edited=\"onEdited()\"></edit-main-settings>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"dualbox-graph-right-section dark\">\r\n <div class=\"dualbox-graph-right-window\">\r\n <button class=\"btn btn-light btn-toggle-right-window\" @click=\"toggleRightWindow\" title=\"shrink window\" data-expanded=\"false\"><i class=\"fa fa-angle-double-left\"></i></button>\r\n <div class=\"dualbox-graph-right-panel light\">\r\n <debug-node-infos v-if=\"debugNodeId !== null\" :id=\"debugNodeId\"></debug-node-infos>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"container-fluid dualbox-graph-main\" @click=\"setMainMenu\">\r\n <div class=\"row\">\r\n <div class=\"app-topbar dark\">\r\n <div class=\"justify-content-left\">\r\n <div class=\"dropdown\">\r\n <button class=\"btn btn-primary dropdown-toggle d-none\" type=\"button\" id=\"add-node-dropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" style=\"margin-right: 5px;\">\r\n Add\r\n </button>\r\n <div class=\"dropdown-menu\" aria-labelledby=\"add-node-dropdown\">\r\n <a class=\"dropdown-item add-box\" @click=\"addBox\" href=\"#\">Add box</a>\r\n <a class=\"dropdown-item add-metabox\" @click=\"addMetabox\" href=\"#\">Add metabox</a>\r\n <a class=\"dropdown-item add-input\" @click=\"addInput\" href=\"#\">Add input</a>\r\n <a class=\"dropdown-item add-output\" @click=\"addOutput\" href=\"#\">Add output</a>\r\n <a class=\"dropdown-item import-metabox\" @click=\"importMetabox\" href=\"#\">Import metabox</a>\r\n </div>\r\n <button class=\"btn btn-light btn-undo\" title=\"undo (ctrl-z)\" @click=\"undo\"><i class=\"fa fa-undo\"></i></button>\r\n <button class=\"btn btn-light btn-redo\" title=\"redo (ctrl-y)\" @click=\"redo\"><i class=\"fa fa-repeat fa-redo\"></i></button>\r\n <div class=\"form-check d-inline-block ml-2\">\r\n <label class=\"form-check-label\">\r\n <input class=\"form-check-input show-events\" type=\"checkbox\" value=\"false\" @click=\"showEvents\">\r\n <span class=\"noselect\">Show events</span>\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"justify-content-center mx-auto\">\r\n <ol class=\"dualbox-app-navigation breadcrumb\"></ol>\r\n </div>\r\n\r\n <div class=\"justify-content-right\">\r\n <div class=\"dropdown selection-menu\" style=\"display: none;\">\r\n <button class=\"btn btn-primary dropdown-toggle\" type=\"button\" id=\"selection-dropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">\r\n Selection\r\n </button>\r\n <div class=\"dropdown-menu dropdown-menu-right\" aria-labelledby=\"add-node-dropdown\">\r\n <a class=\"dropdown-item dualbox-merge-selection\" @click=\"mergeSelection\" href=\"#\">Merge</a>\r\n <a class=\"dropdown-item dualbox-remove-selection\" @click=\"removeSelection\" href=\"#\" style=\"color: red;\">Delete</a>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row\" style=\"height: calc(100% - 58px);\">\r\n <graph-vue :app=\"app\" ref=\"graph\" :displayEvents=\"displayEvents\"></graph-vue>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"tab-pane\" id=\"editor-interface-tab\" style=\"width 100%; height: 100%; background-color: white;\">\r\n <div class=\"db-editor-main\" style=\"width: 100%; height: 100%; overflow: hidden;\">\r\n <div class=\"code-panel\">\r\n <div class=\"button-bar form-inline code-controls\" style=\"position: relative;\">\r\n <button class=\"btn btn-primary btn-save-interface-element\" @click=\"saveInterfaceElement\">Save changes</button>\r\n </div>\r\n <div class=\"code-content\">\r\n <div class=\"code-html-container\">\r\n <div style=\"padding-top: 5px; padding-bottom: 5px; height: 50px; position: relative;\">\r\n <h3 style=\"position: absolute; top: 0; margin: 5px; font-size: 16px; z-index: 100; display: inline-block; margin-top: 5px;\">HTML</h3>\r\n <div class=\"d-inline-block ml-auto form-inline mr-2 mt-2\" style=\"position: absolute; top: 0; right: 0;\">\r\n <button class=\"btn btn-success btn-sm btn-add-interface\" @click=\"addInterface\"><i class=\"fas fa-plus\"></i></button>\r\n <select class=\"form-control btn-sm app-interface-select\" @change=\"selectInterface\" style=\"width: 150px; height: 32px;\">\r\n <option>Load UI...</option>\r\n <option v-for=\"interfaceName in getInterfacesNames()\" :value=\"interfaceName\">{{interfaceName}}</option>\r\n </select>\r\n <button class=\"btn btn-sm btn-light btn-edit-panel-description\" @click=\"editPanelDescription\"><i class=\"fas fa-info\" style=\"padding-left: 8px; padding-right: 8px;\"></i></button>\r\n <button class=\"btn btn-danger btn-sm btn-remove-interface\" @click=\"removeInterface\"><i class=\"fas fa-minus\"></i></button>\r\n </div>\r\n </div>\r\n <div class=\"code-html-text-container\" style=\"position: relative; height: calc(100% - 50px);\">\r\n <textarea class=\"code-html\" v-html=\"getSelectedInterfaceCode()\"></textarea>\r\n </div>\r\n </div>\r\n <div class=\"code-css-container\">\r\n <div style=\"height: 30px;\">\r\n <h3 style=\"position: absolute; top: 0; margin: 5px; font-size: 16px; z-index: 100;\">CSS</h3>\r\n </div>\r\n <div class=\"colde-css-text-container\" style=\"position: relative; height: calc(100% - 30px);\">\r\n <textarea class=\"code-css\" v-model=\"appCss\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"dragbar\"></div>\r\n <div class=\"application-container\">\r\n <div class=\"button-bar form-inline run-options\" style=\"position: relative;\">\r\n <button class=\"btn btn-success btn-run mr-2\" @click=\"runApp\">Run</button>\r\n\r\n <select class=\"form-control run-loglevel mr-1 ml-2\">\r\n <option>error</option>\r\n <option>warn</option>\r\n <option>info</option>\r\n <option>log</option>\r\n <option>debug</option>\r\n </select>\r\n\r\n <input class=\"form-control run-noversioncheck mr-1 ml-3\" type=\"checkbox\" checked>No version checking</input>\r\n <input class=\"form-control run-removetrycatch mr-1 ml-3\" type=\"checkbox\">Remove Try/catch</input>\r\n <input class=\"form-control run-makesynchrone mr-1 ml-3\" type=\"checkbox\">Make Synchrone</input>\r\n <input class=\"form-control run-ressourcecaching mr-1 ml-3\" type=\"checkbox\">Ressource caching</input>\r\n\r\n <div class=\"ml-auto\">\r\n <input class=\"form-control run-profiler mr-1 ml-3\" type=\"checkbox\">Profiler</input>\r\n <input class=\"form-control run-record mr-1 ml-3\" type=\"checkbox\">Record</input>\r\n <button class=\"btn btn-secondary btn-snapshot\" @click=\"takeAndLoadSnapshot\">Snapshot</button>\r\n </div>\r\n </div>\r\n <div class=\"application capture-left-click capture-right-click\"></div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <add-node-vue :display=\"this.addingBox\" :mousePosition=\"this.newBoxPosition\" @closed=\"onAddBoxClosed\"></add-node-vue>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport _ from \"lodash-es\";\r\nimport swal from \"sweetalert2\";\r\n\r\nimport graphVue from \"./graph.vue\";\r\nimport addNodeVue from \"./addNode.vue\";\r\nimport editMainSettingsVue from \"./editMainSettings.vue\";\r\nimport editNodeSettingsVue from \"./editNodeSettings.vue\";\r\nimport debugNodeInfosVue from \"./debugNodeInfos.vue\";\r\n\r\n// CodeMirror\r\nimport CodeMirror from \"codemirror/lib/codemirror.js\";\r\nimport \"codemirror/mode/xml/xml.js\";\r\nimport \"codemirror/mode/css/css.js\";\r\nimport \"codemirror/mode/javascript/javascript.js\";\r\nimport \"codemirror/mode/htmlmixed/htmlmixed.js\";\r\n\r\nimport htmltool from \"@dualbox/dualbox-lib-htmltool\";\r\n\r\nexport default {\r\n props: [\r\n \"app\", // the app\r\n\r\n // Display configuration (online or offline ?)\r\n \"showLoadButton\",\r\n \"showSaveButton\",\r\n \"saveButtonFunction\",\r\n\r\n // modes\r\n \"eventVisibility\" // are events visible\r\n ],\r\n components: {\r\n \"graph-vue\": graphVue,\r\n \"add-node-vue\": addNodeVue,\r\n \"edit-main-settings\": editMainSettingsVue,\r\n \"edit-node-settings\": editNodeSettingsVue,\r\n \"debug-node-infos\": debugNodeInfosVue\r\n },\r\n data() {\r\n return {\r\n // modes\r\n addingBox: false,\r\n leftPanelMode: \"main\", // 'main' to display main menu, 'node' for a node\r\n selectedNodeId: null, // id of the node to display in left menu\r\n debugNodeId: null, // on a snapshot, id of the node to display debug infos\r\n newBoxPosition: null, // track mouse position relative to the graph when adding a node\r\n displayEvents: false,\r\n selectedInterface: null,\r\n\r\n // the specific app css\r\n appCss: \"\"\r\n };\r\n },\r\n created: function() {\r\n this.view = window.dualboxEditor.v;\r\n // TODO: restore this when all menus are migrated to Vue.js\r\n\r\n this.cssCode = null;\r\n this.htmlCode = null;\r\n },\r\n updated: function() {\r\n //console.log('updating main view with: ' + JSON.stringify(this.app));\r\n this.appCss = (this.app && this.app.css) || \"\";\r\n\r\n // Update html and css code editor\r\n this.updateCode();\r\n },\r\n mounted: function() {\r\n //this.view.setMainMenu();\r\n\r\n $(this.$el).bind(\"expandSettings\", function(e) {\r\n // expand\r\n $(this)\r\n .find(\".dualbox-graph-left-section\")\r\n .css(\"margin-left\", \"0\");\r\n $(this)\r\n .find(\".dualbox-graph-main\")\r\n .addClass(\"left-panel-expanded\");\r\n $(this)\r\n .find(\".btn-toggle-left-window\")\r\n .data(\"expanded\", true)\r\n .find(\"i\")\r\n .removeClass(\"fa-angle-double-right\")\r\n .addClass(\"fa-angle-double-left\")\r\n .attr(\"title\", \"shrink window\");\r\n });\r\n\r\n $(this.$el).bind(\"shrinkSettings\", function(e) {\r\n // shrink\r\n $(this)\r\n .find(\".dualbox-graph-left-section\")\r\n .css(\"margin-left\", \"-465px\");\r\n $(this)\r\n .find(\".dualbox-graph-main\")\r\n .removeClass(\"left-panel-expanded\");\r\n $(this)\r\n .find(\".btn-toggle-left-window\")\r\n .data(\"expanded\", false)\r\n .find(\"i\")\r\n .removeClass(\"fa-angle-double-left\")\r\n .addClass(\"fa-angle-double-right\")\r\n .attr(\"title\", \"expand window\");\r\n });\r\n\r\n $(this.$el).bind(\"expandDebug\", function(e) {\r\n // expand\r\n $(this)\r\n .find(\".dualbox-graph-right-section\")\r\n .css(\"margin-right\", \"0\");\r\n $(this)\r\n .find(\".dualbox-graph-main\")\r\n .addClass(\"right-panel-expanded\");\r\n $(this)\r\n .find(\".btn-toggle-right-window\")\r\n .data(\"expanded\", true)\r\n .find(\"i\")\r\n .removeClass(\"fa-angle-double-left\")\r\n .addClass(\"fa-angle-double-right\")\r\n .attr(\"title\", \"shrink window\");\r\n });\r\n\r\n $(this.$el).bind(\"shrinkDebug\", function(e) {\r\n // shrink\r\n $(this)\r\n .find(\".dualbox-graph-right-section\")\r\n .css(\"margin-right\", \"-465px\");\r\n $(this)\r\n .find(\".dualbox-graph-main\")\r\n .removeClass(\"right-panel-expanded\");\r\n $(this)\r\n .find(\".btn-toggle-right-window\")\r\n .data(\"expanded\", false)\r\n .find(\"i\")\r\n .removeClass(\"fa-angle-double-right\")\r\n .addClass(\"fa-angle-double-left\")\r\n .attr(\"title\", \"expand window\");\r\n });\r\n\r\n // bind tabs\r\n var self = this;\r\n $(this.$el)\r\n .find(\"a[data-toggle='tab']\")\r\n .on(\"shown.bs.tab\", function(e) {\r\n var target = $(e.target).attr(\"href\"); // activated tab\r\n if (target == \"#editor-graph-tab\") {\r\n self.view.killApp();\r\n } else if (target == \"#editor-interface-tab\") {\r\n self.htmlCode.refresh();\r\n self.cssCode.refresh();\r\n self.view.runApp(self.getOptions());\r\n }\r\n });\r\n\r\n $(this.$el)\r\n .find(\"a[data-toggle='tab']\")\r\n .on(\"click\", function(e) {\r\n e.preventDefault();\r\n $(this).tab(\"show\");\r\n });\r\n\r\n // Update html and css code editor\r\n this.updateCode();\r\n\r\n // Resize horizontally\r\n $(this.$el)\r\n .find(\".dragbar\")\r\n .mousedown(function(e) {\r\n e.preventDefault();\r\n $(document).mouseup(function(e) {\r\n $(document).unbind(\"mousemove\");\r\n });\r\n $(document).mousemove(function(e) {\r\n $(\".code-panel\").css(\"width\", e.pageX + \"px\");\r\n $(\".application-container\").css(\r\n \"width\",\r\n $(\".db-editor-main\").width() - e.pageX - 5 + \"px\"\r\n );\r\n });\r\n });\r\n\r\n // prevent default behavior for ctrl+s / cmd+s\r\n $(document).keydown(function(event) {\r\n if ((event.ctrlKey || event.metaKey) && event.which == 83) {\r\n event.preventDefault();\r\n return false;\r\n }\r\n });\r\n },\r\n destroyed: function() {\r\n console.log(\"Graph vue destroyed\");\r\n $(\".ContextMenu\").remove();\r\n },\r\n methods: {\r\n getOptions: function() {\r\n return {\r\n profiler: $(this.$el)\r\n .find(\".run-profiler\")\r\n .is(\":checked\"),\r\n logLevel: $(this.$el)\r\n .find(\".run-loglevel\")\r\n .val(),\r\n options: {\r\n noVersionCheck: $(this.$el)\r\n .find(\".run-noversioncheck\")\r\n .is(\":checked\"),\r\n debug: {\r\n removeTryCatch: $(this.$el)\r\n .find(\".run-removetrycatch\")\r\n .is(\":checked\"),\r\n makeSynchrone: $(this.$el)\r\n .find(\".run-makesynchrone\")\r\n .is(\":checked\"),\r\n record: $(this.$el)\r\n .find(\".run-record\")\r\n .is(\":checked\"),\r\n ressourceCaching: $(this.$el)\r\n .find(\".run-ressourcecaching\")\r\n .is(\":checked\")\r\n }\r\n }\r\n };\r\n },\r\n\r\n updateCode: function() {\r\n // instanciate codemirror for html and css\r\n if (!this.htmlCode) {\r\n this.htmlCode = CodeMirror.fromTextArea(\r\n $(this.$el).find(\".code-html\")[0],\r\n {\r\n lineNumbers: true,\r\n mode: \"htmlmixed\",\r\n lineWrapping: true,\r\n extraKeys: {\r\n \"Ctrl-S\": () => {\r\n this.saveInterfaceElement();\r\n this.runApp();\r\n },\r\n \"Cmd-S\": () => {\r\n this.saveInterfaceElement();\r\n this.runApp();\r\n }\r\n }\r\n }\r\n );\r\n }\r\n if (!this.cssCode) {\r\n this.cssCode = CodeMirror.fromTextArea(\r\n $(this.$el).find(\".code-css\")[0],\r\n {\r\n lineNumbers: true,\r\n mode: \"css\",\r\n lineWrapping: true,\r\n extraKeys: {\r\n \"Ctrl-S\": () => {\r\n // save css code into app\r\n this.view.m.data.root.css = this.cssCode.getValue();\r\n this.view.m.save();\r\n this.runApp();\r\n },\r\n \"Cmd-S\": () => {\r\n // save css code into app\r\n this.view.m.data.root.css = this.cssCode.getValue();\r\n this.view.m.save();\r\n this.runApp();\r\n }\r\n }\r\n }\r\n );\r\n }\r\n\r\n this.htmlCode.setValue(this.getSelectedInterfaceCode());\r\n this.cssCode.setValue(this.view.m.get().css || \"\");\r\n },\r\n\r\n loadApp: function() {\r\n var self = this;\r\n\r\n // create a fake input and click it to select a file\r\n var input = $(\"<input/>\", {\r\n type: \"file\",\r\n class: \"upload\",\r\n accept: \".json\"\r\n });\r\n input.change(function(e) {\r\n // if we're not here, go to 1st tab\r\n $(\"a[data-toggle='tab'][href='#editor-graph-tab']\").click();\r\n\r\n // parse the file JSON and load it\r\n var files = e.target.files; // FileList object\r\n var r = new FileReader();\r\n r.onload = function(e) {\r\n var contents = e.target.result;\r\n var json = JSON.parse(contents);\r\n self.view.e.setApp(json);\r\n };\r\n\r\n r.readAsText(files[0]);\r\n });\r\n input.click();\r\n },\r\n saveApp: function() {\r\n // bind the app load\r\n if (this.saveButtonFunction) {\r\n var saveButtonFunction = e => {\r\n var json = this.view.m.getCleanJson();\r\n return this.saveButtonFunction(json);\r\n };\r\n } else {\r\n var saveButtonFunction = e => {\r\n var app = this.view.m.getCleanJson();\r\n var text = JSON.stringify(app, null, 2);\r\n var blob = new Blob([text], {\r\n type: \"application/octet-stream\"\r\n });\r\n\r\n var a = document.createElement(\"a\");\r\n a.href = window.URL.createObjectURL(blob);\r\n a.download = \"app.json\";\r\n\r\n // simulate a click on the link\r\n if (document.createEvent) {\r\n var event = document.createEvent(\"MouseEvents\");\r\n event.initEvent(\"click\", true, true);\r\n a.dispatchEvent(event);\r\n } else {\r\n a.click();\r\n }\r\n };\r\n }\r\n saveButtonFunction();\r\n },\r\n getCurrentMousePosition: function(e) {\r\n return this.$refs.graph.getCurrentMousePosition(e);\r\n },\r\n addBox: function(e) {\r\n this.addingBox = true;\r\n this.newBoxPosition = this.getCurrentMousePosition(e);\r\n this.$forceUpdate();\r\n },\r\n onAddBoxClosed: function() {\r\n this.addingBox = false;\r\n this.$forceUpdate();\r\n },\r\n addMetabox: function(e) {\r\n var self = this;\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n swal({\r\n input: \"text\",\r\n title: \"Choose a name for the metabox\"\r\n }).then(function(result) {\r\n if (result.value) {\r\n self.view.c.addNewMetabox(result.value);\r\n }\r\n });\r\n },\r\n addInput: function(e) {\r\n this.view.c.createInput();\r\n },\r\n addOutput: function(e) {\r\n this.view.c.createOutput();\r\n },\r\n importMetabox: async function(e) {\r\n var self = this;\r\n\r\n const { value: file } = await swal({\r\n title: \"Select your metabox file\",\r\n input: \"file\",\r\n inputAttributes: {\r\n accept: \"application/json\",\r\n \"aria-label\": \"Select your metabox file\"\r\n }\r\n });\r\n\r\n if (file) {\r\n const reader = new FileReader();\r\n reader.onload = e => {\r\n var json = JSON.parse(e.target.result);\r\n\r\n self.view.e\r\n .loadPackages(json)\r\n .then(async () => {\r\n const { value: name } = await swal({\r\n title: \"Choose a name for your metabox\",\r\n input: \"text\",\r\n showCancelButton: true,\r\n inputValidator: value => {\r\n return (\r\n !value && \"You need to write something!\"\r\n );\r\n }\r\n });\r\n\r\n self.view.c.addNewMetabox(name, json);\r\n })\r\n .catch(err => {\r\n console.error(err);\r\n });\r\n };\r\n reader.readAsText(file);\r\n }\r\n },\r\n\r\n getInterfacesNames: function() {\r\n return _.keys(\r\n _.get(this.view.m, [\"data\", \"root\", \"interface\"]) || {}\r\n );\r\n },\r\n\r\n getInterfaceCode: function(uiName) {\r\n var itf = this.view.m.data.root.interface;\r\n var htmlString = htmltool.json2html(itf[uiName]);\r\n var prettyString = htmltool.htmlPrettyPrint(htmlString);\r\n return prettyString;\r\n },\r\n\r\n getSelectedInterfaceCode: function() {\r\n return this.selectedInterface\r\n ? this.getInterfaceCode(this.selectedInterface)\r\n : \"\";\r\n },\r\n\r\n selectInterface: function(e) {\r\n // Load the interface HTML when selected\r\n var uiName = $(e.target).val();\r\n this.selectedInterface = uiName;\r\n if (uiName !== \"\" && uiName !== \"Load UI...\") {\r\n var prettyString = this.getInterfaceCode(uiName);\r\n this.htmlCode.setValue(prettyString);\r\n } else {\r\n this.htmlCode.setValue(\"\");\r\n }\r\n },\r\n saveInterfaceElement: function(e) {\r\n var currentInterface = $(this.$el)\r\n .find(\".app-interface-select\")\r\n .val();\r\n if (currentInterface !== \"\") {\r\n var currentHTML = this.htmlCode.getValue();\r\n\r\n // save html code into app\r\n this.view.m.data.root.interface[\r\n currentInterface\r\n ] = htmltool.html2json(currentHTML);\r\n }\r\n\r\n // save css code into app\r\n this.view.m.data.root.css = this.cssCode.getValue();\r\n this.view.m.save();\r\n },\r\n addInterface: function(e) {\r\n var self = this;\r\n\r\n swal.mixin({\r\n confirmButtonText: \"Next →\",\r\n showCancelButton: true,\r\n progressSteps: [\"1\", \"2\", \"3\"]\r\n })\r\n .queue([\r\n {\r\n input: \"text\",\r\n title: \"Choose a name\",\r\n text: \"Enter a name for the new interface\"\r\n },\r\n {\r\n input: \"select\",\r\n title: \"Choose the type\",\r\n text: \"Is it a viewer panel or a control panel?\",\r\n inputOptions: {\r\n control: \"A control panel\",\r\n viewer: \"A viewer\"\r\n }\r\n },\r\n {\r\n input: \"select\",\r\n title: \"Choose the position\",\r\n text: \"Where do you want to position your panel?\",\r\n inputOptions: {\r\n \"top-left\": \"At the top-left\",\r\n \"top-center\": \"At the top-center\",\r\n \"top-right\": \"At the top-right\",\r\n \"center-left\": \"At the center-left\",\r\n center: \"At the center\",\r\n \"center-right\": \"At the center-right\",\r\n \"bottom-left\": \"At the bottom-left\",\r\n \"bottom-center\": \"At the bottom-center\",\r\n \"bottom-right\": \"At the bottom-right\",\r\n \"whole-screen\": \"I want my panel in full-screen\"\r\n }\r\n }\r\n ])\r\n .then(result => {\r\n if (result.value) {\r\n var name = result.value[0];\r\n var type = result.value[1];\r\n var position = result.value[2];\r\n\r\n if (name === \"\") {\r\n swal.showInputError(\"the name is empty!\");\r\n return false;\r\n }\r\n\r\n var appInterface = self.view.m.data.root.interface;\r\n if (appInterface[name]) {\r\n swal.showInputError(\r\n \"Interface \" + name + \" already exists!\"\r\n );\r\n return false;\r\n } else {\r\n var style = {};\r\n var cssPositionClass = \"dualbox-panel-\" + position;\r\n\r\n // add a basic control\r\n appInterface[name] = {\r\n type: \"Element\",\r\n tagName: \"div\",\r\n attributes: {\r\n className: [\r\n \"dualbox\",\r\n \"dualbox-container\",\r\n \"dualbox-container-\" + name,\r\n type == \"viewer\"\r\n ? \"dualbox-viewer dualbox-mobile-h60\"\r\n : \"dualbox-controls\",\r\n \"dualbox-panel\",\r\n cssPositionClass\r\n ]\r\n },\r\n children: []\r\n };\r\n\r\n // add the value to our select, and load it\r\n $(self.$el)\r\n .find(\".app-interface-select\")\r\n .append(\r\n $(\"<option/>\", {\r\n value: name\r\n }).append(name)\r\n );\r\n $(document).ready(() => {\r\n $(self.$el)\r\n .find(\".app-interface-select\")\r\n .val(name)\r\n .change();\r\n\r\n // set it into the editor\r\n var htmlString = htmltool.json2html(\r\n appInterface[name]\r\n );\r\n var prettyString = htmltool.htmlPrettyPrint(\r\n htmlString\r\n );\r\n this.htmlCode.setValue(prettyString);\r\n self.updateCode();\r\n });\r\n\r\n self.view.m.save();\r\n self.view.runApp(self.getOptions());\r\n }\r\n }\r\n });\r\n },\r\n removeInterface: function(e) {\r\n var self = this;\r\n var name = $(\".app-interface-select\").val();\r\n\r\n swal({\r\n title: \"Confirm deleting \" + name + \" ?\",\r\n type: \"warning\",\r\n showCancelButton: true,\r\n confirmButtonColor: \"#DD6B55\",\r\n confirmButtonText: \"Yes, delete it!\",\r\n closeOnConfirm: true,\r\n closeOnCancel: true\r\n }).then(result => {\r\n if (result.value) {\r\n // set the interface back to first value\r\n $(this.$el)\r\n .find(\r\n \".app-interface-select option[value='\" + name + \"']\"\r\n )\r\n .remove();\r\n $(this.$el)\r\n .find(\".app-interface-select\")\r\n .change();\r\n delete self.view.m.data.root.interface[name];\r\n self.htmlCode.setValue(\"\");\r\n self.view.runApp(self.getOptions());\r\n }\r\n });\r\n },\r\n editPanelDescription: function(e) {\r\n var self = this;\r\n var name = $(\".app-interface-select\").val();\r\n\r\n swal({\r\n title: \"Enter a description for this panel!\",\r\n input: \"textarea\",\r\n inputValue:\r\n this.view.m.data.root.interface[name].description || \"\",\r\n showCancelButton: true,\r\n closeOnConfirm: false,\r\n showLoaderOnConfirm: true,\r\n animation: \"slide-from-top\",\r\n inputPlaceholder: \"Write something\"\r\n }).then(result => {\r\n if (result.value === \"\") {\r\n swal.showInputError(\"You need to write something!\");\r\n return false;\r\n } else {\r\n self.view.m.data.root.interface[name].description =\r\n result.value;\r\n }\r\n });\r\n },\r\n toggleLeftWindow: function(e) {\r\n var expanded = $(e.target)\r\n .closest(\"button\")\r\n .data(\"expanded\");\r\n if (expanded) {\r\n $(this.$el).trigger(\"shrinkSettings\");\r\n } else {\r\n $(this.$el).trigger(\"expandSettings\");\r\n }\r\n },\r\n toggleRightWindow: function(e) {\r\n var expanded = $(e.target)\r\n .closest(\"button\")\r\n .data(\"expanded\");\r\n if (expanded) {\r\n $(this.$el).trigger(\"shrinkDebug\");\r\n } else {\r\n $(this.$el).trigger(\"expandDebug\");\r\n }\r\n },\r\n\r\n showEvents: function(e) {\r\n //this.view.setEventsVisibility( $(e.target).is(':checked') );\r\n this.displayEvents = $(e.target).is(\":checked\");\r\n },\r\n\r\n runApp: function(e) {\r\n this.view.runApp(this.getOptions());\r\n },\r\n\r\n takeAndLoadSnapshot: function(e) {\r\n this.view.takeAndLoadSnapshot();\r\n },\r\n\r\n undo: function(e) {\r\n this.view.c.undo();\r\n },\r\n\r\n redo: function(e) {\r\n this.view.c.redo();\r\n },\r\n\r\n removeSelection: function(e) {\r\n this.view.c.deleteSelection();\r\n },\r\n\r\n mergeSelection: function(e) {\r\n this.view.c.mergeSelection();\r\n },\r\n\r\n setMainMenu: async function(e) {\r\n await this.view.setMainMenu();\r\n },\r\n\r\n getCurrentApplication: function(e) {\r\n // trick to make this function reactive to \"app\" field update\r\n if (this.app) {\r\n return this.view.m.getCurrentApp(true);\r\n } else {\r\n throw \"Error: no app found\";\r\n }\r\n },\r\n\r\n onEdited: function(e) {\r\n console.log(\"Something was edited, forcing new render\");\r\n this.$forceUpdate();\r\n },\r\n\r\n ready: function() {\r\n return new Promise(resolve => {\r\n this.$nextTick(() => {\r\n window.requestAnimationFrame(() => {\r\n $(this.$el).ready(resolve);\r\n });\r\n });\r\n });\r\n }\r\n }\r\n};\r\n</script>\r\n"]}, media: undefined });
|
|
88865
88897
|
|
|
88866
88898
|
};
|
|
88867
88899
|
/* scoped */
|