@dualbox/editor 1.0.66 → 1.0.68

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.
@@ -43750,7 +43750,7 @@ class GraphModel {
43750
43750
  // switch to the next window
43751
43751
  this.data.app = this.data.app || [];
43752
43752
  this.data.app = this.data.app.concat(["metanodes", name]);
43753
- this.data.windows.push([name, metanode]);
43753
+ this.data.windows.push([name, this.data.app]);
43754
43754
  this.save();
43755
43755
  }
43756
43756
 
@@ -66800,8 +66800,8 @@ var script$b = {
66800
66800
  this.activateTooltip();
66801
66801
 
66802
66802
  // bind the json editor
66803
- editor = new _import$1($(this.$el).find('.json-editor')[0], { modes: ['tree', 'code', 'text' ]});
66804
- editor.set({});
66803
+ this.editor = new _import$1($(this.$el).find('.json-editor')[0], { modes: ['tree', 'code', 'text' ]});
66804
+ this.editor.set({});
66805
66805
  },
66806
66806
  beforeUpdate: function() {
66807
66807
  //console.log('[Updating] node-settings');
@@ -66823,6 +66823,11 @@ var script$b = {
66823
66823
  deactivate: function() {
66824
66824
  this.deactivateTooltip();
66825
66825
  },
66826
+ destroyed: function() {
66827
+ if( this.editor ) {
66828
+ this.editor.destroy();
66829
+ }
66830
+ },
66826
66831
  methods: {
66827
66832
  fixCardStyle: function() {
66828
66833
  var card = $(this.$el).find('.module-left-signature .card');
@@ -69011,7 +69016,7 @@ __vue_render__$b._withStripped = true;
69011
69016
  /* style */
69012
69017
  const __vue_inject_styles__$b = function (inject) {
69013
69018
  if (!inject) return
69014
- inject("data-v-3523c2f3_0", { source: "\n.edit-dualbox-node-id {\n margin-bottom: 0px;\n display: inline-block;\n width: 100%;\n}\n.edit-dualbox-node-package-name {\n font-style: italic;\n}\n.btn-edit-dualbox-node-name {\n display: inline-block;\n margin-left: 5px;\n margin-top: -10px;\n position: relative;\n top: -10px;\n vertical-align: bottom;\n}\n.module-left-description {\n padding-top: 30px;\n font-size: 12px;\n text-align: center;\n}\n.card-settings .card-body {\n font-size: 12px;\n padding-left: 5px;\n padding-right: 5px;\n overflow-y: auto;\n}\n.table-desc {\n width: 100%;\n}\n.table-desc > thead > th > td {\n margin-right: 6px;\n}\n.table-desc > tbody > tr > td {\n margin-right: 6px;\n padding-top: 8px;\n padding-bottom: 8px;\n height: 40px;\n}\n.card-header[data-toggle=\"collapse\"] {\n cursor: pointer;\n}\n.card-header[data-toggle=\"collapse\"] h5 {\n user-select: none;\n}\n.card-header[data-toggle=\"collapse\"]:hover .btn-link {\n text-decoration: none;\n}\n.dualbox-node-name, .dualbox-node-name-input {\n max-width: 400px;\n}\n.dualbox-node-name-span {\n max-width: 350px;\n}\n.dualbox-node-name-input {\n display: inline-block;\n border-radius: 4px;\n padding: 4px 8px 4px 8px;\n font-size: 20px;\n max-width: 280px;\n}\n.text-value, .number-value, .boolean-value {\n max-width: 140px;\n}\n.event-if, .event-data {\n max-width: 80px;\n}\n.select-event-target, .select-event-name, .event-if, .event-data {\n font-size: 12px;\n}\n.edit-body {\n overflow-y: hidden;\n overflow-x: hidden;\n max-height: calc(100% - 90px);\n}\n.table-events .event-rooting {\n margin-top: 10px;\n}\n.table-events thead {\n border-bottom: 1px solid #ddd;\n}\n.table-events .tr-event-condition td {\n padding-left: 10px;\n}\n.table-events .tr-event-data td {\n padding-left: 10px;\n}\n.tr-event-condition td, .tr-event-data td {\n height: 20px!important;\n}\n.tr-event-condition, .tr-event-condition td, .tr-event-data, .tr-event-data td {\n padding-top: 1px!important;\n padding-bottom: 1px!important;\n}\n.table-events tr + .event-rooting {\n /* border-top: 1px solid #ddd; */\n}\n.event-rooting td {\n padding-top: 8px!important;\n padding-bottom: 4px!important;\n}\n.event-data-type {\n font-size: 75%;\n border-radius: 5px;\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n}\n.event-data-display {\n font-size: 75%;\n border-radius: 5px;\n border: 1px solid #ddd;\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n}\n.event-if {\n font-size: 75%;\n border-radius: 5px;\n border: 1px solid #ddd;\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n}\ni.fa, i.fas, i.far {\n pointer-events: none;\n}\n.h100 {\n height: 100%;\n}\n\n", map: {"version":3,"sources":["/home/seb/dev/dualbox/editor/js/src/v/templates/editNodeSettings.vue"],"names":[],"mappings":";AACA;IACA,kBAAA;IACA,qBAAA;IACA,WAAA;AACA;AAEA;IACA,kBAAA;AACA;AAEA;IACA,qBAAA;IACA,gBAAA;IACA,iBAAA;IACA,kBAAA;IACA,UAAA;IACA,sBAAA;AACA;AAEA;IACA,iBAAA;IACA,eAAA;IACA,kBAAA;AACA;AAEA;IACA,eAAA;IACA,iBAAA;IACA,kBAAA;IACA,gBAAA;AACA;AAEA;IACA,WAAA;AACA;AAEA;IACA,iBAAA;AACA;AAEA;IACA,iBAAA;IACA,gBAAA;IACA,mBAAA;IACA,YAAA;AACA;AAEA;IACA,eAAA;AACA;AAEA;IACA,iBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,qBAAA;IACA,kBAAA;IACA,wBAAA;IACA,eAAA;IACA,gBAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,eAAA;AACA;AAEA;IACA,eAAA;AACA;AAEA;IACA,kBAAA;IACA,kBAAA;IACA,6BAAA;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","file":"editNodeSettings.vue","sourcesContent":["<style>\n .edit-dualbox-node-id {\n margin-bottom: 0px;\n display: inline-block;\n width: 100%;\n }\n\n .edit-dualbox-node-package-name {\n font-style: italic;\n }\n\n .btn-edit-dualbox-node-name {\n display: inline-block;\n margin-left: 5px;\n margin-top: -10px;\n position: relative;\n top: -10px;\n vertical-align: bottom;\n }\n\n .module-left-description {\n padding-top: 30px;\n font-size: 12px;\n text-align: center;\n }\n\n .card-settings .card-body {\n font-size: 12px;\n padding-left: 5px;\n padding-right: 5px;\n overflow-y: auto;\n }\n\n .table-desc {\n width: 100%;\n }\n\n .table-desc > thead > th > td {\n margin-right: 6px;\n }\n\n .table-desc > tbody > tr > td {\n margin-right: 6px;\n padding-top: 8px;\n padding-bottom: 8px;\n height: 40px;\n }\n\n .card-header[data-toggle=\"collapse\"] {\n cursor: pointer;\n }\n\n .card-header[data-toggle=\"collapse\"] h5 {\n user-select: none;\n }\n\n .card-header[data-toggle=\"collapse\"]:hover .btn-link {\n text-decoration: none;\n }\n\n .dualbox-node-name, .dualbox-node-name-input {\n max-width: 400px;\n }\n\n .dualbox-node-name-span {\n max-width: 350px;\n }\n\n .dualbox-node-name-input {\n display: inline-block;\n border-radius: 4px;\n padding: 4px 8px 4px 8px;\n font-size: 20px;\n max-width: 280px;\n }\n\n .text-value, .number-value, .boolean-value {\n max-width: 140px;\n }\n\n .event-if, .event-data {\n max-width: 80px;\n }\n\n .select-event-target, .select-event-name, .event-if, .event-data {\n font-size: 12px;\n }\n\n .edit-body {\n overflow-y: hidden;\n overflow-x: hidden;\n max-height: calc(100% - 90px);\n }\n\n .table-events .event-rooting {\n margin-top: 10px;\n }\n\n .table-events thead {\n border-bottom: 1px solid #ddd;\n }\n\n .table-events .tr-event-condition td {\n padding-left: 10px;\n }\n\n .table-events .tr-event-data td {\n padding-left: 10px;\n }\n\n .tr-event-condition td, .tr-event-data td {\n height: 20px!important;\n }\n\n .tr-event-condition, .tr-event-condition td, .tr-event-data, .tr-event-data td {\n padding-top: 1px!important;\n padding-bottom: 1px!important;\n }\n\n .table-events tr + .event-rooting {\n /* border-top: 1px solid #ddd; */\n }\n\n .event-rooting td {\n padding-top: 8px!important;\n padding-bottom: 4px!important;\n }\n\n .event-data-type {\n font-size: 75%;\n border-radius: 5px;\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n }\n\n .event-data-display {\n font-size: 75%;\n border-radius: 5px;\n border: 1px solid #ddd;\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n }\n\n .event-if {\n font-size: 75%;\n border-radius: 5px;\n border: 1px solid #ddd;\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n }\n\n i.fa, i.fas, i.far {\n pointer-events: none;\n }\n\n .h100 {\n height: 100%;\n }\n\n</style>\n\n<template>\n <div class=\"edit-node-panel h100\" id=\"edit-node-panel\" :key=\"n.id\">\n <div class=\"edit-node-presentation\" style=\"padding-left: 10px; padding-top: 10px; padding-right: 10px; padding-bottom: 10px;\">\n <h2 class=\"edit-dualbox-node-id\">\n <div v-if=\"nowEditingNodeName\" class=\"dualbox-node-name-edit\">\n <input type=\"text\" class=\"form-control dualbox-node-name-input\" style=\"display: inline-block;\" :value=\"n.graphId\" @keypress=\"changeNodeName\" autofocus/>\n <button class=\"btn btn-primary btn-save-node-name-change\" :data-id=\"n.graphId\" style=\"display: inline-block;\" @click=\"saveNodeName\">Save</button>\n </div>\n <div v-else class=\"dualbox-node-name\">\n <button class=\"btn btn-light btn-sm btn-edit-dualbox-node-name\" @click=\"editNodeName\"><i class=\"fa fa-edit\"></i></button>\n <span class=\"dualbox-node-name-span text-truncate d-inline-block\">{{n.graphId}}</span>\n </div>\n </h2>\n <p style=\"margin-bottom: 0\"><small class=\"edit-dualbox-node-package-name\">{{n.getPackageName()}}</small></p>\n </div>\n\n <div class=\"edit-body\">\n <div class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-desc\" data-toggle=\"collapse\" data-target=\"#dualbox-node-desc-collapse\" aria-expanded=\"true\" aria-controls=\"dualbox-node-desc-collapse\">\n <h5 class=\"mb-0 btn-link\">Description</h5>\n </div>\n\n <div id=\"dualbox-node-desc-collapse\" class=\"collapse show\" aria-labelledby=\"dualbox-node-desc\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\" style=\"padding-left: 15px;\">\n <div class=\"module-left-signature\">\n <graph-node :id=\"n.id\" :example=\"true\" :pkg=\"n.getPackage()\" :n=\"createExampleNode(n)\"></graph-node>\n </div>\n <p class=\"module-left-description\">\n <template v-if=\"n.isInput() || n.isOutput() || n.isMetanode()\">\n <template v-if=\"nowEditingDescription\">\n <textarea class=\"edit-node-description\" rows=4 style=\"width: 100%;\" :value=\"n.getDescription()\" autofocus>\n </textarea>\n <button class=\"btn btn-success\" @click=\"setDescription\">Save</button>\n </template>\n <template v-else>\n <button class=\"btn btn-transparent btn-xs\" @click=\"editDescription\"><i class=\"fa fa-edit\" ></i></button>\n <span> {{ getDescription() }}</span>\n </template>\n </template>\n <span v-else>\n {{ n.getPackage().description || \"[No description available]\" }}\n </span>\n </p>\n </div>\n </div>\n </div>\n\n <div class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-comments\" data-toggle=\"collapse\" data-target=\"#dualbox-node-comments-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-comments-collapse\">\n <h5 class=\"mb-0 btn-link\">Comments</h5>\n </div>\n <div id=\"dualbox-node-comments-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-comments\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <div style=\"padding-left: 15px; padding-right: 15px;\">\n <div v-if=\"nowEditingComment\" class=\"node-comment-edit\">\n <textarea class=\"node-comment\" rows=4 style=\"width: 100%;\" :data-id=\"n.id\" v-model=\"comment\" autofocus>\n </textarea>\n <div style=\"text-align: right; margin-top: 10px;\">\n <button class=\"btn btn-sm btn-secundary\" @click=\"deleteComment\">Delete</button>\n <button class=\"btn btn-sm btn-primary btn-save-comment\" @click=\"saveComment\">Save</button>\n </div>\n </div>\n <p v-else class=\"node-comment-text\">\n <span>{{ n.hasComment() ? n.getComment() : \"[Add a comment]\" }} </span>\n <button class=\"btn btn-sm btn-transparent\" @click=\"editComment\"><i class=\"fa fa-edit\"></i></button>\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Compute options -->\n <div v-if=\"n.isModule()\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-inputs\" data-toggle=\"collapse\" data-target=\"#dualbox-node-compute-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-compute-collapse\">\n <h5 class=\"mb-0 btn-link\">Compute options</h5>\n </div>\n <div id=\"dualbox-node-compute-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-inputs\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <div class=\"form-group\" style=\"padding-left: 20px;\">\n <div>\n <label>\n <input class=\"input-cache-toggle\" type=\"checkbox\" v-bind:checked=\"n.hasCacheActivated()\" @change=\"toggleCache\">\n <span>Cache result <button type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"Keep the result in memory (the cache) to avoid computing this box every-time its result is required. The cache will be invalidated if an input prior to this box is changed.\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button></span>\n </label>\n </div>\n\n <div v-if=\"!n.isMetanode()\">\n <label>\n <input class=\"input-worker-toggle\" type=\"checkbox\" v-bind:data-id=\"n.id\" v-bind:checked=\"n.isParallel()\" @change=\"toggleWorker\" />\n <span>Execute in a worker <button type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"Workers are separate contexts of executions that can execute long-running tasks without blocking the browser execution. Use this for heavy computations.\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button></span>\n </label>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Widget options -->\n <div v-if=\"n.isWidget()\" class=\"card card-default\">\n <div class=\"card-header\" id=\"dualbox-node-widget\" data-toggle=\"collapse\" data-target=\"#dualbox-node-widget-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-widget-collapse\">\n <h5 class=\"mb-0 btn-link\">Widget Options</h5>\n </div>\n <div id=\"dualbox-node-widget-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-widget\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <span>Widget registered to: </span>\n <select class=\"form-control form-control-sm select-widget-registerTo\" style=\"max-width: 250px;\" @change=\"registerToWidget\">\n <option value=\"\">none</option>\n <option v-for=\"target in getSpecialUINodes()\" :key=\"'target-'+target.id\" :value=\"target.graphId\" :selected=\"n.getWidgetRegistration() == target.graphId\">{{target.id}}</option>\n\n </select>\n </div>\n </div>\n </div>\n\n <!-- Inputs -->\n <div v-if=\"n.isInput()\" class=\"card card-default\">\n <div class=\"card-header\" id=\"dualbox-node-default\" data-toggle=\"collapse\" data-target=\"#dualbox-node-default-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-default-collapse\">\n <h5 class=\"mb-0 btn-link\">Default value</h5>\n </div>\n <div id=\"dualbox-node-default-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-default\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <span>Default value:</span>\n <span><display-value :v=\"n.getDefaultValue()\" :type=\"n.getType()\" @edited=\"onEditDefaultValue\"></display-value></span>\n </div>\n </div>\n </div>\n <div v-else-if=\"n.hasInputs()\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-inputs\" data-toggle=\"collapse\" data-target=\"#dualbox-node-inputs-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-inputs-collapse\">\n <h5 class=\"mb-0 btn-link\">Inputs <small><span class=\"badge badge-secondary\">{{n.getInputsNames().length}}</span></small></h5>\n </div>\n <div id=\"dualbox-node-inputs-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-inputs\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Input</th>\n <th>Visible</th>\n <th>Type</th>\n <th>Default</th>\n </thead>\n <tbody>\n <tr v-for=\"key in n.getInputsNames()\" :key=\"'input-'+key\">\n <td>\n {{key}}\n <button v-if=\"n.hasInputDesc(key)\" type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" v-bind:title=\"n.getInputDesc(key)\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button>\n </td>\n <td>\n <input class=\"input-visibility-toggle\" type=\"checkbox\" v-bind:data-id=\"n.id\" v-bind:data-input=\"key\" v-bind:checked=\"n.isInputVisible(key)\" @change=\"toggleInputVisibility\">\n </td>\n <td>\n <!-- If there's a start, then we must edit the type -->\n <display-type :type=\"n.getInputType(key)\" :readonly=\"!n.isInputTemplateType(key)\" @edited=\"onEditInputType(key, $event)\"></display-type>\n </td>\n <td>\n <display-value :v=\"n.getInputDefaultValue(key)\" :type=\"n.getInputType(key)\" @edited=\"onEditInputDefaultValue(key, $event)\" :readonly=\"!n.isFullyDefinedInputType(key)\" :readonlyReason=\"!n.isFullyDefinedInputType(key) ? 'You must first define a full type (without *) before you can edit this value' : ''\"></display-value>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <!-- Outputs -->\n <div v-if=\"n.hasOutputs()\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-outputs\" data-toggle=\"collapse\" data-target=\"#dualbox-node-outputs-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-outputs-collapse\">\n <h5 class=\"mb-0 btn-link\">Outputs <small><span class=\"badge badge-secondary\">{{n.getOutputsNames().length}}</span></small></h5>\n </div>\n <div id=\"dualbox-node-outputs-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-outputs\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Output</th>\n <th>Type</th>\n <th>Visible</th>\n </thead>\n <tbody>\n <tr v-for=\"key in n.getOutputsNames()\" :key=\"'output-'+key\">\n <td>{{key}}\n <button v-if=\"n.hasOutputDesc(key)\" type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" v-bind:title=\"n.getOutputDesc(key)\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button>\n </td>\n <td><display-type :type=\"n.getOutputType(key)\"></display-type></td>\n <td>\n <input class=\"output-visibility-toggle\" type=\"checkbox\" v-bind:data-id=\"n.id\" v-bind:data-output=\"key\" v-bind:checked=\"n.isOutputVisible(key)\" @change=\"toggleOutputVisibility\">\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <!-- Attributes -->\n <div v-if=\"n.hasAttributes()\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-attrs\" data-toggle=\"collapse\" data-target=\"#dualbox-node-attrs-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-attrs-collapse\">\n <h5 class=\"mb-0 btn-link\">Attributes <small><span class=\"badge badge-secondary\">{{n.getAttributesNames().length}}</span></small></h5>\n </div>\n <div id=\"dualbox-node-attrs-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-attrs\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Output</th>\n <th>Type</th>\n <th>Value</th>\n </thead>\n <tbody>\n <tr v-for=\"key in n.getAttributesNames()\" :key=\"'attr-'+key\">\n <td>{{key}}\n <button v-if=\"n.hasAttributeDesc(key)\" type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" :title=\"n.getAttributeDesc(key)\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button>\n </td>\n <td>\n <!-- If there's a start, then we must edit the type -->\n <display-type :type=\"n.getAttributeType(key)\" :readonly=\"!n.isAttributeTemplateType(key)\" @edited=\"onEditAttributeType(key, $event)\"></display-type>\n </td>\n <td>\n <display-value :v=\"n.getAttributeValue(key)\" :type=\"n.getAttributeType(key)\" @edited=\"onEditAttribute(key, $event)\" :readonly=\"!n.isFullyDefinedAttributeType(key)\" :readonlyReason=\"!n.isFullyDefinedInputType(key) ? 'You must first define a full type (without *) before you can edit this value' : ''\"></display-value>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n\n <!-- Loops -->\n <div v-if=\"n.hasInputs()\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-inputs\" data-toggle=\"collapse\" data-target=\"#dualbox-node-loops-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-loops-collapse\">\n <h5 class=\"mb-0 btn-link\">Loops <small><span class=\"badge badge-secondary\">{{ n.hasLoop() ? \"on\" : \"off\" }}</span></small></h5>\n </div>\n <div id=\"dualbox-node-loops-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-inputs\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <h4>Iterators\n <button type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"Iterators will break an array in input into a list of their components. The module will be computed several times, each time with one different component from every iterator input. Inputs that don't define iterators will use their current value as-is for the different computations.\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button>\n </h4>\n <table class=\"table-desc table-striped\">\n <tbody>\n <tr v-for=\"key in n.getInputsNames()\" :key=\"'loop-iterator-'+key\">\n <td>{{key}}</td>\n <td>\n <input class=\"input-iterator-toggle\" type=\"checkbox\" :data-input=\"key\" :checked=\"n.hasIterator(key)\" @change=\"toggleIterator\" />\n </td>\n </tr>\n </tbody>\n </table>\n\n <h4 class=\"mt-2\">Feedback\n <button type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"Feedback (during a loop) is a reinjection of an output result of one iteration into an input of the next iteration.\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button>\n </h4>\n <table class=\"table-desc table-striped\">\n <tbody>\n <tr v-for=\"key in n.getOutputsNames()\" :key=\"'loop-feedback-'+key\">\n <td>{{key}}</td>\n <td>\n <select class=\"form-control form-control-sm select-output-feedback\" :data-output=\"key\" @change=\"selectOutputFeedback\">\n <option value=\"none\">No feedback</option>\n <option v-for=\"i in n.getInputsNames()\" :value=\"i\" :selected=\"n.getFeedback(key) == i\" :key=\"'loop-feedback-input-'+i\">{{i}}</option>\n </select>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <!-- Events -->\n <div v-if=\"n.isUI()\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-events\" data-toggle=\"collapse\" data-target=\"#dualbox-node-events-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-events-collapse\">\n <h5 class=\"mb-0 btn-link\">Events <small><span class=\"badge badge-secondary\">{{n.getOutboundEvents().length}}</span></small></h5>\n </div>\n <div id=\"dualbox-node-events-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-events\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <table class=\"table-events table-desc\" style=\"font-size: 12px!important;\">\n <thead class=\"thead-dark\">\n <th>Target</th>\n <th>Event</th>\n <th>Action</th>\n </thead>\n <tbody>\n <template v-if=\"n.hasOutEvents()\" v-for=\"(evt, index) in n.getOutboundEvents()\" :data-index=\"index\">\n <tr class=\"event-rooting\">\n <td>\n <select v-if=\"evt.node\" class=\"form-control form-control-sm select-event-target\" :data-index=\"index\"@change=\"selectEventTarget\" >\n <option v-for=\"node in getUINodesWithEvents()\" :value=\"node.getGraphId()\" :selected=\"node.getGraphId()==evt.node\" :key=\"node.id\">{{node.getGraphId()}}</option>\n </select>\n <span v-else>{{evt.selector}}</span>\n </td>\n <td>\n <select class=\"form-control form-control-sm select-event-name\" :data-index=\"index\" @change=\"selectEventName\">\n <template v-if=\"evt.node\">\n <option v-for=\"targetEvent in getTargetNodeEvents(evt.node)\" :value=\"targetEvent\" :selected=\"evt.event===targetEvent\" :key=\"targetEvent\">{{targetEvent}}</option>\n </template>\n <template v-else>\n <option value=\"hide\">hide</option>\n <option value=\"show\">show</option>\n </template>\n </select>\n </td>\n <td>\n <button class=\"btn btn-secondary btn-editor-xs\" :data-index=\"index\" @click=\"toggleAdvancedAppEventSettings\" style=\"margin-left: 10px;\" title=\"Toggle advanced event settings\" >\n <i class=\"fas fa-cog\"></i>\n </button>\n <button class=\"btn btn-danger btn-editor-xs btn-remove-event\" :data-index=\"index\" @click=\"removeEvent\">\n <i class=\"fa fa-minus\"></i>\n </button>\n </td>\n </tr>\n <tr v-if=\"evt.if || expanded[index]\" class=\"tr-event-condition\">\n <td colspan=\"3\">\n <span style=\"width: 60px; display: inline-block;\"><i class=\"fas fa-caret-right\"></i> Occur if:</span>\n\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-index=\"index\" :value=\"evt.if\" @change=\"setEventIf\" />\n </td>\n </tr>\n <tr v-if=\"evt.data || evt.datatype || expanded[index]\" class=\"tr-event-data\" colspan=\"3\">\n <td colspan=\"3\">\n <span style=\"width: 53px; display: inline-block;\"><i class=\"fas fa-caret-right\"></i> Data:</span>\n <span style=\"width: 350px;\">\n <display-type :type=\"getDataType(evt)\" @edited=\"onEditEventInDataType(key, index, $event)\"></display-type>\n <display-value :v=\"evt.data\" :type=\"getDataType(evt)\" @edited=\"onEditEventData(key, index, $event)\"></display-value>\n </span>\n </td>\n </tr>\n </template>\n <tr>\n <td colspan=\"5\" style=\"padding-top: 0px; padding-bottom: 0px;\">\n <button class=\"btn btn-sm\" :data-id=\"n.id\" style=\"width: 100%;\" @click=\"addEvent\">Add event</button>\n </td>\n </tr>\n </tbody>\n </table>\n\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"modal edit-value-modal\" tabindex=\"-1\" role=\"dialog\">\n <div class=\"modal-dialog\" role=\"document\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Edit value</h5>\n <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"set-type\">\n <div class=\"form-check\">\n <input type=\"radio\" class=\"form-check-input set-value unset-value\" id=\"unset-value\" name=\"set-value\" value=\"unset-value\" checked>\n <label class=\"form-check-label\" for=\"unset-value\">\n don't set a value\n </label>\n </div>\n <div class=\"form-check\">\n <input type=\"radio\" class=\"form-check-input set-value set-value-null\" id=\"set-value-null\" name=\"set-value\" value=\"set-value-null\">\n <label class=\"form-check-label\" for=\"set-value-null\">\n set null\n </label>\n </div>\n <div class=\"form-check\">\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\">\n <div class=\"form-inline form-check-label\" style=\"height: 24px;\">\n <label for=\"set-value-type\">\n set a value of type:\n <select class=\"form-control choose-value-type d-inline-block form-control-sm ml-2\">\n <option value=\"string\">String</option>\n <option value=\"number\">Number</option>\n <option value=\"boolean\">Boolean</option>\n <option value=\"object\">Object</option>\n <option value=\"file\">File</option>\n </select>\n </label>\n </div>\n </div>\n </div>\n <hr class=\"separator\"/>\n <div class=\"has-value\" style=\"display: none;\">\n <div class=\"define-value define-boolean\" style=\"display: none;\">\n <div class=\"form-inline\">\n <label>Value: </label>\n <select class=\"form-control form-control-sm bool-value d-inline-block ml-2\">\n <option value=true>True</option>\n <option value=false>False</option>\n </select>\n </div>\n </div>\n <div class=\"define-value define-file\" style=\"display: none;\">\n <div class=\"form-inline\">\n <label>File input</label>\n <input type=\"file\" class=\"form-control-file form-control-sm file-value\">\n </div>\n </div>\n <div class=\"define-value define-number\" style=\"display: none;\">\n <div class=\"form-inline\">\n <label>Value: </label>\n <input type=\"number\" class=\"form-control form-control-sm number-value ml-2\"/>\n </div>\n </div>\n <div class=\"define-value define-string\" style=\"display: none;\">\n <div class=\"form-inline\">\n <label>Value: </label>\n <input type=\"text\" class=\"form-control form-control-sm text-value ml-2\"/>\n </div>\n </div>\n <div class=\"define-value define-object\" style=\"display: none;\">\n <label>Value: </label>\n <div class=\"json-editor\" style=\"height: 400px;\"></div>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-primary btn-save\">Save changes</button>\n <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Close</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script>\nimport _ from 'lodash-es';\nimport DisplayTypeVue from './displayType.vue';\nimport DisplayValueVue from './displayValue.vue';\nimport GraphNodeVue from './graphNode.vue';\nimport JSONEditor from '@dualbox/dualbox-lib-jsoneditor';\nimport swal from 'sweetalert2';\n\nexport default {\n props: [\n \"id\", // the GraphNode object\n ],\n components: {\n \"display-type\" : DisplayTypeVue,\n \"display-value\" : DisplayValueVue,\n \"graph-node\" : GraphNodeVue\n },\n data: function () {\n return {\n comment: null,\n expanded: {}, // expanded app events (advanced settings)\n\n // states\n isParallel: false,\n nowEditingComment: false,\n nowEditingNodeName: false,\n nowEditingDescription: false,\n };\n },\n created: function() {\n this.view = window.dualboxEditor.v;\n this.n = this.view.m.getNode(this.id);\n\n // fetch the comment for this node\n this.comment = this.n.hasComment() ? this.n.getComment() : \"\";\n this.isParallel = this.n.isParallel();\n },\n mounted: function() {\n // adapt the style of the example graph node\n // remove the \"position: absolute;\" that messes up the display\n this.fixCardStyle();\n this.fixMaxHeightForCategories();\n\n // allow tooltips\n this.activateTooltip();\n\n // bind the json editor\n editor = new JSONEditor($(this.$el).find('.json-editor')[0], { modes: ['tree', 'code', 'text' ]});\n editor.set({});\n },\n beforeUpdate: function() {\n //console.log('[Updating] node-settings');\n // we need to refresh our node object\n this.n = this.view.m.getNode(this.id); // it breaks updating node name\n this.deactivateTooltip();\n },\n updated: function() {\n //console.log('[Updated] node-settings');\n this.fixCardStyle();\n this.fixMaxHeightForCategories();\n this.activateTooltip();\n this.focus();\n },\n activate: function() {\n this.activateTooltip();\n this.focus();\n },\n deactivate: function() {\n this.deactivateTooltip();\n },\n methods: {\n fixCardStyle: function() {\n var card = $(this.$el).find('.module-left-signature .card');\n card.css('position', 'static').css('point-events', 'none');\n card.find('.point').css(\"visibibility\", \"visible\").find('svg').css(\"visibibility\", \"visible\");\n card.ready(() => {\n var width = Math.max(\n card.find('.inputs').width() + card.find('.outputs').width() + 20,\n card.find('.title').width() + 60,\n card.find('.subtitle').width() + 40\n );\n card.css('width', width + 'px');\n card.addClass('mx-auto');\n });\n },\n\n // setup a max height for each menu, so a scroll appears if there's too much item in it\n fixMaxHeightForCategories : function() {\n let nbActiveCategories = $(this.$el).find('.edit-body > .card-settings').length;\n let headerHeight = $(this.$el).find('.edit-body > .card-settings > .card-header').outerHeight();\n let panelHeight = $(this.$el).height() - $(this.$el).find('.edit-node-presentation').outerHeight();\n let maxCategoryHeight = panelHeight - nbActiveCategories * headerHeight;\n $(this.$el).find('.edit-body').css('height', panelHeight);\n $(this.$el).find('.edit-body > .card-settings > .collapse > .card-body').css('max-height', maxCategoryHeight + \"px\");\n },\n\n activateTooltip: function() {\n $(this.$el).find('[data-toggle=\"tooltip\"]').tooltip();\n },\n\n deactivateTooltip: function() {\n $(this.$el).find('[data-toggle=\"tooltip\"]').tooltip(\"dispose\");\n },\n\n focus: function() {\n $(this.$el).find('[autofocus]').focus();\n },\n\n // for widget registration\n getSpecialUINodes: function() {\n var targets = this.n.m.getSpecialUINodes( this.n.getRegisterType() );\n return targets;\n },\n\n getUINodesWithEvents : function() {\n var nodes = this.n.m.getNodes(\"ui\");\n var eventNodes = nodes.filter( function(n) {\n return n.getEventsNames().length > 0;\n });\n return eventNodes;\n },\n\n getTargetNodeEvents: function(nodeId) {\n var targetNode = this.n.m.getNode(nodeId);\n return targetNode.getEventsNames();\n },\n\n editComment: function(e) {\n this.nowEditingComment = true;\n },\n\n saveComment: function(e) {\n var val = $(this.$el).find('.node-comment').val();\n this.view.c.setComment(this.n.id, val);\n this.nowEditingComment = false;\n this.onEdited();\n },\n\n deleteComment: function(e) {\n this.view.c.deleteComment(this.n.id);\n this.nowEditingComment = false;\n this.onEdited();\n },\n\n addEvent: function(e) {\n this.view.c.addEvent(this.n.id);\n this.onEdited();\n },\n\n toggleInputVisibility: function(e) {\n var inputName = $(e.target).data('input');\n var visible = $(e.target).is(\":checked\");\n if( !this.view.c.setInputVisibility(this.n.id, inputName, visible) ) {\n // failed, reset this to old value\n $(e.target).prop('checked', !visible);\n }\n },\n\n toggleOutputVisibility: function(e) {\n var outputName = $(e.target).data('output');\n var visible = $(e.target).is(\":checked\");\n if( !this.view.c.setOutputVisibility(this.n.id, outputName, visible) ) {\n // failed, reset this to old value\n $(e.target).prop('checked', !visible);\n }\n },\n\n editNodeName: function(e) {\n this.nowEditingNodeName = true;\n },\n\n changeNodeName: function(e) {\n // user pressed enter\n if(e.which == 13 || e.keyCode == 13) {\n this.saveNodeName(e);\n }\n },\n\n saveNodeName: function(e) {\n var newId = $(e.target).parent().find('.dualbox-node-name-input').val();\n this.view.c.renameBox(this.n.graphId, newId, this.n.type);\n\n // get the new node\n switch( this.n.type ) {\n case \"input\": this.n = this.view.m.getNode(\"in-\"+newId); break;\n case \"output\": this.n = this.view.m.getNode(\"in-\"+newId); break;\n default: this.n = this.view.m.getNode(newId);\n }\n\n this.nowEditingNodeName = false;\n },\n\n toggleIterator: function(e) {\n var destInput = $(e.target).attr('data-input');\n if( $(e.target).is(\":checked\") ) {\n this.view.c.setIterator( this.n.id, destInput );\n }\n else {\n this.view.c.unsetIterator( this.n.id, destInput );\n }\n this.onEdited();\n },\n\n registerToWidget: function(e) {\n var targetId = $(e.target).val();\n this.view.c.registerWidget(this.n.id, targetId);\n },\n\n selectOutputFeedback: function(e) {\n var val = $(e.target).val();\n var destOutput = $(e.target).attr('data-output');\n if( val !== \"none\" ) {\n this.view.c.setFeedback( this.n.id, destOutput, val );\n }\n else {\n this.view.c.unsetFeedback( this.n.id, destOutput );\n }\n },\n\n removeEvent: function(e) {\n var index = parseInt($(e.target).attr('data-index'));\n this.view.c.removeEvent( this.n.id, index );\n this.$forceUpdate();\n },\n\n setEventIf: function(e) {\n var index = parseInt($(e.target).attr('data-index'));\n var val = $(e.target).val();\n this.view.c.setEventIf( this.n.id, index, val );\n },\n\n setEventData: function(e) {\n var index = parseInt($(e.target).attr('data-index'));\n var val = $(e.target).val();\n this.view.c.setEventData( this.n.id, index, val );\n },\n\n // TODO: remake this into it's own vue\n selectEventTarget: function(e) {\n var target = $(e.target).val();\n\n // change options of closest .select-event-name according to this new target\n var targetNode = this.view.m.getNode(target);\n var targetEvents = targetNode.getEventsNames();\n\n var index = parseInt($(e.target).attr('data-index'));\n this.view.c.setEventTarget( this.n.id, index, target );\n this.onEdited();\n },\n\n selectEventName: function(e) {\n var index = parseInt($(e.target).attr('data-index'));\n var val = $(e.target).val();\n this.view.c.setEventName( this.n.id, index, val );\n this.onEdited();\n },\n\n toggleCache: function(e) {\n var val = $(e.target).is(':checked');\n this.view.c.setBoxCache( this.n.id, val );\n },\n\n toggleWorker: function(e) {\n var val = $(e.target).is(':checked');\n this.view.c.setBoxParallel( this.n.id, val );\n this.isParallel = val;\n this.onEdited();\n },\n\n editModuleDescription: function(e) {\n var desc = $(e.target).attr('data-desc');\n\n swal({\n title: \"Describe what this metabox does\",\n input: \"textarea\",\n inputValue: desc || \"\",\n showCancelButton: true,\n closeOnConfirm: false,\n showLoaderOnConfirm: true,\n animation: \"slide-from-top\",\n inputPlaceholder: \"This metabox...\"\n }).then( (result) => {\n if (result.value === \"\") {\n swal.showInputError(\"You need to write something!\");\n return false;\n }\n else {\n this.view.c.setMetanodeDescription(this.n.id, result.value);\n }\n });\n },\n\n createExampleNode(n) {\n return this.view.m.createCloneNode(n.getPackage().name, n.id)\n },\n\n onEditInputType(inputName, typeStr) {\n this.n.assignInputType(inputName, typeStr);\n this.onEdited();\n this.view.repaint();\n },\n\n onEditAttributeType(attributeName, typeStr) {\n this.n.assignAttributeType(attributeName, typeStr);\n this.onEdited();\n this.view.repaint();\n },\n\n onEditDefaultValue(val) {\n this.n.setDefaultValue(val);\n this.onEdited();\n this.view.repaint();\n },\n\n onEditInputDefaultValue(inputName, val) {\n if( val === undefined ) {\n this.n.deleteVal(\"input\", inputName);\n this.n.setInputVisibility(inputName, true); // show the input then (connection needed)\n }\n else {\n this.n.val(\"input\", inputName, val );\n this.n.setInputVisibility(inputName, false); // hide inputs with values (no connection needed)\n }\n this.onEdited();\n this.view.repaint();\n },\n\n onEditAttribute(attrName, val) {\n if( val === undefined ) {\n this.n.deleteVal(\"attr\", attrName);\n }\n else {\n this.n.val(\"attr\", attrName, val);\n }\n this.onEdited();\n },\n\n onEditDefaultInput(inputName, val) {\n if( val === undefined ) {\n this.n.deleteVal(\"input\", inputName);\n }\n else {\n this.n.val(\"input\", inputName, val);\n }\n this.onEdited();\n this.view.repaint();\n },\n\n onEdited() {\n // we need to refresh our node object\n this.n = this.view.m.getNode(this.id); // it breaks updating node name\n this.$forceUpdate();\n },\n\n getDataType: function(evt) {\n if( evt.datatype ) {\n return evt.datatype;\n }\n else if( evt.data ) {\n return window.DualBox.Type.detectType(evt.data);\n }\n else {\n return undefined;\n }\n },\n\n toggleAdvancedAppEventSettings: function(e) {\n var index = $(e.target).data('index');\n this.expanded[index] = this.expanded[index] ? false : true;\n this.$forceUpdate();\n },\n\n onEditEventData(key, index, val) {\n this.view.c.setEventData( this.n.id, index, val );\n this.$forceUpdate();\n },\n\n onEditEventInDataType(key, index, type) {\n this.view.c.setEventDataType( this.n.id, index, type);\n\n // check that the set value still match the new type\n // delete it otherwise\n var val = this.n.getOutboundEvents()[index].data;\n try {\n // TODO: ensure type is already loaded (after dualbox) and remove the try/catch\n if( !window.DualBox.Type.check(type, val) ) {\n // delete data (== set undefined)\n this.view.c.setEventData( this.n.id, index, undefined);\n }\n }\n catch(e) {\n this.view.c.setEventData( this.n.id, index, undefined);\n }\n\n this.$forceUpdate();\n },\n\n getDescription() {\n return this.n.getDescription() || \"[Add a description]\"\n },\n\n editDescription() {\n this.nowEditingDescription = true;\n },\n\n setDescription() {\n var val = $(this.$el).find('.edit-node-description').val();\n if( this.n.isInput() ) {\n this.view.c.setInputDescription(this.n.graphId, val);\n }\n else if( this.n.isOutput() ) {\n this.view.c.setOutputDescription(this.n.graphId, val);\n }\n else if( this.n.isMetanode() ) {\n this.view.c.setMetanodeDescription(this.n.graphId, val);\n }\n this.nowEditingDescription = false;\n\n this.$forceUpdate();\n },\n }\n}\n\n\n</script>\n"]}, media: undefined });
69019
+ inject("data-v-6abfccdb_0", { source: "\n.edit-dualbox-node-id {\n margin-bottom: 0px;\n display: inline-block;\n width: 100%;\n}\n.edit-dualbox-node-package-name {\n font-style: italic;\n}\n.btn-edit-dualbox-node-name {\n display: inline-block;\n margin-left: 5px;\n margin-top: -10px;\n position: relative;\n top: -10px;\n vertical-align: bottom;\n}\n.module-left-description {\n padding-top: 30px;\n font-size: 12px;\n text-align: center;\n}\n.card-settings .card-body {\n font-size: 12px;\n padding-left: 5px;\n padding-right: 5px;\n overflow-y: auto;\n}\n.table-desc {\n width: 100%;\n}\n.table-desc > thead > th > td {\n margin-right: 6px;\n}\n.table-desc > tbody > tr > td {\n margin-right: 6px;\n padding-top: 8px;\n padding-bottom: 8px;\n height: 40px;\n}\n.card-header[data-toggle=\"collapse\"] {\n cursor: pointer;\n}\n.card-header[data-toggle=\"collapse\"] h5 {\n user-select: none;\n}\n.card-header[data-toggle=\"collapse\"]:hover .btn-link {\n text-decoration: none;\n}\n.dualbox-node-name, .dualbox-node-name-input {\n max-width: 400px;\n}\n.dualbox-node-name-span {\n max-width: 350px;\n}\n.dualbox-node-name-input {\n display: inline-block;\n border-radius: 4px;\n padding: 4px 8px 4px 8px;\n font-size: 20px;\n max-width: 280px;\n}\n.text-value, .number-value, .boolean-value {\n max-width: 140px;\n}\n.event-if, .event-data {\n max-width: 80px;\n}\n.select-event-target, .select-event-name, .event-if, .event-data {\n font-size: 12px;\n}\n.edit-body {\n overflow-y: hidden;\n overflow-x: hidden;\n max-height: calc(100% - 90px);\n}\n.table-events .event-rooting {\n margin-top: 10px;\n}\n.table-events thead {\n border-bottom: 1px solid #ddd;\n}\n.table-events .tr-event-condition td {\n padding-left: 10px;\n}\n.table-events .tr-event-data td {\n padding-left: 10px;\n}\n.tr-event-condition td, .tr-event-data td {\n height: 20px!important;\n}\n.tr-event-condition, .tr-event-condition td, .tr-event-data, .tr-event-data td {\n padding-top: 1px!important;\n padding-bottom: 1px!important;\n}\n.table-events tr + .event-rooting {\n /* border-top: 1px solid #ddd; */\n}\n.event-rooting td {\n padding-top: 8px!important;\n padding-bottom: 4px!important;\n}\n.event-data-type {\n font-size: 75%;\n border-radius: 5px;\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n}\n.event-data-display {\n font-size: 75%;\n border-radius: 5px;\n border: 1px solid #ddd;\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n}\n.event-if {\n font-size: 75%;\n border-radius: 5px;\n border: 1px solid #ddd;\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n}\ni.fa, i.fas, i.far {\n pointer-events: none;\n}\n.h100 {\n height: 100%;\n}\n\n", map: {"version":3,"sources":["/home/seb/dev/dualbox/editor/js/src/v/templates/editNodeSettings.vue"],"names":[],"mappings":";AACA;IACA,kBAAA;IACA,qBAAA;IACA,WAAA;AACA;AAEA;IACA,kBAAA;AACA;AAEA;IACA,qBAAA;IACA,gBAAA;IACA,iBAAA;IACA,kBAAA;IACA,UAAA;IACA,sBAAA;AACA;AAEA;IACA,iBAAA;IACA,eAAA;IACA,kBAAA;AACA;AAEA;IACA,eAAA;IACA,iBAAA;IACA,kBAAA;IACA,gBAAA;AACA;AAEA;IACA,WAAA;AACA;AAEA;IACA,iBAAA;AACA;AAEA;IACA,iBAAA;IACA,gBAAA;IACA,mBAAA;IACA,YAAA;AACA;AAEA;IACA,eAAA;AACA;AAEA;IACA,iBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,qBAAA;IACA,kBAAA;IACA,wBAAA;IACA,eAAA;IACA,gBAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,eAAA;AACA;AAEA;IACA,eAAA;AACA;AAEA;IACA,kBAAA;IACA,kBAAA;IACA,6BAAA;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","file":"editNodeSettings.vue","sourcesContent":["<style>\n .edit-dualbox-node-id {\n margin-bottom: 0px;\n display: inline-block;\n width: 100%;\n }\n\n .edit-dualbox-node-package-name {\n font-style: italic;\n }\n\n .btn-edit-dualbox-node-name {\n display: inline-block;\n margin-left: 5px;\n margin-top: -10px;\n position: relative;\n top: -10px;\n vertical-align: bottom;\n }\n\n .module-left-description {\n padding-top: 30px;\n font-size: 12px;\n text-align: center;\n }\n\n .card-settings .card-body {\n font-size: 12px;\n padding-left: 5px;\n padding-right: 5px;\n overflow-y: auto;\n }\n\n .table-desc {\n width: 100%;\n }\n\n .table-desc > thead > th > td {\n margin-right: 6px;\n }\n\n .table-desc > tbody > tr > td {\n margin-right: 6px;\n padding-top: 8px;\n padding-bottom: 8px;\n height: 40px;\n }\n\n .card-header[data-toggle=\"collapse\"] {\n cursor: pointer;\n }\n\n .card-header[data-toggle=\"collapse\"] h5 {\n user-select: none;\n }\n\n .card-header[data-toggle=\"collapse\"]:hover .btn-link {\n text-decoration: none;\n }\n\n .dualbox-node-name, .dualbox-node-name-input {\n max-width: 400px;\n }\n\n .dualbox-node-name-span {\n max-width: 350px;\n }\n\n .dualbox-node-name-input {\n display: inline-block;\n border-radius: 4px;\n padding: 4px 8px 4px 8px;\n font-size: 20px;\n max-width: 280px;\n }\n\n .text-value, .number-value, .boolean-value {\n max-width: 140px;\n }\n\n .event-if, .event-data {\n max-width: 80px;\n }\n\n .select-event-target, .select-event-name, .event-if, .event-data {\n font-size: 12px;\n }\n\n .edit-body {\n overflow-y: hidden;\n overflow-x: hidden;\n max-height: calc(100% - 90px);\n }\n\n .table-events .event-rooting {\n margin-top: 10px;\n }\n\n .table-events thead {\n border-bottom: 1px solid #ddd;\n }\n\n .table-events .tr-event-condition td {\n padding-left: 10px;\n }\n\n .table-events .tr-event-data td {\n padding-left: 10px;\n }\n\n .tr-event-condition td, .tr-event-data td {\n height: 20px!important;\n }\n\n .tr-event-condition, .tr-event-condition td, .tr-event-data, .tr-event-data td {\n padding-top: 1px!important;\n padding-bottom: 1px!important;\n }\n\n .table-events tr + .event-rooting {\n /* border-top: 1px solid #ddd; */\n }\n\n .event-rooting td {\n padding-top: 8px!important;\n padding-bottom: 4px!important;\n }\n\n .event-data-type {\n font-size: 75%;\n border-radius: 5px;\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n }\n\n .event-data-display {\n font-size: 75%;\n border-radius: 5px;\n border: 1px solid #ddd;\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n }\n\n .event-if {\n font-size: 75%;\n border-radius: 5px;\n border: 1px solid #ddd;\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n }\n\n i.fa, i.fas, i.far {\n pointer-events: none;\n }\n\n .h100 {\n height: 100%;\n }\n\n</style>\n\n<template>\n <div class=\"edit-node-panel h100\" id=\"edit-node-panel\" :key=\"n.id\">\n <div class=\"edit-node-presentation\" style=\"padding-left: 10px; padding-top: 10px; padding-right: 10px; padding-bottom: 10px;\">\n <h2 class=\"edit-dualbox-node-id\">\n <div v-if=\"nowEditingNodeName\" class=\"dualbox-node-name-edit\">\n <input type=\"text\" class=\"form-control dualbox-node-name-input\" style=\"display: inline-block;\" :value=\"n.graphId\" @keypress=\"changeNodeName\" autofocus/>\n <button class=\"btn btn-primary btn-save-node-name-change\" :data-id=\"n.graphId\" style=\"display: inline-block;\" @click=\"saveNodeName\">Save</button>\n </div>\n <div v-else class=\"dualbox-node-name\">\n <button class=\"btn btn-light btn-sm btn-edit-dualbox-node-name\" @click=\"editNodeName\"><i class=\"fa fa-edit\"></i></button>\n <span class=\"dualbox-node-name-span text-truncate d-inline-block\">{{n.graphId}}</span>\n </div>\n </h2>\n <p style=\"margin-bottom: 0\"><small class=\"edit-dualbox-node-package-name\">{{n.getPackageName()}}</small></p>\n </div>\n\n <div class=\"edit-body\">\n <div class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-desc\" data-toggle=\"collapse\" data-target=\"#dualbox-node-desc-collapse\" aria-expanded=\"true\" aria-controls=\"dualbox-node-desc-collapse\">\n <h5 class=\"mb-0 btn-link\">Description</h5>\n </div>\n\n <div id=\"dualbox-node-desc-collapse\" class=\"collapse show\" aria-labelledby=\"dualbox-node-desc\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\" style=\"padding-left: 15px;\">\n <div class=\"module-left-signature\">\n <graph-node :id=\"n.id\" :example=\"true\" :pkg=\"n.getPackage()\" :n=\"createExampleNode(n)\"></graph-node>\n </div>\n <p class=\"module-left-description\">\n <template v-if=\"n.isInput() || n.isOutput() || n.isMetanode()\">\n <template v-if=\"nowEditingDescription\">\n <textarea class=\"edit-node-description\" rows=4 style=\"width: 100%;\" :value=\"n.getDescription()\" autofocus>\n </textarea>\n <button class=\"btn btn-success\" @click=\"setDescription\">Save</button>\n </template>\n <template v-else>\n <button class=\"btn btn-transparent btn-xs\" @click=\"editDescription\"><i class=\"fa fa-edit\" ></i></button>\n <span> {{ getDescription() }}</span>\n </template>\n </template>\n <span v-else>\n {{ n.getPackage().description || \"[No description available]\" }}\n </span>\n </p>\n </div>\n </div>\n </div>\n\n <div class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-comments\" data-toggle=\"collapse\" data-target=\"#dualbox-node-comments-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-comments-collapse\">\n <h5 class=\"mb-0 btn-link\">Comments</h5>\n </div>\n <div id=\"dualbox-node-comments-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-comments\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <div style=\"padding-left: 15px; padding-right: 15px;\">\n <div v-if=\"nowEditingComment\" class=\"node-comment-edit\">\n <textarea class=\"node-comment\" rows=4 style=\"width: 100%;\" :data-id=\"n.id\" v-model=\"comment\" autofocus>\n </textarea>\n <div style=\"text-align: right; margin-top: 10px;\">\n <button class=\"btn btn-sm btn-secundary\" @click=\"deleteComment\">Delete</button>\n <button class=\"btn btn-sm btn-primary btn-save-comment\" @click=\"saveComment\">Save</button>\n </div>\n </div>\n <p v-else class=\"node-comment-text\">\n <span>{{ n.hasComment() ? n.getComment() : \"[Add a comment]\" }} </span>\n <button class=\"btn btn-sm btn-transparent\" @click=\"editComment\"><i class=\"fa fa-edit\"></i></button>\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Compute options -->\n <div v-if=\"n.isModule()\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-inputs\" data-toggle=\"collapse\" data-target=\"#dualbox-node-compute-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-compute-collapse\">\n <h5 class=\"mb-0 btn-link\">Compute options</h5>\n </div>\n <div id=\"dualbox-node-compute-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-inputs\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <div class=\"form-group\" style=\"padding-left: 20px;\">\n <div>\n <label>\n <input class=\"input-cache-toggle\" type=\"checkbox\" v-bind:checked=\"n.hasCacheActivated()\" @change=\"toggleCache\">\n <span>Cache result <button type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"Keep the result in memory (the cache) to avoid computing this box every-time its result is required. The cache will be invalidated if an input prior to this box is changed.\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button></span>\n </label>\n </div>\n\n <div v-if=\"!n.isMetanode()\">\n <label>\n <input class=\"input-worker-toggle\" type=\"checkbox\" v-bind:data-id=\"n.id\" v-bind:checked=\"n.isParallel()\" @change=\"toggleWorker\" />\n <span>Execute in a worker <button type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"Workers are separate contexts of executions that can execute long-running tasks without blocking the browser execution. Use this for heavy computations.\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button></span>\n </label>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Widget options -->\n <div v-if=\"n.isWidget()\" class=\"card card-default\">\n <div class=\"card-header\" id=\"dualbox-node-widget\" data-toggle=\"collapse\" data-target=\"#dualbox-node-widget-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-widget-collapse\">\n <h5 class=\"mb-0 btn-link\">Widget Options</h5>\n </div>\n <div id=\"dualbox-node-widget-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-widget\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <span>Widget registered to: </span>\n <select class=\"form-control form-control-sm select-widget-registerTo\" style=\"max-width: 250px;\" @change=\"registerToWidget\">\n <option value=\"\">none</option>\n <option v-for=\"target in getSpecialUINodes()\" :key=\"'target-'+target.id\" :value=\"target.graphId\" :selected=\"n.getWidgetRegistration() == target.graphId\">{{target.id}}</option>\n\n </select>\n </div>\n </div>\n </div>\n\n <!-- Inputs -->\n <div v-if=\"n.isInput()\" class=\"card card-default\">\n <div class=\"card-header\" id=\"dualbox-node-default\" data-toggle=\"collapse\" data-target=\"#dualbox-node-default-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-default-collapse\">\n <h5 class=\"mb-0 btn-link\">Default value</h5>\n </div>\n <div id=\"dualbox-node-default-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-default\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <span>Default value:</span>\n <span><display-value :v=\"n.getDefaultValue()\" :type=\"n.getType()\" @edited=\"onEditDefaultValue\"></display-value></span>\n </div>\n </div>\n </div>\n <div v-else-if=\"n.hasInputs()\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-inputs\" data-toggle=\"collapse\" data-target=\"#dualbox-node-inputs-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-inputs-collapse\">\n <h5 class=\"mb-0 btn-link\">Inputs <small><span class=\"badge badge-secondary\">{{n.getInputsNames().length}}</span></small></h5>\n </div>\n <div id=\"dualbox-node-inputs-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-inputs\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Input</th>\n <th>Visible</th>\n <th>Type</th>\n <th>Default</th>\n </thead>\n <tbody>\n <tr v-for=\"key in n.getInputsNames()\" :key=\"'input-'+key\">\n <td>\n {{key}}\n <button v-if=\"n.hasInputDesc(key)\" type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" v-bind:title=\"n.getInputDesc(key)\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button>\n </td>\n <td>\n <input class=\"input-visibility-toggle\" type=\"checkbox\" v-bind:data-id=\"n.id\" v-bind:data-input=\"key\" v-bind:checked=\"n.isInputVisible(key)\" @change=\"toggleInputVisibility\">\n </td>\n <td>\n <!-- If there's a start, then we must edit the type -->\n <display-type :type=\"n.getInputType(key)\" :readonly=\"!n.isInputTemplateType(key)\" @edited=\"onEditInputType(key, $event)\"></display-type>\n </td>\n <td>\n <display-value :v=\"n.getInputDefaultValue(key)\" :type=\"n.getInputType(key)\" @edited=\"onEditInputDefaultValue(key, $event)\" :readonly=\"!n.isFullyDefinedInputType(key)\" :readonlyReason=\"!n.isFullyDefinedInputType(key) ? 'You must first define a full type (without *) before you can edit this value' : ''\"></display-value>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <!-- Outputs -->\n <div v-if=\"n.hasOutputs()\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-outputs\" data-toggle=\"collapse\" data-target=\"#dualbox-node-outputs-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-outputs-collapse\">\n <h5 class=\"mb-0 btn-link\">Outputs <small><span class=\"badge badge-secondary\">{{n.getOutputsNames().length}}</span></small></h5>\n </div>\n <div id=\"dualbox-node-outputs-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-outputs\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Output</th>\n <th>Type</th>\n <th>Visible</th>\n </thead>\n <tbody>\n <tr v-for=\"key in n.getOutputsNames()\" :key=\"'output-'+key\">\n <td>{{key}}\n <button v-if=\"n.hasOutputDesc(key)\" type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" v-bind:title=\"n.getOutputDesc(key)\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button>\n </td>\n <td><display-type :type=\"n.getOutputType(key)\"></display-type></td>\n <td>\n <input class=\"output-visibility-toggle\" type=\"checkbox\" v-bind:data-id=\"n.id\" v-bind:data-output=\"key\" v-bind:checked=\"n.isOutputVisible(key)\" @change=\"toggleOutputVisibility\">\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <!-- Attributes -->\n <div v-if=\"n.hasAttributes()\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-attrs\" data-toggle=\"collapse\" data-target=\"#dualbox-node-attrs-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-attrs-collapse\">\n <h5 class=\"mb-0 btn-link\">Attributes <small><span class=\"badge badge-secondary\">{{n.getAttributesNames().length}}</span></small></h5>\n </div>\n <div id=\"dualbox-node-attrs-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-attrs\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Output</th>\n <th>Type</th>\n <th>Value</th>\n </thead>\n <tbody>\n <tr v-for=\"key in n.getAttributesNames()\" :key=\"'attr-'+key\">\n <td>{{key}}\n <button v-if=\"n.hasAttributeDesc(key)\" type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" :title=\"n.getAttributeDesc(key)\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button>\n </td>\n <td>\n <!-- If there's a start, then we must edit the type -->\n <display-type :type=\"n.getAttributeType(key)\" :readonly=\"!n.isAttributeTemplateType(key)\" @edited=\"onEditAttributeType(key, $event)\"></display-type>\n </td>\n <td>\n <display-value :v=\"n.getAttributeValue(key)\" :type=\"n.getAttributeType(key)\" @edited=\"onEditAttribute(key, $event)\" :readonly=\"!n.isFullyDefinedAttributeType(key)\" :readonlyReason=\"!n.isFullyDefinedInputType(key) ? 'You must first define a full type (without *) before you can edit this value' : ''\"></display-value>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n\n <!-- Loops -->\n <div v-if=\"n.hasInputs()\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-inputs\" data-toggle=\"collapse\" data-target=\"#dualbox-node-loops-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-loops-collapse\">\n <h5 class=\"mb-0 btn-link\">Loops <small><span class=\"badge badge-secondary\">{{ n.hasLoop() ? \"on\" : \"off\" }}</span></small></h5>\n </div>\n <div id=\"dualbox-node-loops-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-inputs\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <h4>Iterators\n <button type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"Iterators will break an array in input into a list of their components. The module will be computed several times, each time with one different component from every iterator input. Inputs that don't define iterators will use their current value as-is for the different computations.\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button>\n </h4>\n <table class=\"table-desc table-striped\">\n <tbody>\n <tr v-for=\"key in n.getInputsNames()\" :key=\"'loop-iterator-'+key\">\n <td>{{key}}</td>\n <td>\n <input class=\"input-iterator-toggle\" type=\"checkbox\" :data-input=\"key\" :checked=\"n.hasIterator(key)\" @change=\"toggleIterator\" />\n </td>\n </tr>\n </tbody>\n </table>\n\n <h4 class=\"mt-2\">Feedback\n <button type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"Feedback (during a loop) is a reinjection of an output result of one iteration into an input of the next iteration.\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button>\n </h4>\n <table class=\"table-desc table-striped\">\n <tbody>\n <tr v-for=\"key in n.getOutputsNames()\" :key=\"'loop-feedback-'+key\">\n <td>{{key}}</td>\n <td>\n <select class=\"form-control form-control-sm select-output-feedback\" :data-output=\"key\" @change=\"selectOutputFeedback\">\n <option value=\"none\">No feedback</option>\n <option v-for=\"i in n.getInputsNames()\" :value=\"i\" :selected=\"n.getFeedback(key) == i\" :key=\"'loop-feedback-input-'+i\">{{i}}</option>\n </select>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <!-- Events -->\n <div v-if=\"n.isUI()\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"dualbox-node-events\" data-toggle=\"collapse\" data-target=\"#dualbox-node-events-collapse\" aria-expanded=\"false\" aria-controls=\"dualbox-node-events-collapse\">\n <h5 class=\"mb-0 btn-link\">Events <small><span class=\"badge badge-secondary\">{{n.getOutboundEvents().length}}</span></small></h5>\n </div>\n <div id=\"dualbox-node-events-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-events\" data-parent=\"#edit-node-panel\">\n <div class=\"card-body\">\n <table class=\"table-events table-desc\" style=\"font-size: 12px!important;\">\n <thead class=\"thead-dark\">\n <th>Target</th>\n <th>Event</th>\n <th>Action</th>\n </thead>\n <tbody>\n <template v-if=\"n.hasOutEvents()\" v-for=\"(evt, index) in n.getOutboundEvents()\" :data-index=\"index\">\n <tr class=\"event-rooting\">\n <td>\n <select v-if=\"evt.node\" class=\"form-control form-control-sm select-event-target\" :data-index=\"index\"@change=\"selectEventTarget\" >\n <option v-for=\"node in getUINodesWithEvents()\" :value=\"node.getGraphId()\" :selected=\"node.getGraphId()==evt.node\" :key=\"node.id\">{{node.getGraphId()}}</option>\n </select>\n <span v-else>{{evt.selector}}</span>\n </td>\n <td>\n <select class=\"form-control form-control-sm select-event-name\" :data-index=\"index\" @change=\"selectEventName\">\n <template v-if=\"evt.node\">\n <option v-for=\"targetEvent in getTargetNodeEvents(evt.node)\" :value=\"targetEvent\" :selected=\"evt.event===targetEvent\" :key=\"targetEvent\">{{targetEvent}}</option>\n </template>\n <template v-else>\n <option value=\"hide\">hide</option>\n <option value=\"show\">show</option>\n </template>\n </select>\n </td>\n <td>\n <button class=\"btn btn-secondary btn-editor-xs\" :data-index=\"index\" @click=\"toggleAdvancedAppEventSettings\" style=\"margin-left: 10px;\" title=\"Toggle advanced event settings\" >\n <i class=\"fas fa-cog\"></i>\n </button>\n <button class=\"btn btn-danger btn-editor-xs btn-remove-event\" :data-index=\"index\" @click=\"removeEvent\">\n <i class=\"fa fa-minus\"></i>\n </button>\n </td>\n </tr>\n <tr v-if=\"evt.if || expanded[index]\" class=\"tr-event-condition\">\n <td colspan=\"3\">\n <span style=\"width: 60px; display: inline-block;\"><i class=\"fas fa-caret-right\"></i> Occur if:</span>\n\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-index=\"index\" :value=\"evt.if\" @change=\"setEventIf\" />\n </td>\n </tr>\n <tr v-if=\"evt.data || evt.datatype || expanded[index]\" class=\"tr-event-data\" colspan=\"3\">\n <td colspan=\"3\">\n <span style=\"width: 53px; display: inline-block;\"><i class=\"fas fa-caret-right\"></i> Data:</span>\n <span style=\"width: 350px;\">\n <display-type :type=\"getDataType(evt)\" @edited=\"onEditEventInDataType(key, index, $event)\"></display-type>\n <display-value :v=\"evt.data\" :type=\"getDataType(evt)\" @edited=\"onEditEventData(key, index, $event)\"></display-value>\n </span>\n </td>\n </tr>\n </template>\n <tr>\n <td colspan=\"5\" style=\"padding-top: 0px; padding-bottom: 0px;\">\n <button class=\"btn btn-sm\" :data-id=\"n.id\" style=\"width: 100%;\" @click=\"addEvent\">Add event</button>\n </td>\n </tr>\n </tbody>\n </table>\n\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"modal edit-value-modal\" tabindex=\"-1\" role=\"dialog\">\n <div class=\"modal-dialog\" role=\"document\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Edit value</h5>\n <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"set-type\">\n <div class=\"form-check\">\n <input type=\"radio\" class=\"form-check-input set-value unset-value\" id=\"unset-value\" name=\"set-value\" value=\"unset-value\" checked>\n <label class=\"form-check-label\" for=\"unset-value\">\n don't set a value\n </label>\n </div>\n <div class=\"form-check\">\n <input type=\"radio\" class=\"form-check-input set-value set-value-null\" id=\"set-value-null\" name=\"set-value\" value=\"set-value-null\">\n <label class=\"form-check-label\" for=\"set-value-null\">\n set null\n </label>\n </div>\n <div class=\"form-check\">\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\">\n <div class=\"form-inline form-check-label\" style=\"height: 24px;\">\n <label for=\"set-value-type\">\n set a value of type:\n <select class=\"form-control choose-value-type d-inline-block form-control-sm ml-2\">\n <option value=\"string\">String</option>\n <option value=\"number\">Number</option>\n <option value=\"boolean\">Boolean</option>\n <option value=\"object\">Object</option>\n <option value=\"file\">File</option>\n </select>\n </label>\n </div>\n </div>\n </div>\n <hr class=\"separator\"/>\n <div class=\"has-value\" style=\"display: none;\">\n <div class=\"define-value define-boolean\" style=\"display: none;\">\n <div class=\"form-inline\">\n <label>Value: </label>\n <select class=\"form-control form-control-sm bool-value d-inline-block ml-2\">\n <option value=true>True</option>\n <option value=false>False</option>\n </select>\n </div>\n </div>\n <div class=\"define-value define-file\" style=\"display: none;\">\n <div class=\"form-inline\">\n <label>File input</label>\n <input type=\"file\" class=\"form-control-file form-control-sm file-value\">\n </div>\n </div>\n <div class=\"define-value define-number\" style=\"display: none;\">\n <div class=\"form-inline\">\n <label>Value: </label>\n <input type=\"number\" class=\"form-control form-control-sm number-value ml-2\"/>\n </div>\n </div>\n <div class=\"define-value define-string\" style=\"display: none;\">\n <div class=\"form-inline\">\n <label>Value: </label>\n <input type=\"text\" class=\"form-control form-control-sm text-value ml-2\"/>\n </div>\n </div>\n <div class=\"define-value define-object\" style=\"display: none;\">\n <label>Value: </label>\n <div class=\"json-editor\" style=\"height: 400px;\"></div>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-primary btn-save\">Save changes</button>\n <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Close</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script>\nimport _ from 'lodash-es';\nimport DisplayTypeVue from './displayType.vue';\nimport DisplayValueVue from './displayValue.vue';\nimport GraphNodeVue from './graphNode.vue';\nimport JSONEditor from '@dualbox/dualbox-lib-jsoneditor';\nimport swal from 'sweetalert2';\n\nexport default {\n props: [\n \"id\", // the GraphNode object\n ],\n components: {\n \"display-type\" : DisplayTypeVue,\n \"display-value\" : DisplayValueVue,\n \"graph-node\" : GraphNodeVue\n },\n data: function () {\n return {\n comment: null,\n expanded: {}, // expanded app events (advanced settings)\n\n // states\n isParallel: false,\n nowEditingComment: false,\n nowEditingNodeName: false,\n nowEditingDescription: false,\n };\n },\n created: function() {\n this.view = window.dualboxEditor.v;\n this.n = this.view.m.getNode(this.id);\n\n // fetch the comment for this node\n this.comment = this.n.hasComment() ? this.n.getComment() : \"\";\n this.isParallel = this.n.isParallel();\n },\n mounted: function() {\n // adapt the style of the example graph node\n // remove the \"position: absolute;\" that messes up the display\n this.fixCardStyle();\n this.fixMaxHeightForCategories();\n\n // allow tooltips\n this.activateTooltip();\n\n // bind the json editor\n this.editor = new JSONEditor($(this.$el).find('.json-editor')[0], { modes: ['tree', 'code', 'text' ]});\n this.editor.set({});\n },\n beforeUpdate: function() {\n //console.log('[Updating] node-settings');\n // we need to refresh our node object\n this.n = this.view.m.getNode(this.id); // it breaks updating node name\n this.deactivateTooltip();\n },\n updated: function() {\n //console.log('[Updated] node-settings');\n this.fixCardStyle();\n this.fixMaxHeightForCategories();\n this.activateTooltip();\n this.focus();\n },\n activate: function() {\n this.activateTooltip();\n this.focus();\n },\n deactivate: function() {\n this.deactivateTooltip();\n },\n destroyed: function() {\n if( this.editor ) {\n this.editor.destroy();\n }\n },\n methods: {\n fixCardStyle: function() {\n var card = $(this.$el).find('.module-left-signature .card');\n card.css('position', 'static').css('point-events', 'none');\n card.find('.point').css(\"visibibility\", \"visible\").find('svg').css(\"visibibility\", \"visible\");\n card.ready(() => {\n var width = Math.max(\n card.find('.inputs').width() + card.find('.outputs').width() + 20,\n card.find('.title').width() + 60,\n card.find('.subtitle').width() + 40\n );\n card.css('width', width + 'px');\n card.addClass('mx-auto');\n });\n },\n\n // setup a max height for each menu, so a scroll appears if there's too much item in it\n fixMaxHeightForCategories : function() {\n let nbActiveCategories = $(this.$el).find('.edit-body > .card-settings').length;\n let headerHeight = $(this.$el).find('.edit-body > .card-settings > .card-header').outerHeight();\n let panelHeight = $(this.$el).height() - $(this.$el).find('.edit-node-presentation').outerHeight();\n let maxCategoryHeight = panelHeight - nbActiveCategories * headerHeight;\n $(this.$el).find('.edit-body').css('height', panelHeight);\n $(this.$el).find('.edit-body > .card-settings > .collapse > .card-body').css('max-height', maxCategoryHeight + \"px\");\n },\n\n activateTooltip: function() {\n $(this.$el).find('[data-toggle=\"tooltip\"]').tooltip();\n },\n\n deactivateTooltip: function() {\n $(this.$el).find('[data-toggle=\"tooltip\"]').tooltip(\"dispose\");\n },\n\n focus: function() {\n $(this.$el).find('[autofocus]').focus();\n },\n\n // for widget registration\n getSpecialUINodes: function() {\n var targets = this.n.m.getSpecialUINodes( this.n.getRegisterType() );\n return targets;\n },\n\n getUINodesWithEvents : function() {\n var nodes = this.n.m.getNodes(\"ui\");\n var eventNodes = nodes.filter( function(n) {\n return n.getEventsNames().length > 0;\n });\n return eventNodes;\n },\n\n getTargetNodeEvents: function(nodeId) {\n var targetNode = this.n.m.getNode(nodeId);\n return targetNode.getEventsNames();\n },\n\n editComment: function(e) {\n this.nowEditingComment = true;\n },\n\n saveComment: function(e) {\n var val = $(this.$el).find('.node-comment').val();\n this.view.c.setComment(this.n.id, val);\n this.nowEditingComment = false;\n this.onEdited();\n },\n\n deleteComment: function(e) {\n this.view.c.deleteComment(this.n.id);\n this.nowEditingComment = false;\n this.onEdited();\n },\n\n addEvent: function(e) {\n this.view.c.addEvent(this.n.id);\n this.onEdited();\n },\n\n toggleInputVisibility: function(e) {\n var inputName = $(e.target).data('input');\n var visible = $(e.target).is(\":checked\");\n if( !this.view.c.setInputVisibility(this.n.id, inputName, visible) ) {\n // failed, reset this to old value\n $(e.target).prop('checked', !visible);\n }\n },\n\n toggleOutputVisibility: function(e) {\n var outputName = $(e.target).data('output');\n var visible = $(e.target).is(\":checked\");\n if( !this.view.c.setOutputVisibility(this.n.id, outputName, visible) ) {\n // failed, reset this to old value\n $(e.target).prop('checked', !visible);\n }\n },\n\n editNodeName: function(e) {\n this.nowEditingNodeName = true;\n },\n\n changeNodeName: function(e) {\n // user pressed enter\n if(e.which == 13 || e.keyCode == 13) {\n this.saveNodeName(e);\n }\n },\n\n saveNodeName: function(e) {\n var newId = $(e.target).parent().find('.dualbox-node-name-input').val();\n this.view.c.renameBox(this.n.graphId, newId, this.n.type);\n\n // get the new node\n switch( this.n.type ) {\n case \"input\": this.n = this.view.m.getNode(\"in-\"+newId); break;\n case \"output\": this.n = this.view.m.getNode(\"in-\"+newId); break;\n default: this.n = this.view.m.getNode(newId);\n }\n\n this.nowEditingNodeName = false;\n },\n\n toggleIterator: function(e) {\n var destInput = $(e.target).attr('data-input');\n if( $(e.target).is(\":checked\") ) {\n this.view.c.setIterator( this.n.id, destInput );\n }\n else {\n this.view.c.unsetIterator( this.n.id, destInput );\n }\n this.onEdited();\n },\n\n registerToWidget: function(e) {\n var targetId = $(e.target).val();\n this.view.c.registerWidget(this.n.id, targetId);\n },\n\n selectOutputFeedback: function(e) {\n var val = $(e.target).val();\n var destOutput = $(e.target).attr('data-output');\n if( val !== \"none\" ) {\n this.view.c.setFeedback( this.n.id, destOutput, val );\n }\n else {\n this.view.c.unsetFeedback( this.n.id, destOutput );\n }\n },\n\n removeEvent: function(e) {\n var index = parseInt($(e.target).attr('data-index'));\n this.view.c.removeEvent( this.n.id, index );\n this.$forceUpdate();\n },\n\n setEventIf: function(e) {\n var index = parseInt($(e.target).attr('data-index'));\n var val = $(e.target).val();\n this.view.c.setEventIf( this.n.id, index, val );\n },\n\n setEventData: function(e) {\n var index = parseInt($(e.target).attr('data-index'));\n var val = $(e.target).val();\n this.view.c.setEventData( this.n.id, index, val );\n },\n\n // TODO: remake this into it's own vue\n selectEventTarget: function(e) {\n var target = $(e.target).val();\n\n // change options of closest .select-event-name according to this new target\n var targetNode = this.view.m.getNode(target);\n var targetEvents = targetNode.getEventsNames();\n\n var index = parseInt($(e.target).attr('data-index'));\n this.view.c.setEventTarget( this.n.id, index, target );\n this.onEdited();\n },\n\n selectEventName: function(e) {\n var index = parseInt($(e.target).attr('data-index'));\n var val = $(e.target).val();\n this.view.c.setEventName( this.n.id, index, val );\n this.onEdited();\n },\n\n toggleCache: function(e) {\n var val = $(e.target).is(':checked');\n this.view.c.setBoxCache( this.n.id, val );\n },\n\n toggleWorker: function(e) {\n var val = $(e.target).is(':checked');\n this.view.c.setBoxParallel( this.n.id, val );\n this.isParallel = val;\n this.onEdited();\n },\n\n editModuleDescription: function(e) {\n var desc = $(e.target).attr('data-desc');\n\n swal({\n title: \"Describe what this metabox does\",\n input: \"textarea\",\n inputValue: desc || \"\",\n showCancelButton: true,\n closeOnConfirm: false,\n showLoaderOnConfirm: true,\n animation: \"slide-from-top\",\n inputPlaceholder: \"This metabox...\"\n }).then( (result) => {\n if (result.value === \"\") {\n swal.showInputError(\"You need to write something!\");\n return false;\n }\n else {\n this.view.c.setMetanodeDescription(this.n.id, result.value);\n }\n });\n },\n\n createExampleNode(n) {\n return this.view.m.createCloneNode(n.getPackage().name, n.id)\n },\n\n onEditInputType(inputName, typeStr) {\n this.n.assignInputType(inputName, typeStr);\n this.onEdited();\n this.view.repaint();\n },\n\n onEditAttributeType(attributeName, typeStr) {\n this.n.assignAttributeType(attributeName, typeStr);\n this.onEdited();\n this.view.repaint();\n },\n\n onEditDefaultValue(val) {\n this.n.setDefaultValue(val);\n this.onEdited();\n this.view.repaint();\n },\n\n onEditInputDefaultValue(inputName, val) {\n if( val === undefined ) {\n this.n.deleteVal(\"input\", inputName);\n this.n.setInputVisibility(inputName, true); // show the input then (connection needed)\n }\n else {\n this.n.val(\"input\", inputName, val );\n this.n.setInputVisibility(inputName, false); // hide inputs with values (no connection needed)\n }\n this.onEdited();\n this.view.repaint();\n },\n\n onEditAttribute(attrName, val) {\n if( val === undefined ) {\n this.n.deleteVal(\"attr\", attrName);\n }\n else {\n this.n.val(\"attr\", attrName, val);\n }\n this.onEdited();\n },\n\n onEditDefaultInput(inputName, val) {\n if( val === undefined ) {\n this.n.deleteVal(\"input\", inputName);\n }\n else {\n this.n.val(\"input\", inputName, val);\n }\n this.onEdited();\n this.view.repaint();\n },\n\n onEdited() {\n // we need to refresh our node object\n this.n = this.view.m.getNode(this.id); // it breaks updating node name\n this.$forceUpdate();\n },\n\n getDataType: function(evt) {\n if( evt.datatype ) {\n return evt.datatype;\n }\n else if( evt.data ) {\n return window.DualBox.Type.detectType(evt.data);\n }\n else {\n return undefined;\n }\n },\n\n toggleAdvancedAppEventSettings: function(e) {\n var index = $(e.target).data('index');\n this.expanded[index] = this.expanded[index] ? false : true;\n this.$forceUpdate();\n },\n\n onEditEventData(key, index, val) {\n this.view.c.setEventData( this.n.id, index, val );\n this.$forceUpdate();\n },\n\n onEditEventInDataType(key, index, type) {\n this.view.c.setEventDataType( this.n.id, index, type);\n\n // check that the set value still match the new type\n // delete it otherwise\n var val = this.n.getOutboundEvents()[index].data;\n try {\n // TODO: ensure type is already loaded (after dualbox) and remove the try/catch\n if( !window.DualBox.Type.check(type, val) ) {\n // delete data (== set undefined)\n this.view.c.setEventData( this.n.id, index, undefined);\n }\n }\n catch(e) {\n this.view.c.setEventData( this.n.id, index, undefined);\n }\n\n this.$forceUpdate();\n },\n\n getDescription() {\n return this.n.getDescription() || \"[Add a description]\"\n },\n\n editDescription() {\n this.nowEditingDescription = true;\n },\n\n setDescription() {\n var val = $(this.$el).find('.edit-node-description').val();\n if( this.n.isInput() ) {\n this.view.c.setInputDescription(this.n.graphId, val);\n }\n else if( this.n.isOutput() ) {\n this.view.c.setOutputDescription(this.n.graphId, val);\n }\n else if( this.n.isMetanode() ) {\n this.view.c.setMetanodeDescription(this.n.graphId, val);\n }\n this.nowEditingDescription = false;\n\n this.$forceUpdate();\n },\n }\n}\n\n\n</script>\n"]}, media: undefined });
69015
69020
 
69016
69021
  };
69017
69022
  /* scoped */
@@ -291,7 +291,7 @@ class GraphModel {
291
291
  // switch to the next window
292
292
  this.data.app = this.data.app || [];
293
293
  this.data.app = this.data.app.concat(["metanodes", name]);
294
- this.data.windows.push([name, metanode]);
294
+ this.data.windows.push([name, this.data.app]);
295
295
  this.save();
296
296
  }
297
297
 
@@ -633,8 +633,8 @@ export default {
633
633
  this.activateTooltip();
634
634
 
635
635
  // bind the json editor
636
- editor = new JSONEditor($(this.$el).find('.json-editor')[0], { modes: ['tree', 'code', 'text' ]});
637
- editor.set({});
636
+ this.editor = new JSONEditor($(this.$el).find('.json-editor')[0], { modes: ['tree', 'code', 'text' ]});
637
+ this.editor.set({});
638
638
  },
639
639
  beforeUpdate: function() {
640
640
  //console.log('[Updating] node-settings');
@@ -656,6 +656,11 @@ export default {
656
656
  deactivate: function() {
657
657
  this.deactivateTooltip();
658
658
  },
659
+ destroyed: function() {
660
+ if( this.editor ) {
661
+ this.editor.destroy();
662
+ }
663
+ },
659
664
  methods: {
660
665
  fixCardStyle: function() {
661
666
  var card = $(this.$el).find('.module-left-signature .card');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dualbox/editor",
3
- "version": "1.0.66",
3
+ "version": "1.0.68",
4
4
  "description": "Editor of Dualbox apps",
5
5
  "browser": "js/dist/GraphEditor.js",
6
6
  "main": "js/dist/GraphEditor.js",