@dualbox/editor 1.0.86 → 1.0.87
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 +243 -429
- package/js/dist/GraphEditor.min.js +242 -428
- package/js/src/c/GraphController.js +8 -3
- package/js/src/m/GraphModel.js +60 -6
- package/js/src/v/GraphView.js +0 -4
- package/js/src/v/Zoomer.js +6 -4
- package/js/src/v/templates/addNode.vue +196 -149
- package/js/src/v/templates/editMainSettings.vue +2 -0
- package/js/src/v/templates/editNodeSettings.vue +0 -92
- package/js/src/v/templates/editValue.vue +15 -4
- package/js/src/v/templates/graphNode.vue +1 -1
- package/package.json +1 -1
- package/js/src/v/templates/addInput.vue +0 -109
|
@@ -44010,6 +44010,14 @@ class GraphModel {
|
|
|
44010
44010
|
this.ensure('ui');
|
|
44011
44011
|
this.getCurrentMetanode().ui[id] = def;
|
|
44012
44012
|
break;
|
|
44013
|
+
case "input":
|
|
44014
|
+
this.ensure('input');
|
|
44015
|
+
this.getCurrentMetanode().input[id] = def;
|
|
44016
|
+
break;
|
|
44017
|
+
case "output":
|
|
44018
|
+
this.ensure('output');
|
|
44019
|
+
this.getCurrentMetanode().output[id] = def;
|
|
44020
|
+
break;
|
|
44013
44021
|
default:
|
|
44014
44022
|
throw type + " is not module or ui, error";
|
|
44015
44023
|
}
|
|
@@ -44375,7 +44383,12 @@ class GraphNode {
|
|
|
44375
44383
|
var defType = this.getDefinitionInputType(inputName);
|
|
44376
44384
|
var t;
|
|
44377
44385
|
if (defType.includes("*")) {
|
|
44378
|
-
|
|
44386
|
+
if (assignedType) {
|
|
44387
|
+
return assignedType;
|
|
44388
|
+
} else {
|
|
44389
|
+
let linkedType = this.getInputLinkedType(inputName);
|
|
44390
|
+
return linkedType ? linkedType : defType;
|
|
44391
|
+
}
|
|
44379
44392
|
} else {
|
|
44380
44393
|
t = defType;
|
|
44381
44394
|
}
|
|
@@ -44401,6 +44414,28 @@ class GraphNode {
|
|
|
44401
44414
|
return lodash.get(this.def, ["assignedTypes", "output", outputName]);
|
|
44402
44415
|
}
|
|
44403
44416
|
|
|
44417
|
+
getInputLinkedType(inputName) {
|
|
44418
|
+
let def = this.getInputDef(inputName);
|
|
44419
|
+
let linkedType = this.getLinkedType(def.typeLink);
|
|
44420
|
+
if (linkedType) {
|
|
44421
|
+
let definitionType = this.getDefinitionInputType(inputName);
|
|
44422
|
+
return definitionType.replaceAll('*', linkedType);
|
|
44423
|
+
} else {
|
|
44424
|
+
return null;
|
|
44425
|
+
}
|
|
44426
|
+
}
|
|
44427
|
+
|
|
44428
|
+
getOutputLinkedType(outputName) {
|
|
44429
|
+
let def = this.getOutputDef(outputName);
|
|
44430
|
+
let linkedType = this.getLinkedType(def.typeLink);
|
|
44431
|
+
if (linkedType) {
|
|
44432
|
+
let definitionType = this.getDefinitionOutputType(outputName);
|
|
44433
|
+
return definitionType.replaceAll('*', linkedType);
|
|
44434
|
+
} else {
|
|
44435
|
+
return null;
|
|
44436
|
+
}
|
|
44437
|
+
}
|
|
44438
|
+
|
|
44404
44439
|
getAttributeAssignedType(attrName) {
|
|
44405
44440
|
return lodash.get(this.def, ["assignedTypes", "attr", attrName]);
|
|
44406
44441
|
}
|
|
@@ -44467,8 +44502,15 @@ class GraphNode {
|
|
|
44467
44502
|
lodash.each(linkedInputs, (linkedInputDef, linkedInputName) => {
|
|
44468
44503
|
var assignedType = this.getInputAssignedType(linkedInputName);
|
|
44469
44504
|
if (assignedType !== undefined && assignedType !== null) {
|
|
44470
|
-
|
|
44471
|
-
|
|
44505
|
+
// build a regexp to fetch the type
|
|
44506
|
+
let re = new RegExp(linkedInputDef.type.replace('*', '(?<type>.*)'));
|
|
44507
|
+
let result = re.exec(assignedType);
|
|
44508
|
+
let type = lodash.get(result, ["groups", "type"]);
|
|
44509
|
+
|
|
44510
|
+
if (type) {
|
|
44511
|
+
linkedType = type;
|
|
44512
|
+
return false; // eol
|
|
44513
|
+
}
|
|
44472
44514
|
}
|
|
44473
44515
|
});
|
|
44474
44516
|
}
|
|
@@ -44476,8 +44518,15 @@ class GraphNode {
|
|
|
44476
44518
|
lodash.each(linkedOutputs, (linkedOutputDef, linkedOutputName) => {
|
|
44477
44519
|
var assignedType = this.getOutputAssignedType(linkedOutputName);
|
|
44478
44520
|
if (assignedType !== undefined && assignedType !== null) {
|
|
44479
|
-
|
|
44480
|
-
|
|
44521
|
+
// build a regexp to fetch the type
|
|
44522
|
+
let re = new RegExp(linkedOutputDef.type.replace('*', '(?<type>.*)'));
|
|
44523
|
+
let result = re.exec(assignedType);
|
|
44524
|
+
let type = lodash.get(result, ["groups", "type"]);
|
|
44525
|
+
|
|
44526
|
+
if (type) {
|
|
44527
|
+
linkedType = type;
|
|
44528
|
+
return false; // eol
|
|
44529
|
+
}
|
|
44481
44530
|
}
|
|
44482
44531
|
});
|
|
44483
44532
|
}
|
|
@@ -44595,7 +44644,12 @@ class GraphNode {
|
|
|
44595
44644
|
var defType = this.getDefinitionOutputType(outputName);
|
|
44596
44645
|
var t;
|
|
44597
44646
|
if (defType.includes("*")) {
|
|
44598
|
-
|
|
44647
|
+
if (assignedType) {
|
|
44648
|
+
return assignedType;
|
|
44649
|
+
} else {
|
|
44650
|
+
let linkedType = this.getOutputLinkedType(outputName);
|
|
44651
|
+
return linkedType ? linkedType : defType;
|
|
44652
|
+
}
|
|
44599
44653
|
} else {
|
|
44600
44654
|
t = defType;
|
|
44601
44655
|
}
|
|
@@ -47241,7 +47295,7 @@ var script = {
|
|
|
47241
47295
|
}
|
|
47242
47296
|
}
|
|
47243
47297
|
];
|
|
47244
|
-
if (this.n.isModule() || this.n.isUI()) {
|
|
47298
|
+
if (this.n.isModule() || this.n.isUI() || this.n.isInput() || this.n.isOutput()) {
|
|
47245
47299
|
contextOptions.push({
|
|
47246
47300
|
name: "Duplicate this box",
|
|
47247
47301
|
fn: () => {
|
|
@@ -47855,7 +47909,7 @@ __vue_render__._withStripped = true;
|
|
|
47855
47909
|
/* style */
|
|
47856
47910
|
const __vue_inject_styles__ = function (inject) {
|
|
47857
47911
|
if (!inject) return
|
|
47858
|
-
inject("data-v-4f0778c6_0", { source: "\n.card-ui {\r\n background-color: #bff2ca !important;\n}\n.card-loop {\r\n /* background-color: #e5e8ea!important; */\r\n border: 5px double #dddddd;\r\n border-width: 4px;\n}\n.card-input {\r\n background-color: #f5d76e !important;\n}\n.card-output {\r\n background-color: #ffb3a7 !important;\n}\n.box-inputs {\r\n float: left;\r\n padding-left: 2px;\r\n padding-right: 5px;\r\n vertical-align: top;\r\n text-align: left;\n}\n.box-outputs {\r\n float: right;\r\n padding-left: 5px;\r\n padding-right: 2px;\r\n vertical-align: top;\r\n text-align: right;\n}\n.dualbox-graph-canvas .card,\r\n.card-node {\r\n /*border: 1px solid #dddddd;*/\r\n box-shadow: 1px 1px 5px #716f6f;\r\n opacity: 1;\r\n cursor: pointer;\r\n z-index: 20;\r\n position: absolute;\r\n -webkit-transition: -webkit-box-shadow 0.15s ease-in;\r\n -moz-transition: -moz-box-shadow 0.15s ease-in;\r\n -o-transition: -o-box-shadow 0.15s ease-in;\r\n transition: box-shadow 0.15s ease-in;\r\n color: #4d4d4d;\r\n user-select: none;\r\n padding: 0px 8px 0px 8px;\r\n overflow: hidden;\r\n background-color: #fff;\r\n -moz-border-radius: 3px;\r\n border-radius: 3px;\r\n font-size: 14px;\r\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n}\n.card-node .card-top {\r\n padding-top: 2px;\n}\n.card-node .card-bottom {\r\n padding-bottom: 2px;\r\n text-align: center;\r\n line-height: 14px;\r\n white-space: nowrap;\n}\n.card-node hr {\r\n margin-top: 2px;\r\n margin-bottom: 2px;\r\n border-color: rgba(0, 0, 0, 0.1);\r\n margin-left: -8px;\r\n margin-right: -8px;\n}\n.card-node:hover {\r\n border-color: #80b2fc;\r\n box-shadow: 1px 1px 10px #80b2fc;\n}\n.card-node.selected,\r\n.card-node.selected:hover {\r\n border-color: #0066ff;\r\n box-shadow: 1px 1px 10px #0066ff;\n}\n.card-node-incomplete {\r\n box-shadow: 1px 1px 5px #dd6666 !important;\n}\n.input-not-resolvable {\r\n color: #dd6666 !important;\n}\n.card-node .title {\r\n vertical-align: top;\r\n font-weight: bold;\n}\n.card-node .subtitle {\r\n color: #929292;\r\n font-size: 11px;\r\n font-style: italic;\r\n vertical-align: center;\r\n font-family: tahoma, sans-serif;\n}\n.card-node .input {\r\n font-size: 13px;\r\n color: #8c8c8c;\n}\n.card-node .output {\r\n font-size: 13px;\r\n color: #8c8c8c;\r\n text-align: right;\n}\n.card-node .jtk-endpoint.active svg circle {\r\n /* fill: #99ff33 */\r\n stroke: #59b300;\n}\n.point {\r\n /* display: inline-block; */\r\n display: none;\r\n position: relative;\r\n top: 3px;\r\n margin-right: 5px;\r\n margin-left: 5px;\n}\n.dualbox-io {\r\n overflow: visible;\r\n margin-left: -8px;\r\n margin-right: -8px;\n}\n.box-inputs {\r\n display: flex;\r\n justify-content: space-between;\r\n position: relative;\r\n padding: 0;\r\n pointer-events: none;\n}\n.types {\r\n color: #6c757d !important;\r\n opacity: 0.7;\r\n pointer-events: none;\n}\n.box-inputs .types {\r\n display: inline-block;\n}\n.box-inputs .name {\r\n display: inline-block;\n}\n.box-inputs .type {\r\n display: block;\r\n text-align: right;\n}\n.box-inputs .point {\r\n display: block;\n}\n.box-inputs .name {\r\n display: block;\n}\n.box-outputs {\r\n display: flex;\r\n justify-content: center;\r\n position: relative;\r\n padding: 0;\r\n pointer-events: none;\n}\n.box-outputs .types {\r\n display: inline-block;\n}\n.box-outputs .point {\r\n display: inline-block;\n}\n.box-outputs .name {\r\n display: inline-block;\n}\n.box-outputs .type {\r\n display: block;\r\n text-align: left;\n}\n.box-outputs .point {\r\n display: block;\n}\n.box-outputs .name {\r\n display: block;\n}\nspan.feedback {\r\n font-weight: bold;\n}\n.event-dock {\r\n background-color: rgb(136, 137, 138);\r\n background-color: #a6a6a6;\r\n width: calc(100% + 18px);\r\n height: 12px;\r\n z-index: 3 !important;\n}\n.event-dock-top {\r\n margin-left: -9px;\r\n margin-right: -9px;\r\n margin-top: -3px;\r\n border-top-left-radius: 4px;\r\n border-top-right-radius: 4px;\r\n margin-bottom: 4px;\n}\n.event-dock-bottom {\r\n margin-left: -9px;\r\n margin-right: -9px;\r\n margin-bottom: -3px;\r\n border-bottom-left-radius: 4px;\r\n border-bottom-right-radius: 4px;\r\n margin-top: 4px;\r\n height: 11px;\r\n /* shorter because of box-shadow */\n}\n.event-label {\r\n z-index: 21;\r\n padding-left: 15px;\r\n transform: rotate(-90deg) translate(0%, -50%) !important;\r\n transform-origin: 0% 0%;\r\n color: #6c757d !important;\r\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\r\n font-size: 14px;\r\n opacity: 0.7;\r\n cursor: pointer;\n}\n.transparent {\r\n opacity: 0.3 !important;\n}\n.card-node {\r\n position: relative;\n}\n.card-comment {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n margin-top: -22px;\r\n color: #f4ad42 !important;\n}\n.card-problem {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n margin-top: -22px;\r\n color: red !important;\n}\n.card-snapshot {\n}\n.card-snapshot-idle {\r\n border: 2px solid gray !important;\r\n box-shadow: 1px 1px 5px gray !important;\r\n opacity: 0.7 !important;\n}\n.card-snapshot-computing {\r\n border: 2px solid darkgreen !important;\r\n box-shadow: 1px 1px 5px darkgreen !important;\r\n opacity: 1 !important;\n}\n.card-snapshot-awaiting-data {\r\n border: 2px solid blue !important;\r\n box-shadow: 1px 1px 5px blue !important;\r\n opacity: 0.7 !important;\n}\n.card-snapshot-ready {\r\n border: 2px solid lightgreen !important;\r\n box-shadow: 1px 1px 5px lightgreen !important;\r\n opacity: 1 !important;\n}\n.card-status {\r\n position: absolute;\r\n bottom: 0;\r\n right: 0;\r\n left: 0;\r\n margin-bottom: -26px;\r\n color: #f4ad42 !important;\r\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\r\n font-weight: bold;\r\n text-align: center;\n}\n.card-status-idle {\r\n color: gray !important;\r\n min-width: 85px;\n}\n.card-status-computing {\r\n color: darkgreen !important;\r\n min-width: 110px;\n}\n.card-status-awaiting-data {\r\n color: blue !important;\r\n min-width: 85px;\n}\n.card-status-ready {\r\n color: lightgreen !important;\r\n min-width: 85px;\n}\n.btn-snapshot-details {\r\n position: relative;\r\n margin-top: -2px;\r\n color: inherit;\n}\nspan.name {\r\n overflow-wrap: normal;\n}\r\n", map: {"version":3,"sources":["C:\\Users\\maxim\\Projects\\dualbox\\editor\\js\\src\\v\\templates\\graphNode.vue"],"names":[],"mappings":";AACA;IACA,oCAAA;AACA;AAEA;IACA,yCAAA;IACA,0BAAA;IACA,iBAAA;AACA;AAEA;IACA,oCAAA;AACA;AAEA;IACA,oCAAA;AACA;AAEA;IACA,WAAA;IACA,iBAAA;IACA,kBAAA;IACA,mBAAA;IACA,gBAAA;AACA;AAEA;IACA,YAAA;IACA,iBAAA;IACA,kBAAA;IACA,mBAAA;IACA,iBAAA;AACA;AAEA;;IAEA,6BAAA;IACA,+BAAA;IACA,UAAA;IACA,eAAA;IACA,WAAA;IACA,kBAAA;IACA,oDAAA;IACA,8CAAA;IACA,0CAAA;IACA,oCAAA;IACA,cAAA;IACA,iBAAA;IACA,wBAAA;IACA,gBAAA;IACA,sBAAA;IACA,uBAAA;IACA,kBAAA;IACA,eAAA;IACA,2DAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,mBAAA;IACA,kBAAA;IACA,iBAAA;IACA,mBAAA;AACA;AAEA;IACA,eAAA;IACA,kBAAA;IACA,gCAAA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,qBAAA;IACA,gCAAA;AACA;AAEA;;IAEA,qBAAA;IACA,gCAAA;AACA;AAEA;IACA,0CAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,mBAAA;IACA,iBAAA;AACA;AAEA;IACA,cAAA;IACA,eAAA;IACA,kBAAA;IACA,sBAAA;IACA,+BAAA;AACA;AAEA;IACA,eAAA;IACA,cAAA;AACA;AAEA;IACA,eAAA;IACA,cAAA;IACA,iBAAA;AACA;AAEA;IACA,kBAAA;IACA,eAAA;AACA;AAEA;IACA,2BAAA;IACA,aAAA;IACA,kBAAA;IACA,QAAA;IACA,iBAAA;IACA,gBAAA;AACA;AAEA;IACA,iBAAA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,aAAA;IACA,8BAAA;IACA,kBAAA;IACA,UAAA;IACA,oBAAA;AACA;AAEA;IACA,yBAAA;IACA,YAAA;IACA,oBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,cAAA;IACA,iBAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,aAAA;IACA,uBAAA;IACA,kBAAA;IACA,UAAA;IACA,oBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,cAAA;IACA,gBAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,iBAAA;AACA;AAEA;IACA,oCAAA;IACA,yBAAA;IACA,wBAAA;IACA,YAAA;IACA,qBAAA;AACA;AAEA;IACA,iBAAA;IACA,kBAAA;IACA,gBAAA;IACA,2BAAA;IACA,4BAAA;IACA,kBAAA;AACA;AAEA;IACA,iBAAA;IACA,kBAAA;IACA,mBAAA;IACA,8BAAA;IACA,+BAAA;IACA,eAAA;IACA,YAAA;IACA,kCAAA;AACA;AAEA;IACA,WAAA;IACA,kBAAA;IACA,wDAAA;IACA,uBAAA;IACA,yBAAA;IACA,2DAAA;IACA,eAAA;IACA,YAAA;IACA,eAAA;AACA;AAEA;IACA,uBAAA;AACA;AAEA;IACA,kBAAA;AACA;AAEA;IACA,kBAAA;IACA,MAAA;IACA,QAAA;IACA,iBAAA;IACA,yBAAA;AACA;AAEA;IACA,kBAAA;IACA,MAAA;IACA,OAAA;IACA,iBAAA;IACA,qBAAA;AACA;AAEA;AACA;AAEA;IACA,iCAAA;IACA,uCAAA;IACA,uBAAA;AACA;AAEA;IACA,sCAAA;IACA,4CAAA;IACA,qBAAA;AACA;AAEA;IACA,iCAAA;IACA,uCAAA;IACA,uBAAA;AACA;AAEA;IACA,uCAAA;IACA,6CAAA;IACA,qBAAA;AACA;AAEA;IACA,kBAAA;IACA,SAAA;IACA,QAAA;IACA,OAAA;IACA,oBAAA;IACA,yBAAA;IACA,2DAAA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,sBAAA;IACA,eAAA;AACA;AAEA;IACA,2BAAA;IACA,gBAAA;AACA;AAEA;IACA,sBAAA;IACA,eAAA;AACA;AAEA;IACA,4BAAA;IACA,eAAA;AACA;AAEA;IACA,kBAAA;IACA,gBAAA;IACA,cAAA;AACA;AAEA;IACA,qBAAA;AACA","file":"graphNode.vue","sourcesContent":["<style>\r\n.card-ui {\r\n background-color: #bff2ca !important;\r\n}\r\n\r\n.card-loop {\r\n /* background-color: #e5e8ea!important; */\r\n border: 5px double #dddddd;\r\n border-width: 4px;\r\n}\r\n\r\n.card-input {\r\n background-color: #f5d76e !important;\r\n}\r\n\r\n.card-output {\r\n background-color: #ffb3a7 !important;\r\n}\r\n\r\n.box-inputs {\r\n float: left;\r\n padding-left: 2px;\r\n padding-right: 5px;\r\n vertical-align: top;\r\n text-align: left;\r\n}\r\n\r\n.box-outputs {\r\n float: right;\r\n padding-left: 5px;\r\n padding-right: 2px;\r\n vertical-align: top;\r\n text-align: right;\r\n}\r\n\r\n.dualbox-graph-canvas .card,\r\n.card-node {\r\n /*border: 1px solid #dddddd;*/\r\n box-shadow: 1px 1px 5px #716f6f;\r\n opacity: 1;\r\n cursor: pointer;\r\n z-index: 20;\r\n position: absolute;\r\n -webkit-transition: -webkit-box-shadow 0.15s ease-in;\r\n -moz-transition: -moz-box-shadow 0.15s ease-in;\r\n -o-transition: -o-box-shadow 0.15s ease-in;\r\n transition: box-shadow 0.15s ease-in;\r\n color: #4d4d4d;\r\n user-select: none;\r\n padding: 0px 8px 0px 8px;\r\n overflow: hidden;\r\n background-color: #fff;\r\n -moz-border-radius: 3px;\r\n border-radius: 3px;\r\n font-size: 14px;\r\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\r\n}\r\n\r\n.card-node .card-top {\r\n padding-top: 2px;\r\n}\r\n\r\n.card-node .card-bottom {\r\n padding-bottom: 2px;\r\n text-align: center;\r\n line-height: 14px;\r\n white-space: nowrap;\r\n}\r\n\r\n.card-node hr {\r\n margin-top: 2px;\r\n margin-bottom: 2px;\r\n border-color: rgba(0, 0, 0, 0.1);\r\n margin-left: -8px;\r\n margin-right: -8px;\r\n}\r\n\r\n.card-node:hover {\r\n border-color: #80b2fc;\r\n box-shadow: 1px 1px 10px #80b2fc;\r\n}\r\n\r\n.card-node.selected,\r\n.card-node.selected:hover {\r\n border-color: #0066ff;\r\n box-shadow: 1px 1px 10px #0066ff;\r\n}\r\n\r\n.card-node-incomplete {\r\n box-shadow: 1px 1px 5px #dd6666 !important;\r\n}\r\n\r\n.input-not-resolvable {\r\n color: #dd6666 !important;\r\n}\r\n\r\n.card-node .title {\r\n vertical-align: top;\r\n font-weight: bold;\r\n}\r\n\r\n.card-node .subtitle {\r\n color: #929292;\r\n font-size: 11px;\r\n font-style: italic;\r\n vertical-align: center;\r\n font-family: tahoma, sans-serif;\r\n}\r\n\r\n.card-node .input {\r\n font-size: 13px;\r\n color: #8c8c8c;\r\n}\r\n\r\n.card-node .output {\r\n font-size: 13px;\r\n color: #8c8c8c;\r\n text-align: right;\r\n}\r\n\r\n.card-node .jtk-endpoint.active svg circle {\r\n /* fill: #99ff33 */\r\n stroke: #59b300;\r\n}\r\n\r\n.point {\r\n /* display: inline-block; */\r\n display: none;\r\n position: relative;\r\n top: 3px;\r\n margin-right: 5px;\r\n margin-left: 5px;\r\n}\r\n\r\n.dualbox-io {\r\n overflow: visible;\r\n margin-left: -8px;\r\n margin-right: -8px;\r\n}\r\n\r\n.box-inputs {\r\n display: flex;\r\n justify-content: space-between;\r\n position: relative;\r\n padding: 0;\r\n pointer-events: none;\r\n}\r\n\r\n.types {\r\n color: #6c757d !important;\r\n opacity: 0.7;\r\n pointer-events: none;\r\n}\r\n\r\n.box-inputs .types {\r\n display: inline-block;\r\n}\r\n\r\n.box-inputs .name {\r\n display: inline-block;\r\n}\r\n\r\n.box-inputs .type {\r\n display: block;\r\n text-align: right;\r\n}\r\n\r\n.box-inputs .point {\r\n display: block;\r\n}\r\n\r\n.box-inputs .name {\r\n display: block;\r\n}\r\n\r\n.box-outputs {\r\n display: flex;\r\n justify-content: center;\r\n position: relative;\r\n padding: 0;\r\n pointer-events: none;\r\n}\r\n\r\n.box-outputs .types {\r\n display: inline-block;\r\n}\r\n\r\n.box-outputs .point {\r\n display: inline-block;\r\n}\r\n\r\n.box-outputs .name {\r\n display: inline-block;\r\n}\r\n\r\n.box-outputs .type {\r\n display: block;\r\n text-align: left;\r\n}\r\n\r\n.box-outputs .point {\r\n display: block;\r\n}\r\n\r\n.box-outputs .name {\r\n display: block;\r\n}\r\n\r\nspan.feedback {\r\n font-weight: bold;\r\n}\r\n\r\n.event-dock {\r\n background-color: rgb(136, 137, 138);\r\n background-color: #a6a6a6;\r\n width: calc(100% + 18px);\r\n height: 12px;\r\n z-index: 3 !important;\r\n}\r\n\r\n.event-dock-top {\r\n margin-left: -9px;\r\n margin-right: -9px;\r\n margin-top: -3px;\r\n border-top-left-radius: 4px;\r\n border-top-right-radius: 4px;\r\n margin-bottom: 4px;\r\n}\r\n\r\n.event-dock-bottom {\r\n margin-left: -9px;\r\n margin-right: -9px;\r\n margin-bottom: -3px;\r\n border-bottom-left-radius: 4px;\r\n border-bottom-right-radius: 4px;\r\n margin-top: 4px;\r\n height: 11px;\r\n /* shorter because of box-shadow */\r\n}\r\n\r\n.event-label {\r\n z-index: 21;\r\n padding-left: 15px;\r\n transform: rotate(-90deg) translate(0%, -50%) !important;\r\n transform-origin: 0% 0%;\r\n color: #6c757d !important;\r\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\r\n font-size: 14px;\r\n opacity: 0.7;\r\n cursor: pointer;\r\n}\r\n\r\n.transparent {\r\n opacity: 0.3 !important;\r\n}\r\n\r\n.card-node {\r\n position: relative;\r\n}\r\n\r\n.card-comment {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n margin-top: -22px;\r\n color: #f4ad42 !important;\r\n}\r\n\r\n.card-problem {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n margin-top: -22px;\r\n color: red !important;\r\n}\r\n\r\n.card-snapshot {\r\n}\r\n\r\n.card-snapshot-idle {\r\n border: 2px solid gray !important;\r\n box-shadow: 1px 1px 5px gray !important;\r\n opacity: 0.7 !important;\r\n}\r\n\r\n.card-snapshot-computing {\r\n border: 2px solid darkgreen !important;\r\n box-shadow: 1px 1px 5px darkgreen !important;\r\n opacity: 1 !important;\r\n}\r\n\r\n.card-snapshot-awaiting-data {\r\n border: 2px solid blue !important;\r\n box-shadow: 1px 1px 5px blue !important;\r\n opacity: 0.7 !important;\r\n}\r\n\r\n.card-snapshot-ready {\r\n border: 2px solid lightgreen !important;\r\n box-shadow: 1px 1px 5px lightgreen !important;\r\n opacity: 1 !important;\r\n}\r\n\r\n.card-status {\r\n position: absolute;\r\n bottom: 0;\r\n right: 0;\r\n left: 0;\r\n margin-bottom: -26px;\r\n color: #f4ad42 !important;\r\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\r\n font-weight: bold;\r\n text-align: center;\r\n}\r\n\r\n.card-status-idle {\r\n color: gray !important;\r\n min-width: 85px;\r\n}\r\n\r\n.card-status-computing {\r\n color: darkgreen !important;\r\n min-width: 110px;\r\n}\r\n\r\n.card-status-awaiting-data {\r\n color: blue !important;\r\n min-width: 85px;\r\n}\r\n\r\n.card-status-ready {\r\n color: lightgreen !important;\r\n min-width: 85px;\r\n}\r\n\r\n.btn-snapshot-details {\r\n position: relative;\r\n margin-top: -2px;\r\n color: inherit;\r\n}\r\n\r\nspan.name {\r\n overflow-wrap: normal;\r\n}\r\n</style>\r\n\r\n<template>\r\n <div class=\"jtk-node card card-node contextmenu\" v-bind:class=\"{ 'card-loop': n.hasLoop(), 'card-ui': n.isUI(), 'card-metanode': n.isMetanode(), 'card-input': n.isInput(), 'card-output': n.isOutput(), 'card-snapshot': n.hasSnapshot(), 'card-snapshot-idle': n.hasSnapshot() && n.isSnapshotStatus(0), 'card-snapshot-computing': n.hasSnapshot() && n.isSnapshotStatus(1), 'card-snapshot-awaiting-data': n.hasSnapshot() && n.isSnapshotStatus(2), 'card-snapshot-ready': n.hasSnapshot() && n.isSnapshotStatus(3) }\" v-bind:id=\"getId()\" v-bind:data-id=\"getId()\" v-bind:data-name=\"pkg.name\" style=\"overflow: visible;\">\r\n <div v-if=\"n.hasComment()\">\r\n <div class=\"card-comment\" data-toggle=\"tooltip\" data-placement=\"top\" :title=\"n.getComment()\">\r\n <i class=\"fas fa-comment-alt\" data-container=\"body\"></i>\r\n </div>\r\n </div>\r\n\r\n <div v-if=\"n.hasSnapshot()\">\r\n <div class=\"card-status\">\r\n <div v-if=\"n.isSnapshotStatus(0)\">\r\n <div class=\"card-status-idle\">\r\n <span>IDLE</span>\r\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\r\n </div>\r\n </div>\r\n\r\n <div v-if=\"n.isSnapshotStatus(1)\">\r\n <div class=\"card-status-computing\">\r\n <span>COMPUTING</span>\r\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\r\n </div>\r\n </div>\r\n\r\n <div v-if=\"n.isSnapshotStatus(2)\">\r\n <div class=\"card-status-awaiting-data\">\r\n <span>WAITING</span>\r\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\r\n </div>\r\n </div>\r\n\r\n <div v-if=\"n.isSnapshotStatus(3)\">\r\n <div class=\"card-status-ready\">\r\n <span>READY</span>\r\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div v-if=\"!example && n.isUI() && !n.isOnAPanel()\">\r\n <div @click=\"registerToPanel\" class=\"card-problem\">\r\n <i class=\"fas fa-exclamation-circle\" data-container=\"body\" data-toggle=\"popover\" data-placement=\"top\" data-content=\"This UI is not set in a panel. It won't have any effect. Go to the Interface tab to add it to a panel.\"></i>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-top\">\r\n <div class=\"d-flex\">\r\n <span class=\"title\" style=\"white-space: nowrap; margin-right: 5px;\">\r\n <span v-if=\"n.isMetanode()\" class=\"badge badge-secondary\"><b>META</b></span> {{n.graphId}}\r\n <i v-if=\"n.isParallel()\" class=\"fas fa-server\" style=\"color: orange;\" title=\"this module is computed in a web worker\"></i>\r\n </span>\r\n\r\n <div class=\"ml-auto\">\r\n <button class=\"btn btn-outline-secondary btn-outline-discrete btn-editor-xs btn-settings\" v-on:click=\"openNodeSettings\"><i class=\"fas fa-cog\"></i></button>\r\n </div>\r\n </div>\r\n </div>\r\n <div v-if=\"!n.isInput() && !n.isOutput()\" class=\"card-center\">\r\n <hr style=\"margin-bottom: 5px;\" />\r\n <div class=\"dualbox-io\" style=\"overflow: visible;\">\r\n <div class=\"inputs\" style=\"display: inline-block; float: left;\">\r\n <div class=\"box-inputs\">\r\n <div class=\"types\">\r\n <span class=\"type\" v-for=\"key in getVisibleInputs()\" v-bind:data-key=\"key\">\r\n {{ n.getInputType(key) }}\r\n </span>\r\n </div>\r\n <div class=\"points\">\r\n <div class=\"point\" v-for=\"key in getVisibleInputs()\" v-bind:data-key=\"key\" v-bind:data-type=\"n.getInputDef(key).type\" v-html=\"point\"></div>\r\n </div>\r\n <div class=\"names\">\r\n <span class=\"name\" v-for=\"key in getVisibleInputs()\" :class=\"{'feedback': n.isFeedbackTarget(key), 'input-not-resolvable': !example && !n.isInputResolvable(key) }\" v-bind:data-input=\"key\">\r\n <span v-if=\"n.hasIterator(key)\"><{{key}}></span>\r\n <span v-else>{{key}}</span>\r\n <small v-if=\"!n.isInputConst(key)\" data-toggle=\"tooltip\" data-trigger=\"hover\" title=\"this value will be cloned at execution time\"><i class=\"fas fa-clone transparent\"></i></small>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"outputs\" style=\"display: inline-block; float: right\">\r\n <div class=\"box-outputs\">\r\n <div class=\"names\">\r\n <span class=\"name\" v-for=\"key in getVisibleOutputs()\" v-bind:class=\"{feedback: n.isFeedbackTarget(key)}\" v-bind:data-output=\"key\">\r\n <span v-if=\"n.hasLoop() && n.hasFeedback(key)\">{{key}}</span>\r\n <span v-else-if=\"n.hasLoop() && !n.hasFeedback(key)\"><{{key}}></span>\r\n <span v-else>{{key}}</span>\r\n\r\n <span v-if=\"n.hasCacheActivated()\">\r\n <i class=\"fa fa-hdd\" title=\"This module has cache activated\"></i>\r\n </span>\r\n </span>\r\n </div>\r\n <div class=\"points\">\r\n <div class=\"point\" v-for=\"key in getVisibleOutputs()\" v-bind:data-key=\"key\" v-bind:data-type=\"n.getOutputDef(key).type\" v-html=\"point\"></div>\r\n </div>\r\n <div class=\"types\">\r\n <span class=\"type\" v-for=\"key in getVisibleOutputs()\" v-bind:data-key=\"key\">\r\n {{ n.getOutputType(key) }}\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr style=\"margin-top: 5px;\" />\r\n <div class=\"card-bottom\">\r\n <span class=\"subtitle\">{{ shortName }}</span>\r\n\r\n <div v-if=\"n.isMetanode()\" class=\"d-inline-block\">\r\n <button class=\"btn btn-outline-secondary btn-outline-discrete btn-editor-xs btn-enter-metanode\" v-on:click=\"enterMetanode\"><i class=\"fas fa-sign-in-alt\"></i></button>\r\n </div>\r\n\r\n <!--\r\n <div v-if=\"n.isUI()\" class=\"event-dock event-dock-bottom\"></div>\r\n -->\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport ContextMenu from \"../ContextMenu\";\r\nimport _ from \"lodash-es\";\r\nimport dbutils from \"../../m/DualboxUtils\";\r\n\r\n// fix inputs types and output types position relatively to the div\r\n$.fn.fixCardDisplay = function() {\r\n var offsetPoint = 12;\r\n var offsetBorder = parseInt($(this).css(\"border-top-width\"));\r\n\r\n // if we have width or height set to 0, we are not ready yet to\r\n // execute this function. Postpone it.\r\n if( $(this).width() === 0 || $(this).height() === 0 ) {\r\n setTimeout(() => {\r\n $(this).fixCardDisplay();\r\n }, 50);\r\n return;\r\n }\r\n\r\n if (\r\n $(this)\r\n .find(\".box-inputs\")\r\n .height() === 0 &&\r\n $(this)\r\n .find(\".box-outputs\")\r\n .height() === 0\r\n ) {\r\n // if this card has no input/output, remove the card center\r\n $(this)\r\n .find(\".card-center\")\r\n .remove();\r\n } else {\r\n // else, adjust the input/output display for endpoints\r\n // 1) translate inputs by the right amount of pixels to have the circle on the line\r\n var boxInputs = $(this).find(\".box-inputs\");\r\n\r\n // fix css names width\r\n var namesDiv = boxInputs.find(\".names\");\r\n namesDiv.css(\"width\", namesDiv.width() + 1 + \"px\");\r\n\r\n // translate inputs to the left\r\n var translateLeft =\r\n boxInputs.find(\".types\").width() + offsetPoint + offsetBorder / 2;\r\n $(this)\r\n .find(\".box-inputs\")\r\n .css(\"transform\", \"translateX(-\" + translateLeft + \"px)\");\r\n\r\n // adjust inputs main div width\r\n $(this)\r\n .find(\".inputs\")\r\n .width(\r\n $(this)\r\n .find(\".inputs\")\r\n .width() -\r\n translateLeft +\r\n 10 /* margin */\r\n );\r\n\r\n // 2) translate outputs by the right amount of pixels to have the circle on the line\r\n var boxOutputs = $(this).find(\".box-outputs\");\r\n\r\n // fix css names with\r\n var namesDiv = boxOutputs.find(\".names\");\r\n namesDiv.css(\"width\", namesDiv.width() + 1 + \"px\");\r\n\r\n // translate inputs to the right\r\n var translateRight =\r\n boxOutputs.find(\".types\").width() + offsetPoint + offsetBorder / 2;\r\n $(this)\r\n .find(\".box-outputs\")\r\n .css(\"transform\", \"translateX(\" + translateRight + \"px)\");\r\n\r\n // adjust output main div width\r\n $(this)\r\n .find(\".outputs\")\r\n .width(\r\n $(this)\r\n .find(\".outputs\")\r\n .width() -\r\n translateRight +\r\n 10 /* margin */\r\n );\r\n\r\n // fix io width\r\n //$('.dualbox-io').css('width', (($(this).find('.inputs').width() + $(this).find('.outputs').width()) + \"px\"));\r\n }\r\n\r\n $(this).ready(() => {\r\n // take the current width and add it as a css property\r\n var width = $(this).width();\r\n width += parseInt($(this).css(\"padding-right\"));\r\n width += parseInt($(this).css(\"padding-left\"));\r\n width += parseInt($(this).css(\"border-left-width\"));\r\n width += parseInt($(this).css(\"border-right-width\"));\r\n $(this).css(\"width\", Math.ceil(width) + \"px\");\r\n });\r\n};\r\n\r\n// find position of element relative to an ancestor matching selector\r\n$.fn.positionFrom = function(selector) {\r\n var ancestor = $(this).closest(selector);\r\n var offset = $(this).offset();\r\n var ancestorOffset = ancestor.offset();\r\n return {\r\n top: offset.top - ancestorOffset.top,\r\n left: offset.left - ancestorOffset.left\r\n };\r\n};\r\n\r\nexport default {\r\n props: [\r\n \"id\", // the module id\r\n \"pkg\", // the module package.json\r\n \"n\", // the GraphNode object (from model)\r\n \"example\", // true if this vue is used as an example display (no need to connect)\r\n \"displayEvents\" // true if events should be displayed\r\n ],\r\n data: function() {\r\n return {\r\n shortName: \"\",\r\n point:\r\n '<svg width=\"14\" height=\"14\" pointer-events=\"all\" position=\"absolute\" version=\"1.1\" xmlns=\"http://www.w3.org/1999/xhtml\"><circle cx=\"7\" cy=\"7\" r=\"5\" version=\"1.1\" xmlns=\"http://www.w3.org/1999/xhtml\" fill=\"#ffffff\" stroke=\"#727272\" style=\"\" stroke-width=\"2\"></circle></svg>'\r\n };\r\n },\r\n beforeUpdate: function() {\r\n //console.log('[UPDATING] ' + this.n.getUniqId());\r\n },\r\n destroyed: function() {\r\n this.deactivateTooltip();\r\n $(\".tooltip\").remove();\r\n },\r\n created: function() {\r\n this.initialized = false;\r\n this.view = window.dualboxEditor.v;\r\n\r\n //console.log('[CREATED] ' + this.n.getUniqId());\r\n // We compute the shortname of our box\r\n if (this.n.isInput() || this.n.isOutput()) {\r\n this.shortName = this.n.getType();\r\n } else {\r\n this.shortName = dbutils.shortName(this.pkg.name);\r\n }\r\n },\r\n mounted: async function() {\r\n //console.log('[MOUNTED] ' + this.n.getUniqId());\r\n var div = $(this.$el);\r\n div.fixCardDisplay();\r\n this.activateTooltip();\r\n return await this.initialize();\r\n },\r\n beforeUpdate: function() {\r\n this.deactivateTooltip();\r\n },\r\n updated: async function() {\r\n //console.log('[UPDATED] ' + this.n.getUniqId());\r\n\r\n // we reset jsPlumb before app update (in graph.vue)\r\n // so we need to initialize again\r\n this.assignContextMenu();\r\n\r\n $(this.$el).fixCardDisplay();\r\n $(this.$el).ready(() => {\r\n this.activateTooltip();\r\n });\r\n return await this.initialize();\r\n },\r\n activate: function() {\r\n this.activateTooltip();\r\n },\r\n deactivate: function() {\r\n this.deactivateTooltip();\r\n },\r\n methods: {\r\n getId: function() {\r\n // if this is an example graphNode, change our \"id\" to \"id-junk\"\r\n // to avoid connection jsplumb conflicts with the real node\r\n return this.example ? this.id + \"-junk\" : this.id;\r\n },\r\n\r\n activateTooltip: function() {\r\n $(this.$el)\r\n .find('[data-toggle=\"tooltip\"]')\r\n .tooltip();\r\n },\r\n\r\n deactivateTooltip: function() {\r\n $(this.$el)\r\n .find('[data-toggle=\"tooltip\"]')\r\n .tooltip(\"dispose\");\r\n },\r\n\r\n initialize: async function() {\r\n var self = this;\r\n var div = $(this.$el);\r\n var id = this.getId();\r\n var view = this.view;\r\n\r\n this.initialized = false;\r\n\r\n if (!this.example) {\r\n // if we have a position, set it\r\n var def = this.n.getDef();\r\n var position = _.get(def, [\"graph\", \"position\"]);\r\n if (position) {\r\n var jsPlumbElement = self.$parent.jsPlumbInstance.getElement(\r\n id\r\n );\r\n self.$parent.jsPlumbInstance.setPosition(\r\n jsPlumbElement,\r\n position\r\n );\r\n }\r\n\r\n // This needs to be registered before draggable\r\n div.on(\"mousedown\", function(e) {\r\n // if this div is not selected already, deselect the other divs\r\n if (!self.$parent.selector.isSelected(this)) {\r\n self.$parent.selector.deselect();\r\n }\r\n });\r\n\r\n await this.initializeJsPlumb();\r\n\r\n div.click(function(e) {\r\n if (e.ctrlKey) {\r\n view.selector.toggleSelection(this);\r\n }\r\n });\r\n\r\n this.assignContextMenu();\r\n }\r\n\r\n return new Promise(resolve => {\r\n div.ready(() => {\r\n //console.log('[INITIALIZED] ' + this.n.getUniqId());\r\n this.initialized = true;\r\n resolve();\r\n });\r\n });\r\n },\r\n\r\n initializeJsPlumb: function() {\r\n var self = this;\r\n var div = $(this.$el);\r\n var id = this.getId();\r\n var view = this.view;\r\n\r\n if (!this.example) {\r\n // If this node was never initialized in this jsplumb instance, do it\r\n if (\r\n !_.get(this.$parent.jsPlumbInstance, [\r\n \"initializedNodes\",\r\n id\r\n ])\r\n ) {\r\n _.set(\r\n this.$parent.jsPlumbInstance,\r\n [\"initializedNodes\", id],\r\n true\r\n ); // initialized\r\n\r\n if (this.n.isInput() || this.n.isOutput()) {\r\n var type = \"*\";\r\n var input = \"value\";\r\n var output = \"value\";\r\n var offsetTop =\r\n $(div)\r\n .find(\".card-top\")\r\n .height() +\r\n 12 /* hr size */ -\r\n 3;\r\n\r\n var uuid = [id, \"input\", input].join(\"#\");\r\n var ep = this.$parent.jsPlumbInstance.addEndpoint(\r\n id,\r\n {\r\n isSource: false,\r\n isTarget: true,\r\n uuid: uuid,\r\n anchor: [0, 0, -1, 0, 0, offsetTop],\r\n maxConnections: 1,\r\n parameters: {\r\n type: \"data\",\r\n target: {\r\n id: id,\r\n input: output\r\n }\r\n }\r\n },\r\n this.$parent.style.inputEndpoint\r\n );\r\n\r\n // add data to the endpoint div so we can identify it easier\r\n $(ep.canvas).attr(\"data-node\", id);\r\n $(ep.canvas).attr(\"data-type\", \"input\");\r\n $(ep.canvas).attr(\"data-input\", input);\r\n\r\n // bind tooltip\r\n $(ep.canvas).attr(\"data-toggle\", \"tooltip\");\r\n $(ep.canvas).attr(\"data-trigger\", \"hover\");\r\n $(ep.canvas).attr(\"data-placement\", \"left\");\r\n $(ep.canvas).attr(\"data-html\", \"true\");\r\n var inputType = view.m\r\n .getNode(id)\r\n .getInputType(\"value\");\r\n $(ep.canvas).attr(\r\n \"title\",\r\n \"Type: <b>\" + inputType + \"</b>\"\r\n );\r\n $(ep.canvas).tooltip();\r\n\r\n // bind context menu to the endpoint\r\n $(ep.canvas).addClass(\"capture-right-click\");\r\n $(ep.canvas).ready(function() {\r\n var menu = new ContextMenu(\r\n \".jtk-endpoint-anchor[data-node='\" +\r\n id.trim() +\r\n \"'][data-input='\" +\r\n input +\r\n \"']\",\r\n [\r\n {\r\n name: \"Create input for here\",\r\n fn: () => {\r\n view.c.createInputFromConnection(\r\n id,\r\n input\r\n );\r\n }\r\n }\r\n ]\r\n );\r\n });\r\n\r\n var uuid = [id, \"output\", output].join(\"#\");\r\n var ep = this.$parent.jsPlumbInstance.addEndpoint(\r\n id,\r\n {\r\n isSource: true,\r\n isTarget: false,\r\n uuid: uuid,\r\n anchor: [1, 0, 1, 0, 0, offsetTop],\r\n parameters: {\r\n type: \"data\",\r\n source: {\r\n id: id,\r\n output: output\r\n }\r\n }\r\n },\r\n this.$parent.style.outputEndpoint\r\n );\r\n\r\n // add data to the endpoint div so we can identify it easier\r\n $(ep.canvas).attr(\"data-node\", id);\r\n $(ep.canvas).attr(\"data-type\", \"output\");\r\n $(ep.canvas).attr(\"data-output\", output);\r\n\r\n // bind tooltip\r\n $(ep.canvas).attr(\"data-toggle\", \"tooltip\");\r\n $(ep.canvas).attr(\"data-trigger\", \"hover\");\r\n $(ep.canvas).attr(\"data-placement\", \"right\");\r\n $(ep.canvas).attr(\"data-html\", \"true\");\r\n var outputType = view.m\r\n .getNode(id)\r\n .getOutputType(\"value\");\r\n $(ep.canvas).attr(\r\n \"title\",\r\n \"Type: <b>\" + outputType + \"</b>\"\r\n );\r\n $(ep.canvas).tooltip();\r\n\r\n // bind context menu to the endpoint\r\n $(ep.canvas).addClass(\"capture-right-click\");\r\n $(ep.canvas).ready(function() {\r\n var menu = new ContextMenu(\r\n \".jtk-endpoint-anchor[data-node='\" +\r\n id.trim() +\r\n \"'][data-output='\" +\r\n output.trim() +\r\n \"']\",\r\n [\r\n {\r\n name: \"Create output for here\",\r\n fn: () => {\r\n view.c.createOutputFromConnection(\r\n id,\r\n output\r\n );\r\n }\r\n }\r\n ]\r\n );\r\n });\r\n } else {\r\n // add input endoints\r\n div.find(\".box-inputs\")\r\n .find(\".point\")\r\n .each(function(index) {\r\n $(this)\r\n .css(\"visibility\", \"hidden\")\r\n .css(\"opacity\", \"0\"); // replaced by jsPlumb point\r\n\r\n var input = div\r\n .find(\".box-inputs\")\r\n .find(\".name\")\r\n .eq(index)\r\n .attr(\"data-input\")\r\n .trim();\r\n var type = view.m\r\n .getNode(id)\r\n .getInputType(input);\r\n\r\n var offsetTop =\r\n $(this).positionFrom(\".card\").top +\r\n $(this).height() / 2 -\r\n 3;\r\n var uuid = [\r\n id,\r\n \"input\",\r\n $(this).data(\"key\")\r\n ].join(\"#\");\r\n var ep = self.$parent.jsPlumbInstance.addEndpoint(\r\n id,\r\n {\r\n isSource: false,\r\n isTarget: true,\r\n uuid: uuid,\r\n anchor: [0, 0, -1, 0, 0, offsetTop],\r\n maxConnections: 1,\r\n parameters: {\r\n type: \"data\",\r\n target: {\r\n id: id,\r\n input: $(this).data(\"key\")\r\n }\r\n }\r\n },\r\n self.$parent.style.inputEndpoint\r\n );\r\n\r\n // add data to the endpoint div so we can identify it easier\r\n $(ep.canvas).attr(\"data-node\", id);\r\n $(ep.canvas).attr(\"data-type\", \"input\");\r\n $(ep.canvas).attr(\"data-input\", input);\r\n\r\n // bind tooltip\r\n $(ep.canvas).attr(\"data-toggle\", \"tooltip\");\r\n $(ep.canvas).attr(\"data-trigger\", \"hover\");\r\n $(ep.canvas).attr(\"data-placement\", \"left\");\r\n $(ep.canvas).attr(\"data-html\", \"true\");\r\n $(ep.canvas).attr(\r\n \"title\",\r\n \"Type: <b>\" + type + \"</b>\"\r\n );\r\n $(ep.canvas).tooltip();\r\n\r\n // bind context menu to the endpoint\r\n $(ep.canvas).addClass(\"capture-right-click\");\r\n $(ep.canvas).ready(function() {\r\n var menu = new ContextMenu(\r\n \".jtk-endpoint-anchor[data-node='\" +\r\n id.trim() +\r\n \"'][data-input='\" +\r\n input.trim() +\r\n \"']\",\r\n [\r\n {\r\n name: \"Create input for here\",\r\n fn: () => {\r\n view.c.createInputFromConnection(\r\n id,\r\n input\r\n );\r\n }\r\n }\r\n ]\r\n );\r\n });\r\n });\r\n\r\n // add output endpoints\r\n div.find(\".box-outputs\")\r\n .find(\".point\")\r\n .each(function(index) {\r\n $(this)\r\n .css(\"visibility\", \"hidden\")\r\n .css(\"opacity\", \"0\"); // replaced by jsPlumb point\r\n\r\n var output = div\r\n .find(\".box-outputs\")\r\n .find(\".name\")\r\n .eq(index)\r\n .attr(\"data-output\")\r\n .trim();\r\n var type = view.m\r\n .getNode(id)\r\n .getOutputType(output);\r\n\r\n var offsetTop =\r\n $(this).positionFrom(\".card\").top +\r\n $(this).height() / 2 -\r\n 3;\r\n var uuid = [\r\n id,\r\n \"output\",\r\n $(this).data(\"key\")\r\n ].join(\"#\");\r\n var ep = self.$parent.jsPlumbInstance.addEndpoint(\r\n id,\r\n {\r\n isSource: true,\r\n isTarget: false,\r\n uuid: uuid,\r\n anchor: [1, 0, 1, 0, 0, offsetTop],\r\n parameters: {\r\n type: \"data\",\r\n source: {\r\n id: id,\r\n output: $(this).data(\"key\")\r\n }\r\n }\r\n },\r\n self.$parent.style.outputEndpoint\r\n );\r\n\r\n // add data to the endpoint div so we can identify it easier\r\n $(ep.canvas).attr(\"data-node\", id);\r\n $(ep.canvas).attr(\"data-type\", \"output\");\r\n $(ep.canvas).attr(\"data-output\", output);\r\n\r\n // bind tooltip\r\n $(ep.canvas).attr(\"data-toggle\", \"tooltip\");\r\n $(ep.canvas).attr(\"data-trigger\", \"hover\");\r\n $(ep.canvas).attr(\"data-placement\", \"right\");\r\n $(ep.canvas).attr(\"data-html\", \"true\");\r\n $(ep.canvas).attr(\r\n \"title\",\r\n \"Type: <b>\" + type + \"</b>\"\r\n );\r\n $(ep.canvas).tooltip();\r\n\r\n // bind context menu to the endpoint\r\n $(ep.canvas).addClass(\"capture-right-click\");\r\n $(ep.canvas).ready(function() {\r\n var menu = new ContextMenu(\r\n \".jtk-endpoint-anchor[data-node='\" +\r\n id.trim() +\r\n \"'][data-output='\" +\r\n output.trim() +\r\n \"']\",\r\n [\r\n {\r\n name: \"Create output for here\",\r\n fn: () => {\r\n view.c.createOutputFromConnection(\r\n id,\r\n output\r\n );\r\n }\r\n }\r\n ]\r\n );\r\n });\r\n });\r\n\r\n if (this.n.isUI() && this.displayEvents) {\r\n // Make this a target for events\r\n this.$parent.jsPlumbInstance.makeTarget(\r\n id,\r\n {\r\n isSource: false,\r\n isTarget: true,\r\n uniqueEndpoint: false,\r\n anchor: \"Continuous\",\r\n uuid: id + \"#event-in\",\r\n paintStyle: {\r\n fill: \"green\",\r\n radius: 3,\r\n stroke: \"#727272\",\r\n strokeWidth: 1\r\n },\r\n parameters: {\r\n type: \"event\",\r\n target: { id: id }\r\n }\r\n },\r\n self.$parent.style.eventEndpoint\r\n );\r\n\r\n // Create an enpoint to create a new event\r\n var ep = this.$parent.jsPlumbInstance.addEndpoint(\r\n id,\r\n {\r\n isSource: true,\r\n isTarget: false,\r\n uuid: id + \"#event-out\",\r\n anchor: [1, 1, 0, 1, 0, -10],\r\n parameters: {\r\n type: \"event\",\r\n source: { id: id }\r\n },\r\n paintStyle: {\r\n fill: \"green\",\r\n radius: 3,\r\n stroke: \"#727272\",\r\n strokeWidth: 1\r\n }\r\n },\r\n this.$parent.style.eventEndpoint\r\n );\r\n\r\n // Add overlay here so we don't mess with splitConnection\r\n ep.addOverlay([\r\n \"PlainArrow\",\r\n {\r\n width: 15,\r\n length: 15,\r\n location: 1,\r\n id: \"arrow\"\r\n }\r\n ]);\r\n\r\n $(ep.canvas).attr(\"data-toggle\", \"tooltip\");\r\n $(ep.canvas).attr(\"data-trigger\", \"hover\");\r\n $(ep.canvas).attr(\"data-placement\", \"bottom\");\r\n $(ep.canvas).attr(\"data-html\", \"true\");\r\n $(ep.canvas).attr(\r\n \"title\",\r\n \"Connect from here ito add an event that will be triggered when this box is done computing.\"\r\n );\r\n $(ep.canvas).tooltip();\r\n }\r\n }\r\n\r\n // Make the div draggable\r\n this.$parent.jsPlumbInstance.draggable(div, {\r\n //containment:true, // not allowed outside of container div\r\n drag: function(e) {\r\n // TODO: bug. After a repaint(), jsPlumb seems to be broken (connections dont follow on div drag)\r\n // It doesn't occur on jsPlumb.reset() instead of creating another instance on beforeUpdate(),\r\n // (as it should be), but we can't do that, because JsPlumb is broken on zoom otherwise...\r\n // One of thoses problem may be fixed later by updating jsPlumb...\r\n // Note: this \"fix\" may affect performances on drag, maybe a setTimeout will do\r\n //self.$parent.jsPlumbInstance.repaintEverything();\r\n self.$parent.jsPlumbInstance.repaint(id);\r\n },\r\n stop: function(e) {\r\n // resize the canvas if necessary\r\n self.$parent.canvasSizeHandler.debouncedResize();\r\n\r\n if (\r\n self.$parent.selector.isMultipleSelectionActive()\r\n ) {\r\n // We just dropped a bunch of divs, ajust all their positions\r\n self.view.m.batch(() => {\r\n self.$parent.selector.each(div => {\r\n var pos = self.$parent.jsPlumbInstance.getPosition(\r\n div\r\n );\r\n view.m\r\n .getNode($(div).attr(\"id\"))\r\n .setPosition(pos);\r\n });\r\n });\r\n } else {\r\n // We just dropped this one, set the new position in the graph model\r\n var el = self.$parent.jsPlumbInstance.getElement(\r\n id\r\n );\r\n $(el).ready(function() {\r\n var pos = self.$parent.jsPlumbInstance.getPosition(\r\n el\r\n );\r\n view.m.getNode(id).setPosition(pos);\r\n });\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n return new Promise(resolve =>\r\n this.$parent.jsPlumbInstance.ready(resolve)\r\n );\r\n },\r\n\r\n assignContextMenu: function() {\r\n var id = this.getId();\r\n\r\n // Create a contextmenu for the div\r\n var contextOptions = [\r\n {\r\n name: \"Remove this box\",\r\n fn: () => {\r\n this.view.c.removeBox(id);\r\n }\r\n }\r\n ];\r\n if (this.n.isModule() || this.n.isUI()) {\r\n contextOptions.push({\r\n name: \"Duplicate this box\",\r\n fn: () => {\r\n this.view.c.duplicateBox(id);\r\n }\r\n });\r\n }\r\n var nodeMenu = new ContextMenu(\"#\" + id, contextOptions);\r\n },\r\n\r\n htmlentities: function(s) {\r\n return this.view.utils.htmlentities(s);\r\n },\r\n\r\n getVisibleInputs: function() {\r\n return this.n.getInputsNames().filter(inputName => {\r\n return this.n.isInputVisible(inputName);\r\n });\r\n },\r\n\r\n getVisibleOutputs: function() {\r\n return this.n.getOutputsNames().filter(outputName => {\r\n return this.n.isOutputVisible(outputName);\r\n });\r\n },\r\n\r\n enterMetanode: function(e) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n this.view.c.enterMetanode(this.id);\r\n },\r\n\r\n openNodeSettings: function(e) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n this.view.openBoxSettings(this.id);\r\n },\r\n\r\n openSnapshotDetails: async function(e) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n await this.view.openDebug(this.id);\r\n },\r\n\r\n registerToPanel: async function(e) {\r\n await this.view.c.registerNodeToInterface(this.id);\r\n }\r\n },\r\n watch: {\r\n app: {\r\n handler: () => {\r\n console.log(\"graphVue.app changed\");\r\n },\r\n deep: true\r\n }\r\n }\r\n};\r\n</script>\r\n"]}, media: undefined });
|
|
47912
|
+
inject("data-v-08972d38_0", { source: "\n.card-ui {\r\n background-color: #bff2ca !important;\n}\n.card-loop {\r\n /* background-color: #e5e8ea!important; */\r\n border: 5px double #dddddd;\r\n border-width: 4px;\n}\n.card-input {\r\n background-color: #f5d76e !important;\n}\n.card-output {\r\n background-color: #ffb3a7 !important;\n}\n.box-inputs {\r\n float: left;\r\n padding-left: 2px;\r\n padding-right: 5px;\r\n vertical-align: top;\r\n text-align: left;\n}\n.box-outputs {\r\n float: right;\r\n padding-left: 5px;\r\n padding-right: 2px;\r\n vertical-align: top;\r\n text-align: right;\n}\n.dualbox-graph-canvas .card,\r\n.card-node {\r\n /*border: 1px solid #dddddd;*/\r\n box-shadow: 1px 1px 5px #716f6f;\r\n opacity: 1;\r\n cursor: pointer;\r\n z-index: 20;\r\n position: absolute;\r\n -webkit-transition: -webkit-box-shadow 0.15s ease-in;\r\n -moz-transition: -moz-box-shadow 0.15s ease-in;\r\n -o-transition: -o-box-shadow 0.15s ease-in;\r\n transition: box-shadow 0.15s ease-in;\r\n color: #4d4d4d;\r\n user-select: none;\r\n padding: 0px 8px 0px 8px;\r\n overflow: hidden;\r\n background-color: #fff;\r\n -moz-border-radius: 3px;\r\n border-radius: 3px;\r\n font-size: 14px;\r\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n}\n.card-node .card-top {\r\n padding-top: 2px;\n}\n.card-node .card-bottom {\r\n padding-bottom: 2px;\r\n text-align: center;\r\n line-height: 14px;\r\n white-space: nowrap;\n}\n.card-node hr {\r\n margin-top: 2px;\r\n margin-bottom: 2px;\r\n border-color: rgba(0, 0, 0, 0.1);\r\n margin-left: -8px;\r\n margin-right: -8px;\n}\n.card-node:hover {\r\n border-color: #80b2fc;\r\n box-shadow: 1px 1px 10px #80b2fc;\n}\n.card-node.selected,\r\n.card-node.selected:hover {\r\n border-color: #0066ff;\r\n box-shadow: 1px 1px 10px #0066ff;\n}\n.card-node-incomplete {\r\n box-shadow: 1px 1px 5px #dd6666 !important;\n}\n.input-not-resolvable {\r\n color: #dd6666 !important;\n}\n.card-node .title {\r\n vertical-align: top;\r\n font-weight: bold;\n}\n.card-node .subtitle {\r\n color: #929292;\r\n font-size: 11px;\r\n font-style: italic;\r\n vertical-align: center;\r\n font-family: tahoma, sans-serif;\n}\n.card-node .input {\r\n font-size: 13px;\r\n color: #8c8c8c;\n}\n.card-node .output {\r\n font-size: 13px;\r\n color: #8c8c8c;\r\n text-align: right;\n}\n.card-node .jtk-endpoint.active svg circle {\r\n /* fill: #99ff33 */\r\n stroke: #59b300;\n}\n.point {\r\n /* display: inline-block; */\r\n display: none;\r\n position: relative;\r\n top: 3px;\r\n margin-right: 5px;\r\n margin-left: 5px;\n}\n.dualbox-io {\r\n overflow: visible;\r\n margin-left: -8px;\r\n margin-right: -8px;\n}\n.box-inputs {\r\n display: flex;\r\n justify-content: space-between;\r\n position: relative;\r\n padding: 0;\r\n pointer-events: none;\n}\n.types {\r\n color: #6c757d !important;\r\n opacity: 0.7;\r\n pointer-events: none;\n}\n.box-inputs .types {\r\n display: inline-block;\n}\n.box-inputs .name {\r\n display: inline-block;\n}\n.box-inputs .type {\r\n display: block;\r\n text-align: right;\n}\n.box-inputs .point {\r\n display: block;\n}\n.box-inputs .name {\r\n display: block;\n}\n.box-outputs {\r\n display: flex;\r\n justify-content: center;\r\n position: relative;\r\n padding: 0;\r\n pointer-events: none;\n}\n.box-outputs .types {\r\n display: inline-block;\n}\n.box-outputs .point {\r\n display: inline-block;\n}\n.box-outputs .name {\r\n display: inline-block;\n}\n.box-outputs .type {\r\n display: block;\r\n text-align: left;\n}\n.box-outputs .point {\r\n display: block;\n}\n.box-outputs .name {\r\n display: block;\n}\nspan.feedback {\r\n font-weight: bold;\n}\n.event-dock {\r\n background-color: rgb(136, 137, 138);\r\n background-color: #a6a6a6;\r\n width: calc(100% + 18px);\r\n height: 12px;\r\n z-index: 3 !important;\n}\n.event-dock-top {\r\n margin-left: -9px;\r\n margin-right: -9px;\r\n margin-top: -3px;\r\n border-top-left-radius: 4px;\r\n border-top-right-radius: 4px;\r\n margin-bottom: 4px;\n}\n.event-dock-bottom {\r\n margin-left: -9px;\r\n margin-right: -9px;\r\n margin-bottom: -3px;\r\n border-bottom-left-radius: 4px;\r\n border-bottom-right-radius: 4px;\r\n margin-top: 4px;\r\n height: 11px;\r\n /* shorter because of box-shadow */\n}\n.event-label {\r\n z-index: 21;\r\n padding-left: 15px;\r\n transform: rotate(-90deg) translate(0%, -50%) !important;\r\n transform-origin: 0% 0%;\r\n color: #6c757d !important;\r\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\r\n font-size: 14px;\r\n opacity: 0.7;\r\n cursor: pointer;\n}\n.transparent {\r\n opacity: 0.3 !important;\n}\n.card-node {\r\n position: relative;\n}\n.card-comment {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n margin-top: -22px;\r\n color: #f4ad42 !important;\n}\n.card-problem {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n margin-top: -22px;\r\n color: red !important;\n}\n.card-snapshot {\n}\n.card-snapshot-idle {\r\n border: 2px solid gray !important;\r\n box-shadow: 1px 1px 5px gray !important;\r\n opacity: 0.7 !important;\n}\n.card-snapshot-computing {\r\n border: 2px solid darkgreen !important;\r\n box-shadow: 1px 1px 5px darkgreen !important;\r\n opacity: 1 !important;\n}\n.card-snapshot-awaiting-data {\r\n border: 2px solid blue !important;\r\n box-shadow: 1px 1px 5px blue !important;\r\n opacity: 0.7 !important;\n}\n.card-snapshot-ready {\r\n border: 2px solid lightgreen !important;\r\n box-shadow: 1px 1px 5px lightgreen !important;\r\n opacity: 1 !important;\n}\n.card-status {\r\n position: absolute;\r\n bottom: 0;\r\n right: 0;\r\n left: 0;\r\n margin-bottom: -26px;\r\n color: #f4ad42 !important;\r\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\r\n font-weight: bold;\r\n text-align: center;\n}\n.card-status-idle {\r\n color: gray !important;\r\n min-width: 85px;\n}\n.card-status-computing {\r\n color: darkgreen !important;\r\n min-width: 110px;\n}\n.card-status-awaiting-data {\r\n color: blue !important;\r\n min-width: 85px;\n}\n.card-status-ready {\r\n color: lightgreen !important;\r\n min-width: 85px;\n}\n.btn-snapshot-details {\r\n position: relative;\r\n margin-top: -2px;\r\n color: inherit;\n}\nspan.name {\r\n overflow-wrap: normal;\n}\r\n", map: {"version":3,"sources":["C:\\Users\\maxim\\Projects\\dualbox\\editor\\js\\src\\v\\templates\\graphNode.vue"],"names":[],"mappings":";AACA;IACA,oCAAA;AACA;AAEA;IACA,yCAAA;IACA,0BAAA;IACA,iBAAA;AACA;AAEA;IACA,oCAAA;AACA;AAEA;IACA,oCAAA;AACA;AAEA;IACA,WAAA;IACA,iBAAA;IACA,kBAAA;IACA,mBAAA;IACA,gBAAA;AACA;AAEA;IACA,YAAA;IACA,iBAAA;IACA,kBAAA;IACA,mBAAA;IACA,iBAAA;AACA;AAEA;;IAEA,6BAAA;IACA,+BAAA;IACA,UAAA;IACA,eAAA;IACA,WAAA;IACA,kBAAA;IACA,oDAAA;IACA,8CAAA;IACA,0CAAA;IACA,oCAAA;IACA,cAAA;IACA,iBAAA;IACA,wBAAA;IACA,gBAAA;IACA,sBAAA;IACA,uBAAA;IACA,kBAAA;IACA,eAAA;IACA,2DAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,mBAAA;IACA,kBAAA;IACA,iBAAA;IACA,mBAAA;AACA;AAEA;IACA,eAAA;IACA,kBAAA;IACA,gCAAA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,qBAAA;IACA,gCAAA;AACA;AAEA;;IAEA,qBAAA;IACA,gCAAA;AACA;AAEA;IACA,0CAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,mBAAA;IACA,iBAAA;AACA;AAEA;IACA,cAAA;IACA,eAAA;IACA,kBAAA;IACA,sBAAA;IACA,+BAAA;AACA;AAEA;IACA,eAAA;IACA,cAAA;AACA;AAEA;IACA,eAAA;IACA,cAAA;IACA,iBAAA;AACA;AAEA;IACA,kBAAA;IACA,eAAA;AACA;AAEA;IACA,2BAAA;IACA,aAAA;IACA,kBAAA;IACA,QAAA;IACA,iBAAA;IACA,gBAAA;AACA;AAEA;IACA,iBAAA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,aAAA;IACA,8BAAA;IACA,kBAAA;IACA,UAAA;IACA,oBAAA;AACA;AAEA;IACA,yBAAA;IACA,YAAA;IACA,oBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,cAAA;IACA,iBAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,aAAA;IACA,uBAAA;IACA,kBAAA;IACA,UAAA;IACA,oBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,cAAA;IACA,gBAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,iBAAA;AACA;AAEA;IACA,oCAAA;IACA,yBAAA;IACA,wBAAA;IACA,YAAA;IACA,qBAAA;AACA;AAEA;IACA,iBAAA;IACA,kBAAA;IACA,gBAAA;IACA,2BAAA;IACA,4BAAA;IACA,kBAAA;AACA;AAEA;IACA,iBAAA;IACA,kBAAA;IACA,mBAAA;IACA,8BAAA;IACA,+BAAA;IACA,eAAA;IACA,YAAA;IACA,kCAAA;AACA;AAEA;IACA,WAAA;IACA,kBAAA;IACA,wDAAA;IACA,uBAAA;IACA,yBAAA;IACA,2DAAA;IACA,eAAA;IACA,YAAA;IACA,eAAA;AACA;AAEA;IACA,uBAAA;AACA;AAEA;IACA,kBAAA;AACA;AAEA;IACA,kBAAA;IACA,MAAA;IACA,QAAA;IACA,iBAAA;IACA,yBAAA;AACA;AAEA;IACA,kBAAA;IACA,MAAA;IACA,OAAA;IACA,iBAAA;IACA,qBAAA;AACA;AAEA;AACA;AAEA;IACA,iCAAA;IACA,uCAAA;IACA,uBAAA;AACA;AAEA;IACA,sCAAA;IACA,4CAAA;IACA,qBAAA;AACA;AAEA;IACA,iCAAA;IACA,uCAAA;IACA,uBAAA;AACA;AAEA;IACA,uCAAA;IACA,6CAAA;IACA,qBAAA;AACA;AAEA;IACA,kBAAA;IACA,SAAA;IACA,QAAA;IACA,OAAA;IACA,oBAAA;IACA,yBAAA;IACA,2DAAA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,sBAAA;IACA,eAAA;AACA;AAEA;IACA,2BAAA;IACA,gBAAA;AACA;AAEA;IACA,sBAAA;IACA,eAAA;AACA;AAEA;IACA,4BAAA;IACA,eAAA;AACA;AAEA;IACA,kBAAA;IACA,gBAAA;IACA,cAAA;AACA;AAEA;IACA,qBAAA;AACA","file":"graphNode.vue","sourcesContent":["<style>\r\n.card-ui {\r\n background-color: #bff2ca !important;\r\n}\r\n\r\n.card-loop {\r\n /* background-color: #e5e8ea!important; */\r\n border: 5px double #dddddd;\r\n border-width: 4px;\r\n}\r\n\r\n.card-input {\r\n background-color: #f5d76e !important;\r\n}\r\n\r\n.card-output {\r\n background-color: #ffb3a7 !important;\r\n}\r\n\r\n.box-inputs {\r\n float: left;\r\n padding-left: 2px;\r\n padding-right: 5px;\r\n vertical-align: top;\r\n text-align: left;\r\n}\r\n\r\n.box-outputs {\r\n float: right;\r\n padding-left: 5px;\r\n padding-right: 2px;\r\n vertical-align: top;\r\n text-align: right;\r\n}\r\n\r\n.dualbox-graph-canvas .card,\r\n.card-node {\r\n /*border: 1px solid #dddddd;*/\r\n box-shadow: 1px 1px 5px #716f6f;\r\n opacity: 1;\r\n cursor: pointer;\r\n z-index: 20;\r\n position: absolute;\r\n -webkit-transition: -webkit-box-shadow 0.15s ease-in;\r\n -moz-transition: -moz-box-shadow 0.15s ease-in;\r\n -o-transition: -o-box-shadow 0.15s ease-in;\r\n transition: box-shadow 0.15s ease-in;\r\n color: #4d4d4d;\r\n user-select: none;\r\n padding: 0px 8px 0px 8px;\r\n overflow: hidden;\r\n background-color: #fff;\r\n -moz-border-radius: 3px;\r\n border-radius: 3px;\r\n font-size: 14px;\r\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\r\n}\r\n\r\n.card-node .card-top {\r\n padding-top: 2px;\r\n}\r\n\r\n.card-node .card-bottom {\r\n padding-bottom: 2px;\r\n text-align: center;\r\n line-height: 14px;\r\n white-space: nowrap;\r\n}\r\n\r\n.card-node hr {\r\n margin-top: 2px;\r\n margin-bottom: 2px;\r\n border-color: rgba(0, 0, 0, 0.1);\r\n margin-left: -8px;\r\n margin-right: -8px;\r\n}\r\n\r\n.card-node:hover {\r\n border-color: #80b2fc;\r\n box-shadow: 1px 1px 10px #80b2fc;\r\n}\r\n\r\n.card-node.selected,\r\n.card-node.selected:hover {\r\n border-color: #0066ff;\r\n box-shadow: 1px 1px 10px #0066ff;\r\n}\r\n\r\n.card-node-incomplete {\r\n box-shadow: 1px 1px 5px #dd6666 !important;\r\n}\r\n\r\n.input-not-resolvable {\r\n color: #dd6666 !important;\r\n}\r\n\r\n.card-node .title {\r\n vertical-align: top;\r\n font-weight: bold;\r\n}\r\n\r\n.card-node .subtitle {\r\n color: #929292;\r\n font-size: 11px;\r\n font-style: italic;\r\n vertical-align: center;\r\n font-family: tahoma, sans-serif;\r\n}\r\n\r\n.card-node .input {\r\n font-size: 13px;\r\n color: #8c8c8c;\r\n}\r\n\r\n.card-node .output {\r\n font-size: 13px;\r\n color: #8c8c8c;\r\n text-align: right;\r\n}\r\n\r\n.card-node .jtk-endpoint.active svg circle {\r\n /* fill: #99ff33 */\r\n stroke: #59b300;\r\n}\r\n\r\n.point {\r\n /* display: inline-block; */\r\n display: none;\r\n position: relative;\r\n top: 3px;\r\n margin-right: 5px;\r\n margin-left: 5px;\r\n}\r\n\r\n.dualbox-io {\r\n overflow: visible;\r\n margin-left: -8px;\r\n margin-right: -8px;\r\n}\r\n\r\n.box-inputs {\r\n display: flex;\r\n justify-content: space-between;\r\n position: relative;\r\n padding: 0;\r\n pointer-events: none;\r\n}\r\n\r\n.types {\r\n color: #6c757d !important;\r\n opacity: 0.7;\r\n pointer-events: none;\r\n}\r\n\r\n.box-inputs .types {\r\n display: inline-block;\r\n}\r\n\r\n.box-inputs .name {\r\n display: inline-block;\r\n}\r\n\r\n.box-inputs .type {\r\n display: block;\r\n text-align: right;\r\n}\r\n\r\n.box-inputs .point {\r\n display: block;\r\n}\r\n\r\n.box-inputs .name {\r\n display: block;\r\n}\r\n\r\n.box-outputs {\r\n display: flex;\r\n justify-content: center;\r\n position: relative;\r\n padding: 0;\r\n pointer-events: none;\r\n}\r\n\r\n.box-outputs .types {\r\n display: inline-block;\r\n}\r\n\r\n.box-outputs .point {\r\n display: inline-block;\r\n}\r\n\r\n.box-outputs .name {\r\n display: inline-block;\r\n}\r\n\r\n.box-outputs .type {\r\n display: block;\r\n text-align: left;\r\n}\r\n\r\n.box-outputs .point {\r\n display: block;\r\n}\r\n\r\n.box-outputs .name {\r\n display: block;\r\n}\r\n\r\nspan.feedback {\r\n font-weight: bold;\r\n}\r\n\r\n.event-dock {\r\n background-color: rgb(136, 137, 138);\r\n background-color: #a6a6a6;\r\n width: calc(100% + 18px);\r\n height: 12px;\r\n z-index: 3 !important;\r\n}\r\n\r\n.event-dock-top {\r\n margin-left: -9px;\r\n margin-right: -9px;\r\n margin-top: -3px;\r\n border-top-left-radius: 4px;\r\n border-top-right-radius: 4px;\r\n margin-bottom: 4px;\r\n}\r\n\r\n.event-dock-bottom {\r\n margin-left: -9px;\r\n margin-right: -9px;\r\n margin-bottom: -3px;\r\n border-bottom-left-radius: 4px;\r\n border-bottom-right-radius: 4px;\r\n margin-top: 4px;\r\n height: 11px;\r\n /* shorter because of box-shadow */\r\n}\r\n\r\n.event-label {\r\n z-index: 21;\r\n padding-left: 15px;\r\n transform: rotate(-90deg) translate(0%, -50%) !important;\r\n transform-origin: 0% 0%;\r\n color: #6c757d !important;\r\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\r\n font-size: 14px;\r\n opacity: 0.7;\r\n cursor: pointer;\r\n}\r\n\r\n.transparent {\r\n opacity: 0.3 !important;\r\n}\r\n\r\n.card-node {\r\n position: relative;\r\n}\r\n\r\n.card-comment {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n margin-top: -22px;\r\n color: #f4ad42 !important;\r\n}\r\n\r\n.card-problem {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n margin-top: -22px;\r\n color: red !important;\r\n}\r\n\r\n.card-snapshot {\r\n}\r\n\r\n.card-snapshot-idle {\r\n border: 2px solid gray !important;\r\n box-shadow: 1px 1px 5px gray !important;\r\n opacity: 0.7 !important;\r\n}\r\n\r\n.card-snapshot-computing {\r\n border: 2px solid darkgreen !important;\r\n box-shadow: 1px 1px 5px darkgreen !important;\r\n opacity: 1 !important;\r\n}\r\n\r\n.card-snapshot-awaiting-data {\r\n border: 2px solid blue !important;\r\n box-shadow: 1px 1px 5px blue !important;\r\n opacity: 0.7 !important;\r\n}\r\n\r\n.card-snapshot-ready {\r\n border: 2px solid lightgreen !important;\r\n box-shadow: 1px 1px 5px lightgreen !important;\r\n opacity: 1 !important;\r\n}\r\n\r\n.card-status {\r\n position: absolute;\r\n bottom: 0;\r\n right: 0;\r\n left: 0;\r\n margin-bottom: -26px;\r\n color: #f4ad42 !important;\r\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\r\n font-weight: bold;\r\n text-align: center;\r\n}\r\n\r\n.card-status-idle {\r\n color: gray !important;\r\n min-width: 85px;\r\n}\r\n\r\n.card-status-computing {\r\n color: darkgreen !important;\r\n min-width: 110px;\r\n}\r\n\r\n.card-status-awaiting-data {\r\n color: blue !important;\r\n min-width: 85px;\r\n}\r\n\r\n.card-status-ready {\r\n color: lightgreen !important;\r\n min-width: 85px;\r\n}\r\n\r\n.btn-snapshot-details {\r\n position: relative;\r\n margin-top: -2px;\r\n color: inherit;\r\n}\r\n\r\nspan.name {\r\n overflow-wrap: normal;\r\n}\r\n</style>\r\n\r\n<template>\r\n <div class=\"jtk-node card card-node contextmenu\" v-bind:class=\"{ 'card-loop': n.hasLoop(), 'card-ui': n.isUI(), 'card-metanode': n.isMetanode(), 'card-input': n.isInput(), 'card-output': n.isOutput(), 'card-snapshot': n.hasSnapshot(), 'card-snapshot-idle': n.hasSnapshot() && n.isSnapshotStatus(0), 'card-snapshot-computing': n.hasSnapshot() && n.isSnapshotStatus(1), 'card-snapshot-awaiting-data': n.hasSnapshot() && n.isSnapshotStatus(2), 'card-snapshot-ready': n.hasSnapshot() && n.isSnapshotStatus(3) }\" v-bind:id=\"getId()\" v-bind:data-id=\"getId()\" v-bind:data-name=\"pkg.name\" style=\"overflow: visible;\">\r\n <div v-if=\"n.hasComment()\">\r\n <div class=\"card-comment\" data-toggle=\"tooltip\" data-placement=\"top\" :title=\"n.getComment()\">\r\n <i class=\"fas fa-comment-alt\" data-container=\"body\"></i>\r\n </div>\r\n </div>\r\n\r\n <div v-if=\"n.hasSnapshot()\">\r\n <div class=\"card-status\">\r\n <div v-if=\"n.isSnapshotStatus(0)\">\r\n <div class=\"card-status-idle\">\r\n <span>IDLE</span>\r\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\r\n </div>\r\n </div>\r\n\r\n <div v-if=\"n.isSnapshotStatus(1)\">\r\n <div class=\"card-status-computing\">\r\n <span>COMPUTING</span>\r\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\r\n </div>\r\n </div>\r\n\r\n <div v-if=\"n.isSnapshotStatus(2)\">\r\n <div class=\"card-status-awaiting-data\">\r\n <span>WAITING</span>\r\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\r\n </div>\r\n </div>\r\n\r\n <div v-if=\"n.isSnapshotStatus(3)\">\r\n <div class=\"card-status-ready\">\r\n <span>READY</span>\r\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div v-if=\"!example && n.isUI() && !n.isOnAPanel()\">\r\n <div @click=\"registerToPanel\" class=\"card-problem\">\r\n <i class=\"fas fa-exclamation-circle\" data-container=\"body\" data-toggle=\"popover\" data-placement=\"top\" data-content=\"This UI is not set in a panel. It won't have any effect. Go to the Interface tab to add it to a panel.\"></i>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-top\">\r\n <div class=\"d-flex\">\r\n <span class=\"title\" style=\"white-space: nowrap; margin-right: 5px;\">\r\n <span v-if=\"n.isMetanode()\" class=\"badge badge-secondary\"><b>META</b></span> {{n.graphId}}\r\n <i v-if=\"n.isParallel()\" class=\"fas fa-server\" style=\"color: orange;\" title=\"this module is computed in a web worker\"></i>\r\n </span>\r\n\r\n <div class=\"ml-auto\">\r\n <button class=\"btn btn-outline-secondary btn-outline-discrete btn-editor-xs btn-settings\" v-on:click=\"openNodeSettings\"><i class=\"fas fa-cog\"></i></button>\r\n </div>\r\n </div>\r\n </div>\r\n <div v-if=\"!n.isInput() && !n.isOutput()\" class=\"card-center\">\r\n <hr style=\"margin-bottom: 5px;\" />\r\n <div class=\"dualbox-io\" style=\"overflow: visible;\">\r\n <div class=\"inputs\" style=\"display: inline-block; float: left;\">\r\n <div class=\"box-inputs\">\r\n <div class=\"types\">\r\n <span class=\"type\" v-for=\"key in getVisibleInputs()\" v-bind:data-key=\"key\">\r\n {{ n.getInputType(key) }}\r\n </span>\r\n </div>\r\n <div class=\"points\">\r\n <div class=\"point\" v-for=\"key in getVisibleInputs()\" v-bind:data-key=\"key\" v-bind:data-type=\"n.getInputDef(key).type\" v-html=\"point\"></div>\r\n </div>\r\n <div class=\"names\">\r\n <span class=\"name\" v-for=\"key in getVisibleInputs()\" :class=\"{'feedback': n.isFeedbackTarget(key), 'input-not-resolvable': !example && !n.isInputResolvable(key) }\" v-bind:data-input=\"key\">\r\n <span v-if=\"n.hasIterator(key)\"><{{key}}></span>\r\n <span v-else>{{key}}</span>\r\n <small v-if=\"!n.isInputConst(key)\" data-toggle=\"tooltip\" data-trigger=\"hover\" title=\"this value will be cloned at execution time\"><i class=\"fas fa-clone transparent\"></i></small>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"outputs\" style=\"display: inline-block; float: right\">\r\n <div class=\"box-outputs\">\r\n <div class=\"names\">\r\n <span class=\"name\" v-for=\"key in getVisibleOutputs()\" v-bind:class=\"{feedback: n.isFeedbackTarget(key)}\" v-bind:data-output=\"key\">\r\n <span v-if=\"n.hasLoop() && n.hasFeedback(key)\">{{key}}</span>\r\n <span v-else-if=\"n.hasLoop() && !n.hasFeedback(key)\"><{{key}}></span>\r\n <span v-else>{{key}}</span>\r\n\r\n <span v-if=\"n.hasCacheActivated()\">\r\n <i class=\"fa fa-hdd\" title=\"This module has cache activated\"></i>\r\n </span>\r\n </span>\r\n </div>\r\n <div class=\"points\">\r\n <div class=\"point\" v-for=\"key in getVisibleOutputs()\" v-bind:data-key=\"key\" v-bind:data-type=\"n.getOutputDef(key).type\" v-html=\"point\"></div>\r\n </div>\r\n <div class=\"types\">\r\n <span class=\"type\" v-for=\"key in getVisibleOutputs()\" v-bind:data-key=\"key\">\r\n {{ n.getOutputType(key) }}\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr style=\"margin-top: 5px;\" />\r\n <div class=\"card-bottom\">\r\n <span class=\"subtitle\">{{ shortName }}</span>\r\n\r\n <div v-if=\"n.isMetanode()\" class=\"d-inline-block\">\r\n <button class=\"btn btn-outline-secondary btn-outline-discrete btn-editor-xs btn-enter-metanode\" v-on:click=\"enterMetanode\"><i class=\"fas fa-sign-in-alt\"></i></button>\r\n </div>\r\n\r\n <!--\r\n <div v-if=\"n.isUI()\" class=\"event-dock event-dock-bottom\"></div>\r\n -->\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport ContextMenu from \"../ContextMenu\";\r\nimport _ from \"lodash-es\";\r\nimport dbutils from \"../../m/DualboxUtils\";\r\n\r\n// fix inputs types and output types position relatively to the div\r\n$.fn.fixCardDisplay = function() {\r\n var offsetPoint = 12;\r\n var offsetBorder = parseInt($(this).css(\"border-top-width\"));\r\n\r\n // if we have width or height set to 0, we are not ready yet to\r\n // execute this function. Postpone it.\r\n if( $(this).width() === 0 || $(this).height() === 0 ) {\r\n setTimeout(() => {\r\n $(this).fixCardDisplay();\r\n }, 50);\r\n return;\r\n }\r\n\r\n if (\r\n $(this)\r\n .find(\".box-inputs\")\r\n .height() === 0 &&\r\n $(this)\r\n .find(\".box-outputs\")\r\n .height() === 0\r\n ) {\r\n // if this card has no input/output, remove the card center\r\n $(this)\r\n .find(\".card-center\")\r\n .remove();\r\n } else {\r\n // else, adjust the input/output display for endpoints\r\n // 1) translate inputs by the right amount of pixels to have the circle on the line\r\n var boxInputs = $(this).find(\".box-inputs\");\r\n\r\n // fix css names width\r\n var namesDiv = boxInputs.find(\".names\");\r\n namesDiv.css(\"width\", namesDiv.width() + 1 + \"px\");\r\n\r\n // translate inputs to the left\r\n var translateLeft =\r\n boxInputs.find(\".types\").width() + offsetPoint + offsetBorder / 2;\r\n $(this)\r\n .find(\".box-inputs\")\r\n .css(\"transform\", \"translateX(-\" + translateLeft + \"px)\");\r\n\r\n // adjust inputs main div width\r\n $(this)\r\n .find(\".inputs\")\r\n .width(\r\n $(this)\r\n .find(\".inputs\")\r\n .width() -\r\n translateLeft +\r\n 10 /* margin */\r\n );\r\n\r\n // 2) translate outputs by the right amount of pixels to have the circle on the line\r\n var boxOutputs = $(this).find(\".box-outputs\");\r\n\r\n // fix css names with\r\n var namesDiv = boxOutputs.find(\".names\");\r\n namesDiv.css(\"width\", namesDiv.width() + 1 + \"px\");\r\n\r\n // translate inputs to the right\r\n var translateRight =\r\n boxOutputs.find(\".types\").width() + offsetPoint + offsetBorder / 2;\r\n $(this)\r\n .find(\".box-outputs\")\r\n .css(\"transform\", \"translateX(\" + translateRight + \"px)\");\r\n\r\n // adjust output main div width\r\n $(this)\r\n .find(\".outputs\")\r\n .width(\r\n $(this)\r\n .find(\".outputs\")\r\n .width() -\r\n translateRight +\r\n 10 /* margin */\r\n );\r\n\r\n // fix io width\r\n //$('.dualbox-io').css('width', (($(this).find('.inputs').width() + $(this).find('.outputs').width()) + \"px\"));\r\n }\r\n\r\n $(this).ready(() => {\r\n // take the current width and add it as a css property\r\n var width = $(this).width();\r\n width += parseInt($(this).css(\"padding-right\"));\r\n width += parseInt($(this).css(\"padding-left\"));\r\n width += parseInt($(this).css(\"border-left-width\"));\r\n width += parseInt($(this).css(\"border-right-width\"));\r\n $(this).css(\"width\", Math.ceil(width) + \"px\");\r\n });\r\n};\r\n\r\n// find position of element relative to an ancestor matching selector\r\n$.fn.positionFrom = function(selector) {\r\n var ancestor = $(this).closest(selector);\r\n var offset = $(this).offset();\r\n var ancestorOffset = ancestor.offset();\r\n return {\r\n top: offset.top - ancestorOffset.top,\r\n left: offset.left - ancestorOffset.left\r\n };\r\n};\r\n\r\nexport default {\r\n props: [\r\n \"id\", // the module id\r\n \"pkg\", // the module package.json\r\n \"n\", // the GraphNode object (from model)\r\n \"example\", // true if this vue is used as an example display (no need to connect)\r\n \"displayEvents\" // true if events should be displayed\r\n ],\r\n data: function() {\r\n return {\r\n shortName: \"\",\r\n point:\r\n '<svg width=\"14\" height=\"14\" pointer-events=\"all\" position=\"absolute\" version=\"1.1\" xmlns=\"http://www.w3.org/1999/xhtml\"><circle cx=\"7\" cy=\"7\" r=\"5\" version=\"1.1\" xmlns=\"http://www.w3.org/1999/xhtml\" fill=\"#ffffff\" stroke=\"#727272\" style=\"\" stroke-width=\"2\"></circle></svg>'\r\n };\r\n },\r\n beforeUpdate: function() {\r\n //console.log('[UPDATING] ' + this.n.getUniqId());\r\n },\r\n destroyed: function() {\r\n this.deactivateTooltip();\r\n $(\".tooltip\").remove();\r\n },\r\n created: function() {\r\n this.initialized = false;\r\n this.view = window.dualboxEditor.v;\r\n\r\n //console.log('[CREATED] ' + this.n.getUniqId());\r\n // We compute the shortname of our box\r\n if (this.n.isInput() || this.n.isOutput()) {\r\n this.shortName = this.n.getType();\r\n } else {\r\n this.shortName = dbutils.shortName(this.pkg.name);\r\n }\r\n },\r\n mounted: async function() {\r\n //console.log('[MOUNTED] ' + this.n.getUniqId());\r\n var div = $(this.$el);\r\n div.fixCardDisplay();\r\n this.activateTooltip();\r\n return await this.initialize();\r\n },\r\n beforeUpdate: function() {\r\n this.deactivateTooltip();\r\n },\r\n updated: async function() {\r\n //console.log('[UPDATED] ' + this.n.getUniqId());\r\n\r\n // we reset jsPlumb before app update (in graph.vue)\r\n // so we need to initialize again\r\n this.assignContextMenu();\r\n\r\n $(this.$el).fixCardDisplay();\r\n $(this.$el).ready(() => {\r\n this.activateTooltip();\r\n });\r\n return await this.initialize();\r\n },\r\n activate: function() {\r\n this.activateTooltip();\r\n },\r\n deactivate: function() {\r\n this.deactivateTooltip();\r\n },\r\n methods: {\r\n getId: function() {\r\n // if this is an example graphNode, change our \"id\" to \"id-junk\"\r\n // to avoid connection jsplumb conflicts with the real node\r\n return this.example ? this.id + \"-junk\" : this.id;\r\n },\r\n\r\n activateTooltip: function() {\r\n $(this.$el)\r\n .find('[data-toggle=\"tooltip\"]')\r\n .tooltip();\r\n },\r\n\r\n deactivateTooltip: function() {\r\n $(this.$el)\r\n .find('[data-toggle=\"tooltip\"]')\r\n .tooltip(\"dispose\");\r\n },\r\n\r\n initialize: async function() {\r\n var self = this;\r\n var div = $(this.$el);\r\n var id = this.getId();\r\n var view = this.view;\r\n\r\n this.initialized = false;\r\n\r\n if (!this.example) {\r\n // if we have a position, set it\r\n var def = this.n.getDef();\r\n var position = _.get(def, [\"graph\", \"position\"]);\r\n if (position) {\r\n var jsPlumbElement = self.$parent.jsPlumbInstance.getElement(\r\n id\r\n );\r\n self.$parent.jsPlumbInstance.setPosition(\r\n jsPlumbElement,\r\n position\r\n );\r\n }\r\n\r\n // This needs to be registered before draggable\r\n div.on(\"mousedown\", function(e) {\r\n // if this div is not selected already, deselect the other divs\r\n if (!self.$parent.selector.isSelected(this)) {\r\n self.$parent.selector.deselect();\r\n }\r\n });\r\n\r\n await this.initializeJsPlumb();\r\n\r\n div.click(function(e) {\r\n if (e.ctrlKey) {\r\n view.selector.toggleSelection(this);\r\n }\r\n });\r\n\r\n this.assignContextMenu();\r\n }\r\n\r\n return new Promise(resolve => {\r\n div.ready(() => {\r\n //console.log('[INITIALIZED] ' + this.n.getUniqId());\r\n this.initialized = true;\r\n resolve();\r\n });\r\n });\r\n },\r\n\r\n initializeJsPlumb: function() {\r\n var self = this;\r\n var div = $(this.$el);\r\n var id = this.getId();\r\n var view = this.view;\r\n\r\n if (!this.example) {\r\n // If this node was never initialized in this jsplumb instance, do it\r\n if (\r\n !_.get(this.$parent.jsPlumbInstance, [\r\n \"initializedNodes\",\r\n id\r\n ])\r\n ) {\r\n _.set(\r\n this.$parent.jsPlumbInstance,\r\n [\"initializedNodes\", id],\r\n true\r\n ); // initialized\r\n\r\n if (this.n.isInput() || this.n.isOutput()) {\r\n var type = \"*\";\r\n var input = \"value\";\r\n var output = \"value\";\r\n var offsetTop =\r\n $(div)\r\n .find(\".card-top\")\r\n .height() +\r\n 12 /* hr size */ -\r\n 3;\r\n\r\n var uuid = [id, \"input\", input].join(\"#\");\r\n var ep = this.$parent.jsPlumbInstance.addEndpoint(\r\n id,\r\n {\r\n isSource: false,\r\n isTarget: true,\r\n uuid: uuid,\r\n anchor: [0, 0, -1, 0, 0, offsetTop],\r\n maxConnections: 1,\r\n parameters: {\r\n type: \"data\",\r\n target: {\r\n id: id,\r\n input: output\r\n }\r\n }\r\n },\r\n this.$parent.style.inputEndpoint\r\n );\r\n\r\n // add data to the endpoint div so we can identify it easier\r\n $(ep.canvas).attr(\"data-node\", id);\r\n $(ep.canvas).attr(\"data-type\", \"input\");\r\n $(ep.canvas).attr(\"data-input\", input);\r\n\r\n // bind tooltip\r\n $(ep.canvas).attr(\"data-toggle\", \"tooltip\");\r\n $(ep.canvas).attr(\"data-trigger\", \"hover\");\r\n $(ep.canvas).attr(\"data-placement\", \"left\");\r\n $(ep.canvas).attr(\"data-html\", \"true\");\r\n var inputType = view.m\r\n .getNode(id)\r\n .getInputType(\"value\");\r\n $(ep.canvas).attr(\r\n \"title\",\r\n \"Type: <b>\" + inputType + \"</b>\"\r\n );\r\n $(ep.canvas).tooltip();\r\n\r\n // bind context menu to the endpoint\r\n $(ep.canvas).addClass(\"capture-right-click\");\r\n $(ep.canvas).ready(function() {\r\n var menu = new ContextMenu(\r\n \".jtk-endpoint-anchor[data-node='\" +\r\n id.trim() +\r\n \"'][data-input='\" +\r\n input +\r\n \"']\",\r\n [\r\n {\r\n name: \"Create input for here\",\r\n fn: () => {\r\n view.c.createInputFromConnection(\r\n id,\r\n input\r\n );\r\n }\r\n }\r\n ]\r\n );\r\n });\r\n\r\n var uuid = [id, \"output\", output].join(\"#\");\r\n var ep = this.$parent.jsPlumbInstance.addEndpoint(\r\n id,\r\n {\r\n isSource: true,\r\n isTarget: false,\r\n uuid: uuid,\r\n anchor: [1, 0, 1, 0, 0, offsetTop],\r\n parameters: {\r\n type: \"data\",\r\n source: {\r\n id: id,\r\n output: output\r\n }\r\n }\r\n },\r\n this.$parent.style.outputEndpoint\r\n );\r\n\r\n // add data to the endpoint div so we can identify it easier\r\n $(ep.canvas).attr(\"data-node\", id);\r\n $(ep.canvas).attr(\"data-type\", \"output\");\r\n $(ep.canvas).attr(\"data-output\", output);\r\n\r\n // bind tooltip\r\n $(ep.canvas).attr(\"data-toggle\", \"tooltip\");\r\n $(ep.canvas).attr(\"data-trigger\", \"hover\");\r\n $(ep.canvas).attr(\"data-placement\", \"right\");\r\n $(ep.canvas).attr(\"data-html\", \"true\");\r\n var outputType = view.m\r\n .getNode(id)\r\n .getOutputType(\"value\");\r\n $(ep.canvas).attr(\r\n \"title\",\r\n \"Type: <b>\" + outputType + \"</b>\"\r\n );\r\n $(ep.canvas).tooltip();\r\n\r\n // bind context menu to the endpoint\r\n $(ep.canvas).addClass(\"capture-right-click\");\r\n $(ep.canvas).ready(function() {\r\n var menu = new ContextMenu(\r\n \".jtk-endpoint-anchor[data-node='\" +\r\n id.trim() +\r\n \"'][data-output='\" +\r\n output.trim() +\r\n \"']\",\r\n [\r\n {\r\n name: \"Create output for here\",\r\n fn: () => {\r\n view.c.createOutputFromConnection(\r\n id,\r\n output\r\n );\r\n }\r\n }\r\n ]\r\n );\r\n });\r\n } else {\r\n // add input endoints\r\n div.find(\".box-inputs\")\r\n .find(\".point\")\r\n .each(function(index) {\r\n $(this)\r\n .css(\"visibility\", \"hidden\")\r\n .css(\"opacity\", \"0\"); // replaced by jsPlumb point\r\n\r\n var input = div\r\n .find(\".box-inputs\")\r\n .find(\".name\")\r\n .eq(index)\r\n .attr(\"data-input\")\r\n .trim();\r\n var type = view.m\r\n .getNode(id)\r\n .getInputType(input);\r\n\r\n var offsetTop =\r\n $(this).positionFrom(\".card\").top +\r\n $(this).height() / 2 -\r\n 3;\r\n var uuid = [\r\n id,\r\n \"input\",\r\n $(this).data(\"key\")\r\n ].join(\"#\");\r\n var ep = self.$parent.jsPlumbInstance.addEndpoint(\r\n id,\r\n {\r\n isSource: false,\r\n isTarget: true,\r\n uuid: uuid,\r\n anchor: [0, 0, -1, 0, 0, offsetTop],\r\n maxConnections: 1,\r\n parameters: {\r\n type: \"data\",\r\n target: {\r\n id: id,\r\n input: $(this).data(\"key\")\r\n }\r\n }\r\n },\r\n self.$parent.style.inputEndpoint\r\n );\r\n\r\n // add data to the endpoint div so we can identify it easier\r\n $(ep.canvas).attr(\"data-node\", id);\r\n $(ep.canvas).attr(\"data-type\", \"input\");\r\n $(ep.canvas).attr(\"data-input\", input);\r\n\r\n // bind tooltip\r\n $(ep.canvas).attr(\"data-toggle\", \"tooltip\");\r\n $(ep.canvas).attr(\"data-trigger\", \"hover\");\r\n $(ep.canvas).attr(\"data-placement\", \"left\");\r\n $(ep.canvas).attr(\"data-html\", \"true\");\r\n $(ep.canvas).attr(\r\n \"title\",\r\n \"Type: <b>\" + type + \"</b>\"\r\n );\r\n $(ep.canvas).tooltip();\r\n\r\n // bind context menu to the endpoint\r\n $(ep.canvas).addClass(\"capture-right-click\");\r\n $(ep.canvas).ready(function() {\r\n var menu = new ContextMenu(\r\n \".jtk-endpoint-anchor[data-node='\" +\r\n id.trim() +\r\n \"'][data-input='\" +\r\n input.trim() +\r\n \"']\",\r\n [\r\n {\r\n name: \"Create input for here\",\r\n fn: () => {\r\n view.c.createInputFromConnection(\r\n id,\r\n input\r\n );\r\n }\r\n }\r\n ]\r\n );\r\n });\r\n });\r\n\r\n // add output endpoints\r\n div.find(\".box-outputs\")\r\n .find(\".point\")\r\n .each(function(index) {\r\n $(this)\r\n .css(\"visibility\", \"hidden\")\r\n .css(\"opacity\", \"0\"); // replaced by jsPlumb point\r\n\r\n var output = div\r\n .find(\".box-outputs\")\r\n .find(\".name\")\r\n .eq(index)\r\n .attr(\"data-output\")\r\n .trim();\r\n var type = view.m\r\n .getNode(id)\r\n .getOutputType(output);\r\n\r\n var offsetTop =\r\n $(this).positionFrom(\".card\").top +\r\n $(this).height() / 2 -\r\n 3;\r\n var uuid = [\r\n id,\r\n \"output\",\r\n $(this).data(\"key\")\r\n ].join(\"#\");\r\n var ep = self.$parent.jsPlumbInstance.addEndpoint(\r\n id,\r\n {\r\n isSource: true,\r\n isTarget: false,\r\n uuid: uuid,\r\n anchor: [1, 0, 1, 0, 0, offsetTop],\r\n parameters: {\r\n type: \"data\",\r\n source: {\r\n id: id,\r\n output: $(this).data(\"key\")\r\n }\r\n }\r\n },\r\n self.$parent.style.outputEndpoint\r\n );\r\n\r\n // add data to the endpoint div so we can identify it easier\r\n $(ep.canvas).attr(\"data-node\", id);\r\n $(ep.canvas).attr(\"data-type\", \"output\");\r\n $(ep.canvas).attr(\"data-output\", output);\r\n\r\n // bind tooltip\r\n $(ep.canvas).attr(\"data-toggle\", \"tooltip\");\r\n $(ep.canvas).attr(\"data-trigger\", \"hover\");\r\n $(ep.canvas).attr(\"data-placement\", \"right\");\r\n $(ep.canvas).attr(\"data-html\", \"true\");\r\n $(ep.canvas).attr(\r\n \"title\",\r\n \"Type: <b>\" + type + \"</b>\"\r\n );\r\n $(ep.canvas).tooltip();\r\n\r\n // bind context menu to the endpoint\r\n $(ep.canvas).addClass(\"capture-right-click\");\r\n $(ep.canvas).ready(function() {\r\n var menu = new ContextMenu(\r\n \".jtk-endpoint-anchor[data-node='\" +\r\n id.trim() +\r\n \"'][data-output='\" +\r\n output.trim() +\r\n \"']\",\r\n [\r\n {\r\n name: \"Create output for here\",\r\n fn: () => {\r\n view.c.createOutputFromConnection(\r\n id,\r\n output\r\n );\r\n }\r\n }\r\n ]\r\n );\r\n });\r\n });\r\n\r\n if (this.n.isUI() && this.displayEvents) {\r\n // Make this a target for events\r\n this.$parent.jsPlumbInstance.makeTarget(\r\n id,\r\n {\r\n isSource: false,\r\n isTarget: true,\r\n uniqueEndpoint: false,\r\n anchor: \"Continuous\",\r\n uuid: id + \"#event-in\",\r\n paintStyle: {\r\n fill: \"green\",\r\n radius: 3,\r\n stroke: \"#727272\",\r\n strokeWidth: 1\r\n },\r\n parameters: {\r\n type: \"event\",\r\n target: { id: id }\r\n }\r\n },\r\n self.$parent.style.eventEndpoint\r\n );\r\n\r\n // Create an enpoint to create a new event\r\n var ep = this.$parent.jsPlumbInstance.addEndpoint(\r\n id,\r\n {\r\n isSource: true,\r\n isTarget: false,\r\n uuid: id + \"#event-out\",\r\n anchor: [1, 1, 0, 1, 0, -10],\r\n parameters: {\r\n type: \"event\",\r\n source: { id: id }\r\n },\r\n paintStyle: {\r\n fill: \"green\",\r\n radius: 3,\r\n stroke: \"#727272\",\r\n strokeWidth: 1\r\n }\r\n },\r\n this.$parent.style.eventEndpoint\r\n );\r\n\r\n // Add overlay here so we don't mess with splitConnection\r\n ep.addOverlay([\r\n \"PlainArrow\",\r\n {\r\n width: 15,\r\n length: 15,\r\n location: 1,\r\n id: \"arrow\"\r\n }\r\n ]);\r\n\r\n $(ep.canvas).attr(\"data-toggle\", \"tooltip\");\r\n $(ep.canvas).attr(\"data-trigger\", \"hover\");\r\n $(ep.canvas).attr(\"data-placement\", \"bottom\");\r\n $(ep.canvas).attr(\"data-html\", \"true\");\r\n $(ep.canvas).attr(\r\n \"title\",\r\n \"Connect from here ito add an event that will be triggered when this box is done computing.\"\r\n );\r\n $(ep.canvas).tooltip();\r\n }\r\n }\r\n\r\n // Make the div draggable\r\n this.$parent.jsPlumbInstance.draggable(div, {\r\n //containment:true, // not allowed outside of container div\r\n drag: function(e) {\r\n // TODO: bug. After a repaint(), jsPlumb seems to be broken (connections dont follow on div drag)\r\n // It doesn't occur on jsPlumb.reset() instead of creating another instance on beforeUpdate(),\r\n // (as it should be), but we can't do that, because JsPlumb is broken on zoom otherwise...\r\n // One of thoses problem may be fixed later by updating jsPlumb...\r\n // Note: this \"fix\" may affect performances on drag, maybe a setTimeout will do\r\n //self.$parent.jsPlumbInstance.repaintEverything();\r\n self.$parent.jsPlumbInstance.repaint(id);\r\n },\r\n stop: function(e) {\r\n // resize the canvas if necessary\r\n self.$parent.canvasSizeHandler.debouncedResize();\r\n\r\n if (\r\n self.$parent.selector.isMultipleSelectionActive()\r\n ) {\r\n // We just dropped a bunch of divs, ajust all their positions\r\n self.view.m.batch(() => {\r\n self.$parent.selector.each(div => {\r\n var pos = self.$parent.jsPlumbInstance.getPosition(\r\n div\r\n );\r\n view.m\r\n .getNode($(div).attr(\"id\"))\r\n .setPosition(pos);\r\n });\r\n });\r\n } else {\r\n // We just dropped this one, set the new position in the graph model\r\n var el = self.$parent.jsPlumbInstance.getElement(\r\n id\r\n );\r\n $(el).ready(function() {\r\n var pos = self.$parent.jsPlumbInstance.getPosition(\r\n el\r\n );\r\n view.m.getNode(id).setPosition(pos);\r\n });\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n return new Promise(resolve =>\r\n this.$parent.jsPlumbInstance.ready(resolve)\r\n );\r\n },\r\n\r\n assignContextMenu: function() {\r\n var id = this.getId();\r\n\r\n // Create a contextmenu for the div\r\n var contextOptions = [\r\n {\r\n name: \"Remove this box\",\r\n fn: () => {\r\n this.view.c.removeBox(id);\r\n }\r\n }\r\n ];\r\n if (this.n.isModule() || this.n.isUI() || this.n.isInput() || this.n.isOutput()) {\r\n contextOptions.push({\r\n name: \"Duplicate this box\",\r\n fn: () => {\r\n this.view.c.duplicateBox(id);\r\n }\r\n });\r\n }\r\n var nodeMenu = new ContextMenu(\"#\" + id, contextOptions);\r\n },\r\n\r\n htmlentities: function(s) {\r\n return this.view.utils.htmlentities(s);\r\n },\r\n\r\n getVisibleInputs: function() {\r\n return this.n.getInputsNames().filter(inputName => {\r\n return this.n.isInputVisible(inputName);\r\n });\r\n },\r\n\r\n getVisibleOutputs: function() {\r\n return this.n.getOutputsNames().filter(outputName => {\r\n return this.n.isOutputVisible(outputName);\r\n });\r\n },\r\n\r\n enterMetanode: function(e) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n this.view.c.enterMetanode(this.id);\r\n },\r\n\r\n openNodeSettings: function(e) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n this.view.openBoxSettings(this.id);\r\n },\r\n\r\n openSnapshotDetails: async function(e) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n await this.view.openDebug(this.id);\r\n },\r\n\r\n registerToPanel: async function(e) {\r\n await this.view.c.registerNodeToInterface(this.id);\r\n }\r\n },\r\n watch: {\r\n app: {\r\n handler: () => {\r\n console.log(\"graphVue.app changed\");\r\n },\r\n deep: true\r\n }\r\n }\r\n};\r\n</script>\r\n"]}, media: undefined });
|
|
47859
47913
|
|
|
47860
47914
|
};
|
|
47861
47915
|
/* scoped */
|
|
@@ -47903,10 +47957,12 @@ class Zoomer {
|
|
|
47903
47957
|
}
|
|
47904
47958
|
|
|
47905
47959
|
initialize() {
|
|
47906
|
-
this.container.off('mousewheel');
|
|
47907
|
-
this.container.on('mousewheel', (e) => {
|
|
47908
|
-
|
|
47909
|
-
|
|
47960
|
+
this.container.off('mousewheel DOMMouseScroll');
|
|
47961
|
+
this.container.on('mousewheel DOMMouseScroll', (e) => {
|
|
47962
|
+
let evt = e.originalEvent;
|
|
47963
|
+
let direction = (evt.detail < 0 || evt.wheelDelta > 0) ? 1 : -1; // normalize wheel to +1 or -1
|
|
47964
|
+
|
|
47965
|
+
if (direction > 0) {
|
|
47910
47966
|
this.zoomIn(e);
|
|
47911
47967
|
} else {
|
|
47912
47968
|
this.zoomOut(e);
|
|
@@ -63594,35 +63650,35 @@ var script$5 = {
|
|
|
63594
63650
|
"mousePosition" // mouse position when this panel was opened
|
|
63595
63651
|
],
|
|
63596
63652
|
components: {
|
|
63597
|
-
|
|
63598
|
-
|
|
63599
|
-
|
|
63653
|
+
"search-results": SearchResultsVue,
|
|
63654
|
+
"display-result": DisplayResultVue,
|
|
63655
|
+
"edit-type": EditTypeVue
|
|
63600
63656
|
},
|
|
63601
|
-
data: function
|
|
63657
|
+
data: function() {
|
|
63602
63658
|
return {
|
|
63603
63659
|
error: null,
|
|
63604
63660
|
|
|
63605
63661
|
searchText: {}, // the search text, indexed by selectedType
|
|
63606
63662
|
results: {}, // dictionary of arrays, indexed by selectedType
|
|
63607
|
-
selectedResult
|
|
63663
|
+
selectedResult: {}, // dictionary of string, indexed by selectedType
|
|
63608
63664
|
selectedType: "module",
|
|
63609
63665
|
inputType: "*",
|
|
63610
63666
|
outputType: "*"
|
|
63611
|
-
}
|
|
63667
|
+
};
|
|
63612
63668
|
},
|
|
63613
63669
|
created: function() {
|
|
63614
63670
|
this.view = window.dualboxEditor.v;
|
|
63615
63671
|
},
|
|
63616
63672
|
updated: function() {
|
|
63617
|
-
console.log(
|
|
63673
|
+
console.log("AddNode updated !");
|
|
63618
63674
|
this.updateVisibility();
|
|
63619
63675
|
this.setSearchFocus();
|
|
63620
63676
|
|
|
63621
|
-
if(
|
|
63677
|
+
if (!this.display) {
|
|
63622
63678
|
// make sure the modal disappeared
|
|
63623
|
-
$(this.$el).modal(
|
|
63624
|
-
$(
|
|
63625
|
-
$(
|
|
63679
|
+
$(this.$el).modal("hide");
|
|
63680
|
+
$("body").removeClass("modal-open");
|
|
63681
|
+
$(".modal-backdrop").remove();
|
|
63626
63682
|
}
|
|
63627
63683
|
},
|
|
63628
63684
|
mounted: function() {
|
|
@@ -63633,23 +63689,24 @@ var script$5 = {
|
|
|
63633
63689
|
this.setSearchFocus();
|
|
63634
63690
|
});
|
|
63635
63691
|
$(this.$el).on("hide.bs.modal", () => {
|
|
63636
|
-
self.$emit(
|
|
63692
|
+
self.$emit("closed");
|
|
63637
63693
|
});
|
|
63638
63694
|
|
|
63639
|
-
$(this.$el)
|
|
63640
|
-
|
|
63641
|
-
|
|
63642
|
-
|
|
63643
|
-
|
|
63644
|
-
|
|
63645
|
-
|
|
63695
|
+
$(this.$el)
|
|
63696
|
+
.find('[data-toggle="pill"]')
|
|
63697
|
+
.on("shown.bs.tab", e => {
|
|
63698
|
+
this.setSearchFocus();
|
|
63699
|
+
var selectedResult = this.getSelectedResult();
|
|
63700
|
+
if (selectedResult) {
|
|
63701
|
+
this.$refs.searchResults.selected = selectedResult.name;
|
|
63702
|
+
}
|
|
63703
|
+
});
|
|
63646
63704
|
},
|
|
63647
63705
|
methods: {
|
|
63648
|
-
updateVisibility
|
|
63649
|
-
if(
|
|
63706
|
+
updateVisibility: function() {
|
|
63707
|
+
if (this.display) {
|
|
63650
63708
|
$(this.$el).modal("show");
|
|
63651
|
-
}
|
|
63652
|
-
else {
|
|
63709
|
+
} else {
|
|
63653
63710
|
$(this.$el).modal("hide");
|
|
63654
63711
|
}
|
|
63655
63712
|
},
|
|
@@ -63657,11 +63714,28 @@ var script$5 = {
|
|
|
63657
63714
|
closeModal: function() {
|
|
63658
63715
|
// don't mutate prop directly, mute the parent
|
|
63659
63716
|
// this.display = false;
|
|
63660
|
-
|
|
63717
|
+
|
|
63718
|
+
return new Promise((resolve, reject) => {
|
|
63719
|
+
this.$emit("closed");
|
|
63720
|
+
|
|
63721
|
+
let forceCloseModal = () => {
|
|
63722
|
+
if (!this.display) {
|
|
63723
|
+
resolve();
|
|
63724
|
+
} else {
|
|
63725
|
+
this.$emit("closed");
|
|
63726
|
+
setTimeout(forceCloseModal, 100);
|
|
63727
|
+
}
|
|
63728
|
+
};
|
|
63729
|
+
|
|
63730
|
+
this.$nextTick(forceCloseModal);
|
|
63731
|
+
});
|
|
63661
63732
|
},
|
|
63662
63733
|
|
|
63663
|
-
setSearchFocus
|
|
63664
|
-
$(this.$el)
|
|
63734
|
+
setSearchFocus: function() {
|
|
63735
|
+
$(this.$el)
|
|
63736
|
+
.find(".nav-link.active")
|
|
63737
|
+
.find("input")
|
|
63738
|
+
.focus();
|
|
63665
63739
|
},
|
|
63666
63740
|
|
|
63667
63741
|
selectType(t) {
|
|
@@ -63670,81 +63744,100 @@ var script$5 = {
|
|
|
63670
63744
|
this.searchText[t] = searchText;
|
|
63671
63745
|
},
|
|
63672
63746
|
|
|
63673
|
-
addSelectedNode: function(e) {
|
|
63674
|
-
switch(
|
|
63675
|
-
|
|
63676
|
-
|
|
63677
|
-
|
|
63678
|
-
|
|
63679
|
-
|
|
63680
|
-
this.$nextTick(() => {
|
|
63747
|
+
addSelectedNode: async function(e) {
|
|
63748
|
+
switch (this.selectedType) {
|
|
63749
|
+
case "module":
|
|
63750
|
+
case "ui":
|
|
63751
|
+
var selectedNode = $(".node-result.selected")[0];
|
|
63752
|
+
if (selectedNode) {
|
|
63753
|
+
await this.closeModal();
|
|
63681
63754
|
// add node to the controller
|
|
63682
|
-
var packageName = $(selectedNode).data(
|
|
63755
|
+
var packageName = $(selectedNode).data("package");
|
|
63683
63756
|
this.view.c.addNewBox(packageName, this.mousePosition);
|
|
63684
|
-
}
|
|
63685
|
-
|
|
63686
|
-
|
|
63687
|
-
|
|
63688
|
-
|
|
63689
|
-
}
|
|
63690
|
-
break;
|
|
63757
|
+
} else {
|
|
63758
|
+
sweetalert2_all("Please select a node", "", "error");
|
|
63759
|
+
return;
|
|
63760
|
+
}
|
|
63761
|
+
break;
|
|
63691
63762
|
|
|
63692
|
-
|
|
63693
|
-
|
|
63694
|
-
|
|
63695
|
-
|
|
63696
|
-
|
|
63697
|
-
this
|
|
63698
|
-
|
|
63699
|
-
|
|
63763
|
+
case "input":
|
|
63764
|
+
var type = this.$refs.inputType.get();
|
|
63765
|
+
var name = $(this.$el)
|
|
63766
|
+
.find(".input-name")
|
|
63767
|
+
.val();
|
|
63768
|
+
var desc = $(this.$el)
|
|
63769
|
+
.find(".input-description")
|
|
63770
|
+
.val();
|
|
63771
|
+
if (type !== undefined && name) {
|
|
63772
|
+
await this.closeModal();
|
|
63773
|
+
this.view.c.addInput(
|
|
63774
|
+
name,
|
|
63775
|
+
type,
|
|
63776
|
+
desc,
|
|
63777
|
+
this.mousePosition
|
|
63778
|
+
);
|
|
63700
63779
|
// reset fields
|
|
63701
63780
|
this.$refs.inputType.resetChanges();
|
|
63702
|
-
$(this.$el)
|
|
63703
|
-
|
|
63704
|
-
|
|
63705
|
-
|
|
63706
|
-
|
|
63707
|
-
|
|
63708
|
-
|
|
63709
|
-
|
|
63710
|
-
|
|
63781
|
+
$(this.$el)
|
|
63782
|
+
.find(".input-name")
|
|
63783
|
+
.val("");
|
|
63784
|
+
$(this.$el)
|
|
63785
|
+
.find(".input-description")
|
|
63786
|
+
.val("");
|
|
63787
|
+
} else {
|
|
63788
|
+
sweetalert2_all("Please complete all fields", "", "error");
|
|
63789
|
+
return;
|
|
63790
|
+
}
|
|
63791
|
+
break;
|
|
63711
63792
|
|
|
63712
|
-
|
|
63713
|
-
|
|
63714
|
-
|
|
63715
|
-
|
|
63716
|
-
|
|
63717
|
-
this
|
|
63718
|
-
|
|
63719
|
-
|
|
63793
|
+
case "output":
|
|
63794
|
+
var name = $(this.$el)
|
|
63795
|
+
.find(".output-name")
|
|
63796
|
+
.val();
|
|
63797
|
+
var type = this.$refs.outputType.get();
|
|
63798
|
+
var desc = $(this.$el)
|
|
63799
|
+
.find(".output-description")
|
|
63800
|
+
.val();
|
|
63801
|
+
if (type !== undefined && name) {
|
|
63802
|
+
await this.closeModal();
|
|
63803
|
+
this.view.c.addOutput(
|
|
63804
|
+
name,
|
|
63805
|
+
type,
|
|
63806
|
+
desc,
|
|
63807
|
+
this.mousePosition
|
|
63808
|
+
);
|
|
63720
63809
|
// reset fields
|
|
63721
63810
|
this.$refs.outputType.resetChanges();
|
|
63722
|
-
$(this.$el)
|
|
63723
|
-
|
|
63724
|
-
|
|
63725
|
-
|
|
63726
|
-
|
|
63727
|
-
|
|
63728
|
-
|
|
63729
|
-
|
|
63730
|
-
|
|
63811
|
+
$(this.$el)
|
|
63812
|
+
.find(".output-name")
|
|
63813
|
+
.val("");
|
|
63814
|
+
$(this.$el)
|
|
63815
|
+
.find(".output-description")
|
|
63816
|
+
.val("");
|
|
63817
|
+
} else {
|
|
63818
|
+
sweetalert2_all("Please complete all fields", "", "error");
|
|
63819
|
+
return;
|
|
63820
|
+
}
|
|
63821
|
+
break;
|
|
63731
63822
|
|
|
63732
|
-
|
|
63733
|
-
|
|
63734
|
-
|
|
63735
|
-
|
|
63736
|
-
|
|
63737
|
-
|
|
63738
|
-
|
|
63823
|
+
case "metanode":
|
|
63824
|
+
var name = $(this.$el)
|
|
63825
|
+
.find(".metanode-name")
|
|
63826
|
+
.val();
|
|
63827
|
+
var desc = $(this.$el)
|
|
63828
|
+
.find(".metanode-description")
|
|
63829
|
+
.val();
|
|
63830
|
+
if (!name) {
|
|
63831
|
+
sweetalert2_all("Please complete name field", "", "error");
|
|
63832
|
+
return;
|
|
63833
|
+
}
|
|
63739
63834
|
|
|
63740
|
-
|
|
63741
|
-
|
|
63835
|
+
var json = this.metanodeJSON || {};
|
|
63836
|
+
json.description = desc;
|
|
63742
63837
|
|
|
63743
|
-
|
|
63744
|
-
this.$nextTick(() => {
|
|
63838
|
+
await this.closeModal();
|
|
63745
63839
|
this.view.c.addNewMetabox(name, json, this.mousePosition);
|
|
63746
|
-
|
|
63747
|
-
default:
|
|
63840
|
+
default:
|
|
63748
63841
|
}
|
|
63749
63842
|
},
|
|
63750
63843
|
|
|
@@ -63753,12 +63846,14 @@ var script$5 = {
|
|
|
63753
63846
|
var text = this.searchText[this.selectedType];
|
|
63754
63847
|
try {
|
|
63755
63848
|
this.error = null;
|
|
63756
|
-
this.results[this.selectedType] = await this.view.e.search(
|
|
63849
|
+
this.results[this.selectedType] = await this.view.e.search(
|
|
63850
|
+
text,
|
|
63851
|
+
this.selectedType
|
|
63852
|
+
);
|
|
63757
63853
|
this.$forceUpdate();
|
|
63758
|
-
}
|
|
63759
|
-
catch(e) {
|
|
63854
|
+
} catch (e) {
|
|
63760
63855
|
this.error = e;
|
|
63761
|
-
sweetalert2_all(
|
|
63856
|
+
sweetalert2_all("error searching packages", e.reason, "error");
|
|
63762
63857
|
}
|
|
63763
63858
|
},
|
|
63764
63859
|
|
|
@@ -63769,14 +63864,14 @@ var script$5 = {
|
|
|
63769
63864
|
setSelectedResult: function(packageName) {
|
|
63770
63865
|
// first, find the selected result in the list
|
|
63771
63866
|
var selectedPackage = null;
|
|
63772
|
-
lodash.each(this.getResults(),
|
|
63773
|
-
if(
|
|
63867
|
+
lodash.each(this.getResults(), r => {
|
|
63868
|
+
if (r.name == packageName) {
|
|
63774
63869
|
selectedPackage = r;
|
|
63775
63870
|
return false;
|
|
63776
63871
|
}
|
|
63777
63872
|
});
|
|
63778
63873
|
|
|
63779
|
-
if(
|
|
63874
|
+
if (!selectedPackage) {
|
|
63780
63875
|
throw "Could not find package named " + packageName;
|
|
63781
63876
|
}
|
|
63782
63877
|
|
|
@@ -63794,16 +63889,18 @@ var script$5 = {
|
|
|
63794
63889
|
|
|
63795
63890
|
getNbResults: function() {
|
|
63796
63891
|
var results = this.getResults();
|
|
63797
|
-
return results && results.length ? results.length: 0;
|
|
63892
|
+
return results && results.length ? results.length : 0;
|
|
63798
63893
|
},
|
|
63799
63894
|
|
|
63800
63895
|
onMetaboxFileSelect: function(e) {
|
|
63801
63896
|
var file = e.target.files[0];
|
|
63802
63897
|
const reader = new FileReader();
|
|
63803
|
-
reader.onload =
|
|
63898
|
+
reader.onload = e => {
|
|
63804
63899
|
this.metanodeJSON = JSON.parse(e.target.result);
|
|
63805
|
-
if(
|
|
63806
|
-
$(this.$el)
|
|
63900
|
+
if (this.metanodeJSON.description) {
|
|
63901
|
+
$(this.$el)
|
|
63902
|
+
.find(".metanode-description")
|
|
63903
|
+
.val(this.metanodeJSON.description);
|
|
63807
63904
|
}
|
|
63808
63905
|
};
|
|
63809
63906
|
reader.readAsText(file);
|
|
@@ -64205,7 +64302,9 @@ var __vue_render__$5 = function() {
|
|
|
64205
64302
|
},
|
|
64206
64303
|
[
|
|
64207
64304
|
_c("h2", { staticClass: "mt-2" }, [
|
|
64208
|
-
_vm._v(
|
|
64305
|
+
_vm._v(
|
|
64306
|
+
"Add a new Metabox\n "
|
|
64307
|
+
)
|
|
64209
64308
|
]),
|
|
64210
64309
|
_vm._v(" "),
|
|
64211
64310
|
_vm._m(10),
|
|
@@ -64453,11 +64552,11 @@ __vue_render__$5._withStripped = true;
|
|
|
64453
64552
|
/* style */
|
|
64454
64553
|
const __vue_inject_styles__$5 = function (inject) {
|
|
64455
64554
|
if (!inject) return
|
|
64456
|
-
inject("data-v-1749da54_0", { source: "\n.add-node-modal .modal-body[data-v-1749da54] {\r\n height: 70vh;\n}\n.h100[data-v-1749da54] {\r\n height: 100%!important;\r\n min-height: 100%!important;\n}\n.table-desc th[data-v-1749da54], .table-desc td[data-v-1749da54] {\r\n margin-right: 10px;\n}\n#add-node-modal .modal-dialog[data-v-1749da54] {\r\n min-width: calc(100% - 40px)!important;\r\n height: calc(100% - 40px);\r\n margin: 20px;\r\n padding: 0;\n}\n#add-node-modal .modal-content[data-v-1749da54] {\r\n height: auto;\r\n min-height: 100%;\r\n border-radius: 0;\n}\n.nav-item[data-v-1749da54] {\r\n margin-left: 15px;\r\n margin-right: 15px;\n}\n.nav-link[data-v-1749da54] {\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-bottom: 4px;\r\n padding-top: 4px;\r\n vertical-align: middle;\r\n position: relative;\r\n user-select: none;\n}\n.nav-link.active[data-v-1749da54] {\r\n top: 0px;\r\n border-top-left-radius: 5px;\r\n border-bottom-left-radius: 5px;\n}\n.nav-link > span[data-v-1749da54] {\r\n padding-left: 10px;\r\n padding-right: 10px;\n}\n.nav-link.active > span[data-v-1749da54] {\r\n color: black;\n}\n.input-search[data-v-1749da54] {\r\n display: none;\r\n width: 1px;\r\n height: 24px;\r\n box-shadow: none!important;\r\n border-color: rgba(0,0,0,0.3)!important;\n}\n.nav-link.active .input-search[data-v-1749da54] {\r\n display: inline-block;\r\n border-top-left-radius: 0px;\r\n border-bottom-left-radius: 0px;\r\n transition: width 1s;\r\n width: 200px;\n}\n.nav-compute > a.active > input[data-v-1749da54] {\r\n background-color: rgba(0,0,0,0.3)!important;\n}\n.nav-compute > a.active[data-v-1749da54], .nav-compute > a.active > input[data-v-1749da54] {\r\n background-color: rgba(0,0,0,0.3)!important;\r\n color: rgba(255,255,255,0.5);\n}\n.nav-compute> a.active > .input-search[data-v-1749da54]::placeholder {\r\n color: rgba(255,255,255,0.5);\n}\n.nav-uis > a.active[data-v-1749da54], .nav-uis > a.active > input[data-v-1749da54] {\r\n background-color: #bff2ca!important;\n}\n.nav-inputs > a.active[data-v-1749da54] {\r\n background-color: #f5d76e!important;\n}\n.nav-compute > a.active > input[data-v-1749da54] {\r\n background-color: rgba(0,0,0,0.8);\n}\n.nav-outputs > a.active[data-v-1749da54], .nav-outputs > a.active > input[data-v-1749da54] {\r\n background-color: #ffb3a7!important;\n}\n.message-container[data-v-1749da54] {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\n}\n.message[data-v-1749da54] {\r\n position: absolute;\r\n top: 50%;\r\n transform: translateY(-80%);\r\n left: 0;\r\n right: 0;\r\n opacity: 0.6;\r\n text-align: center;\n}\n.tab-content[data-v-1749da54], .tab-pane[data-v-1749da54] {\r\n width: 100%;\r\n height: 100%;\n}\nlabel[data-v-1749da54] {\r\n font-size: 20px;\r\n margin-top: 20px;\n}\nfieldset[data-v-1749da54] {\r\n border: 1px solid rgba(0,0,0,0.1);\r\n margin: 10px;\r\n padding: 20px;\r\n min-width: 600px;\n}\r\n", map: {"version":3,"sources":["C:\\Users\\maxim\\Projects\\dualbox\\editor\\js\\src\\v\\templates\\addNode.vue"],"names":[],"mappings":";AACA;IACA,YAAA;AACA;AAEA;IACA,sBAAA;IACA,0BAAA;AACA;AAEA;IACA,kBAAA;AACA;AAEA;EACA,sCAAA;EACA,yBAAA;EACA,YAAA;EACA,UAAA;AACA;AAEA;EACA,YAAA;EACA,gBAAA;EACA,gBAAA;AACA;AAEA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,iBAAA;IACA,kBAAA;IACA,mBAAA;IACA,gBAAA;IACA,sBAAA;IACA,kBAAA;IACA,iBAAA;AACA;AAEA;IACA,QAAA;IACA,2BAAA;IACA,8BAAA;AACA;AAEA;IACA,kBAAA;IACA,mBAAA;AACA;AAEA;IACA,YAAA;AACA;AAEA;IACA,aAAA;IACA,UAAA;IACA,YAAA;IACA,0BAAA;IACA,uCAAA;AACA;AAEA;IACA,qBAAA;IACA,2BAAA;IACA,8BAAA;IACA,oBAAA;IACA,YAAA;AACA;AACA;IACA,2CAAA;AACA;AAEA;IACA,2CAAA;IACA,4BAAA;AACA;AAEA;IACA,4BAAA;AACA;AAEA;IACA,mCAAA;AACA;AAEA;IACA,mCAAA;AACA;AAEA;IACA,iCAAA;AACA;AAEA;IACA,mCAAA;AACA;AAEA;IACA,kBAAA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,kBAAA;IACA,QAAA;IACA,2BAAA;IACA,OAAA;IACA,QAAA;IACA,YAAA;IACA,kBAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,eAAA;IACA,gBAAA;AACA;AAEA;IACA,iCAAA;IACA,YAAA;IACA,aAAA;IACA,gBAAA;AACA","file":"addNode.vue","sourcesContent":["<style scoped>\r\n.add-node-modal .modal-body {\r\n height: 70vh;\r\n}\r\n\r\n.h100 {\r\n height: 100%!important;\r\n min-height: 100%!important;\r\n}\r\n\r\n.table-desc th, .table-desc td {\r\n margin-right: 10px;\r\n}\r\n\r\n#add-node-modal .modal-dialog {\r\n min-width: calc(100% - 40px)!important;\r\n height: calc(100% - 40px);\r\n margin: 20px;\r\n padding: 0;\r\n}\r\n\r\n#add-node-modal .modal-content {\r\n height: auto;\r\n min-height: 100%;\r\n border-radius: 0;\r\n}\r\n\r\n.nav-item {\r\n margin-left: 15px;\r\n margin-right: 15px;\r\n}\r\n\r\n.nav-link {\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-bottom: 4px;\r\n padding-top: 4px;\r\n vertical-align: middle;\r\n position: relative;\r\n user-select: none;\r\n}\r\n\r\n.nav-link.active {\r\n top: 0px;\r\n border-top-left-radius: 5px;\r\n border-bottom-left-radius: 5px;\r\n}\r\n\r\n.nav-link > span {\r\n padding-left: 10px;\r\n padding-right: 10px;\r\n}\r\n\r\n.nav-link.active > span {\r\n color: black;\r\n}\r\n\r\n.input-search {\r\n display: none;\r\n width: 1px;\r\n height: 24px;\r\n box-shadow: none!important;\r\n border-color: rgba(0,0,0,0.3)!important;\r\n}\r\n\r\n.nav-link.active .input-search {\r\n display: inline-block;\r\n border-top-left-radius: 0px;\r\n border-bottom-left-radius: 0px;\r\n transition: width 1s;\r\n width: 200px;\r\n}\r\n.nav-compute > a.active > input {\r\n background-color: rgba(0,0,0,0.3)!important;\r\n}\r\n\r\n.nav-compute > a.active, .nav-compute > a.active > input {\r\n background-color: rgba(0,0,0,0.3)!important;\r\n color: rgba(255,255,255,0.5);\r\n}\r\n\r\n.nav-compute> a.active > .input-search::placeholder {\r\n color: rgba(255,255,255,0.5);\r\n}\r\n\r\n.nav-uis > a.active, .nav-uis > a.active > input {\r\n background-color: #bff2ca!important;\r\n}\r\n\r\n.nav-inputs > a.active {\r\n background-color: #f5d76e!important;\r\n}\r\n\r\n.nav-compute > a.active > input {\r\n background-color: rgba(0,0,0,0.8);\r\n}\r\n\r\n.nav-outputs > a.active, .nav-outputs > a.active > input {\r\n background-color: #ffb3a7!important;\r\n}\r\n\r\n.message-container {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n.message {\r\n position: absolute;\r\n top: 50%;\r\n transform: translateY(-80%);\r\n left: 0;\r\n right: 0;\r\n opacity: 0.6;\r\n text-align: center;\r\n}\r\n\r\n.tab-content, .tab-pane {\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\nlabel {\r\n font-size: 20px;\r\n margin-top: 20px;\r\n}\r\n\r\nfieldset {\r\n border: 1px solid rgba(0,0,0,0.1);\r\n margin: 10px;\r\n padding: 20px;\r\n min-width: 600px;\r\n}\r\n</style>\r\n\r\n<template>\r\n <div class=\"modal fade add-node-modal\" :class=\"{ 'hide' : !display }\" id=\"add-node-modal\" tabindex=\"-1\" role=\"dialog\">\r\n <div class=\"modal-dialog\" role=\"document\">\r\n <div class=\"modal-content h100\">\r\n <div class=\"modal-header\">\r\n <h5 class=\"modal-title\">Add Box</h5>\r\n <ul class=\"nav nav-pills mr-auto ml-2\">\r\n <li class=\"nav-item nav-compute\">\r\n <a class=\"nav-link active\" href=\"#add-module-or-ui\" data-toggle=\"pill\" @click=\"selectType('module')\" draggable=\"false\">\r\n <span>Compute</span>\r\n <input class=\"form-control input-sm input-search search-modules\" type=\"text\" placeholder=\"Search modules...\" id=\"search-modules\" v-model=\"searchText['module']\" @input=\"searchModules\" autofocus/>\r\n </a>\r\n </li>\r\n <li class=\"nav-item nav-uis\">\r\n <a class=\"nav-link\" href=\"#add-module-or-ui\" data-toggle=\"pill\" @click=\"selectType('ui')\" draggable=\"false\">\r\n <span>UI</span>\r\n <input class=\"form-control input-sm input-search search-ui\" type=\"text\" placeholder=\"Search UIs...\" id=\"search-uis\" @input=\"searchModules\" v-model=\"searchText['ui']\" autofocus/>\r\n </a>\r\n </li>\r\n <li class=\"nav-item nav-inputs\" @click=\"selectType('input')\">\r\n <a class=\"nav-link\" href=\"#add-input\" data-toggle=\"pill\" draggable=\"false\"><span>Input</span></a>\r\n </li>\r\n <li class=\"nav-item nav-outputs\" @click=\"selectType('output')\">\r\n <a class=\"nav-link\" href=\"#add-output\"data-toggle=\"pill\" draggable=\"false\"><span>Output</span></a>\r\n </li>\r\n <li class=\"nav-item nav-outputs\" @click=\"selectType('metanode')\">\r\n <a class=\"nav-link\" href=\"#add-metanode\"data-toggle=\"pill\" draggable=\"false\"><span>Metabox</span></a>\r\n </li>\r\n </ul>\r\n\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 class=\"container-fluid h100\">\r\n\r\n <div class=\"tab-content\">\r\n <div class=\"tab-pane active\" id=\"add-module-or-ui\" role=\"tabpanel\" aria-labelledby=\"add-module-or-ui-tab\">\r\n <div class=\"row h100\">\r\n <div v-if=\"getSearchText().length == 0\" class=\"message-container\">\r\n <p class=\"message\"><i class=\"fas fa-search\"></i> Type something to search through the Dualbox library.</p>\r\n </div>\r\n <div v-else-if=\"getNbResults() == 0\">\r\n <p class=\"message\"><i class=\"fas fa-search\"></i> No results.</p>\r\n </div>\r\n <template v-else>\r\n <div class=\"col-md-4 h100\" style=\"padding-left: 0; padding-right: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <search-results ref=\"searchResults\" :results=\"getResults()\" :err=\"error\" @resultSelected=\"setSelectedResult\"></search-results>\r\n </div>\r\n <div class=\"col-md-8 h100\" style=\"padding-left: 15px; padding-right: 0;\">\r\n <display-result ref=\"displayResults\" v-if=\"getSelectedResult()\" :result=\"getSelectedResult()\"></display-result>\r\n <div v-else class=\"message-container\">\r\n <p class=\"message\">Select a result to display</p>\r\n </div>\r\n </div>\r\n </template>\r\n </div>\r\n </div>\r\n <div class=\"tab-pane\" id=\"add-input\" role=\"tabpanel\" aria-labelledby=\"add-input-tab\">\r\n <div class=\"row\">\r\n <fieldset class=\"mx-auto\" style=\"margin-top: 50px;\">\r\n <h2 class=\"mt-2\">Add a new input</h2>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"input-name\">Input name:</label>\r\n <input type=\"text\" class=\"form-control input-name\" id=\"input-name\" placeholder=\"Enter name...\" autofocus required>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"input-name\">Input type:</label>\r\n <input style=\"display: none;\" required/>\r\n <edit-type ref=\"inputType\" :type=\"inputType\" :displayOKButton=\"false\"></edit-type>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"input-description\">Input description:</label>\r\n <textarea class=\"input-description\" rows=4 style=\"width: 100%;\" placeholder=\"Enter description\" autofocus>\r\n </textarea>\r\n </div>\r\n </fieldset>\r\n </div>\r\n </div>\r\n <div class=\"tab-pane\" id=\"add-output\" role=\"tabpanel\" aria-labelledby=\"add-output-tab\">\r\n <div class=\"row\">\r\n <fieldset class=\"mx-auto\" style=\"margin-top: 50px;\">\r\n <h2 class=\"mt-2\">Add a new output</h2>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"output-name\">Output name:</label>\r\n <input type=\"text\" class=\"form-control output-name\" id=\"output-name\" placeholder=\"Enter name...\" autofocus required>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"output-name\">Output type:</label>\r\n <input style=\"display: none;\" required/>\r\n <edit-type ref=\"outputType\" :type=\"outputType\" :displayOKButton=\"false\"></edit-type>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"output-description\">Output description:</label>\r\n <textarea class=\"output-description\" rows=4 style=\"width: 100%;\" placeholder=\"Enter description\" autofocus>\r\n </textarea>\r\n </div>\r\n </fieldset>\r\n </div>\r\n </div>\r\n <div class=\"tab-pane\" id=\"add-metanode\" role=\"tabpanel\" aria-labelledby=\"add-metanode-tab\">\r\n <div class=\"row\">\r\n <fieldset class=\"mx-auto\" style=\"margin-top: 50px;\">\r\n <h2 class=\"mt-2\">Add a new Metabox <!--<button class=\"btn btn-outline-secondary float-right\" @click=\"importMetabox\"><i class=\"fas fa-upload\"></i></button>--></h2>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"metanode-name\">Metabox name:</label>\r\n <input type=\"text\" class=\"form-control metanode-name\" id=\"metanode-name\" placeholder=\"Enter name...\" autofocus required>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"metanode-def\">Metabox definition (optional):</label>\r\n <input type=\"file\" class=\"form-control-file\" id=\"metanode-def\" @change=\"onMetaboxFileSelect\">\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"metanode-description\">Metabox description:</label>\r\n <textarea class=\"metanode-description\" rows=4 style=\"width: 100%;\" placeholder=\"Enter description\" autofocus>\r\n </textarea>\r\n </div>\r\n </fieldset>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Close</button>\r\n <button type=\"button\" class=\"btn btn-primary add-node-btn\" @click=\"addSelectedNode\">Add node</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport _ from 'lodash-es';\r\nimport swal from 'sweetalert2';\r\nimport SearchResultsVue from './searchResults.vue';\r\nimport DisplayResultVue from './displayResult.vue';\r\nimport EditTypeVue from './editType.vue'\r\n\r\nexport default {\r\n props: [\r\n \"display\", // original state (true = show, false=hide) of the modal\r\n \"mousePosition\" // mouse position when this panel was opened\r\n ],\r\n components: {\r\n 'search-results' : SearchResultsVue,\r\n 'display-result' : DisplayResultVue,\r\n 'edit-type' : EditTypeVue\r\n },\r\n data: function () {\r\n return {\r\n error: null,\r\n\r\n searchText: {}, // the search text, indexed by selectedType\r\n results: {}, // dictionary of arrays, indexed by selectedType\r\n selectedResult : {}, // dictionary of string, indexed by selectedType\r\n selectedType: \"module\",\r\n inputType: \"*\",\r\n outputType: \"*\"\r\n }\r\n },\r\n created: function() {\r\n this.view = window.dualboxEditor.v;\r\n },\r\n updated: function() {\r\n console.log('AddNode updated !');\r\n this.updateVisibility();\r\n this.setSearchFocus();\r\n\r\n if( !this.display ) {\r\n // make sure the modal disappeared\r\n $(this.$el).modal('hide');\r\n $('body').removeClass('modal-open');\r\n $('.modal-backdrop').remove();\r\n }\r\n },\r\n mounted: function() {\r\n var self = this;\r\n this.updateVisibility(); // to init our modal\r\n\r\n $(this.$el).on(\"shown.bs.modal\", () => {\r\n this.setSearchFocus();\r\n });\r\n $(this.$el).on(\"hide.bs.modal\", () => {\r\n self.$emit('closed');\r\n });\r\n\r\n $(this.$el).find('[data-toggle=\"pill\"]').on('shown.bs.tab', (e) => {\r\n this.setSearchFocus();\r\n var selectedResult = this.getSelectedResult();\r\n if( selectedResult ) {\r\n this.$refs.searchResults.selected = selectedResult.name;\r\n }\r\n });\r\n },\r\n methods: {\r\n updateVisibility : function() {\r\n if( this.display ) {\r\n $(this.$el).modal(\"show\");\r\n }\r\n else {\r\n $(this.$el).modal(\"hide\");\r\n }\r\n },\r\n\r\n closeModal: function() {\r\n // don't mutate prop directly, mute the parent\r\n // this.display = false;\r\n this.$emit('closed');\r\n },\r\n\r\n setSearchFocus : function() {\r\n $(this.$el).find('.nav-link.active').find('input').focus();\r\n },\r\n\r\n selectType(t) {\r\n let searchText = this.searchText[this.selectedType];\r\n this.selectedType = t;\r\n this.searchText[t] = searchText;\r\n },\r\n\r\n addSelectedNode: function(e) {\r\n switch( this.selectedType ) {\r\n case \"module\":\r\n case \"ui\":\r\n var selectedNode = $('.node-result.selected')[0];\r\n if( selectedNode ) {\r\n this.closeModal();\r\n this.$nextTick(() => {\r\n // add node to the controller\r\n var packageName = $(selectedNode).data('package');\r\n this.view.c.addNewBox(packageName, this.mousePosition);\r\n });\r\n }\r\n else {\r\n swal('Please select a node', '', 'error');\r\n return;\r\n }\r\n break;\r\n\r\n case \"input\":\r\n var type = this.$refs.inputType.get();\r\n var name = $(this.$el).find('.input-name').val();\r\n var desc = $(this.$el).find('.input-description').val();\r\n if( type !== undefined && name ) {\r\n this.closeModal();\r\n this.$nextTick(() => {\r\n this.view.c.addInput(name, type, desc, this.mousePosition);\r\n // reset fields\r\n this.$refs.inputType.resetChanges();\r\n $(this.$el).find('.input-name').val(\"\");\r\n $(this.$el).find('.input-description').val(\"\");\r\n });\r\n }\r\n else {\r\n swal('Please complete all fields', '', 'error');\r\n return;\r\n }\r\n break;\r\n\r\n case \"output\":\r\n var name = $(this.$el).find('.output-name').val();\r\n var type = this.$refs.outputType.get();\r\n var desc = $(this.$el).find('.output-description').val();\r\n if( type !== undefined && name ) {\r\n this.closeModal();\r\n this.$nextTick(() => {\r\n this.view.c.addOutput(name, type, desc, this.mousePosition);\r\n // reset fields\r\n this.$refs.outputType.resetChanges();\r\n $(this.$el).find('.output-name').val(\"\");\r\n $(this.$el).find('.output-description').val(\"\");\r\n });\r\n }\r\n else {\r\n swal('Please complete all fields', '', 'error');\r\n return;\r\n }\r\n break;\r\n\r\n case \"metanode\":\r\n var name = $(this.$el).find('.metanode-name').val();\r\n var desc = $(this.$el).find('.metanode-description').val();\r\n if( !name ) {\r\n swal('Please complete name field', '', 'error');\r\n return;\r\n }\r\n\r\n var json = this.metanodeJSON || {};\r\n json.description = desc;\r\n\r\n this.closeModal();\r\n this.$nextTick(() => {\r\n this.view.c.addNewMetabox(name, json, this.mousePosition);\r\n });\r\n default:\r\n }\r\n },\r\n\r\n searchModules: async function(e) {\r\n //var text = $(e.target).val();\r\n var text = this.searchText[this.selectedType];\r\n try {\r\n this.error = null;\r\n this.results[this.selectedType] = await this.view.e.search(text, this.selectedType);\r\n this.$forceUpdate();\r\n }\r\n catch(e) {\r\n this.error = e;\r\n swal('error searching packages', e.reason, \"error\");\r\n }\r\n },\r\n\r\n getSearchText: function() {\r\n return this.searchText[this.selectedType] || \"\";\r\n },\r\n\r\n setSelectedResult: function(packageName) {\r\n // first, find the selected result in the list\r\n var selectedPackage = null;\r\n _.each(this.getResults(), (r) => {\r\n if( r.name == packageName ) {\r\n selectedPackage = r;\r\n return false;\r\n }\r\n });\r\n\r\n if( !selectedPackage ) {\r\n throw \"Could not find package named \" + packageName;\r\n }\r\n\r\n this.selectedResult[this.selectedType] = selectedPackage;\r\n this.$forceUpdate();\r\n },\r\n\r\n getSelectedResult: function() {\r\n return this.selectedResult[this.selectedType];\r\n },\r\n\r\n getResults: function() {\r\n return this.results[this.selectedType] || null;\r\n },\r\n\r\n getNbResults: function() {\r\n var results = this.getResults();\r\n return results && results.length ? results.length: 0;\r\n },\r\n\r\n onMetaboxFileSelect: function(e) {\r\n var file = e.target.files[0];\r\n const reader = new FileReader()\r\n reader.onload = (e) => {\r\n this.metanodeJSON = JSON.parse(e.target.result);\r\n if( this.metanodeJSON.description ) {\r\n $(this.$el).find('.metanode-description').val(this.metanodeJSON.description);\r\n }\r\n }\r\n reader.readAsText(file)\r\n }\r\n }\r\n}\r\n\r\n</script>\r\n\r\n"]}, media: undefined });
|
|
64555
|
+
inject("data-v-2cca907e_0", { source: "\n.add-node-modal .modal-body[data-v-2cca907e] {\r\n height: 70vh;\n}\n.h100[data-v-2cca907e] {\r\n height: 100% !important;\r\n min-height: 100% !important;\n}\n.table-desc th[data-v-2cca907e],\r\n.table-desc td[data-v-2cca907e] {\r\n margin-right: 10px;\n}\n#add-node-modal .modal-dialog[data-v-2cca907e] {\r\n min-width: calc(100% - 40px) !important;\r\n height: calc(100% - 40px);\r\n margin: 20px;\r\n padding: 0;\n}\n#add-node-modal .modal-content[data-v-2cca907e] {\r\n height: auto;\r\n min-height: 100%;\r\n border-radius: 0;\n}\n.nav-item[data-v-2cca907e] {\r\n margin-left: 15px;\r\n margin-right: 15px;\n}\n.nav-link[data-v-2cca907e] {\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-bottom: 4px;\r\n padding-top: 4px;\r\n vertical-align: middle;\r\n position: relative;\r\n user-select: none;\n}\n.nav-link.active[data-v-2cca907e] {\r\n top: 0px;\r\n border-top-left-radius: 5px;\r\n border-bottom-left-radius: 5px;\n}\n.nav-link > span[data-v-2cca907e] {\r\n padding-left: 10px;\r\n padding-right: 10px;\n}\n.nav-link.active > span[data-v-2cca907e] {\r\n color: black;\n}\n.input-search[data-v-2cca907e] {\r\n display: none;\r\n width: 1px;\r\n height: 24px;\r\n box-shadow: none !important;\r\n border-color: rgba(0, 0, 0, 0.3) !important;\n}\n.nav-link.active .input-search[data-v-2cca907e] {\r\n display: inline-block;\r\n border-top-left-radius: 0px;\r\n border-bottom-left-radius: 0px;\r\n transition: width 1s;\r\n width: 200px;\n}\n.nav-compute > a.active > input[data-v-2cca907e] {\r\n background-color: rgba(0, 0, 0, 0.3) !important;\n}\n.nav-compute > a.active[data-v-2cca907e],\r\n.nav-compute > a.active > input[data-v-2cca907e] {\r\n background-color: rgba(0, 0, 0, 0.3) !important;\r\n color: rgba(255, 255, 255, 0.5);\n}\n.nav-compute > a.active > .input-search[data-v-2cca907e]::placeholder {\r\n color: rgba(255, 255, 255, 0.5);\n}\n.nav-uis > a.active[data-v-2cca907e],\r\n.nav-uis > a.active > input[data-v-2cca907e] {\r\n background-color: #bff2ca !important;\n}\n.nav-inputs > a.active[data-v-2cca907e] {\r\n background-color: #f5d76e !important;\n}\n.nav-compute > a.active > input[data-v-2cca907e] {\r\n background-color: rgba(0, 0, 0, 0.8);\n}\n.nav-outputs > a.active[data-v-2cca907e],\r\n.nav-outputs > a.active > input[data-v-2cca907e] {\r\n background-color: #ffb3a7 !important;\n}\n.message-container[data-v-2cca907e] {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\n}\n.message[data-v-2cca907e] {\r\n position: absolute;\r\n top: 50%;\r\n transform: translateY(-80%);\r\n left: 0;\r\n right: 0;\r\n opacity: 0.6;\r\n text-align: center;\n}\n.tab-content[data-v-2cca907e],\r\n.tab-pane[data-v-2cca907e] {\r\n width: 100%;\r\n height: 100%;\n}\nlabel[data-v-2cca907e] {\r\n font-size: 20px;\r\n margin-top: 20px;\n}\nfieldset[data-v-2cca907e] {\r\n border: 1px solid rgba(0, 0, 0, 0.1);\r\n margin: 10px;\r\n padding: 20px;\r\n min-width: 600px;\n}\r\n", map: {"version":3,"sources":["C:\\Users\\maxim\\Projects\\dualbox\\editor\\js\\src\\v\\templates\\addNode.vue"],"names":[],"mappings":";AACA;IACA,YAAA;AACA;AAEA;IACA,uBAAA;IACA,2BAAA;AACA;AAEA;;IAEA,kBAAA;AACA;AAEA;IACA,uCAAA;IACA,yBAAA;IACA,YAAA;IACA,UAAA;AACA;AAEA;IACA,YAAA;IACA,gBAAA;IACA,gBAAA;AACA;AAEA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,iBAAA;IACA,kBAAA;IACA,mBAAA;IACA,gBAAA;IACA,sBAAA;IACA,kBAAA;IACA,iBAAA;AACA;AAEA;IACA,QAAA;IACA,2BAAA;IACA,8BAAA;AACA;AAEA;IACA,kBAAA;IACA,mBAAA;AACA;AAEA;IACA,YAAA;AACA;AAEA;IACA,aAAA;IACA,UAAA;IACA,YAAA;IACA,2BAAA;IACA,2CAAA;AACA;AAEA;IACA,qBAAA;IACA,2BAAA;IACA,8BAAA;IACA,oBAAA;IACA,YAAA;AACA;AACA;IACA,+CAAA;AACA;AAEA;;IAEA,+CAAA;IACA,+BAAA;AACA;AAEA;IACA,+BAAA;AACA;AAEA;;IAEA,oCAAA;AACA;AAEA;IACA,oCAAA;AACA;AAEA;IACA,oCAAA;AACA;AAEA;;IAEA,oCAAA;AACA;AAEA;IACA,kBAAA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,kBAAA;IACA,QAAA;IACA,2BAAA;IACA,OAAA;IACA,QAAA;IACA,YAAA;IACA,kBAAA;AACA;AAEA;;IAEA,WAAA;IACA,YAAA;AACA;AAEA;IACA,eAAA;IACA,gBAAA;AACA;AAEA;IACA,oCAAA;IACA,YAAA;IACA,aAAA;IACA,gBAAA;AACA","file":"addNode.vue","sourcesContent":["<style scoped>\r\n.add-node-modal .modal-body {\r\n height: 70vh;\r\n}\r\n\r\n.h100 {\r\n height: 100% !important;\r\n min-height: 100% !important;\r\n}\r\n\r\n.table-desc th,\r\n.table-desc td {\r\n margin-right: 10px;\r\n}\r\n\r\n#add-node-modal .modal-dialog {\r\n min-width: calc(100% - 40px) !important;\r\n height: calc(100% - 40px);\r\n margin: 20px;\r\n padding: 0;\r\n}\r\n\r\n#add-node-modal .modal-content {\r\n height: auto;\r\n min-height: 100%;\r\n border-radius: 0;\r\n}\r\n\r\n.nav-item {\r\n margin-left: 15px;\r\n margin-right: 15px;\r\n}\r\n\r\n.nav-link {\r\n padding-left: 4px;\r\n padding-right: 4px;\r\n padding-bottom: 4px;\r\n padding-top: 4px;\r\n vertical-align: middle;\r\n position: relative;\r\n user-select: none;\r\n}\r\n\r\n.nav-link.active {\r\n top: 0px;\r\n border-top-left-radius: 5px;\r\n border-bottom-left-radius: 5px;\r\n}\r\n\r\n.nav-link > span {\r\n padding-left: 10px;\r\n padding-right: 10px;\r\n}\r\n\r\n.nav-link.active > span {\r\n color: black;\r\n}\r\n\r\n.input-search {\r\n display: none;\r\n width: 1px;\r\n height: 24px;\r\n box-shadow: none !important;\r\n border-color: rgba(0, 0, 0, 0.3) !important;\r\n}\r\n\r\n.nav-link.active .input-search {\r\n display: inline-block;\r\n border-top-left-radius: 0px;\r\n border-bottom-left-radius: 0px;\r\n transition: width 1s;\r\n width: 200px;\r\n}\r\n.nav-compute > a.active > input {\r\n background-color: rgba(0, 0, 0, 0.3) !important;\r\n}\r\n\r\n.nav-compute > a.active,\r\n.nav-compute > a.active > input {\r\n background-color: rgba(0, 0, 0, 0.3) !important;\r\n color: rgba(255, 255, 255, 0.5);\r\n}\r\n\r\n.nav-compute > a.active > .input-search::placeholder {\r\n color: rgba(255, 255, 255, 0.5);\r\n}\r\n\r\n.nav-uis > a.active,\r\n.nav-uis > a.active > input {\r\n background-color: #bff2ca !important;\r\n}\r\n\r\n.nav-inputs > a.active {\r\n background-color: #f5d76e !important;\r\n}\r\n\r\n.nav-compute > a.active > input {\r\n background-color: rgba(0, 0, 0, 0.8);\r\n}\r\n\r\n.nav-outputs > a.active,\r\n.nav-outputs > a.active > input {\r\n background-color: #ffb3a7 !important;\r\n}\r\n\r\n.message-container {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n.message {\r\n position: absolute;\r\n top: 50%;\r\n transform: translateY(-80%);\r\n left: 0;\r\n right: 0;\r\n opacity: 0.6;\r\n text-align: center;\r\n}\r\n\r\n.tab-content,\r\n.tab-pane {\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\nlabel {\r\n font-size: 20px;\r\n margin-top: 20px;\r\n}\r\n\r\nfieldset {\r\n border: 1px solid rgba(0, 0, 0, 0.1);\r\n margin: 10px;\r\n padding: 20px;\r\n min-width: 600px;\r\n}\r\n</style>\r\n\r\n<template>\r\n <div class=\"modal fade add-node-modal\" :class=\"{ 'hide' : !display }\" id=\"add-node-modal\" tabindex=\"-1\" role=\"dialog\">\r\n <div class=\"modal-dialog\" role=\"document\">\r\n <div class=\"modal-content h100\">\r\n <div class=\"modal-header\">\r\n <h5 class=\"modal-title\">Add Box</h5>\r\n <ul class=\"nav nav-pills mr-auto ml-2\">\r\n <li class=\"nav-item nav-compute\">\r\n <a class=\"nav-link active\" href=\"#add-module-or-ui\" data-toggle=\"pill\" @click=\"selectType('module')\" draggable=\"false\">\r\n <span>Compute</span>\r\n <input class=\"form-control input-sm input-search search-modules\" type=\"text\" placeholder=\"Search modules...\" id=\"search-modules\" v-model=\"searchText['module']\" @input=\"searchModules\" autofocus />\r\n </a>\r\n </li>\r\n <li class=\"nav-item nav-uis\">\r\n <a class=\"nav-link\" href=\"#add-module-or-ui\" data-toggle=\"pill\" @click=\"selectType('ui')\" draggable=\"false\">\r\n <span>UI</span>\r\n <input class=\"form-control input-sm input-search search-ui\" type=\"text\" placeholder=\"Search UIs...\" id=\"search-uis\" @input=\"searchModules\" v-model=\"searchText['ui']\" autofocus />\r\n </a>\r\n </li>\r\n <li class=\"nav-item nav-inputs\" @click=\"selectType('input')\">\r\n <a class=\"nav-link\" href=\"#add-input\" data-toggle=\"pill\" draggable=\"false\"><span>Input</span></a>\r\n </li>\r\n <li class=\"nav-item nav-outputs\" @click=\"selectType('output')\">\r\n <a class=\"nav-link\" href=\"#add-output\" data-toggle=\"pill\" draggable=\"false\"><span>Output</span></a>\r\n </li>\r\n <li class=\"nav-item nav-outputs\" @click=\"selectType('metanode')\">\r\n <a class=\"nav-link\" href=\"#add-metanode\" data-toggle=\"pill\" draggable=\"false\"><span>Metabox</span></a>\r\n </li>\r\n </ul>\r\n\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 class=\"container-fluid h100\">\r\n\r\n <div class=\"tab-content\">\r\n <div class=\"tab-pane active\" id=\"add-module-or-ui\" role=\"tabpanel\" aria-labelledby=\"add-module-or-ui-tab\">\r\n <div class=\"row h100\">\r\n <div v-if=\"getSearchText().length == 0\" class=\"message-container\">\r\n <p class=\"message\"><i class=\"fas fa-search\"></i> Type something to search through the Dualbox library.</p>\r\n </div>\r\n <div v-else-if=\"getNbResults() == 0\">\r\n <p class=\"message\"><i class=\"fas fa-search\"></i> No results.</p>\r\n </div>\r\n <template v-else>\r\n <div class=\"col-md-4 h100\" style=\"padding-left: 0; padding-right: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <search-results ref=\"searchResults\" :results=\"getResults()\" :err=\"error\" @resultSelected=\"setSelectedResult\"></search-results>\r\n </div>\r\n <div class=\"col-md-8 h100\" style=\"padding-left: 15px; padding-right: 0;\">\r\n <display-result ref=\"displayResults\" v-if=\"getSelectedResult()\" :result=\"getSelectedResult()\"></display-result>\r\n <div v-else class=\"message-container\">\r\n <p class=\"message\">Select a result to display</p>\r\n </div>\r\n </div>\r\n </template>\r\n </div>\r\n </div>\r\n <div class=\"tab-pane\" id=\"add-input\" role=\"tabpanel\" aria-labelledby=\"add-input-tab\">\r\n <div class=\"row\">\r\n <fieldset class=\"mx-auto\" style=\"margin-top: 50px;\">\r\n <h2 class=\"mt-2\">Add a new input</h2>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"input-name\">Input name:</label>\r\n <input type=\"text\" class=\"form-control input-name\" id=\"input-name\" placeholder=\"Enter name...\" autofocus required>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"input-name\">Input type:</label>\r\n <input style=\"display: none;\" required />\r\n <edit-type ref=\"inputType\" :type=\"inputType\" :displayOKButton=\"false\"></edit-type>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"input-description\">Input description:</label>\r\n <textarea class=\"input-description\" rows=4 style=\"width: 100%;\" placeholder=\"Enter description\" autofocus>\r\n </textarea>\r\n </div>\r\n </fieldset>\r\n </div>\r\n </div>\r\n <div class=\"tab-pane\" id=\"add-output\" role=\"tabpanel\" aria-labelledby=\"add-output-tab\">\r\n <div class=\"row\">\r\n <fieldset class=\"mx-auto\" style=\"margin-top: 50px;\">\r\n <h2 class=\"mt-2\">Add a new output</h2>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"output-name\">Output name:</label>\r\n <input type=\"text\" class=\"form-control output-name\" id=\"output-name\" placeholder=\"Enter name...\" autofocus required>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"output-name\">Output type:</label>\r\n <input style=\"display: none;\" required />\r\n <edit-type ref=\"outputType\" :type=\"outputType\" :displayOKButton=\"false\"></edit-type>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"output-description\">Output description:</label>\r\n <textarea class=\"output-description\" rows=4 style=\"width: 100%;\" placeholder=\"Enter description\" autofocus>\r\n </textarea>\r\n </div>\r\n </fieldset>\r\n </div>\r\n </div>\r\n <div class=\"tab-pane\" id=\"add-metanode\" role=\"tabpanel\" aria-labelledby=\"add-metanode-tab\">\r\n <div class=\"row\">\r\n <fieldset class=\"mx-auto\" style=\"margin-top: 50px;\">\r\n <h2 class=\"mt-2\">Add a new Metabox\r\n <!--<button class=\"btn btn-outline-secondary float-right\" @click=\"importMetabox\"><i class=\"fas fa-upload\"></i></button>-->\r\n </h2>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"metanode-name\">Metabox name:</label>\r\n <input type=\"text\" class=\"form-control metanode-name\" id=\"metanode-name\" placeholder=\"Enter name...\" autofocus required>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"metanode-def\">Metabox definition (optional):</label>\r\n <input type=\"file\" class=\"form-control-file\" id=\"metanode-def\" @change=\"onMetaboxFileSelect\">\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label for=\"metanode-description\">Metabox description:</label>\r\n <textarea class=\"metanode-description\" rows=4 style=\"width: 100%;\" placeholder=\"Enter description\" autofocus>\r\n </textarea>\r\n </div>\r\n </fieldset>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Close</button>\r\n <button type=\"button\" class=\"btn btn-primary add-node-btn\" @click=\"addSelectedNode\">Add node</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport _ from \"lodash-es\";\r\nimport swal from \"sweetalert2\";\r\nimport SearchResultsVue from \"./searchResults.vue\";\r\nimport DisplayResultVue from \"./displayResult.vue\";\r\nimport EditTypeVue from \"./editType.vue\";\r\n\r\nexport default {\r\n props: [\r\n \"display\", // original state (true = show, false=hide) of the modal\r\n \"mousePosition\" // mouse position when this panel was opened\r\n ],\r\n components: {\r\n \"search-results\": SearchResultsVue,\r\n \"display-result\": DisplayResultVue,\r\n \"edit-type\": EditTypeVue\r\n },\r\n data: function() {\r\n return {\r\n error: null,\r\n\r\n searchText: {}, // the search text, indexed by selectedType\r\n results: {}, // dictionary of arrays, indexed by selectedType\r\n selectedResult: {}, // dictionary of string, indexed by selectedType\r\n selectedType: \"module\",\r\n inputType: \"*\",\r\n outputType: \"*\"\r\n };\r\n },\r\n created: function() {\r\n this.view = window.dualboxEditor.v;\r\n },\r\n updated: function() {\r\n console.log(\"AddNode updated !\");\r\n this.updateVisibility();\r\n this.setSearchFocus();\r\n\r\n if (!this.display) {\r\n // make sure the modal disappeared\r\n $(this.$el).modal(\"hide\");\r\n $(\"body\").removeClass(\"modal-open\");\r\n $(\".modal-backdrop\").remove();\r\n }\r\n },\r\n mounted: function() {\r\n var self = this;\r\n this.updateVisibility(); // to init our modal\r\n\r\n $(this.$el).on(\"shown.bs.modal\", () => {\r\n this.setSearchFocus();\r\n });\r\n $(this.$el).on(\"hide.bs.modal\", () => {\r\n self.$emit(\"closed\");\r\n });\r\n\r\n $(this.$el)\r\n .find('[data-toggle=\"pill\"]')\r\n .on(\"shown.bs.tab\", e => {\r\n this.setSearchFocus();\r\n var selectedResult = this.getSelectedResult();\r\n if (selectedResult) {\r\n this.$refs.searchResults.selected = selectedResult.name;\r\n }\r\n });\r\n },\r\n methods: {\r\n updateVisibility: function() {\r\n if (this.display) {\r\n $(this.$el).modal(\"show\");\r\n } else {\r\n $(this.$el).modal(\"hide\");\r\n }\r\n },\r\n\r\n closeModal: function() {\r\n // don't mutate prop directly, mute the parent\r\n // this.display = false;\r\n\r\n return new Promise((resolve, reject) => {\r\n this.$emit(\"closed\");\r\n\r\n let forceCloseModal = () => {\r\n if (!this.display) {\r\n resolve();\r\n } else {\r\n this.$emit(\"closed\");\r\n setTimeout(forceCloseModal, 100);\r\n }\r\n };\r\n\r\n this.$nextTick(forceCloseModal);\r\n });\r\n },\r\n\r\n setSearchFocus: function() {\r\n $(this.$el)\r\n .find(\".nav-link.active\")\r\n .find(\"input\")\r\n .focus();\r\n },\r\n\r\n selectType(t) {\r\n let searchText = this.searchText[this.selectedType];\r\n this.selectedType = t;\r\n this.searchText[t] = searchText;\r\n },\r\n\r\n addSelectedNode: async function(e) {\r\n switch (this.selectedType) {\r\n case \"module\":\r\n case \"ui\":\r\n var selectedNode = $(\".node-result.selected\")[0];\r\n if (selectedNode) {\r\n await this.closeModal();\r\n // add node to the controller\r\n var packageName = $(selectedNode).data(\"package\");\r\n this.view.c.addNewBox(packageName, this.mousePosition);\r\n } else {\r\n swal(\"Please select a node\", \"\", \"error\");\r\n return;\r\n }\r\n break;\r\n\r\n case \"input\":\r\n var type = this.$refs.inputType.get();\r\n var name = $(this.$el)\r\n .find(\".input-name\")\r\n .val();\r\n var desc = $(this.$el)\r\n .find(\".input-description\")\r\n .val();\r\n if (type !== undefined && name) {\r\n await this.closeModal();\r\n this.view.c.addInput(\r\n name,\r\n type,\r\n desc,\r\n this.mousePosition\r\n );\r\n // reset fields\r\n this.$refs.inputType.resetChanges();\r\n $(this.$el)\r\n .find(\".input-name\")\r\n .val(\"\");\r\n $(this.$el)\r\n .find(\".input-description\")\r\n .val(\"\");\r\n } else {\r\n swal(\"Please complete all fields\", \"\", \"error\");\r\n return;\r\n }\r\n break;\r\n\r\n case \"output\":\r\n var name = $(this.$el)\r\n .find(\".output-name\")\r\n .val();\r\n var type = this.$refs.outputType.get();\r\n var desc = $(this.$el)\r\n .find(\".output-description\")\r\n .val();\r\n if (type !== undefined && name) {\r\n await this.closeModal();\r\n this.view.c.addOutput(\r\n name,\r\n type,\r\n desc,\r\n this.mousePosition\r\n );\r\n // reset fields\r\n this.$refs.outputType.resetChanges();\r\n $(this.$el)\r\n .find(\".output-name\")\r\n .val(\"\");\r\n $(this.$el)\r\n .find(\".output-description\")\r\n .val(\"\");\r\n } else {\r\n swal(\"Please complete all fields\", \"\", \"error\");\r\n return;\r\n }\r\n break;\r\n\r\n case \"metanode\":\r\n var name = $(this.$el)\r\n .find(\".metanode-name\")\r\n .val();\r\n var desc = $(this.$el)\r\n .find(\".metanode-description\")\r\n .val();\r\n if (!name) {\r\n swal(\"Please complete name field\", \"\", \"error\");\r\n return;\r\n }\r\n\r\n var json = this.metanodeJSON || {};\r\n json.description = desc;\r\n\r\n await this.closeModal();\r\n this.view.c.addNewMetabox(name, json, this.mousePosition);\r\n default:\r\n }\r\n },\r\n\r\n searchModules: async function(e) {\r\n //var text = $(e.target).val();\r\n var text = this.searchText[this.selectedType];\r\n try {\r\n this.error = null;\r\n this.results[this.selectedType] = await this.view.e.search(\r\n text,\r\n this.selectedType\r\n );\r\n this.$forceUpdate();\r\n } catch (e) {\r\n this.error = e;\r\n swal(\"error searching packages\", e.reason, \"error\");\r\n }\r\n },\r\n\r\n getSearchText: function() {\r\n return this.searchText[this.selectedType] || \"\";\r\n },\r\n\r\n setSelectedResult: function(packageName) {\r\n // first, find the selected result in the list\r\n var selectedPackage = null;\r\n _.each(this.getResults(), r => {\r\n if (r.name == packageName) {\r\n selectedPackage = r;\r\n return false;\r\n }\r\n });\r\n\r\n if (!selectedPackage) {\r\n throw \"Could not find package named \" + packageName;\r\n }\r\n\r\n this.selectedResult[this.selectedType] = selectedPackage;\r\n this.$forceUpdate();\r\n },\r\n\r\n getSelectedResult: function() {\r\n return this.selectedResult[this.selectedType];\r\n },\r\n\r\n getResults: function() {\r\n return this.results[this.selectedType] || null;\r\n },\r\n\r\n getNbResults: function() {\r\n var results = this.getResults();\r\n return results && results.length ? results.length : 0;\r\n },\r\n\r\n onMetaboxFileSelect: function(e) {\r\n var file = e.target.files[0];\r\n const reader = new FileReader();\r\n reader.onload = e => {\r\n this.metanodeJSON = JSON.parse(e.target.result);\r\n if (this.metanodeJSON.description) {\r\n $(this.$el)\r\n .find(\".metanode-description\")\r\n .val(this.metanodeJSON.description);\r\n }\r\n };\r\n reader.readAsText(file);\r\n }\r\n }\r\n};\r\n</script>\r\n\r\n"]}, media: undefined });
|
|
64457
64556
|
|
|
64458
64557
|
};
|
|
64459
64558
|
/* scoped */
|
|
64460
|
-
const __vue_scope_id__$5 = "data-v-
|
|
64559
|
+
const __vue_scope_id__$5 = "data-v-2cca907e";
|
|
64461
64560
|
/* module identifier */
|
|
64462
64561
|
const __vue_module_identifier__$5 = undefined;
|
|
64463
64562
|
/* functional template */
|
|
@@ -64905,6 +65004,8 @@ catch(e) {
|
|
|
64905
65004
|
|
|
64906
65005
|
//
|
|
64907
65006
|
|
|
65007
|
+
var JSONEditorMode = "tree";
|
|
65008
|
+
|
|
64908
65009
|
String.prototype.hashCode = function() {
|
|
64909
65010
|
var hash = 0,
|
|
64910
65011
|
i,
|
|
@@ -65016,8 +65117,12 @@ var script$8 = {
|
|
|
65016
65117
|
this.editor = new _import$1(
|
|
65017
65118
|
$(this.$el).find(".field-editor")[0],
|
|
65018
65119
|
{
|
|
65120
|
+
mode: JSONEditorMode,
|
|
65019
65121
|
modes: ["tree", "code", "text"],
|
|
65020
|
-
onChange: this.debouncedJsonEmit
|
|
65122
|
+
onChange: this.debouncedJsonEmit,
|
|
65123
|
+
onModeChange: (newMode) => {
|
|
65124
|
+
JSONEditorMode = newMode;
|
|
65125
|
+
}
|
|
65021
65126
|
}
|
|
65022
65127
|
);
|
|
65023
65128
|
}
|
|
@@ -65388,9 +65493,9 @@ var __vue_render__$8 = function() {
|
|
|
65388
65493
|
? [
|
|
65389
65494
|
_vm.dataType === "string"
|
|
65390
65495
|
? [
|
|
65391
|
-
_c("
|
|
65496
|
+
_c("textarea", {
|
|
65392
65497
|
staticClass: "edit-value-input",
|
|
65393
|
-
attrs: { type: "text" },
|
|
65498
|
+
attrs: { rows: "3", type: "text" },
|
|
65394
65499
|
domProps: { value: _vm.v },
|
|
65395
65500
|
on: {
|
|
65396
65501
|
keyup: [
|
|
@@ -65537,7 +65642,8 @@ var __vue_render__$8 = function() {
|
|
|
65537
65642
|
padding: "0",
|
|
65538
65643
|
"background-color": "white",
|
|
65539
65644
|
"overflow-y": "auto",
|
|
65540
|
-
"border-right": "1px solid rgba(0, 0, 0, 0.125)"
|
|
65645
|
+
"border-right": "1px solid rgba(0, 0, 0, 0.125)",
|
|
65646
|
+
"max-height": "500px"
|
|
65541
65647
|
}
|
|
65542
65648
|
},
|
|
65543
65649
|
[
|
|
@@ -65551,7 +65657,10 @@ var __vue_render__$8 = function() {
|
|
|
65551
65657
|
staticClass:
|
|
65552
65658
|
"list-group-item list-group-item-action",
|
|
65553
65659
|
class: { active: _vm.isSelectedIndex(index) },
|
|
65554
|
-
staticStyle: {
|
|
65660
|
+
staticStyle: {
|
|
65661
|
+
"text-align": "center",
|
|
65662
|
+
padding: "12px"
|
|
65663
|
+
},
|
|
65555
65664
|
attrs: {
|
|
65556
65665
|
draggable: _vm.isArrayType(),
|
|
65557
65666
|
"data-key": index,
|
|
@@ -65686,11 +65795,11 @@ __vue_render__$8._withStripped = true;
|
|
|
65686
65795
|
/* style */
|
|
65687
65796
|
const __vue_inject_styles__$8 = function (inject) {
|
|
65688
65797
|
if (!inject) return
|
|
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 });
|
|
65798
|
+
inject("data-v-d7e27fa2_0", { source: "\n.template-value-container[data-v-d7e27fa2],\r\n.field-editor[data-v-d7e27fa2] {\r\n margin-bottom: 10px;\n}\n.template-value-message[data-v-d7e27fa2] {\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-d7e27fa2] {\r\n border-bottom: 2px solid blue;\n}\n.edit-input-value[type=\"text\"][data-v-d7e27fa2] {\r\n font-size: 75px;\n}\r\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;AAEA;IACA,eAAA;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\r\n.edit-input-value[type=\"text\"] {\r\n font-size: 75px;\r\n}\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 <textarea rows=3 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); max-height: 500px;\">\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; padding: 12px;\" @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\nvar JSONEditorMode = \"tree\";\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 mode: JSONEditorMode,\r\n modes: [\"tree\", \"code\", \"text\"],\r\n onChange: this.debouncedJsonEmit,\r\n onModeChange: (newMode) => {\r\n JSONEditorMode = newMode;\r\n }\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 });
|
|
65690
65799
|
|
|
65691
65800
|
};
|
|
65692
65801
|
/* scoped */
|
|
65693
|
-
const __vue_scope_id__$8 = "data-v-
|
|
65802
|
+
const __vue_scope_id__$8 = "data-v-d7e27fa2";
|
|
65694
65803
|
/* module identifier */
|
|
65695
65804
|
const __vue_module_identifier__$8 = undefined;
|
|
65696
65805
|
/* functional template */
|
|
@@ -67365,7 +67474,7 @@ __vue_render__$a._withStripped = true;
|
|
|
67365
67474
|
/* style */
|
|
67366
67475
|
const __vue_inject_styles__$a = function (inject) {
|
|
67367
67476
|
if (!inject) return
|
|
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 });
|
|
67477
|
+
inject("data-v-0f5578f2_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);\r\n max-height: calc(100vh - 120px);\r\n overflow: auto;\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;IACA,+BAAA;IACA,cAAA;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 max-height: calc(100vh - 120px);\r\n overflow: auto;\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 });
|
|
67369
67478
|
|
|
67370
67479
|
};
|
|
67371
67480
|
/* scoped */
|
|
@@ -67432,10 +67541,6 @@ var script$b = {
|
|
|
67432
67541
|
|
|
67433
67542
|
// allow tooltips
|
|
67434
67543
|
this.activateTooltip();
|
|
67435
|
-
|
|
67436
|
-
// bind the json editor
|
|
67437
|
-
this.editor = new _import$1($(this.$el).find('.json-editor')[0], { modes: ['tree', 'code', 'text' ]});
|
|
67438
|
-
this.editor.set({});
|
|
67439
67544
|
},
|
|
67440
67545
|
beforeUpdate: function() {
|
|
67441
67546
|
//console.log('[Updating] node-settings');
|
|
@@ -67457,11 +67562,6 @@ var script$b = {
|
|
|
67457
67562
|
deactivate: function() {
|
|
67458
67563
|
this.deactivateTooltip();
|
|
67459
67564
|
},
|
|
67460
|
-
destroyed: function() {
|
|
67461
|
-
if( this.editor ) {
|
|
67462
|
-
this.editor.destroy();
|
|
67463
|
-
}
|
|
67464
|
-
},
|
|
67465
67565
|
methods: {
|
|
67466
67566
|
fixCardStyle: function() {
|
|
67467
67567
|
var card = $(this.$el).find('.module-left-signature .card');
|
|
@@ -69125,9 +69225,7 @@ var __vue_render__$b = function() {
|
|
|
69125
69225
|
)
|
|
69126
69226
|
])
|
|
69127
69227
|
: _vm._e()
|
|
69128
|
-
])
|
|
69129
|
-
_vm._v(" "),
|
|
69130
|
-
_vm._m(15)
|
|
69228
|
+
])
|
|
69131
69229
|
]
|
|
69132
69230
|
)
|
|
69133
69231
|
};
|
|
@@ -69388,295 +69486,6 @@ var __vue_staticRenderFns__$b = [
|
|
|
69388
69486
|
{ staticStyle: { width: "53px", display: "inline-block" } },
|
|
69389
69487
|
[_c("i", { staticClass: "fas fa-caret-right" }), _vm._v(" Data:")]
|
|
69390
69488
|
)
|
|
69391
|
-
},
|
|
69392
|
-
function() {
|
|
69393
|
-
var _vm = this;
|
|
69394
|
-
var _h = _vm.$createElement;
|
|
69395
|
-
var _c = _vm._self._c || _h;
|
|
69396
|
-
return _c(
|
|
69397
|
-
"div",
|
|
69398
|
-
{
|
|
69399
|
-
staticClass: "modal edit-value-modal",
|
|
69400
|
-
attrs: { tabindex: "-1", role: "dialog" }
|
|
69401
|
-
},
|
|
69402
|
-
[
|
|
69403
|
-
_c(
|
|
69404
|
-
"div",
|
|
69405
|
-
{ staticClass: "modal-dialog", attrs: { role: "document" } },
|
|
69406
|
-
[
|
|
69407
|
-
_c("div", { staticClass: "modal-content" }, [
|
|
69408
|
-
_c("div", { staticClass: "modal-header" }, [
|
|
69409
|
-
_c("h5", { staticClass: "modal-title" }, [
|
|
69410
|
-
_vm._v("Edit value")
|
|
69411
|
-
]),
|
|
69412
|
-
_vm._v(" "),
|
|
69413
|
-
_c(
|
|
69414
|
-
"button",
|
|
69415
|
-
{
|
|
69416
|
-
staticClass: "close",
|
|
69417
|
-
attrs: {
|
|
69418
|
-
type: "button",
|
|
69419
|
-
"data-dismiss": "modal",
|
|
69420
|
-
"aria-label": "Close"
|
|
69421
|
-
}
|
|
69422
|
-
},
|
|
69423
|
-
[
|
|
69424
|
-
_c("span", { attrs: { "aria-hidden": "true" } }, [
|
|
69425
|
-
_vm._v("×")
|
|
69426
|
-
])
|
|
69427
|
-
]
|
|
69428
|
-
)
|
|
69429
|
-
]),
|
|
69430
|
-
_vm._v(" "),
|
|
69431
|
-
_c("div", { staticClass: "modal-body" }, [
|
|
69432
|
-
_c("div", { staticClass: "set-type" }, [
|
|
69433
|
-
_c("div", { staticClass: "form-check" }, [
|
|
69434
|
-
_c("input", {
|
|
69435
|
-
staticClass: "form-check-input set-value unset-value",
|
|
69436
|
-
attrs: {
|
|
69437
|
-
type: "radio",
|
|
69438
|
-
id: "unset-value",
|
|
69439
|
-
name: "set-value",
|
|
69440
|
-
value: "unset-value",
|
|
69441
|
-
checked: ""
|
|
69442
|
-
}
|
|
69443
|
-
}),
|
|
69444
|
-
_vm._v(" "),
|
|
69445
|
-
_c(
|
|
69446
|
-
"label",
|
|
69447
|
-
{
|
|
69448
|
-
staticClass: "form-check-label",
|
|
69449
|
-
attrs: { for: "unset-value" }
|
|
69450
|
-
},
|
|
69451
|
-
[
|
|
69452
|
-
_vm._v(
|
|
69453
|
-
"\n don't set a value\n "
|
|
69454
|
-
)
|
|
69455
|
-
]
|
|
69456
|
-
)
|
|
69457
|
-
]),
|
|
69458
|
-
_vm._v(" "),
|
|
69459
|
-
_c("div", { staticClass: "form-check" }, [
|
|
69460
|
-
_c("input", {
|
|
69461
|
-
staticClass: "form-check-input set-value set-value-null",
|
|
69462
|
-
attrs: {
|
|
69463
|
-
type: "radio",
|
|
69464
|
-
id: "set-value-null",
|
|
69465
|
-
name: "set-value",
|
|
69466
|
-
value: "set-value-null"
|
|
69467
|
-
}
|
|
69468
|
-
}),
|
|
69469
|
-
_vm._v(" "),
|
|
69470
|
-
_c(
|
|
69471
|
-
"label",
|
|
69472
|
-
{
|
|
69473
|
-
staticClass: "form-check-label",
|
|
69474
|
-
attrs: { for: "set-value-null" }
|
|
69475
|
-
},
|
|
69476
|
-
[
|
|
69477
|
-
_vm._v(
|
|
69478
|
-
"\n set null\n "
|
|
69479
|
-
)
|
|
69480
|
-
]
|
|
69481
|
-
)
|
|
69482
|
-
]),
|
|
69483
|
-
_vm._v(" "),
|
|
69484
|
-
_c("div", { staticClass: "form-check" }, [
|
|
69485
|
-
_c("input", {
|
|
69486
|
-
staticClass: "form-check-input set-value set-value-type",
|
|
69487
|
-
attrs: {
|
|
69488
|
-
type: "radio",
|
|
69489
|
-
id: "set-value-type",
|
|
69490
|
-
name: "set-value",
|
|
69491
|
-
value: "set-value-type",
|
|
69492
|
-
"aria-label": "Set a value of type"
|
|
69493
|
-
}
|
|
69494
|
-
}),
|
|
69495
|
-
_vm._v(" "),
|
|
69496
|
-
_c(
|
|
69497
|
-
"div",
|
|
69498
|
-
{
|
|
69499
|
-
staticClass: "form-inline form-check-label",
|
|
69500
|
-
staticStyle: { height: "24px" }
|
|
69501
|
-
},
|
|
69502
|
-
[
|
|
69503
|
-
_c("label", { attrs: { for: "set-value-type" } }, [
|
|
69504
|
-
_vm._v(
|
|
69505
|
-
"\n set a value of type:\n "
|
|
69506
|
-
),
|
|
69507
|
-
_c(
|
|
69508
|
-
"select",
|
|
69509
|
-
{
|
|
69510
|
-
staticClass:
|
|
69511
|
-
"form-control choose-value-type d-inline-block form-control-sm ml-2"
|
|
69512
|
-
},
|
|
69513
|
-
[
|
|
69514
|
-
_c("option", { attrs: { value: "string" } }, [
|
|
69515
|
-
_vm._v("String")
|
|
69516
|
-
]),
|
|
69517
|
-
_vm._v(" "),
|
|
69518
|
-
_c("option", { attrs: { value: "number" } }, [
|
|
69519
|
-
_vm._v("Number")
|
|
69520
|
-
]),
|
|
69521
|
-
_vm._v(" "),
|
|
69522
|
-
_c("option", { attrs: { value: "boolean" } }, [
|
|
69523
|
-
_vm._v("Boolean")
|
|
69524
|
-
]),
|
|
69525
|
-
_vm._v(" "),
|
|
69526
|
-
_c("option", { attrs: { value: "object" } }, [
|
|
69527
|
-
_vm._v("Object")
|
|
69528
|
-
]),
|
|
69529
|
-
_vm._v(" "),
|
|
69530
|
-
_c("option", { attrs: { value: "file" } }, [
|
|
69531
|
-
_vm._v("File")
|
|
69532
|
-
])
|
|
69533
|
-
]
|
|
69534
|
-
)
|
|
69535
|
-
])
|
|
69536
|
-
]
|
|
69537
|
-
)
|
|
69538
|
-
])
|
|
69539
|
-
]),
|
|
69540
|
-
_vm._v(" "),
|
|
69541
|
-
_c("hr", { staticClass: "separator" }),
|
|
69542
|
-
_vm._v(" "),
|
|
69543
|
-
_c(
|
|
69544
|
-
"div",
|
|
69545
|
-
{
|
|
69546
|
-
staticClass: "has-value",
|
|
69547
|
-
staticStyle: { display: "none" }
|
|
69548
|
-
},
|
|
69549
|
-
[
|
|
69550
|
-
_c(
|
|
69551
|
-
"div",
|
|
69552
|
-
{
|
|
69553
|
-
staticClass: "define-value define-boolean",
|
|
69554
|
-
staticStyle: { display: "none" }
|
|
69555
|
-
},
|
|
69556
|
-
[
|
|
69557
|
-
_c("div", { staticClass: "form-inline" }, [
|
|
69558
|
-
_c("label", [_vm._v("Value: ")]),
|
|
69559
|
-
_vm._v(" "),
|
|
69560
|
-
_c(
|
|
69561
|
-
"select",
|
|
69562
|
-
{
|
|
69563
|
-
staticClass:
|
|
69564
|
-
"form-control form-control-sm bool-value d-inline-block ml-2"
|
|
69565
|
-
},
|
|
69566
|
-
[
|
|
69567
|
-
_c("option", { attrs: { value: "true" } }, [
|
|
69568
|
-
_vm._v("True")
|
|
69569
|
-
]),
|
|
69570
|
-
_vm._v(" "),
|
|
69571
|
-
_c("option", { attrs: { value: "false" } }, [
|
|
69572
|
-
_vm._v("False")
|
|
69573
|
-
])
|
|
69574
|
-
]
|
|
69575
|
-
)
|
|
69576
|
-
])
|
|
69577
|
-
]
|
|
69578
|
-
),
|
|
69579
|
-
_vm._v(" "),
|
|
69580
|
-
_c(
|
|
69581
|
-
"div",
|
|
69582
|
-
{
|
|
69583
|
-
staticClass: "define-value define-file",
|
|
69584
|
-
staticStyle: { display: "none" }
|
|
69585
|
-
},
|
|
69586
|
-
[
|
|
69587
|
-
_c("div", { staticClass: "form-inline" }, [
|
|
69588
|
-
_c("label", [_vm._v("File input")]),
|
|
69589
|
-
_vm._v(" "),
|
|
69590
|
-
_c("input", {
|
|
69591
|
-
staticClass:
|
|
69592
|
-
"form-control-file form-control-sm file-value",
|
|
69593
|
-
attrs: { type: "file" }
|
|
69594
|
-
})
|
|
69595
|
-
])
|
|
69596
|
-
]
|
|
69597
|
-
),
|
|
69598
|
-
_vm._v(" "),
|
|
69599
|
-
_c(
|
|
69600
|
-
"div",
|
|
69601
|
-
{
|
|
69602
|
-
staticClass: "define-value define-number",
|
|
69603
|
-
staticStyle: { display: "none" }
|
|
69604
|
-
},
|
|
69605
|
-
[
|
|
69606
|
-
_c("div", { staticClass: "form-inline" }, [
|
|
69607
|
-
_c("label", [_vm._v("Value: ")]),
|
|
69608
|
-
_vm._v(" "),
|
|
69609
|
-
_c("input", {
|
|
69610
|
-
staticClass:
|
|
69611
|
-
"form-control form-control-sm number-value ml-2",
|
|
69612
|
-
attrs: { type: "number" }
|
|
69613
|
-
})
|
|
69614
|
-
])
|
|
69615
|
-
]
|
|
69616
|
-
),
|
|
69617
|
-
_vm._v(" "),
|
|
69618
|
-
_c(
|
|
69619
|
-
"div",
|
|
69620
|
-
{
|
|
69621
|
-
staticClass: "define-value define-string",
|
|
69622
|
-
staticStyle: { display: "none" }
|
|
69623
|
-
},
|
|
69624
|
-
[
|
|
69625
|
-
_c("div", { staticClass: "form-inline" }, [
|
|
69626
|
-
_c("label", [_vm._v("Value: ")]),
|
|
69627
|
-
_vm._v(" "),
|
|
69628
|
-
_c("input", {
|
|
69629
|
-
staticClass:
|
|
69630
|
-
"form-control form-control-sm text-value ml-2",
|
|
69631
|
-
attrs: { type: "text" }
|
|
69632
|
-
})
|
|
69633
|
-
])
|
|
69634
|
-
]
|
|
69635
|
-
),
|
|
69636
|
-
_vm._v(" "),
|
|
69637
|
-
_c(
|
|
69638
|
-
"div",
|
|
69639
|
-
{
|
|
69640
|
-
staticClass: "define-value define-object",
|
|
69641
|
-
staticStyle: { display: "none" }
|
|
69642
|
-
},
|
|
69643
|
-
[
|
|
69644
|
-
_c("label", [_vm._v("Value: ")]),
|
|
69645
|
-
_vm._v(" "),
|
|
69646
|
-
_c("div", {
|
|
69647
|
-
staticClass: "json-editor",
|
|
69648
|
-
staticStyle: { height: "400px" }
|
|
69649
|
-
})
|
|
69650
|
-
]
|
|
69651
|
-
)
|
|
69652
|
-
]
|
|
69653
|
-
)
|
|
69654
|
-
]),
|
|
69655
|
-
_vm._v(" "),
|
|
69656
|
-
_c("div", { staticClass: "modal-footer" }, [
|
|
69657
|
-
_c(
|
|
69658
|
-
"button",
|
|
69659
|
-
{
|
|
69660
|
-
staticClass: "btn btn-primary btn-save",
|
|
69661
|
-
attrs: { type: "button" }
|
|
69662
|
-
},
|
|
69663
|
-
[_vm._v("Save changes")]
|
|
69664
|
-
),
|
|
69665
|
-
_vm._v(" "),
|
|
69666
|
-
_c(
|
|
69667
|
-
"button",
|
|
69668
|
-
{
|
|
69669
|
-
staticClass: "btn btn-secondary",
|
|
69670
|
-
attrs: { type: "button", "data-dismiss": "modal" }
|
|
69671
|
-
},
|
|
69672
|
-
[_vm._v("Close")]
|
|
69673
|
-
)
|
|
69674
|
-
])
|
|
69675
|
-
])
|
|
69676
|
-
]
|
|
69677
|
-
)
|
|
69678
|
-
]
|
|
69679
|
-
)
|
|
69680
69489
|
}
|
|
69681
69490
|
];
|
|
69682
69491
|
__vue_render__$b._withStripped = true;
|
|
@@ -69684,7 +69493,7 @@ __vue_render__$b._withStripped = true;
|
|
|
69684
69493
|
/* style */
|
|
69685
69494
|
const __vue_inject_styles__$b = function (inject) {
|
|
69686
69495
|
if (!inject) return
|
|
69687
|
-
inject("data-v-135e50fe_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.card-settings > .card-header {\n padding-top: 6px;\n padding-bottom: 6px;\n padding-left: 12px;\n padding-right: 12px;\n}\n.card-settings > .card-header > h5 {\n font-size: 20px;\n}\n\n", map: {"version":3,"sources":["C:\\Users\\maxim\\Projects\\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;AAEA;IACA,gBAAA;IACA,mBAAA;IACA,kBAAA;IACA,mBAAA;AACA;AAEA;IACA,eAAA;AACA","file":"editNodeSettings.vue","sourcesContent":["<style>\r\n .edit-dualbox-node-id {\r\n margin-bottom: 0px;\r\n display: inline-block;\r\n width: 100%;\r\n }\r\n\r\n .edit-dualbox-node-package-name {\r\n font-style: italic;\r\n }\r\n\r\n .btn-edit-dualbox-node-name {\r\n display: inline-block;\r\n margin-left: 5px;\r\n margin-top: -10px;\r\n position: relative;\r\n top: -10px;\r\n vertical-align: bottom;\r\n }\r\n\r\n .module-left-description {\r\n padding-top: 30px;\r\n font-size: 12px;\r\n text-align: center;\r\n }\r\n\r\n .card-settings .card-body {\r\n font-size: 12px;\r\n padding-left: 5px;\r\n padding-right: 5px;\r\n overflow-y: auto;\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 .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 .dualbox-node-name, .dualbox-node-name-input {\r\n max-width: 400px;\r\n }\r\n\r\n .dualbox-node-name-span {\r\n max-width: 350px;\r\n }\r\n\r\n .dualbox-node-name-input {\r\n display: inline-block;\r\n border-radius: 4px;\r\n padding: 4px 8px 4px 8px;\r\n font-size: 20px;\r\n max-width: 280px;\r\n }\r\n\r\n .text-value, .number-value, .boolean-value {\r\n max-width: 140px;\r\n }\r\n\r\n .event-if, .event-data {\r\n max-width: 80px;\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 .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\n i.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-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-settings > .card-header > h5 {\r\n font-size: 20px;\r\n }\r\n\r\n</style>\r\n\r\n<template>\r\n <div class=\"edit-node-panel h100\" id=\"edit-node-panel\" :key=\"n.id\">\r\n <div class=\"edit-node-presentation\" style=\"padding-left: 10px; padding-top: 10px; padding-right: 10px; padding-bottom: 10px;\">\r\n <h2 class=\"edit-dualbox-node-id\">\r\n <div v-if=\"nowEditingNodeName\" class=\"dualbox-node-name-edit\">\r\n <input type=\"text\" class=\"form-control dualbox-node-name-input\" style=\"display: inline-block;\" :value=\"n.graphId\" @keypress=\"changeNodeName\" autofocus/>\r\n <button class=\"btn btn-primary btn-save-node-name-change\" :data-id=\"n.graphId\" style=\"display: inline-block;\" @click=\"saveNodeName\">Save</button>\r\n </div>\r\n <div v-else class=\"dualbox-node-name\">\r\n <span class=\"dualbox-node-name-span text-truncate d-inline-block\" @click=\"editNodeName\">{{n.graphId}}</span>\r\n </div>\r\n </h2>\r\n <p style=\"margin-bottom: 0\"><small class=\"edit-dualbox-node-package-name\">{{n.getPackageName()}}</small></p>\r\n </div>\r\n\r\n <div class=\"edit-body\">\r\n <div class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Description</h5>\r\n </div>\r\n\r\n <div id=\"dualbox-node-desc-collapse\" class=\"collapse show\" aria-labelledby=\"dualbox-node-desc\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\" style=\"padding-left: 15px;\">\r\n <div class=\"module-left-signature\">\r\n <graph-node :id=\"n.id\" :example=\"true\" :pkg=\"n.getPackage()\" :n=\"createExampleNode(n)\"></graph-node>\r\n </div>\r\n <p class=\"module-left-description\">\r\n <template v-if=\"n.isInput() || n.isOutput() || n.isMetanode()\">\r\n <template v-if=\"nowEditingDescription\">\r\n <textarea class=\"edit-node-description\" rows=4 style=\"width: 100%;\" :value=\"n.getDescription()\" autofocus>\r\n </textarea>\r\n <button class=\"btn btn-success\" @click=\"setDescription\">Save</button>\r\n </template>\r\n <template v-else>\r\n <button class=\"btn btn-transparent btn-xs\" @click=\"editDescription\"><i class=\"fa fa-edit\" ></i></button>\r\n <span> {{ getDescription() }}</span>\r\n </template>\r\n </template>\r\n <span v-else>\r\n {{ n.getPackage().description || \"[No description available]\" }}\r\n </span>\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Comments</h5>\r\n </div>\r\n <div id=\"dualbox-node-comments-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-comments\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <div style=\"padding-left: 15px; padding-right: 15px;\">\r\n <div v-if=\"nowEditingComment\" class=\"node-comment-edit\">\r\n <textarea class=\"node-comment\" rows=4 style=\"width: 100%;\" :data-id=\"n.id\" v-model=\"comment\" autofocus>\r\n </textarea>\r\n <div style=\"text-align: right; margin-top: 10px;\">\r\n <button class=\"btn btn-sm btn-secundary\" @click=\"deleteComment\">Delete</button>\r\n <button class=\"btn btn-sm btn-primary btn-save-comment\" @click=\"saveComment\">Save</button>\r\n </div>\r\n </div>\r\n <p v-else class=\"node-comment-text\">\r\n <span>{{ n.hasComment() ? n.getComment() : \"[Add a comment]\" }} </span>\r\n <button class=\"btn btn-xs btn-transparent\" @click=\"editComment\"><i class=\"fa fa-edit\"></i></button>\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Compute options -->\r\n <div v-if=\"n.isModule()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Compute options</h5>\r\n </div>\r\n <div id=\"dualbox-node-compute-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-inputs\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <div class=\"form-group\" style=\"padding-left: 20px;\">\r\n <div>\r\n <label>\r\n <input class=\"input-cache-toggle\" type=\"checkbox\" v-bind:checked=\"n.hasCacheActivated()\" @change=\"toggleCache\">\r\n <span>Cache result <button type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" 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>\r\n </label>\r\n </div>\r\n\r\n <div v-if=\"!n.isMetanode()\">\r\n <label>\r\n <input class=\"input-worker-toggle\" type=\"checkbox\" v-bind:data-id=\"n.id\" v-bind:checked=\"n.isParallel()\" @change=\"toggleWorker\" />\r\n <span>Execute in a worker <button type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" 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>\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Widget options -->\r\n <div v-if=\"n.isWidget()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Widget Options</h5>\r\n </div>\r\n <div id=\"dualbox-node-widget-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-widget\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <span>Widget registered to: </span>\r\n <select class=\"form-control form-control-sm select-widget-registerTo\" style=\"max-width: 250px;\" @change=\"registerToWidget\">\r\n <option value=\"\">none</option>\r\n <option v-for=\"target in getSpecialUINodes()\" :key=\"'target-'+target.id\" :value=\"target.graphId\" :selected=\"n.getWidgetRegistration() == target.graphId\">{{target.id}}</option>\r\n\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Inputs -->\r\n <div v-if=\"n.isInput()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Default value</h5>\r\n </div>\r\n <div id=\"dualbox-node-default-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-default\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <span>Default value:</span>\r\n <span><display-value :v=\"n.getDefaultValue()\" :type=\"n.getType()\" @edited=\"onEditDefaultValue\"></display-value></span>\r\n </div>\r\n </div>\r\n </div>\r\n <div v-else-if=\"n.hasInputs()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Inputs <small><span class=\"badge badge-secondary\">{{n.getInputsNames().length}}</span></small></h5>\r\n </div>\r\n <div id=\"dualbox-node-inputs-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-inputs\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <table class=\"table-desc table-striped\">\r\n <thead class=\"thead-dark\">\r\n <th>Input</th>\r\n <th>Visible</th>\r\n <th>Type</th>\r\n <th>Default</th>\r\n </thead>\r\n <tbody>\r\n <tr v-for=\"key in n.getInputsNames()\" :key=\"'input-'+key\">\r\n <td>\r\n {{key}}\r\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>\r\n </td>\r\n <td>\r\n <input v-if=\"n.isInputHideable(key)\" 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\">\r\n <span v-else class=\"d-inline-block\" tabindex=\"0\" data-toggle=\"tooltip\" data-trigger=\"hover\" data-placement=\"right\" data-original-title=\"Input is not connected, and has no default value. Cannot hide it yet.\">\r\n <input class=\"input-visibility-toggle\" style=\"pointer-events: none;\" type=\"checkbox\" v-bind:checked=\"n.isInputVisible(key)\" disabled>\r\n </span>\r\n </td>\r\n <td>\r\n <!-- If there's a start, then we must edit the type -->\r\n <display-type :type=\"n.getInputType(key)\" :readonly=\"!n.isInputTemplateType(key)\" @edited=\"onEditInputType(key, $event)\"></display-type>\r\n </td>\r\n <td>\r\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>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Outputs -->\r\n <div v-if=\"n.hasOutputs()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Outputs <small><span class=\"badge badge-secondary\">{{n.getOutputsNames().length}}</span></small></h5>\r\n </div>\r\n <div id=\"dualbox-node-outputs-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-outputs\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <table class=\"table-desc table-striped\">\r\n <thead class=\"thead-dark\">\r\n <th>Output</th>\r\n <th>Type</th>\r\n <th>Visible</th>\r\n </thead>\r\n <tbody>\r\n <tr v-for=\"key in n.getOutputsNames()\" :key=\"'output-'+key\">\r\n <td>{{key}}\r\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>\r\n </td>\r\n <td><display-type :type=\"n.getOutputType(key)\" @edited=\"onEditOutputType(key, $event)\"></display-type></td>\r\n <td>\r\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\">\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Attributes -->\r\n <div v-if=\"n.hasAttributes()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Attributes <small><span class=\"badge badge-secondary\">{{n.getAttributesNames().length}}</span></small></h5>\r\n </div>\r\n <div id=\"dualbox-node-attrs-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-attrs\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <table class=\"table-desc table-striped\">\r\n <thead class=\"thead-dark\">\r\n <th>Output</th>\r\n <th>Type</th>\r\n <th>Value</th>\r\n </thead>\r\n <tbody>\r\n <tr v-for=\"key in n.getAttributesNames()\" :key=\"'attr-'+key\">\r\n <td>{{key}}\r\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>\r\n </td>\r\n <td>\r\n <!-- If there's a start, then we must edit the type -->\r\n <display-type :type=\"n.getAttributeType(key)\" :readonly=\"!n.isAttributeTemplateType(key)\" @edited=\"onEditAttributeType(key, $event)\"></display-type>\r\n </td>\r\n <td>\r\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>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <!-- Loops -->\r\n <div v-if=\"n.hasInputs()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Loops <small><span class=\"badge badge-secondary\">{{ n.hasLoop() ? \"on\" : \"off\" }}</span></small></h5>\r\n </div>\r\n <div id=\"dualbox-node-loops-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-inputs\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <h4>Iterators\r\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>\r\n </h4>\r\n <table class=\"table-desc table-striped\">\r\n <tbody>\r\n <tr v-for=\"key in n.getInputsNames()\" :key=\"'loop-iterator-'+key\">\r\n <td>{{key}}</td>\r\n <td>\r\n <input class=\"input-iterator-toggle\" type=\"checkbox\" :data-input=\"key\" :checked=\"n.hasIterator(key)\" @change=\"toggleIterator\" />\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <h4 class=\"mt-2\">Feedback\r\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>\r\n </h4>\r\n <table class=\"table-desc table-striped\">\r\n <tbody>\r\n <tr v-for=\"key in n.getOutputsNames()\" :key=\"'loop-feedback-'+key\">\r\n <td>{{key}}</td>\r\n <td>\r\n <select class=\"form-control form-control-sm select-output-feedback\" :data-output=\"key\" @change=\"selectOutputFeedback\">\r\n <option value=\"none\">No feedback</option>\r\n <option v-for=\"i in n.getInputsNames()\" :value=\"i\" :selected=\"n.getFeedback(key) == i\" :key=\"'loop-feedback-input-'+i\">{{i}}</option>\r\n </select>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Events -->\r\n <div v-if=\"n.isUI()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Events <small><span class=\"badge badge-secondary\">{{n.getOutboundEvents().length}}</span></small></h5>\r\n </div>\r\n <div id=\"dualbox-node-events-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-events\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\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>Action</th>\r\n </thead>\r\n <tbody>\r\n <template v-if=\"n.hasOutEvents()\" v-for=\"(evt, index) in n.getOutboundEvents()\" :data-index=\"index\">\r\n <tr class=\"event-rooting\">\r\n <td>\r\n <select v-if=\"evt.node\" class=\"form-control form-control-sm select-event-target\" :data-index=\"index\"@change=\"selectEventTarget\" >\r\n <option v-for=\"node in getUINodesWithEvents()\" :value=\"node.getGraphId()\" :selected=\"node.getGraphId()==evt.node\" :key=\"node.id\">{{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\" :data-index=\"index\" @change=\"selectEventName\">\r\n <template v-if=\"evt.node\">\r\n <option v-for=\"targetEvent in getTargetNodeEvents(evt.node)\" :value=\"targetEvent\" :selected=\"evt.event===targetEvent\" :key=\"targetEvent\">{{targetEvent}}</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>\r\n <button class=\"btn btn-secondary btn-editor-xs\" :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 btn-remove-event\" :data-index=\"index\" @click=\"removeEvent\">\r\n <i class=\"fa fa-minus\"></i>\r\n </button>\r\n </td>\r\n </tr>\r\n <tr v-if=\"evt.if || expanded[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-index=\"index\" :value=\"evt.if\" @change=\"setEventIf\" />\r\n </td>\r\n </tr>\r\n <tr v-if=\"evt.data || evt.datatype || expanded[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)\" @edited=\"onEditEventData(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\" :data-id=\"n.id\" style=\"width: 100%;\" @click=\"addEvent\">Add event</button>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\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 class=\"set-type\">\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 <option value=\"file\">File</option>\r\n </select>\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n <hr class=\"separator\"/>\r\n <div class=\"has-value\" style=\"display: none;\">\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-file\" style=\"display: none;\">\r\n <div class=\"form-inline\">\r\n <label>File input</label>\r\n <input type=\"file\" class=\"form-control-file form-control-sm file-value\">\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</template>\r\n\r\n<script>\r\nimport _ from 'lodash-es';\r\nimport DisplayTypeVue from './displayType.vue';\r\nimport DisplayValueVue from './displayValue.vue';\r\nimport GraphNodeVue from './graphNode.vue';\r\nimport JSONEditor from '@dualbox/dualbox-lib-jsoneditor';\r\nimport swal from 'sweetalert2';\r\n\r\nexport default {\r\n props: [\r\n \"id\", // the GraphNode object\r\n ],\r\n components: {\r\n \"display-type\" : DisplayTypeVue,\r\n \"display-value\" : DisplayValueVue,\r\n \"graph-node\" : GraphNodeVue\r\n },\r\n data: function () {\r\n return {\r\n comment: null,\r\n expanded: {}, // expanded app events (advanced settings)\r\n\r\n // states\r\n isParallel: false,\r\n nowEditingComment: false,\r\n nowEditingNodeName: false,\r\n nowEditingDescription: false,\r\n };\r\n },\r\n created: function() {\r\n this.view = window.dualboxEditor.v;\r\n this.n = this.view.m.getNode(this.id);\r\n\r\n // fetch the comment for this node\r\n this.comment = this.n.hasComment() ? this.n.getComment() : \"\";\r\n this.isParallel = this.n.isParallel();\r\n },\r\n mounted: function() {\r\n // adapt the style of the example graph node\r\n // remove the \"position: absolute;\" that messes up the display\r\n this.fixCardStyle();\r\n this.fixMaxHeightForCategories();\r\n\r\n // allow tooltips\r\n this.activateTooltip();\r\n\r\n // bind the json editor\r\n this.editor = new JSONEditor($(this.$el).find('.json-editor')[0], { modes: ['tree', 'code', 'text' ]});\r\n this.editor.set({});\r\n },\r\n beforeUpdate: function() {\r\n //console.log('[Updating] node-settings');\r\n // we need to refresh our node object\r\n this.n = this.view.m.getNode(this.id); // it breaks updating node name\r\n this.deactivateTooltip();\r\n },\r\n updated: function() {\r\n //console.log('[Updated] node-settings');\r\n this.fixCardStyle();\r\n this.fixMaxHeightForCategories();\r\n this.activateTooltip();\r\n this.focus();\r\n },\r\n activate: function() {\r\n this.activateTooltip();\r\n this.focus();\r\n },\r\n deactivate: function() {\r\n this.deactivateTooltip();\r\n },\r\n destroyed: function() {\r\n if( this.editor ) {\r\n this.editor.destroy();\r\n }\r\n },\r\n methods: {\r\n fixCardStyle: function() {\r\n var card = $(this.$el).find('.module-left-signature .card');\r\n card.css('position', 'static').css('point-events', 'none');\r\n card.find('.point').css(\"visibibility\", \"visible\").find('svg').css(\"visibibility\", \"visible\");\r\n card.ready(() => {\r\n var width = Math.max(\r\n card.find('.inputs').width() + card.find('.outputs').width() + 20,\r\n card.find('.title').width() + 60,\r\n card.find('.subtitle').width() + 40\r\n );\r\n card.css('width', width + 'px');\r\n card.addClass('mx-auto');\r\n });\r\n },\r\n\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-settings').length;\r\n let headerHeight = $(this.$el).find('.edit-body > .card-settings > .card-header').outerHeight();\r\n let panelHeight = $(this.$el).height() - $(this.$el).find('.edit-node-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-settings > .collapse > .card-body').css('max-height', maxCategoryHeight + \"px\");\r\n },\r\n\r\n activateTooltip: function() {\r\n $(this.$el).find('[data-toggle=\"tooltip\"]').tooltip();\r\n },\r\n\r\n deactivateTooltip: function() {\r\n $(this.$el).find('[data-toggle=\"tooltip\"]').tooltip(\"dispose\");\r\n },\r\n\r\n focus: function() {\r\n $(this.$el).find('[autofocus]').focus();\r\n },\r\n\r\n // for widget registration\r\n getSpecialUINodes: function() {\r\n var targets = this.n.m.getSpecialUINodes( this.n.getRegisterType() );\r\n return targets;\r\n },\r\n\r\n getUINodesWithEvents : function() {\r\n var nodes = this.n.m.getNodes(\"ui\");\r\n var eventNodes = nodes.filter( function(n) {\r\n return n.getEventsNames().length > 0;\r\n });\r\n return eventNodes;\r\n },\r\n\r\n getTargetNodeEvents: function(nodeId) {\r\n var targetNode = this.n.m.getNode(nodeId);\r\n return targetNode.getEventsNames();\r\n },\r\n\r\n editComment: function(e) {\r\n this.nowEditingComment = true;\r\n },\r\n\r\n saveComment: function(e) {\r\n var val = $(this.$el).find('.node-comment').val();\r\n this.view.c.setComment(this.n.id, val);\r\n this.nowEditingComment = false;\r\n this.onEdited();\r\n },\r\n\r\n deleteComment: function(e) {\r\n this.view.c.deleteComment(this.n.id);\r\n this.nowEditingComment = false;\r\n this.onEdited();\r\n },\r\n\r\n addEvent: function(e) {\r\n this.view.c.addEvent(this.n.id);\r\n this.onEdited();\r\n },\r\n\r\n toggleInputVisibility: function(e) {\r\n var inputName = $(e.target).data('input');\r\n var visible = $(e.target).is(\":checked\");\r\n if( !this.view.c.setInputVisibility(this.n.id, inputName, visible) ) {\r\n // failed, reset this to old value\r\n $(e.target).prop('checked', !visible);\r\n }\r\n },\r\n\r\n toggleOutputVisibility: function(e) {\r\n var outputName = $(e.target).data('output');\r\n var visible = $(e.target).is(\":checked\");\r\n if( !this.view.c.setOutputVisibility(this.n.id, outputName, visible) ) {\r\n // failed, reset this to old value\r\n $(e.target).prop('checked', !visible);\r\n }\r\n },\r\n\r\n editNodeName: function(e) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n this.nowEditingNodeName = true;\r\n },\r\n\r\n changeNodeName: function(e) {\r\n // user pressed enter\r\n if(e.which == 13 || e.keyCode == 13) {\r\n this.saveNodeName(e);\r\n }\r\n },\r\n\r\n saveNodeName: function(e) {\r\n var newId = $(e.target).parent().find('.dualbox-node-name-input').val();\r\n this.view.c.renameBox(this.n.graphId, newId, this.n.type);\r\n\r\n // get the new node\r\n switch( this.n.type ) {\r\n case \"input\": this.n = this.view.m.getNode(\"in-\"+newId); break;\r\n case \"output\": this.n = this.view.m.getNode(\"in-\"+newId); break;\r\n default: this.n = this.view.m.getNode(newId);\r\n }\r\n\r\n this.nowEditingNodeName = false;\r\n },\r\n\r\n toggleIterator: function(e) {\r\n var destInput = $(e.target).attr('data-input');\r\n if( $(e.target).is(\":checked\") ) {\r\n this.view.c.setIterator( this.n.id, destInput );\r\n }\r\n else {\r\n this.view.c.unsetIterator( this.n.id, destInput );\r\n }\r\n this.onEdited();\r\n },\r\n\r\n registerToWidget: function(e) {\r\n var targetId = $(e.target).val();\r\n this.view.c.registerWidget(this.n.id, targetId);\r\n },\r\n\r\n selectOutputFeedback: function(e) {\r\n var val = $(e.target).val();\r\n var destOutput = $(e.target).attr('data-output');\r\n if( val !== \"none\" ) {\r\n this.view.c.setFeedback( this.n.id, destOutput, val );\r\n }\r\n else {\r\n this.view.c.unsetFeedback( this.n.id, destOutput );\r\n }\r\n },\r\n\r\n removeEvent: function(e) {\r\n var index = parseInt($(e.target).attr('data-index'));\r\n this.view.c.removeEvent( this.n.id, index );\r\n this.$forceUpdate();\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( this.n.id, index, val );\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( this.n.id, index, val );\r\n },\r\n\r\n // TODO: remake this into it's own vue\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\r\n var index = parseInt($(e.target).attr('data-index'));\r\n this.view.c.setEventTarget( this.n.id, 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( this.n.id, index, val );\r\n this.onEdited();\r\n },\r\n\r\n toggleCache: function(e) {\r\n var val = $(e.target).is(':checked');\r\n this.view.c.setBoxCache( this.n.id, val );\r\n },\r\n\r\n toggleWorker: function(e) {\r\n var val = $(e.target).is(':checked');\r\n this.view.c.setBoxParallel( this.n.id, val );\r\n this.isParallel = val;\r\n this.onEdited();\r\n },\r\n\r\n editModuleDescription: function(e) {\r\n var desc = $(e.target).attr('data-desc');\r\n\r\n swal({\r\n title: \"Describe what this metabox does\",\r\n input: \"textarea\",\r\n inputValue: desc || \"\",\r\n showCancelButton: true,\r\n closeOnConfirm: false,\r\n showLoaderOnConfirm: true,\r\n animation: \"slide-from-top\",\r\n inputPlaceholder: \"This metabox...\"\r\n }).then( (result) => {\r\n if (result.value === \"\") {\r\n swal.showInputError(\"You need to write something!\");\r\n return false;\r\n }\r\n else {\r\n this.view.c.setMetanodeDescription(this.n.id, result.value);\r\n }\r\n });\r\n },\r\n\r\n createExampleNode(n) {\r\n return this.view.m.createCloneNode(n.getPackage().name, n.id)\r\n },\r\n\r\n onEditInputType(inputName, typeStr) {\r\n this.n.assignInputType(inputName, typeStr);\r\n this.onEdited();\r\n this.view.repaint();\r\n },\r\n\r\n onEditOutputType(outputName, typeStr) {\r\n this.n.assignOutputType(outputName, typeStr);\r\n this.onEdited();\r\n this.view.repaint();\r\n },\r\n\r\n onEditAttributeType(attributeName, typeStr) {\r\n this.n.assignAttributeType(attributeName, typeStr);\r\n this.onEdited();\r\n this.view.repaint();\r\n },\r\n\r\n onEditDefaultValue(val) {\r\n this.n.setDefaultValue(val);\r\n this.onEdited();\r\n this.view.repaint();\r\n },\r\n\r\n onEditInputDefaultValue(inputName, val) {\r\n if( val === undefined ) {\r\n this.n.deleteVal(\"input\", inputName);\r\n this.n.setInputVisibility(inputName, true); // show the input then (connection needed)\r\n }\r\n else {\r\n this.n.val(\"input\", inputName, val );\r\n this.n.setInputVisibility(inputName, false); // hide inputs with values (no connection needed)\r\n }\r\n this.onEdited();\r\n this.view.repaint();\r\n },\r\n\r\n onEditAttribute(attrName, val) {\r\n if( val === undefined ) {\r\n this.n.deleteVal(\"attr\", attrName);\r\n }\r\n else {\r\n this.n.val(\"attr\", attrName, val);\r\n }\r\n this.onEdited();\r\n },\r\n\r\n onEditDefaultInput(inputName, val) {\r\n if( val === undefined ) {\r\n this.n.deleteVal(\"input\", inputName);\r\n }\r\n else {\r\n this.n.val(\"input\", inputName, val);\r\n }\r\n this.onEdited();\r\n this.view.repaint();\r\n },\r\n\r\n onEdited() {\r\n // we need to refresh our node object\r\n this.n = this.view.m.getNode(this.id); // it breaks updating node name\r\n this.$forceUpdate();\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 index = $(e.target).data('index');\r\n this.expanded[index] = this.expanded[index] ? false : true;\r\n this.$forceUpdate();\r\n },\r\n\r\n onEditEventData(key, index, val) {\r\n this.view.c.setEventData( this.n.id, index, val );\r\n this.$forceUpdate();\r\n },\r\n\r\n onEditEventInDataType(key, index, type) {\r\n this.view.c.setEventDataType( this.n.id, 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.n.getOutboundEvents()[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( this.n.id, index, undefined);\r\n }\r\n }\r\n catch(e) {\r\n this.view.c.setEventData( this.n.id, index, undefined);\r\n }\r\n\r\n this.$forceUpdate();\r\n },\r\n\r\n getDescription() {\r\n return this.n.getDescription() || \"[Add a description]\"\r\n },\r\n\r\n editDescription() {\r\n this.nowEditingDescription = true;\r\n },\r\n\r\n setDescription() {\r\n var val = $(this.$el).find('.edit-node-description').val();\r\n if( this.n.isInput() ) {\r\n this.view.c.setInputDescription(this.n.graphId, val);\r\n }\r\n else if( this.n.isOutput() ) {\r\n this.view.c.setOutputDescription(this.n.graphId, val);\r\n }\r\n else if( this.n.isMetanode() ) {\r\n this.view.c.setMetanodeDescription(this.n.graphId, val);\r\n }\r\n this.nowEditingDescription = false;\r\n\r\n this.$forceUpdate();\r\n },\r\n }\r\n}\r\n\r\n\r\n</script>\r\n"]}, media: undefined });
|
|
69496
|
+
inject("data-v-560c5170_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.card-settings > .card-header {\n padding-top: 6px;\n padding-bottom: 6px;\n padding-left: 12px;\n padding-right: 12px;\n}\n.card-settings > .card-header > h5 {\n font-size: 20px;\n}\n\n", map: {"version":3,"sources":["C:\\Users\\maxim\\Projects\\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;AAEA;IACA,gBAAA;IACA,mBAAA;IACA,kBAAA;IACA,mBAAA;AACA;AAEA;IACA,eAAA;AACA","file":"editNodeSettings.vue","sourcesContent":["<style>\r\n .edit-dualbox-node-id {\r\n margin-bottom: 0px;\r\n display: inline-block;\r\n width: 100%;\r\n }\r\n\r\n .edit-dualbox-node-package-name {\r\n font-style: italic;\r\n }\r\n\r\n .btn-edit-dualbox-node-name {\r\n display: inline-block;\r\n margin-left: 5px;\r\n margin-top: -10px;\r\n position: relative;\r\n top: -10px;\r\n vertical-align: bottom;\r\n }\r\n\r\n .module-left-description {\r\n padding-top: 30px;\r\n font-size: 12px;\r\n text-align: center;\r\n }\r\n\r\n .card-settings .card-body {\r\n font-size: 12px;\r\n padding-left: 5px;\r\n padding-right: 5px;\r\n overflow-y: auto;\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 .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 .dualbox-node-name, .dualbox-node-name-input {\r\n max-width: 400px;\r\n }\r\n\r\n .dualbox-node-name-span {\r\n max-width: 350px;\r\n }\r\n\r\n .dualbox-node-name-input {\r\n display: inline-block;\r\n border-radius: 4px;\r\n padding: 4px 8px 4px 8px;\r\n font-size: 20px;\r\n max-width: 280px;\r\n }\r\n\r\n .text-value, .number-value, .boolean-value {\r\n max-width: 140px;\r\n }\r\n\r\n .event-if, .event-data {\r\n max-width: 80px;\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 .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\n i.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-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-settings > .card-header > h5 {\r\n font-size: 20px;\r\n }\r\n\r\n</style>\r\n\r\n<template>\r\n <div class=\"edit-node-panel h100\" id=\"edit-node-panel\" :key=\"n.id\">\r\n <div class=\"edit-node-presentation\" style=\"padding-left: 10px; padding-top: 10px; padding-right: 10px; padding-bottom: 10px;\">\r\n <h2 class=\"edit-dualbox-node-id\">\r\n <div v-if=\"nowEditingNodeName\" class=\"dualbox-node-name-edit\">\r\n <input type=\"text\" class=\"form-control dualbox-node-name-input\" style=\"display: inline-block;\" :value=\"n.graphId\" @keypress=\"changeNodeName\" autofocus/>\r\n <button class=\"btn btn-primary btn-save-node-name-change\" :data-id=\"n.graphId\" style=\"display: inline-block;\" @click=\"saveNodeName\">Save</button>\r\n </div>\r\n <div v-else class=\"dualbox-node-name\">\r\n <span class=\"dualbox-node-name-span text-truncate d-inline-block\" @click=\"editNodeName\">{{n.graphId}}</span>\r\n </div>\r\n </h2>\r\n <p style=\"margin-bottom: 0\"><small class=\"edit-dualbox-node-package-name\">{{n.getPackageName()}}</small></p>\r\n </div>\r\n\r\n <div class=\"edit-body\">\r\n <div class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Description</h5>\r\n </div>\r\n\r\n <div id=\"dualbox-node-desc-collapse\" class=\"collapse show\" aria-labelledby=\"dualbox-node-desc\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\" style=\"padding-left: 15px;\">\r\n <div class=\"module-left-signature\">\r\n <graph-node :id=\"n.id\" :example=\"true\" :pkg=\"n.getPackage()\" :n=\"createExampleNode(n)\"></graph-node>\r\n </div>\r\n <p class=\"module-left-description\">\r\n <template v-if=\"n.isInput() || n.isOutput() || n.isMetanode()\">\r\n <template v-if=\"nowEditingDescription\">\r\n <textarea class=\"edit-node-description\" rows=4 style=\"width: 100%;\" :value=\"n.getDescription()\" autofocus>\r\n </textarea>\r\n <button class=\"btn btn-success\" @click=\"setDescription\">Save</button>\r\n </template>\r\n <template v-else>\r\n <button class=\"btn btn-transparent btn-xs\" @click=\"editDescription\"><i class=\"fa fa-edit\" ></i></button>\r\n <span> {{ getDescription() }}</span>\r\n </template>\r\n </template>\r\n <span v-else>\r\n {{ n.getPackage().description || \"[No description available]\" }}\r\n </span>\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Comments</h5>\r\n </div>\r\n <div id=\"dualbox-node-comments-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-comments\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <div style=\"padding-left: 15px; padding-right: 15px;\">\r\n <div v-if=\"nowEditingComment\" class=\"node-comment-edit\">\r\n <textarea class=\"node-comment\" rows=4 style=\"width: 100%;\" :data-id=\"n.id\" v-model=\"comment\" autofocus>\r\n </textarea>\r\n <div style=\"text-align: right; margin-top: 10px;\">\r\n <button class=\"btn btn-sm btn-secundary\" @click=\"deleteComment\">Delete</button>\r\n <button class=\"btn btn-sm btn-primary btn-save-comment\" @click=\"saveComment\">Save</button>\r\n </div>\r\n </div>\r\n <p v-else class=\"node-comment-text\">\r\n <span>{{ n.hasComment() ? n.getComment() : \"[Add a comment]\" }} </span>\r\n <button class=\"btn btn-xs btn-transparent\" @click=\"editComment\"><i class=\"fa fa-edit\"></i></button>\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Compute options -->\r\n <div v-if=\"n.isModule()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Compute options</h5>\r\n </div>\r\n <div id=\"dualbox-node-compute-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-inputs\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <div class=\"form-group\" style=\"padding-left: 20px;\">\r\n <div>\r\n <label>\r\n <input class=\"input-cache-toggle\" type=\"checkbox\" v-bind:checked=\"n.hasCacheActivated()\" @change=\"toggleCache\">\r\n <span>Cache result <button type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" 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>\r\n </label>\r\n </div>\r\n\r\n <div v-if=\"!n.isMetanode()\">\r\n <label>\r\n <input class=\"input-worker-toggle\" type=\"checkbox\" v-bind:data-id=\"n.id\" v-bind:checked=\"n.isParallel()\" @change=\"toggleWorker\" />\r\n <span>Execute in a worker <button type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" 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>\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Widget options -->\r\n <div v-if=\"n.isWidget()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Widget Options</h5>\r\n </div>\r\n <div id=\"dualbox-node-widget-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-widget\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <span>Widget registered to: </span>\r\n <select class=\"form-control form-control-sm select-widget-registerTo\" style=\"max-width: 250px;\" @change=\"registerToWidget\">\r\n <option value=\"\">none</option>\r\n <option v-for=\"target in getSpecialUINodes()\" :key=\"'target-'+target.id\" :value=\"target.graphId\" :selected=\"n.getWidgetRegistration() == target.graphId\">{{target.id}}</option>\r\n\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Inputs -->\r\n <div v-if=\"n.isInput()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Default value</h5>\r\n </div>\r\n <div id=\"dualbox-node-default-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-default\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <span>Default value:</span>\r\n <span><display-value :v=\"n.getDefaultValue()\" :type=\"n.getType()\" @edited=\"onEditDefaultValue\"></display-value></span>\r\n </div>\r\n </div>\r\n </div>\r\n <div v-else-if=\"n.hasInputs()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Inputs <small><span class=\"badge badge-secondary\">{{n.getInputsNames().length}}</span></small></h5>\r\n </div>\r\n <div id=\"dualbox-node-inputs-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-inputs\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <table class=\"table-desc table-striped\">\r\n <thead class=\"thead-dark\">\r\n <th>Input</th>\r\n <th>Visible</th>\r\n <th>Type</th>\r\n <th>Default</th>\r\n </thead>\r\n <tbody>\r\n <tr v-for=\"key in n.getInputsNames()\" :key=\"'input-'+key\">\r\n <td>\r\n {{key}}\r\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>\r\n </td>\r\n <td>\r\n <input v-if=\"n.isInputHideable(key)\" 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\">\r\n <span v-else class=\"d-inline-block\" tabindex=\"0\" data-toggle=\"tooltip\" data-trigger=\"hover\" data-placement=\"right\" data-original-title=\"Input is not connected, and has no default value. Cannot hide it yet.\">\r\n <input class=\"input-visibility-toggle\" style=\"pointer-events: none;\" type=\"checkbox\" v-bind:checked=\"n.isInputVisible(key)\" disabled>\r\n </span>\r\n </td>\r\n <td>\r\n <!-- If there's a start, then we must edit the type -->\r\n <display-type :type=\"n.getInputType(key)\" :readonly=\"!n.isInputTemplateType(key)\" @edited=\"onEditInputType(key, $event)\"></display-type>\r\n </td>\r\n <td>\r\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>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Outputs -->\r\n <div v-if=\"n.hasOutputs()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Outputs <small><span class=\"badge badge-secondary\">{{n.getOutputsNames().length}}</span></small></h5>\r\n </div>\r\n <div id=\"dualbox-node-outputs-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-outputs\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <table class=\"table-desc table-striped\">\r\n <thead class=\"thead-dark\">\r\n <th>Output</th>\r\n <th>Type</th>\r\n <th>Visible</th>\r\n </thead>\r\n <tbody>\r\n <tr v-for=\"key in n.getOutputsNames()\" :key=\"'output-'+key\">\r\n <td>{{key}}\r\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>\r\n </td>\r\n <td><display-type :type=\"n.getOutputType(key)\" @edited=\"onEditOutputType(key, $event)\"></display-type></td>\r\n <td>\r\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\">\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Attributes -->\r\n <div v-if=\"n.hasAttributes()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Attributes <small><span class=\"badge badge-secondary\">{{n.getAttributesNames().length}}</span></small></h5>\r\n </div>\r\n <div id=\"dualbox-node-attrs-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-attrs\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <table class=\"table-desc table-striped\">\r\n <thead class=\"thead-dark\">\r\n <th>Output</th>\r\n <th>Type</th>\r\n <th>Value</th>\r\n </thead>\r\n <tbody>\r\n <tr v-for=\"key in n.getAttributesNames()\" :key=\"'attr-'+key\">\r\n <td>{{key}}\r\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>\r\n </td>\r\n <td>\r\n <!-- If there's a start, then we must edit the type -->\r\n <display-type :type=\"n.getAttributeType(key)\" :readonly=\"!n.isAttributeTemplateType(key)\" @edited=\"onEditAttributeType(key, $event)\"></display-type>\r\n </td>\r\n <td>\r\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>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <!-- Loops -->\r\n <div v-if=\"n.hasInputs()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Loops <small><span class=\"badge badge-secondary\">{{ n.hasLoop() ? \"on\" : \"off\" }}</span></small></h5>\r\n </div>\r\n <div id=\"dualbox-node-loops-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-inputs\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\r\n <h4>Iterators\r\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>\r\n </h4>\r\n <table class=\"table-desc table-striped\">\r\n <tbody>\r\n <tr v-for=\"key in n.getInputsNames()\" :key=\"'loop-iterator-'+key\">\r\n <td>{{key}}</td>\r\n <td>\r\n <input class=\"input-iterator-toggle\" type=\"checkbox\" :data-input=\"key\" :checked=\"n.hasIterator(key)\" @change=\"toggleIterator\" />\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <h4 class=\"mt-2\">Feedback\r\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>\r\n </h4>\r\n <table class=\"table-desc table-striped\">\r\n <tbody>\r\n <tr v-for=\"key in n.getOutputsNames()\" :key=\"'loop-feedback-'+key\">\r\n <td>{{key}}</td>\r\n <td>\r\n <select class=\"form-control form-control-sm select-output-feedback\" :data-output=\"key\" @change=\"selectOutputFeedback\">\r\n <option value=\"none\">No feedback</option>\r\n <option v-for=\"i in n.getInputsNames()\" :value=\"i\" :selected=\"n.getFeedback(key) == i\" :key=\"'loop-feedback-input-'+i\">{{i}}</option>\r\n </select>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Events -->\r\n <div v-if=\"n.isUI()\" class=\"card card-settings\">\r\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\">\r\n <h5 class=\"mb-0 btn-link\">Events <small><span class=\"badge badge-secondary\">{{n.getOutboundEvents().length}}</span></small></h5>\r\n </div>\r\n <div id=\"dualbox-node-events-collapse\" class=\"collapse\" aria-labelledby=\"dualbox-node-events\" data-parent=\"#edit-node-panel\">\r\n <div class=\"card-body\">\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>Action</th>\r\n </thead>\r\n <tbody>\r\n <template v-if=\"n.hasOutEvents()\" v-for=\"(evt, index) in n.getOutboundEvents()\" :data-index=\"index\">\r\n <tr class=\"event-rooting\">\r\n <td>\r\n <select v-if=\"evt.node\" class=\"form-control form-control-sm select-event-target\" :data-index=\"index\"@change=\"selectEventTarget\" >\r\n <option v-for=\"node in getUINodesWithEvents()\" :value=\"node.getGraphId()\" :selected=\"node.getGraphId()==evt.node\" :key=\"node.id\">{{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\" :data-index=\"index\" @change=\"selectEventName\">\r\n <template v-if=\"evt.node\">\r\n <option v-for=\"targetEvent in getTargetNodeEvents(evt.node)\" :value=\"targetEvent\" :selected=\"evt.event===targetEvent\" :key=\"targetEvent\">{{targetEvent}}</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>\r\n <button class=\"btn btn-secondary btn-editor-xs\" :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 btn-remove-event\" :data-index=\"index\" @click=\"removeEvent\">\r\n <i class=\"fa fa-minus\"></i>\r\n </button>\r\n </td>\r\n </tr>\r\n <tr v-if=\"evt.if || expanded[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-index=\"index\" :value=\"evt.if\" @change=\"setEventIf\" />\r\n </td>\r\n </tr>\r\n <tr v-if=\"evt.data || evt.datatype || expanded[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)\" @edited=\"onEditEventData(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\" :data-id=\"n.id\" style=\"width: 100%;\" @click=\"addEvent\">Add event</button>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport _ from 'lodash-es';\r\nimport DisplayTypeVue from './displayType.vue';\r\nimport DisplayValueVue from './displayValue.vue';\r\nimport GraphNodeVue from './graphNode.vue';\r\nimport swal from 'sweetalert2';\r\n\r\nexport default {\r\n props: [\r\n \"id\", // the GraphNode object\r\n ],\r\n components: {\r\n \"display-type\" : DisplayTypeVue,\r\n \"display-value\" : DisplayValueVue,\r\n \"graph-node\" : GraphNodeVue\r\n },\r\n data: function () {\r\n return {\r\n comment: null,\r\n expanded: {}, // expanded app events (advanced settings)\r\n\r\n // states\r\n isParallel: false,\r\n nowEditingComment: false,\r\n nowEditingNodeName: false,\r\n nowEditingDescription: false,\r\n };\r\n },\r\n created: function() {\r\n this.view = window.dualboxEditor.v;\r\n this.n = this.view.m.getNode(this.id);\r\n\r\n // fetch the comment for this node\r\n this.comment = this.n.hasComment() ? this.n.getComment() : \"\";\r\n this.isParallel = this.n.isParallel();\r\n },\r\n mounted: function() {\r\n // adapt the style of the example graph node\r\n // remove the \"position: absolute;\" that messes up the display\r\n this.fixCardStyle();\r\n this.fixMaxHeightForCategories();\r\n\r\n // allow tooltips\r\n this.activateTooltip();\r\n },\r\n beforeUpdate: function() {\r\n //console.log('[Updating] node-settings');\r\n // we need to refresh our node object\r\n this.n = this.view.m.getNode(this.id); // it breaks updating node name\r\n this.deactivateTooltip();\r\n },\r\n updated: function() {\r\n //console.log('[Updated] node-settings');\r\n this.fixCardStyle();\r\n this.fixMaxHeightForCategories();\r\n this.activateTooltip();\r\n this.focus();\r\n },\r\n activate: function() {\r\n this.activateTooltip();\r\n this.focus();\r\n },\r\n deactivate: function() {\r\n this.deactivateTooltip();\r\n },\r\n methods: {\r\n fixCardStyle: function() {\r\n var card = $(this.$el).find('.module-left-signature .card');\r\n card.css('position', 'static').css('point-events', 'none');\r\n card.find('.point').css(\"visibibility\", \"visible\").find('svg').css(\"visibibility\", \"visible\");\r\n card.ready(() => {\r\n var width = Math.max(\r\n card.find('.inputs').width() + card.find('.outputs').width() + 20,\r\n card.find('.title').width() + 60,\r\n card.find('.subtitle').width() + 40\r\n );\r\n card.css('width', width + 'px');\r\n card.addClass('mx-auto');\r\n });\r\n },\r\n\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-settings').length;\r\n let headerHeight = $(this.$el).find('.edit-body > .card-settings > .card-header').outerHeight();\r\n let panelHeight = $(this.$el).height() - $(this.$el).find('.edit-node-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-settings > .collapse > .card-body').css('max-height', maxCategoryHeight + \"px\");\r\n },\r\n\r\n activateTooltip: function() {\r\n $(this.$el).find('[data-toggle=\"tooltip\"]').tooltip();\r\n },\r\n\r\n deactivateTooltip: function() {\r\n $(this.$el).find('[data-toggle=\"tooltip\"]').tooltip(\"dispose\");\r\n },\r\n\r\n focus: function() {\r\n $(this.$el).find('[autofocus]').focus();\r\n },\r\n\r\n // for widget registration\r\n getSpecialUINodes: function() {\r\n var targets = this.n.m.getSpecialUINodes( this.n.getRegisterType() );\r\n return targets;\r\n },\r\n\r\n getUINodesWithEvents : function() {\r\n var nodes = this.n.m.getNodes(\"ui\");\r\n var eventNodes = nodes.filter( function(n) {\r\n return n.getEventsNames().length > 0;\r\n });\r\n return eventNodes;\r\n },\r\n\r\n getTargetNodeEvents: function(nodeId) {\r\n var targetNode = this.n.m.getNode(nodeId);\r\n return targetNode.getEventsNames();\r\n },\r\n\r\n editComment: function(e) {\r\n this.nowEditingComment = true;\r\n },\r\n\r\n saveComment: function(e) {\r\n var val = $(this.$el).find('.node-comment').val();\r\n this.view.c.setComment(this.n.id, val);\r\n this.nowEditingComment = false;\r\n this.onEdited();\r\n },\r\n\r\n deleteComment: function(e) {\r\n this.view.c.deleteComment(this.n.id);\r\n this.nowEditingComment = false;\r\n this.onEdited();\r\n },\r\n\r\n addEvent: function(e) {\r\n this.view.c.addEvent(this.n.id);\r\n this.onEdited();\r\n },\r\n\r\n toggleInputVisibility: function(e) {\r\n var inputName = $(e.target).data('input');\r\n var visible = $(e.target).is(\":checked\");\r\n if( !this.view.c.setInputVisibility(this.n.id, inputName, visible) ) {\r\n // failed, reset this to old value\r\n $(e.target).prop('checked', !visible);\r\n }\r\n },\r\n\r\n toggleOutputVisibility: function(e) {\r\n var outputName = $(e.target).data('output');\r\n var visible = $(e.target).is(\":checked\");\r\n if( !this.view.c.setOutputVisibility(this.n.id, outputName, visible) ) {\r\n // failed, reset this to old value\r\n $(e.target).prop('checked', !visible);\r\n }\r\n },\r\n\r\n editNodeName: function(e) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n this.nowEditingNodeName = true;\r\n },\r\n\r\n changeNodeName: function(e) {\r\n // user pressed enter\r\n if(e.which == 13 || e.keyCode == 13) {\r\n this.saveNodeName(e);\r\n }\r\n },\r\n\r\n saveNodeName: function(e) {\r\n var newId = $(e.target).parent().find('.dualbox-node-name-input').val();\r\n this.view.c.renameBox(this.n.graphId, newId, this.n.type);\r\n\r\n // get the new node\r\n switch( this.n.type ) {\r\n case \"input\": this.n = this.view.m.getNode(\"in-\"+newId); break;\r\n case \"output\": this.n = this.view.m.getNode(\"in-\"+newId); break;\r\n default: this.n = this.view.m.getNode(newId);\r\n }\r\n\r\n this.nowEditingNodeName = false;\r\n },\r\n\r\n toggleIterator: function(e) {\r\n var destInput = $(e.target).attr('data-input');\r\n if( $(e.target).is(\":checked\") ) {\r\n this.view.c.setIterator( this.n.id, destInput );\r\n }\r\n else {\r\n this.view.c.unsetIterator( this.n.id, destInput );\r\n }\r\n this.onEdited();\r\n },\r\n\r\n registerToWidget: function(e) {\r\n var targetId = $(e.target).val();\r\n this.view.c.registerWidget(this.n.id, targetId);\r\n },\r\n\r\n selectOutputFeedback: function(e) {\r\n var val = $(e.target).val();\r\n var destOutput = $(e.target).attr('data-output');\r\n if( val !== \"none\" ) {\r\n this.view.c.setFeedback( this.n.id, destOutput, val );\r\n }\r\n else {\r\n this.view.c.unsetFeedback( this.n.id, destOutput );\r\n }\r\n },\r\n\r\n removeEvent: function(e) {\r\n var index = parseInt($(e.target).attr('data-index'));\r\n this.view.c.removeEvent( this.n.id, index );\r\n this.$forceUpdate();\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( this.n.id, index, val );\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( this.n.id, index, val );\r\n },\r\n\r\n // TODO: remake this into it's own vue\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\r\n var index = parseInt($(e.target).attr('data-index'));\r\n this.view.c.setEventTarget( this.n.id, 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( this.n.id, index, val );\r\n this.onEdited();\r\n },\r\n\r\n toggleCache: function(e) {\r\n var val = $(e.target).is(':checked');\r\n this.view.c.setBoxCache( this.n.id, val );\r\n },\r\n\r\n toggleWorker: function(e) {\r\n var val = $(e.target).is(':checked');\r\n this.view.c.setBoxParallel( this.n.id, val );\r\n this.isParallel = val;\r\n this.onEdited();\r\n },\r\n\r\n editModuleDescription: function(e) {\r\n var desc = $(e.target).attr('data-desc');\r\n\r\n swal({\r\n title: \"Describe what this metabox does\",\r\n input: \"textarea\",\r\n inputValue: desc || \"\",\r\n showCancelButton: true,\r\n closeOnConfirm: false,\r\n showLoaderOnConfirm: true,\r\n animation: \"slide-from-top\",\r\n inputPlaceholder: \"This metabox...\"\r\n }).then( (result) => {\r\n if (result.value === \"\") {\r\n swal.showInputError(\"You need to write something!\");\r\n return false;\r\n }\r\n else {\r\n this.view.c.setMetanodeDescription(this.n.id, result.value);\r\n }\r\n });\r\n },\r\n\r\n createExampleNode(n) {\r\n return this.view.m.createCloneNode(n.getPackage().name, n.id)\r\n },\r\n\r\n onEditInputType(inputName, typeStr) {\r\n this.n.assignInputType(inputName, typeStr);\r\n this.onEdited();\r\n this.view.repaint();\r\n },\r\n\r\n onEditOutputType(outputName, typeStr) {\r\n this.n.assignOutputType(outputName, typeStr);\r\n this.onEdited();\r\n this.view.repaint();\r\n },\r\n\r\n onEditAttributeType(attributeName, typeStr) {\r\n this.n.assignAttributeType(attributeName, typeStr);\r\n this.onEdited();\r\n this.view.repaint();\r\n },\r\n\r\n onEditDefaultValue(val) {\r\n this.n.setDefaultValue(val);\r\n this.onEdited();\r\n this.view.repaint();\r\n },\r\n\r\n onEditInputDefaultValue(inputName, val) {\r\n if( val === undefined ) {\r\n this.n.deleteVal(\"input\", inputName);\r\n this.n.setInputVisibility(inputName, true); // show the input then (connection needed)\r\n }\r\n else {\r\n this.n.val(\"input\", inputName, val );\r\n this.n.setInputVisibility(inputName, false); // hide inputs with values (no connection needed)\r\n }\r\n this.onEdited();\r\n this.view.repaint();\r\n },\r\n\r\n onEditAttribute(attrName, val) {\r\n if( val === undefined ) {\r\n this.n.deleteVal(\"attr\", attrName);\r\n }\r\n else {\r\n this.n.val(\"attr\", attrName, val);\r\n }\r\n this.onEdited();\r\n },\r\n\r\n onEditDefaultInput(inputName, val) {\r\n if( val === undefined ) {\r\n this.n.deleteVal(\"input\", inputName);\r\n }\r\n else {\r\n this.n.val(\"input\", inputName, val);\r\n }\r\n this.onEdited();\r\n this.view.repaint();\r\n },\r\n\r\n onEdited() {\r\n // we need to refresh our node object\r\n this.n = this.view.m.getNode(this.id); // it breaks updating node name\r\n this.$forceUpdate();\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 index = $(e.target).data('index');\r\n this.expanded[index] = this.expanded[index] ? false : true;\r\n this.$forceUpdate();\r\n },\r\n\r\n onEditEventData(key, index, val) {\r\n this.view.c.setEventData( this.n.id, index, val );\r\n this.$forceUpdate();\r\n },\r\n\r\n onEditEventInDataType(key, index, type) {\r\n this.view.c.setEventDataType( this.n.id, 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.n.getOutboundEvents()[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( this.n.id, index, undefined);\r\n }\r\n }\r\n catch(e) {\r\n this.view.c.setEventData( this.n.id, index, undefined);\r\n }\r\n\r\n this.$forceUpdate();\r\n },\r\n\r\n getDescription() {\r\n return this.n.getDescription() || \"[Add a description]\"\r\n },\r\n\r\n editDescription() {\r\n this.nowEditingDescription = true;\r\n },\r\n\r\n setDescription() {\r\n var val = $(this.$el).find('.edit-node-description').val();\r\n if( this.n.isInput() ) {\r\n this.view.c.setInputDescription(this.n.graphId, val);\r\n }\r\n else if( this.n.isOutput() ) {\r\n this.view.c.setOutputDescription(this.n.graphId, val);\r\n }\r\n else if( this.n.isMetanode() ) {\r\n this.view.c.setMetanodeDescription(this.n.graphId, val);\r\n }\r\n this.nowEditingDescription = false;\r\n\r\n this.$forceUpdate();\r\n },\r\n }\r\n}\r\n\r\n\r\n</script>\r\n"]}, media: undefined });
|
|
69688
69497
|
|
|
69689
69498
|
};
|
|
69690
69499
|
/* scoped */
|
|
@@ -89723,8 +89532,12 @@ class GraphController {
|
|
|
89723
89532
|
}
|
|
89724
89533
|
|
|
89725
89534
|
createId(name) {
|
|
89726
|
-
|
|
89727
|
-
|
|
89535
|
+
if (name) {
|
|
89536
|
+
var shortName = utils.shortName(name);
|
|
89537
|
+
return shortName + '-' + utils.randomString(8);
|
|
89538
|
+
} else {
|
|
89539
|
+
return utils.randomString(8);
|
|
89540
|
+
}
|
|
89728
89541
|
}
|
|
89729
89542
|
|
|
89730
89543
|
registerNodeToInterface(id) {
|
|
@@ -89854,10 +89667,11 @@ class GraphController {
|
|
|
89854
89667
|
var node = this.m.getNode(id);
|
|
89855
89668
|
var type = node.type;
|
|
89856
89669
|
var def = lodash.cloneDeep(node.getDef());
|
|
89857
|
-
var newId = this.createId(def.module);
|
|
89670
|
+
var newId = this.createId(def.module || def.type);
|
|
89858
89671
|
|
|
89859
89672
|
// remove links, change position a little bit
|
|
89860
89673
|
delete def.links;
|
|
89674
|
+
delete def.link;
|
|
89861
89675
|
var leftPosition = idx_1(def, o => o.graph.position.left);
|
|
89862
89676
|
if (leftPosition) {
|
|
89863
89677
|
def.graph.position.left = (parseInt(leftPosition) + 200).toString();
|