caixanegra 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/caixanegra/api.js +16 -0
- data/app/assets/javascripts/caixanegra/designer.js +131 -3
- data/app/assets/stylesheets/caixanegra/designer.scss +152 -2
- data/app/controllers/caixanegra/api/designer/inputs_controller.rb +32 -0
- data/app/views/caixanegra/designer/index.html.erb +21 -0
- data/config/routes.rb +3 -0
- data/lib/caixanegra/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 182cc119673359db756adcca903e137025ed5283bdae367d7d6c662fc5fdc061
|
4
|
+
data.tar.gz: f075d702d2f361678a7775d286cb7f3b9ec1cb556778b22c4180588efe32d830
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29c0edd8fab4949cab99f6d513b987cda6c87b2fb29fbeb33e447616ff580c0a9fbd3413a2fe4281828f28a8ac1123942fcecbdbeedf7511c64cb000384bd797
|
7
|
+
data.tar.gz: 23e9e398d71b3900759d8a944f20ddf1920ac1f38bb5961d3e36a34d112e36a488301d3c4709de8c9cfc48a8a9f995869ebfea90ed20acf72915b6c61ac48345
|
@@ -66,4 +66,20 @@ window.Caixanegra.API = class {
|
|
66
66
|
request.send(JSON.stringify(initialCarryOver));
|
67
67
|
});
|
68
68
|
}
|
69
|
+
|
70
|
+
evaluateRegex(expression, sample) {
|
71
|
+
return new Promise((resolve, reject) => {
|
72
|
+
const request = new XMLHttpRequest();
|
73
|
+
|
74
|
+
request.addEventListener("load", (event) => {
|
75
|
+
resolve(JSON.parse(event.target.response));
|
76
|
+
});
|
77
|
+
request.addEventListener("error", () => {
|
78
|
+
reject();
|
79
|
+
});
|
80
|
+
|
81
|
+
request.open("GET", `${this.mountedPath()}/api/designer/inputs/evaluate_regex?expression=${encodeURIComponent(expression)}&sample=${encodeURIComponent(sample)}`);
|
82
|
+
request.send();
|
83
|
+
});
|
84
|
+
}
|
69
85
|
}
|
@@ -307,6 +307,11 @@ window.Caixanegra.Designer = {
|
|
307
307
|
document.querySelector("#importFlow").addEventListener("click", this.#importFlow.bind(this));
|
308
308
|
document.querySelector("#exportFlow").addEventListener("click", this.#exportFlow.bind(this));
|
309
309
|
document.querySelector("#importFlowFile").addEventListener("change", this.#importFlowFileChanged.bind(this));
|
310
|
+
document.querySelector("#regexInput").addEventListener("keyup", this.#updateRegexInput.bind(this));
|
311
|
+
document.querySelector("#regexSample").addEventListener("keyup", this.#startRegexEvaluation.bind(this));
|
312
|
+
document.querySelector("#addRegexVariables").addEventListener("click", this.#addRegexVariablesRow.bind(this))
|
313
|
+
document.querySelector("#regexEditorToggleVars").addEventListener("click", this.#toggleRegexVariables.bind(this));
|
314
|
+
document.querySelector("#dismissRegexEditor").addEventListener("click", this.#dismissRegexEditor.bind(this));
|
310
315
|
this.toggleBlocker(true, "loading your flow");
|
311
316
|
window.addEventListener("resize", this.#windowResized.bind(drawingSurface));
|
312
317
|
drawingSurface.addEventListener("update_start", this.#engineUpdate.bind(this));
|
@@ -319,7 +324,6 @@ window.Caixanegra.Designer = {
|
|
319
324
|
|
320
325
|
this.gre.disable();
|
321
326
|
this.getUnits();
|
322
|
-
this.loadFlow();
|
323
327
|
this.gre.enable();
|
324
328
|
}
|
325
329
|
|
@@ -600,7 +604,7 @@ window.Caixanegra.Designer = {
|
|
600
604
|
});
|
601
605
|
|
602
606
|
this.#loadedComponents.catalog = true;
|
603
|
-
this.
|
607
|
+
this.loadFlow();
|
604
608
|
});
|
605
609
|
}
|
606
610
|
|
@@ -620,6 +624,10 @@ window.Caixanegra.Designer = {
|
|
620
624
|
this.#units = [];
|
621
625
|
|
622
626
|
(flowData?.units || []).forEach((unit) => {
|
627
|
+
const catalogUnit = this.#catalog.find((cUnit) => cUnit.class === unit.class);
|
628
|
+
if (catalogUnit) {
|
629
|
+
unit.color = catalogUnit.color;
|
630
|
+
}
|
623
631
|
this.createUnit(unit);
|
624
632
|
});
|
625
633
|
|
@@ -1278,9 +1286,10 @@ window.Caixanegra.Designer = {
|
|
1278
1286
|
case "regex":
|
1279
1287
|
{
|
1280
1288
|
valueInput = document.createElement("input");
|
1281
|
-
if(matrix.type === "regex") { valueInput.classList.add("-
|
1289
|
+
if(matrix.type === "regex") { valueInput.classList.add("-regex")}
|
1282
1290
|
valueInput.value = unit.mappings[input]?.value || matrix.default || "";
|
1283
1291
|
valueInput.addEventListener("change", this.#unitInputValueChanged.bind(this));
|
1292
|
+
valueInput.addEventListener("click", this.#regexEditor.bind(this));
|
1284
1293
|
}
|
1285
1294
|
break;
|
1286
1295
|
case "dataset":
|
@@ -1380,6 +1389,125 @@ window.Caixanegra.Designer = {
|
|
1380
1389
|
this.selectedUnit.mappings[input].value = ev.target.value;
|
1381
1390
|
}
|
1382
1391
|
|
1392
|
+
#toggleRegexVariables() {
|
1393
|
+
const target = document.querySelector("#blocker .regexEditor > div:last-child");
|
1394
|
+
if(target.classList.contains("-visible")) {
|
1395
|
+
target.classList.remove("-visible");
|
1396
|
+
} else {
|
1397
|
+
target.classList.add("-visible");
|
1398
|
+
}
|
1399
|
+
}
|
1400
|
+
|
1401
|
+
#updateRegexInput() {
|
1402
|
+
this.blocker.editorListener.value = this.blocker.querySelector("#regexInput").value;
|
1403
|
+
|
1404
|
+
this.#startRegexEvaluation();
|
1405
|
+
}
|
1406
|
+
|
1407
|
+
#startRegexEvaluation() {
|
1408
|
+
window.clearTimeout(this.blocker.evalTimeout);
|
1409
|
+
this.blocker.querySelector("#regexResults").innerHTML = "wating input end...";
|
1410
|
+
this.blocker.evalTimeout = window.setTimeout(this.#evaluateRegex.bind(this), 1500);
|
1411
|
+
}
|
1412
|
+
|
1413
|
+
#evaluateRegex() {
|
1414
|
+
this.blocker.querySelector("#regexResults").innerHTML = "evaluating...";
|
1415
|
+
let expression = this.blocker.querySelector("#regexInput").value;
|
1416
|
+
const sample = this.blocker.querySelector("#regexSample").value;
|
1417
|
+
document.querySelectorAll("#regexVariablesList .regex-variable-entry").forEach((pair) => {
|
1418
|
+
const placeholder = pair.querySelector("input.placeholder").value;
|
1419
|
+
const value = pair.querySelector("input.value").value;
|
1420
|
+
expression = expression.replace(new RegExp(placeholder, "g"), value);
|
1421
|
+
});
|
1422
|
+
|
1423
|
+
this.api.evaluateRegex(expression, sample).then((response) => {
|
1424
|
+
const tableEntries = Object.keys(response).length - 2 > 0;
|
1425
|
+
|
1426
|
+
this.blocker.querySelector("#regexResults").innerHTML = "";
|
1427
|
+
const expression = document.createElement("div");
|
1428
|
+
const full_match = document.createElement("div");
|
1429
|
+
expression.innerHTML = `<strong>Expression: </strong><code>${response["_expression"] || "unable to get expression"}</code>`;
|
1430
|
+
full_match.innerHTML = `<strong>Full Match: </strong><code>${response["_full"] || "unable to get full match"}</code>`;
|
1431
|
+
|
1432
|
+
this.blocker.querySelector("#regexResults").append(expression, full_match);
|
1433
|
+
|
1434
|
+
if (tableEntries) {
|
1435
|
+
const table = document.createElement("table");
|
1436
|
+
let tr = document.createElement("tr");
|
1437
|
+
let th = document.createElement("th");
|
1438
|
+
th.innerHTML = "capture";
|
1439
|
+
tr.append(th);
|
1440
|
+
th = document.createElement("th");
|
1441
|
+
th.innerHTML = "match";
|
1442
|
+
tr.append(th);
|
1443
|
+
table.append(tr);
|
1444
|
+
|
1445
|
+
for (const key of Object.keys(response)) {
|
1446
|
+
if (key.startsWith("_")) { continue; }
|
1447
|
+
|
1448
|
+
tr = document.createElement("tr");
|
1449
|
+
let td = document.createElement("td");
|
1450
|
+
td.innerHTML = key;
|
1451
|
+
tr.append(td);
|
1452
|
+
td = document.createElement("td");
|
1453
|
+
td.innerHTML = response[key];
|
1454
|
+
tr.append(td);
|
1455
|
+
|
1456
|
+
table.append(tr);
|
1457
|
+
}
|
1458
|
+
|
1459
|
+
this.blocker.querySelector("#regexResults").append(table);
|
1460
|
+
}
|
1461
|
+
}).catch((error) => {
|
1462
|
+
this.blocker.querySelector("#regexResults").innerHTML = "unable to evaluate";
|
1463
|
+
});
|
1464
|
+
}
|
1465
|
+
|
1466
|
+
#regexEditor(ev) {
|
1467
|
+
this.blocker.classList.add("-in-regex-editor");
|
1468
|
+
this.blocker.classList.remove("-released");
|
1469
|
+
this.blocker.editorListener = ev.target;
|
1470
|
+
this.blocker.querySelector("#regexInput").value = ev.target.value;
|
1471
|
+
|
1472
|
+
this.#startRegexEvaluation();
|
1473
|
+
}
|
1474
|
+
|
1475
|
+
#dismissRegexEditor() {
|
1476
|
+
this.blocker.classList.remove("-in-regex-editor");
|
1477
|
+
this.blocker.classList.add("-released");
|
1478
|
+
}
|
1479
|
+
|
1480
|
+
#removeRegexVariable() {
|
1481
|
+
this.parentElement.remove();
|
1482
|
+
}
|
1483
|
+
|
1484
|
+
#addRegexVariablesRow() {
|
1485
|
+
const list = document.querySelector("#regexVariablesList");
|
1486
|
+
|
1487
|
+
const wrapper = document.createElement("div");
|
1488
|
+
const name = document.createElement("input");
|
1489
|
+
const value = document.createElement("input");
|
1490
|
+
const remove = document.createElement("button");
|
1491
|
+
|
1492
|
+
name.placeholder = "placeholder";
|
1493
|
+
name.classList.add("placeholder");
|
1494
|
+
value.classList.add("value");
|
1495
|
+
name.autocomplete=false;
|
1496
|
+
value.autocomplete=false;
|
1497
|
+
value.placeholder = "value";
|
1498
|
+
remove.innerHTML = "-";
|
1499
|
+
|
1500
|
+
remove.addEventListener("click", this.#removeRegexVariable.bind(remove));
|
1501
|
+
|
1502
|
+
name.addEventListener("keyup", this.#startRegexEvaluation.bind(this));
|
1503
|
+
value.addEventListener("keyup", this.#startRegexEvaluation.bind(this));
|
1504
|
+
|
1505
|
+
wrapper.classList.add("regex-variable-entry");
|
1506
|
+
|
1507
|
+
wrapper.append(name, value, remove);
|
1508
|
+
list.append(wrapper);
|
1509
|
+
}
|
1510
|
+
|
1383
1511
|
#addUnitExitMapping(ev) {
|
1384
1512
|
const unit = this.selectedUnit;
|
1385
1513
|
const mapping = { use: "", as: "" };
|
@@ -538,6 +538,7 @@ $accent-contrast-color: darken($accent-color, 20%);
|
|
538
538
|
}
|
539
539
|
|
540
540
|
input {
|
541
|
+
position: relative;
|
541
542
|
width: 100%;
|
542
543
|
box-sizing: border-box;
|
543
544
|
background-color: $accent-highlight-color;
|
@@ -545,7 +546,7 @@ $accent-contrast-color: darken($accent-color, 20%);
|
|
545
546
|
border: none;
|
546
547
|
outline: none;
|
547
548
|
|
548
|
-
&.-
|
549
|
+
&.-regex {
|
549
550
|
font-family: monospace;
|
550
551
|
}
|
551
552
|
}
|
@@ -790,7 +791,7 @@ $accent-contrast-color: darken($accent-color, 20%);
|
|
790
791
|
left:0;
|
791
792
|
right:0;
|
792
793
|
bottom:0;
|
793
|
-
background-color:
|
794
|
+
background-color: rgba(0,0,0, .5);
|
794
795
|
transition: opacity 250ms ease-in-out;
|
795
796
|
opacity: 1;
|
796
797
|
|
@@ -817,6 +818,155 @@ $accent-contrast-color: darken($accent-color, 20%);
|
|
817
818
|
}
|
818
819
|
}
|
819
820
|
|
821
|
+
.regexEditor {
|
822
|
+
position: absolute;
|
823
|
+
top: 50%;
|
824
|
+
left: 50%;
|
825
|
+
transform: translate(-50%, -50%);
|
826
|
+
display: none;
|
827
|
+
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
828
|
+
min-width: 70%;
|
829
|
+
flex-direction: row;
|
830
|
+
align-items: center;
|
831
|
+
justify-content: center;
|
832
|
+
|
833
|
+
& > div {
|
834
|
+
background-color: $accent-color;
|
835
|
+
box-shadow: $accent-shadow;
|
836
|
+
border-radius: 5px;
|
837
|
+
display: flex;
|
838
|
+
flex-direction: column;
|
839
|
+
padding: 12px;
|
840
|
+
position: relative;
|
841
|
+
font-size: 16px;
|
842
|
+
|
843
|
+
&:first-child {
|
844
|
+
margin-right: 15px;
|
845
|
+
width: 70%;
|
846
|
+
z-index: 10;
|
847
|
+
font-size: 0.8em;
|
848
|
+
}
|
849
|
+
|
850
|
+
&:last-child {
|
851
|
+
font-size: 0.8em;
|
852
|
+
transform: translateX(-200%);
|
853
|
+
width: 0;
|
854
|
+
box-shadow: 0 0 0 rgba(0,0,0,0);
|
855
|
+
z-index: 9;
|
856
|
+
overflow: hidden;
|
857
|
+
transition: all 250ms ease-in-out;
|
858
|
+
|
859
|
+
&.-visible {
|
860
|
+
transform: translateX(0%);
|
861
|
+
width: 30%;
|
862
|
+
}
|
863
|
+
}
|
864
|
+
}
|
865
|
+
|
866
|
+
label {
|
867
|
+
margin-bottom: 4px;
|
868
|
+
}
|
869
|
+
|
870
|
+
input {
|
871
|
+
margin-bottom: 6px;
|
872
|
+
box-sizing: border-box;
|
873
|
+
background-color: #9c9c9c;
|
874
|
+
padding: 6px 4px;
|
875
|
+
border: none;
|
876
|
+
outline: none;
|
877
|
+
}
|
878
|
+
|
879
|
+
#regexInput {
|
880
|
+
font-family: monospace;
|
881
|
+
font-size: 1.1em;
|
882
|
+
}
|
883
|
+
|
884
|
+
#regexSample {
|
885
|
+
font-size: 0.8em;
|
886
|
+
}
|
887
|
+
|
888
|
+
#regexResults {
|
889
|
+
padding: 8px;
|
890
|
+
background-color:rgb(200, 200, 200);
|
891
|
+
color: black;
|
892
|
+
max-height: 50vh;
|
893
|
+
overflow: auto;
|
894
|
+
display: block;
|
895
|
+
margin-bottom: 30px;
|
896
|
+
font-size: 0.7em;
|
897
|
+
|
898
|
+
table {
|
899
|
+
margin-top: 15px;
|
900
|
+
width: 100%;
|
901
|
+
border-collapse: collapse;
|
902
|
+
|
903
|
+
th, td {
|
904
|
+
text-align: left;
|
905
|
+
border: 1px solid rgba(0,0,0,.3);
|
906
|
+
padding: 4px;
|
907
|
+
}
|
908
|
+
|
909
|
+
tr:nth-child(even) {
|
910
|
+
background-color: rgba(0,0,0,.15);
|
911
|
+
}
|
912
|
+
}
|
913
|
+
}
|
914
|
+
|
915
|
+
#regexVariables {
|
916
|
+
#regexVariablesList {
|
917
|
+
margin-bottom: 15px;
|
918
|
+
}
|
919
|
+
|
920
|
+
.regex-variable-entry {
|
921
|
+
display: flex;
|
922
|
+
flex-direction: row;
|
923
|
+
margin: 2px 0;
|
924
|
+
align-items: center;
|
925
|
+
|
926
|
+
input {
|
927
|
+
width: 100%;
|
928
|
+
margin-bottom: 0;
|
929
|
+
|
930
|
+
&:first-child {
|
931
|
+
margin-right: 5px;
|
932
|
+
}
|
933
|
+
}
|
934
|
+
|
935
|
+
button {
|
936
|
+
margin-left: 5px;
|
937
|
+
}
|
938
|
+
}
|
939
|
+
}
|
940
|
+
|
941
|
+
button {
|
942
|
+
background-color: $accent-highlight-color;
|
943
|
+
border: 1px solid $accent-color;
|
944
|
+
color: black;
|
945
|
+
padding: 3px 6px;
|
946
|
+
cursor: pointer;
|
947
|
+
transition: all 250ms ease-in-out;
|
948
|
+
|
949
|
+
&:hover {
|
950
|
+
background-color: $accent-contrast-color;
|
951
|
+
color: $accent-highlight-color;
|
952
|
+
}
|
953
|
+
}
|
954
|
+
|
955
|
+
#regexEditorToggleVars {
|
956
|
+
float: right;
|
957
|
+
}
|
958
|
+
}
|
959
|
+
|
960
|
+
&.-in-regex-editor {
|
961
|
+
.information {
|
962
|
+
display: none;
|
963
|
+
}
|
964
|
+
|
965
|
+
.regexEditor {
|
966
|
+
display: flex;
|
967
|
+
}
|
968
|
+
}
|
969
|
+
|
820
970
|
&.-released {
|
821
971
|
pointer-events: none;
|
822
972
|
opacity: 0;
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Caixanegra
|
2
|
+
module API
|
3
|
+
module Designer
|
4
|
+
class InputsController < ::Caixanegra::APIController
|
5
|
+
def evaluate_regex
|
6
|
+
full_match = sample.match(Regexp.new(expression, Regexp::IGNORECASE))
|
7
|
+
direct = { "_full": full_match.to_s, "_expression": expression }
|
8
|
+
captures = {}
|
9
|
+
|
10
|
+
(full_match&.captures || []).each_with_index do |capture, index|
|
11
|
+
captures["c#{index}"] = capture
|
12
|
+
end
|
13
|
+
named_captures = full_match&.named_captures || {}
|
14
|
+
|
15
|
+
render json: direct.merge(captures).merge(named_captures).symbolize_keys
|
16
|
+
rescue RegexpError
|
17
|
+
head 422
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def expression
|
23
|
+
@expression ||= params[:expression]
|
24
|
+
end
|
25
|
+
|
26
|
+
def sample
|
27
|
+
@sample ||= params[:sample]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -108,6 +108,27 @@
|
|
108
108
|
<div>caixa<span>negra</span></div>
|
109
109
|
<div class="message">loading your flow</div>
|
110
110
|
</div>
|
111
|
+
<div class="regexEditor">
|
112
|
+
<div>
|
113
|
+
<label for="regexInput">Regular Expression</label>
|
114
|
+
<input id="regexInput" type="text" />
|
115
|
+
<label for="regexSample" placeholder="type sample text here">Sample</label>
|
116
|
+
<input id="regexSample" type="text" />
|
117
|
+
<label for="regexResults">Result</label>
|
118
|
+
<div id="regexResults"></div>
|
119
|
+
<div>
|
120
|
+
<button id="dismissRegexEditor">dismiss</button>
|
121
|
+
<button id="regexEditorToggleVars">vars</button>
|
122
|
+
</div>
|
123
|
+
</div>
|
124
|
+
<div>
|
125
|
+
<label for="regexVariables">Variables</label>
|
126
|
+
<div id="regexVariables">
|
127
|
+
<div id="regexVariablesList"></div>
|
128
|
+
<button id="addRegexVariables">add</button>
|
129
|
+
</div>
|
130
|
+
</div>
|
131
|
+
</div>
|
111
132
|
</div>
|
112
133
|
<div id="action_messenger">
|
113
134
|
<div class="icon icon-error">
|
data/config/routes.rb
CHANGED
data/lib/caixanegra/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: caixanegra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sergiorribeiro
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-10-
|
11
|
+
date: 2023-10-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -57,6 +57,7 @@ files:
|
|
57
57
|
- app/assets/stylesheets/caixanegra/application.css
|
58
58
|
- app/assets/stylesheets/caixanegra/designer.scss
|
59
59
|
- app/controllers/caixanegra/api/designer/flows_controller.rb
|
60
|
+
- app/controllers/caixanegra/api/designer/inputs_controller.rb
|
60
61
|
- app/controllers/caixanegra/api/designer/units_controller.rb
|
61
62
|
- app/controllers/caixanegra/api_controller.rb
|
62
63
|
- app/controllers/caixanegra/application_controller.rb
|