Skip to content

Commit 2decbed

Browse files
committed
Ability to update keywords
Signed-off-by: worksofliam <mrliamallan@live.co.uk>
1 parent 1e6fae7 commit 2decbed

File tree

2 files changed

+193
-58
lines changed

2 files changed

+193
-58
lines changed

webui/index.html

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818

1919
<div style="display: flex; height: 100vh;">
2020
<!-- Left Sidebar -->
21-
<div id="recordFormatSidebar" style="width: 20%; background-color: var(--vscode-sideBar-background);">
21+
<div style="width: 20%; background-color: var(--vscode-sideBar-background);">
22+
<div id="recordFormatSidebar">
23+
</div>
24+
<div id="keywordEditorArea">
25+
</div>
2226
</div>
2327

2428
<!-- Main Content -->
@@ -27,7 +31,9 @@
2731
</div>
2832

2933
<!-- Right Sidebar -->
30-
<div id="fieldInfoSidebar" style="width: 20%; background-color: var(--vscode-sideBar-background);">
34+
<div style="width: 20%; background-color: var(--vscode-sideBar-background);">
35+
<div id="fieldInfoSidebar">
36+
</div>
3137
</div>
3238
</div></div>
3339

webui/main.js

Lines changed: 185 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,8 @@ let lastActiveKonvaElement;
728728
* @param {FieldInfo} [fieldInfo]
729729
*/
730730
function setActiveField(konvaElement, fieldInfo) {
731+
clearKeywordEditor();
732+
731733
if (lastActiveKonvaElement) {
732734
const bg = lastActiveKonvaElement.findOne(`#bg`);
733735
// Remove background from last active element
@@ -984,44 +986,16 @@ function sendFieldUpdate(recordFormat, originalFieldName, newFieldInfo) {
984986
/**
985987
* Used to create panels for editable key/value lists.
986988
* @param {string} id
987-
* @param {Keyword[]} keywords
989+
* @param {Keyword[]} inputKeywords
988990
* @param {(keywords: Keyword[]) => void} [onUpdate]
989991
*/
990-
function createKeywordPanel(id, keywords, onUpdate) {
992+
function createKeywordPanel(id, inputKeywords, onUpdate) {
993+
/** @type {Keyword[]} */
994+
const keywords = JSON.parse(JSON.stringify(inputKeywords));
995+
991996
const section = document.createElement(`div`);
992997
section.id = id;
993998

994-
const createInputCell = (id, value, readonly) => {
995-
const cell = document.createElement(`vscode-table-cell`);
996-
997-
if (readonly) {
998-
cell.innerText = value;
999-
1000-
} else {
1001-
const input = document.createElement(`code`);
1002-
input.id = id;
1003-
input.innerText = value;
1004-
1005-
input.setAttribute(`contenteditable`, `true`);
1006-
1007-
cell.appendChild(input);
1008-
}
1009-
1010-
return cell;
1011-
};
1012-
1013-
const createDeleteButtonCell = (onClick) => {
1014-
const cell = document.createElement(`vscode-table-cell`);
1015-
1016-
const button = document.createElement(`vscode-icon`);
1017-
button.setAttribute(`name`, `trash`);
1018-
button.onclick = onClick;
1019-
1020-
cell.appendChild(button);
1021-
1022-
return cell;
1023-
};
1024-
1025999
const tree = document.createElement(`vscode-tree`);
10261000
tree.id = id;
10271001

@@ -1044,25 +1018,43 @@ function createKeywordPanel(id, keywords, onUpdate) {
10441018
open: 'folder-opened',
10451019
};
10461020

1047-
tree.data = keywords.map((keyword, index) => {
1048-
return {
1049-
icons,
1050-
label: keyword.name,
1051-
value: keyword,
1052-
description: keyword.value,
1053-
actions,
1054-
subItems: keyword.conditions.map(c => ({
1055-
label: String(c.indicator),
1056-
description: c.negate ? `Negated` : undefined,
1057-
icons
1058-
})),
1059-
};
1060-
});
1021+
const rerenderTree = () => {
1022+
tree.data = keywords.map((keyword, index) => {
1023+
return {
1024+
icons,
1025+
label: keyword.name,
1026+
value: keyword,
1027+
description: keyword.value,
1028+
actions,
1029+
subItems: keyword.conditions.map(c => ({
1030+
label: String(c.indicator),
1031+
description: c.negate ? `Negated` : undefined,
1032+
icons
1033+
})),
1034+
};
1035+
});
1036+
};
1037+
1038+
rerenderTree();
10611039

10621040
tree.addEventListener('vsc-run-action', (event) => {
10631041
console.log(event.detail);
10641042
// TODO: check event.action for `delete` and `edit`
10651043
// TODO: show UI here and update event.value with changes value
1044+
1045+
/** @type {Keyword} */
1046+
const currentKeyword = event.detail.value;
1047+
editKeyword(event.detail.value, (newKeyword) => {
1048+
const oldKeywordIndex = keywords.findIndex(k => k.name === currentKeyword.name && k.value === currentKeyword.value)
1049+
if (oldKeywordIndex >= 0) {
1050+
keywords[oldKeywordIndex] = newKeyword;
1051+
} else {
1052+
keywords.push(newKeyword);
1053+
}
1054+
1055+
clearKeywordEditor();
1056+
rerenderTree();
1057+
});
10661058
});
10671059

10681060
section.appendChild(tree);
@@ -1084,15 +1076,8 @@ function createKeywordPanel(id, keywords, onUpdate) {
10841076
updateButton.style.display = `block`;
10851077

10861078
updateButton.addEventListener(`click`, (e) => {
1087-
const rows = section.querySelectorAll(`[id^='${ROW_PREFIX}']`);
1088-
console.log(rows);
1089-
1090-
/** @type {Keyword[]} */
1091-
let newKeywords = [];
1092-
1093-
// Update newKeywors based on tree.data
1094-
1095-
onUpdate(newKeywords);
1079+
// As we update keywords, the `keywords` variable is updated
1080+
onUpdate(keywords);
10961081
});
10971082

10981083
section.appendChild(newKeyword);
@@ -1181,4 +1166,148 @@ function createValuesPanel(id, properties, onUpdate) {
11811166
}
11821167

11831168
return section;
1169+
}
1170+
1171+
function clearKeywordEditor() {
1172+
const keywordEditorArea = document.getElementById(`keywordEditorArea`);
1173+
keywordEditorArea.innerHTML = ``;
1174+
}
1175+
1176+
/**
1177+
* @param {Keyword} keyword
1178+
* @param {(keyword: Keyword) => void} onUpdate
1179+
*/
1180+
function editKeyword(keyword, onUpdate) {
1181+
const group = document.createElement(`vscode-form-group`);
1182+
group.id = `currentKeywordEditor`;
1183+
group.setAttribute(`variant`, `vertical`);
1184+
group.style.paddingLeft = `1em`;
1185+
group.style.paddingRight = `1em`;
1186+
1187+
const createLabel = (label, forId) => {
1188+
const labelElement = document.createElement(`vscode-label`);
1189+
labelElement.setAttribute(`for`, forId);
1190+
labelElement.innerText = label;
1191+
labelElement.style.marginTop = `0.5em`;
1192+
return labelElement;
1193+
};
1194+
1195+
const createInputField = (id, value) => {
1196+
const input = document.createElement(`vscode-textfield`);
1197+
input.setAttribute(`id`, id);
1198+
input.setAttribute(`value`, value);
1199+
return input;
1200+
};
1201+
1202+
const createIndicatorSelect = (id, defaultValue) => {
1203+
const select = document.createElement(`vscode-single-select`);
1204+
select.setAttribute(`id`, id);
1205+
1206+
const options = [`None`];
1207+
1208+
for (let i = 1; i <= 99; i++) {
1209+
options.push(i);
1210+
}
1211+
1212+
options.forEach(option => {
1213+
const optionElement = document.createElement(`vscode-option`);
1214+
optionElement.setAttribute(`value`, option);
1215+
optionElement.innerText = option;
1216+
1217+
if (option === defaultValue) {
1218+
optionElement.setAttribute(`selected`, `true`);
1219+
}
1220+
1221+
select.appendChild(optionElement);
1222+
});
1223+
1224+
return select;
1225+
};
1226+
1227+
const createCheckbox = (id, label, checked) => {
1228+
const checkbox = document.createElement(`vscode-checkbox`);
1229+
checkbox.setAttribute(`id`, id);
1230+
checkbox.setAttribute(`label`, label);
1231+
if (checked) {
1232+
checkbox.setAttribute(`checked`, checked);
1233+
}
1234+
return checkbox;
1235+
};
1236+
1237+
group.appendChild(createLabel(`Keyword`, `keyword`));
1238+
group.appendChild(createInputField(`keyword`, keyword.name));
1239+
1240+
group.appendChild(createLabel(`Value`, `value`));
1241+
group.appendChild(createInputField(`value`, keyword.value || ``));
1242+
1243+
group.appendChild(createLabel(`Indicator 1`, `ind1`));
1244+
group.appendChild(createIndicatorSelect(`ind1`, keyword.conditions[0]?.indicator));
1245+
1246+
group.appendChild(createCheckbox(`neg1`, `Negate`, keyword.conditions[0]?.negate));
1247+
1248+
group.appendChild(createLabel(`Indicator 2`, `ind2`));
1249+
group.appendChild(createIndicatorSelect(`ind2`, keyword.conditions[1]?.indicator));
1250+
1251+
group.appendChild(createCheckbox(`neg2`, `Negate`, keyword.conditions[1]?.negate));
1252+
1253+
group.appendChild(createLabel(`Indicator 3`, `ind3`));
1254+
group.appendChild(createIndicatorSelect(`ind3`, keyword.conditions[2]?.indicator));
1255+
1256+
group.appendChild(createCheckbox(`neg3`, `Negate`, keyword.conditions[2]?.negate));
1257+
1258+
const button = document.createElement(`vscode-button`);
1259+
button.setAttribute(`icon`, `check`);
1260+
button.style.marginTop = `1em`;
1261+
button.style.display = `block`;
1262+
button.innerText = `Save`;
1263+
button.onclick = () => {
1264+
const keywordName = group.querySelector(`#keyword`).value;
1265+
const keywordValue = group.querySelector(`#value`).value;
1266+
1267+
const ind1 = group.querySelector(`#ind1`).value;
1268+
const neg1 = group.querySelector(`#neg1`).checked;
1269+
1270+
const ind2 = group.querySelector(`#ind2`).value;
1271+
const neg2 = group.querySelector(`#neg2`).checked;
1272+
1273+
const ind3 = group.querySelector(`#ind3`).value;
1274+
const neg3 = group.querySelector(`#neg3`).checked;
1275+
1276+
const newKeyword = {
1277+
name: keywordName,
1278+
value: keywordValue ? keywordValue : undefined,
1279+
conditions: []
1280+
};
1281+
1282+
if (ind1 !== `None`) {
1283+
newKeyword.conditions.push({
1284+
indicator: ind1,
1285+
negate: neg1
1286+
});
1287+
}
1288+
1289+
if (ind2 !== `None`) {
1290+
newKeyword.conditions.push({
1291+
indicator: ind2,
1292+
negate: neg2
1293+
});
1294+
}
1295+
1296+
if (ind3 !== `None`) {
1297+
newKeyword.conditions.push({
1298+
indicator: ind3,
1299+
negate: neg3
1300+
});
1301+
}
1302+
1303+
onUpdate(newKeyword);
1304+
};
1305+
1306+
group.appendChild(button);
1307+
1308+
const keywordEditorArea = document.getElementById(`keywordEditorArea`);
1309+
keywordEditorArea.innerHTML = ``;
1310+
1311+
keywordEditorArea.appendChild(document.createElement(`vscode-divider`));
1312+
keywordEditorArea.appendChild(group);
11841313
}

0 commit comments

Comments
 (0)