code refactoring and UI/UX improvements

This commit is contained in:
sairaj mote 2022-09-17 19:36:03 +05:30
parent 6a567fad00
commit 2ea6f1ebaa
4 changed files with 127 additions and 158 deletions

View File

@ -487,6 +487,10 @@ ul {
margin-right: auto; margin-right: auto;
} }
.margin-top-1 {
margin-top: 1rem;
}
.margin-bottom-0-5 { .margin-bottom-0-5 {
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
@ -906,7 +910,7 @@ ul {
} }
#sheet_description { #sheet_description {
margin-top: 0.8rem; margin-top: 0.5rem;
opacity: 0.8; opacity: 0.8;
} }
@ -941,27 +945,21 @@ ul {
#toggle_details { #toggle_details {
transform: rotateX(180deg); transform: rotateX(180deg);
padding: 0.4rem;
background-color: rgba(var(--text-color), 0.1);
} }
#sheet_details { #sheet_details {
padding: 1rem; padding: 1rem;
margin-bottom: 1rem;
}
#sheet_details .flex:first-of-type {
margin-bottom: 1rem;
} }
#sheet_details .flex:nth-of-type(2) { #sheet_details .flex:nth-of-type(2) {
margin-bottom: 1rem; padding: 0.5rem 0;
} }
#sheet_details .flex:not(:first-of-type) { #sheet_details .flex:nth-of-type(2) button:first-of-type {
margin-bottom: 0.3rem; margin-left: -0.7rem;
} }
#sheet_details.collapse { #sheet_details.collapse {
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
margin-bottom: 0;
}
#sheet_details.collapse .flex {
margin-bottom: 0;
} }
#sheet_details.collapse #toggle_details { #sheet_details.collapse #toggle_details {
transform: none; transform: none;
@ -1063,6 +1061,10 @@ th.ascending::after {
#group_by sm-select:last-of-type { #group_by sm-select:last-of-type {
margin-left: 0.5rem; margin-left: 0.5rem;
} }
#group_by th,
#group_by td {
padding: 1rem;
}
#side_bar { #side_bar {
position: fixed; position: fixed;

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -481,7 +481,9 @@ ul {
.margin-right-auto { .margin-right-auto {
margin-right: auto; margin-right: auto;
} }
.margin-top-1 {
margin-top: 1rem;
}
.margin-bottom-0-5 { .margin-bottom-0-5 {
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
@ -895,7 +897,7 @@ ul {
background: rgba(var(--text-color), 0.1); background: rgba(var(--text-color), 0.1);
} }
#sheet_description { #sheet_description {
margin-top: 0.8rem; margin-top: 0.5rem;
opacity: 0.8; opacity: 0.8;
} }
#sheet_editors { #sheet_editors {
@ -925,25 +927,19 @@ ul {
} }
#toggle_details { #toggle_details {
transform: rotateX(180deg); transform: rotateX(180deg);
padding: 0.4rem;
background-color: rgba(var(--text-color), 0.1);
} }
#sheet_details { #sheet_details {
padding: 1rem; padding: 1rem;
margin-bottom: 1rem;
.flex:first-of-type {
margin-bottom: 1rem;
}
.flex:nth-of-type(2) { .flex:nth-of-type(2) {
margin-bottom: 1rem; padding: 0.5rem 0;
} button:first-of-type {
.flex:not(:first-of-type) { margin-left: -0.7rem;
margin-bottom: 0.3rem; }
} }
&.collapse { &.collapse {
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
margin-bottom: 0;
.flex {
margin-bottom: 0;
}
#toggle_details { #toggle_details {
transform: none; transform: none;
} }
@ -1042,6 +1038,10 @@ th.ascending::after {
sm-select:last-of-type { sm-select:last-of-type {
margin-left: 0.5rem; margin-left: 0.5rem;
} }
th,
td {
padding: 1rem;
}
} }
#side_bar { #side_bar {

View File

@ -758,6 +758,14 @@
}) })
} }
document.addEventListener('popupopened', e => {
let popup = e.detail.popup
switch (popup.id) {
case 'group_by':
renderGroup()
break;
}
})
document.addEventListener('popupclosed', e => { document.addEventListener('popupclosed', e => {
let popup = e.detail.popup let popup = e.detail.popup
switch (popup.id) { switch (popup.id) {
@ -765,6 +773,9 @@
getRef('columns_container').innerHTML = '' getRef('columns_container').innerHTML = ''
getRef('editors_container').innerHTML = '' getRef('editors_container').innerHTML = ''
break; break;
case 'group_by':
renderElem(getRef("group_by_view"), html``)
break;
} }
}) })
function showLoader() { function showLoader() {
@ -785,32 +796,25 @@
el.setAttribute(key, attrs[key]); el.setAttribute(key, attrs[key]);
} }
} }
delegate(getRef('people_container'), 'click', '.person-card', e => {
copyToLogInput(e.delegateTarget.dataset.floId)
})
let currentTableHeader let currentTableHeader
document.addEventListener('click', e => { delegate(getRef('sheet_container__header'), 'click', 'th', e => {
try { if (currentTableHeader && currentTableHeader !== e.delegateTarget)
if (e.target.closest(".person-card")) currentTableHeader.classList.remove('ascending', 'descending')
copyToLogInput(e.target.closest(".person-card").dataset.floId) sortTable(e.delegateTarget.cellIndex, e.delegateTarget.classList.contains('descending'))
else if (e.target.closest("th")) { if (e.delegateTarget.classList.contains('descending'))
let trgt = e.target.closest('th') e.delegateTarget.classList.add('ascending')
if (currentTableHeader && currentTableHeader !== trgt) else
currentTableHeader.classList.remove('ascending', 'descending') e.delegateTarget.classList.remove('ascending')
sortTable(trgt.cellIndex, trgt.classList.contains('descending')) e.delegateTarget.classList.toggle('descending')
if (trgt.classList.contains('descending')) currentTableHeader = e.delegateTarget
trgt.classList.add('ascending')
else
trgt.classList.remove('ascending')
trgt.classList.toggle('descending')
currentTableHeader = trgt
}
} catch (error) {
//do nothing
}
}) })
const observer = new IntersectionObserver((entries, observer) => { const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => { entries.forEach(entry => {
if (entry.isIntersecting) { if (entry.isIntersecting) {
let { id, title, description, editors, attributes, sheet, isWriteable, isSubAdmin } = floGlobals.currentSheet; renderSheetView({ ...floGlobals.currentSheet, onlyRenderTable: true, lazyLoad: true })
renderSheetView(id, title, description, editors, attributes, sheet, isWriteable, isSubAdmin, true, true)
observer.disconnect() observer.disconnect()
} }
}) })
@ -828,20 +832,15 @@
if (this.value.trim !== '') { if (this.value.trim !== '') {
for (child of getRef('sheets_container').children) { for (child of getRef('sheets_container').children) {
if (child.id === 'add_new_sheet') continue if (child.id === 'add_new_sheet') continue
if (child.dataset.name.toUpperCase().indexOf(this.value.toUpperCase()) > -1) { if (child.dataset.name.toLowerCase().includes(this.value.trim().toLowerCase())) {
child.classList.remove('hidden') child.classList.remove('hidden')
} } else {
else {
child.classList.add('hidden') child.classList.add('hidden')
} }
} }
} }
}) })
function removeUnderscore(word) {
return word.replace(/_/g, ' ')
}
const render = { const render = {
sheetCard(sheetId, details) { sheetCard(sheetId, details) {
const { title, editors } = details const { title, editors } = details
@ -1073,39 +1072,28 @@
}).catch(error => notify(`Save Unsuccessful [${error}]`, error)) }).catch(error => notify(`Save Unsuccessful [${error}]`, error))
}) })
getRef('first_select').addEventListener("change", function (e) { getRef('first_select').addEventListener("change", renderGroup)
getRef('second_select').addEventListener("change", renderGroup)
function renderGroup() {
try { try {
let sheetId = floGlobals.currentSheet.id; const type = getRef('first_select').value
let sheet = floGlobals.currentSheet.sheet; const column = getRef('second_select').value
let type = this.value; const { sheetId, sheet } = floGlobals.currentSheet
if (type === 'count') { if (type === 'count') {
getRef('second_select').classList.add("hidden") getRef('second_select').classList.add("hidden")
let data = logSheet.groupBy.count(sheetId, sheet) let data = logSheet.groupBy.count(sheetId, sheet)
renderGroupByView("count", data) renderGroupByView("count", data)
} else { } else {
getRef('second_select').classList.remove("hidden") getRef('second_select').classList.remove("hidden")
let column = getRef('second_select').value;
let data = logSheet.groupBy[type](sheetId, sheet, column); let data = logSheet.groupBy[type](sheetId, sheet, column);
renderGroupByView(`${type}(${column})`, data) renderGroupByView(`${type}(${column})`, data)
} }
} catch (error) { } catch (error) {
notify(error, "error") notify(error, "error")
} }
}) }
getRef('second_select').addEventListener("change", function (e) {
try {
console.log(this)
let sheetId = floGlobals.currentSheet.id;
let sheet = floGlobals.currentSheet.sheet;
let type = getRef('first_select').value;
let column = this.value;
let data = logSheet.groupBy[type](sheetId, sheet, column);
renderGroupByView(`${type}(${column})`, data)
} catch (error) {
notify(error, "error")
}
})
function clearElement(element) { function clearElement(element) {
element.innerHTML = ''; element.innerHTML = '';
@ -1184,12 +1172,11 @@
let input = document.forms['new-log'][0] let input = document.forms['new-log'][0]
if (input.tagName === 'INPUT') if (input.tagName === 'INPUT')
input.value = floID; input.value = floID;
console.log(floID, input)
} }
function enterLog(e) { function enterLog(e) {
e.preventDefault() e.preventDefault()
let sheetId = floGlobals.currentSheet.id; let sheetId = floGlobals.currentSheet.sheetId;
let form = document.forms['new-log'], let form = document.forms['new-log'],
allFormElements = document.querySelectorAll('input[form="new-log"]') allFormElements = document.querySelectorAll('input[form="new-log"]')
if (form[0].tagName === 'INPUT') { if (form[0].tagName === 'INPUT') {
@ -1243,9 +1230,8 @@
getRef('sheet_type').classList.remove('placeholder') getRef('sheet_type').classList.remove('placeholder')
getRef('sheet_description').classList.remove('placeholder') getRef('sheet_description').classList.remove('placeholder')
getRef('sheet_container__header').classList.remove('hidden') getRef('sheet_container__header').classList.remove('hidden')
let data = logSheet.viewLogs(sheetId) const { id, title, description, editors, attributes, sheet } = logSheet.viewLogs(sheetId)
renderSheetView(data.id, data.title, data.description, data.editors, data.attributes, data.sheet.reverse(), renderSheetView({ sheetId: id, title, description, editors, attributes, sheet: sheet.reverse() })
!data.editors || data.editors.includes(myFloID), floGlobals.subAdmins.includes(myFloID))
}).catch(error => notify(error, "error")) }).catch(error => notify(error, "error"))
} }
@ -1289,22 +1275,15 @@
let startingIndex = 0, let startingIndex = 0,
endingIndex = 0 endingIndex = 0
function renderSheetView(sheetId, title, description, editors, attributes, sheet, isWriteable, isSubAdmin, onlyRenderTable = false, lazyLoad = false) { function renderSheetView(details = {}) {
const { sheetId, title, description, editors, attributes, sheet, onlyRenderTable = false, lazyLoad = false } = details
const isWriteable = !editors || editors.includes(myFloID)
const isSubAdmin = floGlobals.subAdmins.includes(myFloID)
if (!lazyLoad) if (!lazyLoad)
floGlobals.currentSheet = { floGlobals.currentSheet = { sheetId, title, description, editors, attributes, sheet, }
id: sheetId,
title,
description,
editors,
attributes,
sheet,
isWriteable,
isSubAdmin,
}
const parseVectorClock = (vc) => { const parseVectorClock = (vc) => {
vc = vc.split('_') const [vectorClock, floID] = vc.split('_')
let time = new Date(parseInt(vc[0])).toString().slice(4, 24); let time = new Date(parseInt(vectorClock)).toString().slice(4, 24);
let floID = vc[1]
return `by ${floID} (${time})` return `by ${floID} (${time})`
} }
const createGradeField = (vc, grade) => { const createGradeField = (vc, grade) => {
@ -1315,8 +1294,8 @@
if (!isWriteable || !isSubAdmin || vc.split('_')[1] == myFloID) if (!isWriteable || !isSubAdmin || vc.split('_')[1] == myFloID)
gradeField.disabled = true; gradeField.disabled = true;
else { else {
gradeField.addEventListener("keypress", (event) => { gradeField.addEventListener("keydown", (event) => {
if (event.keyCode == 13) { if (event.key === 'Enter') {
event.preventDefault(); event.preventDefault();
gradeField.disabled = true; gradeField.disabled = true;
logSheet.gradeLog(sheetId, vc, gradeField.value) logSheet.gradeLog(sheetId, vc, gradeField.value)
@ -1338,61 +1317,51 @@
if (!onlyRenderTable) { if (!onlyRenderTable) {
//Add Sheet Details //Add Sheet Details
getRef('sheet_heading').textContent = title; getRef('sheet_heading').textContent = title;
if (editors) { getRef('sheet_type').textContent = editors ? 'Private' : 'Public';
getRef('sheet_type').textContent = 'Private' renderElem(getRef('sheet_editors'), html`${editors ? html`Maintained by: ${editors.map(editor => html`<div class="editor">${editor}</div>`)}` : ''}`)
editors.forEach(editor => {
let card = document.createElement('div')
card.className = 'editor'
card.textContent = editor;
frag.append(card)
})
getRef('sheet_editors').innerHTML = 'Maintained by: '
getRef('sheet_editors').append(frag)
}
else {
getRef('sheet_type').textContent = 'Public'
getRef('sheet_editors').innerHTML = ''
}
getRef('sheet_description').textContent = description; getRef('sheet_description').textContent = description;
clearElement(getRef('sheet_container__header'))
let row = getRef('sheet_container__header').insertRow();
row.append(createTh("FLO ID"), createTh("Grade"));
attributes.forEach(a => row.append(createTh(a)))
//Add input fields if writable
let blockEditingID = (!isSubAdmin && (editors || true)); let blockEditingID = (!isSubAdmin && (editors || true));
let addLogRow = null
//Add input fields if writable
if (isWriteable && !lazyLoad) { if (isWriteable && !lazyLoad) {
getRef('sheet_container__header').append(html.node` addLogRow = html`
<tr> <tr>
<td><input form="new-log" class="log-input" value="${blockEditingID ? myFloID : ''}" ?readonly=${blockEditingID}></td> <td>${blockEditingID ? myFloID : html`<input form="new-log" class="log-input">`}</td>
<td></td> <td></td>
${attributes.map(attr => html`<td><input form="new-log" class="log-input"></td>`)} ${attributes.map(attr => html`<td><input form="new-log" class="log-input"></td>`)}
</tr> </tr>
`) `;
} }
renderElem(getRef('sheet_container__header'), html`
<tr>
<th>FLO ID</th>
<th>Grade</th>
${attributes.map(attr => html`<th>${attr}</th>`)}
</tr>
${addLogRow}
`)
} }
if (onlyRenderTable) { if (onlyRenderTable) {
if (!lazyLoad) if (!lazyLoad)
getRef('sheet_container__body').innerHTML = '' getRef('sheet_container__body').innerHTML = ''
} }
for (let i = startingIndex; i < endingIndex; i++) { for (let i = startingIndex; i < endingIndex; i++) {
let data = sheet[i] const { log, floID, vc, grade } = sheet[i]
if (!data.log || !data.floID || !data.vc) if (!log || !floID || !vc)
continue; continue;
let row = document.createElement('tr') frag.append(html.node`
row.setAttribute("title", parseVectorClock(data.vc)) <tr title="${parseVectorClock(vc)}">
row.append(createCell(data.floID)) <td>${floID}</td>
let gradeF = document.createElement('td') <td>${createGradeField(vc, grade)}</td>
gradeF.append(createGradeField(data.vc, data.grade)) ${log.map(l => html`<td>${l}</td>`)}
row.append(gradeF) </tr>
data.log.forEach(l => row.append(createCell(l))) `)
frag.append(row)
} }
getRef('sheet_container__body').append(frag) getRef('sheet_container__body').append(frag)
if (!onlyRenderTable) { if (!onlyRenderTable) {
//Add options for groupBy //Add options for groupBy
getRef('group_by_title').textContent = `Group ${title} by`; getRef('group_by_title').textContent = `Group ${title} by`;
getRef('group_by_view').innerHTML =
`<table><thead><tr><th>FLO ID</th><th><i>null</i></th></tr></thead></table>`
let colSelect = clearElement(getRef('group_by_menu').children[1]); let colSelect = clearElement(getRef('group_by_menu').children[1]);
attributes.forEach(a => { attributes.forEach(a => {
let opt = document.createElement('sm-option'); let opt = document.createElement('sm-option');
@ -1404,22 +1373,27 @@
} }
function renderGroupByView(groupName, groupData) { function renderGroupByView(groupName, groupData) {
let table = document.createElement("table") renderElem(getRef("group_by_view"), html`
let head = table.createTHead().insertRow(0) <table class="margin-top-1">
head.insertCell(0).textContent = "FLO ID"; <thead>
head.insertCell(1).textContent = groupName; <tr>
let tbody = document.createElement("tbody") <th>FLO ID</th>
for (floID in groupData) { <th>${groupName}</th>
let row = tbody.insertRow(0); </tr>
row.insertCell(0).textContent = floID </thead>
row.insertCell(1).textContent = groupData[floID] <tbody>
} ${Object.keys(groupData).map(floID => html`
table.appendChild(tbody); <tr>
clearElement(getRef("group_by_view")).appendChild(table); <td>${floID}</td>
<td>${groupData[floID]}</td>
</tr>
`)}
</tbody>
</table>
`)
} }
function sortTable(n, ascending) { function sortTable(n, ascending) {
console.log(n)
if (ascending) { if (ascending) {
if (n === 0) if (n === 0)
floGlobals.currentSheet.sheet.sort((a, b) => a.floID.toLowerCase().localeCompare(b.floID.toLowerCase())) floGlobals.currentSheet.sheet.sort((a, b) => a.floID.toLowerCase().localeCompare(b.floID.toLowerCase()))
@ -1427,8 +1401,7 @@
floGlobals.currentSheet.sheet.sort((a, b) => { floGlobals.currentSheet.sheet.sort((a, b) => {
if (a.grade === b.grade) { if (a.grade === b.grade) {
return 0; return 0;
} } else {
else {
return (a.grade < b.grade) ? -1 : 1; return (a.grade < b.grade) ? -1 : 1;
} }
}) })
@ -1439,12 +1412,10 @@
let y = (b.log[n - 2]) ? b.log[n - 2].toLowerCase() : b.log[n - 2] let y = (b.log[n - 2]) ? b.log[n - 2].toLowerCase() : b.log[n - 2]
if (x === y) { if (x === y) {
return 0; return 0;
} } else {
else {
return (x < y) ? -1 : 1; return (x < y) ? -1 : 1;
} }
} } else
else
return a.log[n - 2] - b.log[n - 2] return a.log[n - 2] - b.log[n - 2]
}) })
} else { } else {
@ -1454,8 +1425,7 @@
floGlobals.currentSheet.sheet.sort((a, b) => { floGlobals.currentSheet.sheet.sort((a, b) => {
if (a.grade === b.grade) { if (a.grade === b.grade) {
return 0; return 0;
} } else {
else {
return (a.grade > b.grade) ? -1 : 1; return (a.grade > b.grade) ? -1 : 1;
} }
}) })
@ -1466,17 +1436,14 @@
let y = (b.log[n - 2]) ? b.log[n - 2].toLowerCase() : b.log[n - 2] let y = (b.log[n - 2]) ? b.log[n - 2].toLowerCase() : b.log[n - 2]
if (x === y) { if (x === y) {
return 0; return 0;
} } else {
else {
return (x > y) ? -1 : 1; return (x > y) ? -1 : 1;
} }
} } else
else
return b.log[n - 2] - a.log[n - 2] return b.log[n - 2] - a.log[n - 2]
}) })
} }
let { id, title, description, editors, attributes, sheet, isWriteable, isSubAdmin } = floGlobals.currentSheet renderSheetView({ ...floGlobals.currentSheet, onlyRenderTable: true })
renderSheetView(id, title, description, editors, attributes, sheet, isWriteable, isSubAdmin, true, false)
} }
</script> </script>
</body> </body>