Skip to content

Commit d7fde28

Browse files
committed
Standardardise record format view
Signed-off-by: worksofliam <mrliamallan@live.co.uk>
1 parent 86c3b93 commit d7fde28

File tree

1 file changed

+98
-83
lines changed

1 file changed

+98
-83
lines changed

webui/main.js

Lines changed: 98 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* @typedef {import("konva").default.Layer} Layer
1010
* @typedef {{label: string, id?: string, value: string}} Property
1111
* @typedef {{[key: string]: string}} NewProperties
12+
* @typedef {{title: string, html: string|Element, open?: boolean}} Section
1213
*/
1314

1415
const colours = {
@@ -757,34 +758,26 @@ function setActiveField(konvaElement, fieldInfo) {
757758
function updateRecordFormatSidebar(recordInfo, globalInfo) {
758759
const sidebar = document.getElementById(`recordFormatSidebar`);
759760

760-
/** @type {{title: string, html: string, open?: boolean}[]} */
761+
/** @type {Section[]} */
761762
let sections = [];
762763

763-
if (globalInfo) {
764-
const fileKeywordRows = globalInfo.keywords.map(keyword => {
765-
return `<vscode-table-row><vscode-table-cell>${keyword.name}</vscode-table-cell><vscode-table-cell>${keyword.value ? `<code>${keyword.value}</code>` : ``}</vscode-table-cell></vscode-table-row>`;
766-
}).join(``);
764+
// TODO: support updating record formats
767765

766+
if (globalInfo) {
768767
sections.push({
769-
title: `Global Keywords`,
770-
html: `<vscode-table><vscode-table-body slot="body">${fileKeywordRows}</vscode-table-body></vscode-table>`,
771-
open: false
768+
title: `File Keywords`,
769+
html: createKeywordPanel(`keywords-${globalInfo.name}`, globalInfo.keywords),
770+
open: true
772771
});
773772
}
774773

775-
const keywordRows = recordInfo.keywords.map(keyword => {
776-
return `<vscode-table-row><vscode-table-cell>${keyword.name}</vscode-table-cell><vscode-table-cell>${keyword.value ? `<code>${keyword.value}</code>` : ``}</vscode-table-cell></vscode-table-row>`;
777-
}).join(``);
778-
779774
sections.push({
780-
title: `Keywords`,
781-
html: `<vscode-table><vscode-table-body slot="body">${keywordRows}</vscode-table-body></vscode-table>`,
775+
title: `Format Keywords`,
776+
html: createKeywordPanel(`keywords-${recordInfo.name}`, recordInfo.keywords),
782777
open: true
783778
});
784779

785-
sidebar.innerHTML = sections.map(section => {
786-
return `<vscode-collapsible title="${section.title}" ${section.open ? `open` : ``}>${section.html}</vscode-collapsible>`;
787-
}).join(``);
780+
renderSections(sidebar, sections);
788781
}
789782

790783
function clearFieldInfo() {
@@ -840,7 +833,7 @@ function clearFieldInfo() {
840833
function updateSelectedFieldSidebar(fieldInfo) {
841834
const sidebar = document.getElementById(`fieldInfoSidebar`);
842835

843-
/** @type {{title: string, html: string|Element, open?: boolean}[]} */
836+
/** @type {Section[]} */
844837
let sections = [];
845838

846839
/** @type {Property[]} */
@@ -894,6 +887,31 @@ function updateSelectedFieldSidebar(fieldInfo) {
894887
}
895888
);
896889

890+
renderSections(sidebar, sections);
891+
892+
const deleteButton = document.createElement(`vscode-button`);
893+
deleteButton.setAttribute(`secondary`, `true`);
894+
deleteButton.innerText = `Delete`;
895+
896+
// Center the button
897+
deleteButton.style.margin = `1em`;
898+
deleteButton.style.display = `block`;
899+
900+
deleteButton.addEventListener(`click`, (e) => {
901+
if (fieldInfo.name) {
902+
sendDelete(lastSelectedFormat, fieldInfo.name);
903+
}
904+
});
905+
906+
sidebar.appendChild(deleteButton);
907+
}
908+
909+
/**
910+
*
911+
* @param {HTMLElement} sidebar
912+
* @param {Section[]} sections
913+
*/
914+
function renderSections(sidebar, sections) {
897915
sidebar.innerHTML = ``;
898916

899917
for (let section of sections) {
@@ -911,22 +929,6 @@ function updateSelectedFieldSidebar(fieldInfo) {
911929

912930
sidebar.appendChild(newSection);
913931
}
914-
915-
const deleteButton = document.createElement(`vscode-button`);
916-
deleteButton.setAttribute(`secondary`, `true`);
917-
deleteButton.innerText = `Delete`;
918-
919-
// Center the button
920-
deleteButton.style.margin = `1em`;
921-
deleteButton.style.display = `block`;
922-
923-
deleteButton.addEventListener(`click`, (e) => {
924-
if (fieldInfo.name) {
925-
sendDelete(lastSelectedFormat, fieldInfo.name);
926-
}
927-
});
928-
929-
sidebar.appendChild(deleteButton);
930932
}
931933

932934
/**
@@ -980,24 +982,30 @@ function sendFieldUpdate(recordFormat, originalFieldName, newFieldInfo) {
980982
}
981983

982984
/**
985+
* Used to create panels for editable key/value lists
983986
* @param {string} id
984987
* @param {Keyword[]} keywords
985-
* @param {(keywords: Keyword[]) => void} onUpdate
988+
* @param {(keywords: Keyword[]) => void} [onUpdate]
986989
*/
987990
function createKeywordPanel(id, keywords, onUpdate) {
988991
const section = document.createElement(`div`);
989992
section.id = id;
990993

991-
const createInputCell = (id, value, placeHolder) => {
994+
const createInputCell = (id, value, readonly) => {
992995
const cell = document.createElement(`vscode-table-cell`);
993996

994-
const input = document.createElement(`code`);
995-
input.id = id;
996-
input.innerText = value;
997+
if (readonly) {
998+
cell.innerText = value;
997999

998-
input.setAttribute(`contenteditable`, `true`);
1000+
} else {
1001+
const input = document.createElement(`code`);
1002+
input.id = id;
1003+
input.innerText = value;
9991004

1000-
cell.appendChild(input);
1005+
input.setAttribute(`contenteditable`, `true`);
1006+
1007+
cell.appendChild(input);
1008+
}
10011009

10021010
return cell;
10031011
};
@@ -1021,6 +1029,7 @@ function createKeywordPanel(id, keywords, onUpdate) {
10211029
const tableBody = document.createElement(`vscode-table-body`);
10221030
tableBody.setAttribute(`slot`, `body`);
10231031

1032+
const readonly = onUpdate === undefined;
10241033
const ROW_PREFIX = `c-row-`;
10251034
for (let i = 0; i < keywords.length; i++) {
10261035
const keyword = keywords[i];
@@ -1032,11 +1041,15 @@ function createKeywordPanel(id, keywords, onUpdate) {
10321041
row.remove();
10331042
});
10341043

1035-
const keywordCell = createInputCell(`c-${i}-keyword`, keyword.name, `Keyword`);
1036-
const valueCell = createInputCell(`c-${i}-value`, keyword.value || ``, `no value`);
1044+
// TODO: might be cool to have the keyword validated against a list?
1045+
const keywordCell = createInputCell(`c-${i}-keyword`, keyword.name, readonly);
1046+
const valueCell = createInputCell(`c-${i}-value`, keyword.value || ``, readonly);
10371047
// TODO: Consider how conditions should be handled?
10381048

1039-
row.appendChild(deleteKeywordButton);
1049+
if (!readonly) {
1050+
row.appendChild(deleteKeywordButton);
1051+
}
1052+
10401053
row.appendChild(keywordCell);
10411054
row.appendChild(valueCell);
10421055

@@ -1045,55 +1058,57 @@ function createKeywordPanel(id, keywords, onUpdate) {
10451058

10461059
table.appendChild(tableBody);
10471060

1048-
const newKeyword = document.createElement(`vscode-button`);
1049-
newKeyword.setAttribute(`icon`, `add`);
1050-
1051-
newKeyword.innerText = `New Keyword`;
1052-
newKeyword.style.margin = `1em`;
1053-
newKeyword.style.display = `block`;
1061+
section.appendChild(table);
10541062

1055-
// TODO: event listener
1063+
if (onUpdate) {
10561064

1057-
const updateButton = document.createElement(`vscode-button`);
1058-
updateButton.innerText = `Update`;
1065+
const newKeyword = document.createElement(`vscode-button`);
1066+
newKeyword.setAttribute(`icon`, `add`);
10591067

1060-
// Center the button
1061-
updateButton.style.margin = `1em`;
1062-
updateButton.style.display = `block`;
1063-
1064-
updateButton.addEventListener(`click`, (e) => {
1065-
const rows = section.querySelectorAll(`[id^='${ROW_PREFIX}']`);
1066-
console.log(rows);
1067-
1068-
/** @type {Keyword[]} */
1069-
let newKeywords = [];
1070-
1071-
rows.forEach(row => {
1072-
// TODO: how to handle conditions? D:
1073-
const keywordCell = row.querySelector(`[id^='c-'][id$='-keyword']`);
1074-
const valueCell = row.querySelector(`[id^='c-'][id$='-value']`);
1075-
1076-
if (keywordCell && valueCell) {
1077-
newKeywords.push({
1078-
name: keywordCell.innerText,
1079-
value: valueCell.innerText,
1080-
conditions: []
1081-
});
1082-
}
1083-
});
1068+
newKeyword.innerText = `New Keyword`;
1069+
newKeyword.style.margin = `1em`;
1070+
newKeyword.style.display = `block`;
1071+
// TODO: event listener
1072+
const updateButton = document.createElement(`vscode-button`);
1073+
updateButton.innerText = `Update`;
1074+
1075+
// Center the button
1076+
updateButton.style.margin = `1em`;
1077+
updateButton.style.display = `block`;
10841078

1085-
onUpdate(newKeywords);
1086-
});
1079+
updateButton.addEventListener(`click`, (e) => {
1080+
const rows = section.querySelectorAll(`[id^='${ROW_PREFIX}']`);
1081+
console.log(rows);
10871082

1088-
section.appendChild(table);
1089-
section.appendChild(newKeyword);
1090-
section.appendChild(updateButton);
1083+
/** @type {Keyword[]} */
1084+
let newKeywords = [];
1085+
1086+
rows.forEach(row => {
1087+
// TODO: how to handle conditions? D:
1088+
const keywordCell = row.querySelector(`[id^='c-'][id$='-keyword']`);
1089+
const valueCell = row.querySelector(`[id^='c-'][id$='-value']`);
1090+
1091+
if (keywordCell && valueCell) {
1092+
newKeywords.push({
1093+
name: keywordCell.innerText,
1094+
value: valueCell.innerText,
1095+
conditions: []
1096+
});
1097+
}
1098+
});
1099+
1100+
onUpdate(newKeywords);
1101+
});
1102+
1103+
section.appendChild(newKeyword);
1104+
section.appendChild(updateButton);
1105+
}
10911106

10921107
return section;
10931108
}
10941109

10951110
/**
1096-
*
1111+
* Used to create a panel for editable properties
10971112
* @param {string} id
10981113
* @param {Property[]} properties
10991114
* @param {(newProps: NewProperties) => {}} onUpdate

0 commit comments

Comments
 (0)