From f22c64e30cf88317a36f763ffe6b76f8a02ff4a4 Mon Sep 17 00:00:00 2001 From: Yurii Date: Sat, 13 Jan 2024 13:00:43 +0300 Subject: [PATCH] feat: human-readable uptime formatting --- data/index.html | 4 +- data/static/app.js.gz | Bin 3631 -> 3704 bytes noCompressedData/static/app.js | 137 ++++++++++++++++++--------------- 3 files changed, 75 insertions(+), 66 deletions(-) diff --git a/data/index.html b/data/index.html index 31b4f99..937d08b 100644 --- a/data/index.html +++ b/data/index.html @@ -95,11 +95,11 @@ Uptime: - sec. + days, hours, min., sec. Free memory: - of bytes, max block: bytes + of bytes, max free block: bytes Last reset reason: diff --git a/data/static/app.js.gz b/data/static/app.js.gz index 870a8c339eab3129f900208f166acf77e2c5fc45..bd9e3e7518b65f61c46f8bca1b151763c3fe6042 100644 GIT binary patch literal 3704 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 W$u+^|8f>vg<@ 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 z zWgj)qXw6WRHC?i6mrf3jP%-_Ui$m8AyS~uYbKPJK-`O9~f|oVNG?kTQZKo;?Of)d5 zhO(8*rCct#)igPb6nvZ)D~1J9u)F2aJch*4Z0;cqWScq3GT_7cAU{Al);M04?_$`By#3bp!@7U_*g)j>jJUP;kJE2nxGBv8mabQlYvE^}+| zsgdPq5FJkheRQHfeeeWf&Q=hJdgs8B!SmxzsUW0%>DS%%9^bG(*)Y5)V@7a<{7`C0!*HJuqZXEl27_;ag zn#?Bwi|EvfuafpN;1dOTL8UgY`oigIGeW6RJkquu93gc>*d>Lbs)Ur~@Tf=);Rzwo zaX8h89w*s54hx_cg?;D*4(X1Z;J0_+GV=D4#5cu_q_FPolyP+{uR9dqyYG1I z3kZjEfF{h`7vVPG7!?|rHPeO-MUjgB4=k+t z4TzjDB$?d;e_#pqSLS2#8J*|{7Owq_&JxWKuK%PQKk752QP+mn)pNP{8ARBLD#H3Z zHpIQ6H+U6~9Q9@Jl)P9B3}kvdHMr`JxuTrrlRx(;9;N-_l;U zo@M=nN?(TW$e2pcEu~wuD zP@_PhEWE7CwOaeIZnFlKty=jzAgQvY=JwCi?_VWqO|a#SP6o10{0Fa$^kGg(002Zx B{jLB2 diff --git a/noCompressedData/static/app.js b/noCompressedData/static/app.js index 58c1780..09c2f56 100644 --- a/noCompressedData/static/app.js +++ b/noCompressedData/static/app.js @@ -10,17 +10,9 @@ function setupForm(formSelector) { if (button) { defaultText = button.textContent; - button.onmouseout = function (event) { - if (button.hasAttribute('aria-busy')) { - return; - } - - button.classList.remove('success', 'failed'); - button.textContent = defaultText; - }; } - form.addEventListener('submit', async function (event) { + form.addEventListener('submit', async (event) => { event.preventDefault(); if (button) { @@ -29,24 +21,33 @@ function setupForm(formSelector) { button.setAttribute('aria-busy', true); } - const onSuccess = function (response) { + const onSuccess = (response) => { if (button) { button.textContent = 'Saved'; - button.removeAttribute('disabled'); button.classList.add('success'); button.removeAttribute('aria-busy'); + setTimeout(() => { + button.removeAttribute('disabled'); + button.classList.remove('success', 'failed'); + button.textContent = defaultText; + }, 5000); } - } + }; - const onFailed = function (response) { + const onFailed = (response) => { if (button) { button.textContent = 'Error'; - button.removeAttribute('disabled'); button.classList.add('failed'); button.removeAttribute('aria-busy'); + + setTimeout(() => { + button.removeAttribute('disabled'); + button.classList.remove('success', 'failed'); + button.textContent = defaultText; + }, 5000); } - } + }; try { let fd = new FormData(form); @@ -92,7 +93,7 @@ function setupNetworkScanForm(formSelector, tableSelector) { defaultText = button.innerHTML; } - const onSubmitFn = async function (event) { + const onSubmitFn = async (event) => { if (event) { event.preventDefault(); } @@ -109,7 +110,7 @@ function setupNetworkScanForm(formSelector, tableSelector) { return; } - const onSuccess = async function (response) { + const onSuccess = async (response) => { let result = await response.json(); console.log('networks: ', result); @@ -158,9 +159,9 @@ function setupNetworkScanForm(formSelector, tableSelector) { button.removeAttribute('disabled'); button.removeAttribute('aria-busy'); } - } + }; - const onFailed = async function (response) { + const onFailed = async (response) => { table.classList.remove('hidden'); if (button) { @@ -168,10 +169,10 @@ function setupNetworkScanForm(formSelector, tableSelector) { button.removeAttribute('disabled'); button.removeAttribute('aria-busy'); } - } + }; let attempts = 5; - let timer = setInterval(async function () { + let timer = setInterval(async () => { attempts--; try { @@ -208,17 +209,9 @@ function setupRestoreBackupForm(formSelector) { if (button) { defaultText = button.textContent; - button.onmouseout = function (event) { - if (button.hasAttribute('aria-busy')) { - return; - } - - button.classList.remove('success', 'failed'); - button.textContent = defaultText; - }; } - form.addEventListener('submit', async function (event) { + form.addEventListener('submit', async (event) => { event.preventDefault(); if (button) { @@ -227,23 +220,33 @@ function setupRestoreBackupForm(formSelector) { button.setAttribute('aria-busy', true); } - const onSuccess = function (response) { + const onSuccess = (response) => { if (button) { button.textContent = 'Restored'; - button.removeAttribute('disabled'); button.classList.add('success'); button.removeAttribute('aria-busy'); - } - } - const onFailed = function (response) { + setTimeout(() => { + button.removeAttribute('disabled'); + button.classList.remove('success', 'failed'); + button.textContent = defaultText; + }, 5000); + } + }; + + const onFailed = (response) => { if (button) { button.textContent = 'Error'; - button.removeAttribute('disabled'); button.classList.add('failed'); button.removeAttribute('aria-busy'); + + setTimeout(() => { + button.removeAttribute('disabled'); + button.classList.remove('success', 'failed'); + button.textContent = defaultText; + }, 5000); } - } + }; const files = form.querySelector('#restore-file').files; if (files.length <= 0) { @@ -253,7 +256,7 @@ function setupRestoreBackupForm(formSelector) { let reader = new FileReader(); reader.readAsText(files[0]); - reader.onload = async function() { + reader.onload = async function () { try { let response = await fetch(url, { method: 'POST', @@ -263,19 +266,19 @@ function setupRestoreBackupForm(formSelector) { }, body: reader.result }); - + if (response.ok) { onSuccess(response); - + } else { onFailed(response); } - + } catch (err) { onFailed(false); } }; - reader.onerror = function() { + reader.onerror = function () { console.log(reader.error); }; }); @@ -293,17 +296,9 @@ function setupUpgradeForm(formSelector) { if (button) { defaultText = button.textContent; - button.onmouseout = function (event) { - if (button.hasAttribute('aria-busy')) { - return; - } - - button.classList.remove('success', 'failed'); - button.textContent = defaultText; - }; } - const statusToText = function (status) { + const statusToText = (status) => { switch (status) { case 0: return "None"; @@ -324,9 +319,9 @@ function setupUpgradeForm(formSelector) { default: return "Unknown"; } - } + }; - const onResult = async function (response) { + const onResult = async (response) => { if (!response) { return; } @@ -368,28 +363,38 @@ function setupUpgradeForm(formSelector) { } } } - } + }; - const onSuccess = function (response) { + const onSuccess = (response) => { onResult(response); if (button) { button.textContent = defaultText; - button.removeAttribute('disabled'); button.removeAttribute('aria-busy'); - } - } - const onFailed = function (response) { + setTimeout(() => { + button.removeAttribute('disabled'); + button.classList.remove('success', 'failed'); + button.textContent = defaultText; + }, 5000); + } + }; + + const onFailed = (response) => { if (button) { button.textContent = 'Error'; - button.removeAttribute('disabled'); button.classList.add('failed'); button.removeAttribute('aria-busy'); - } - } - form.addEventListener('submit', async function (event) { + setTimeout(() => { + button.removeAttribute('disabled'); + button.classList.remove('success', 'failed'); + button.textContent = defaultText; + }, 5000); + } + }; + + form.addEventListener('submit', async (event) => { event.preventDefault(); if (button) { @@ -532,6 +537,10 @@ async function loadVars() { setValue('.version', result.system.version); setValue('.build-date', result.system.buildDate); setValue('.uptime', result.system.uptime); + setValue('.uptime-days', Math.floor(result.system.uptime / 86400)); + setValue('.uptime-hours', Math.floor(result.system.uptime % 86400 / 3600)); + setValue('.uptime-min', Math.floor(result.system.uptime % 3600 / 60)); + setValue('.uptime-sec', Math.floor(result.system.uptime % 60)); setValue('.free-heap', result.system.freeHeap); setValue('.total-heap', result.system.totalHeap); setValue('.max-free-block-heap', result.system.maxFreeBlockHeap); @@ -602,7 +611,7 @@ function form2json(data) { let value = pair[1]; if (value === 'true' || value === 'false') { value = value === 'true'; - } else if (typeof(value) === 'string' && value.trim() !== '' && !isNaN(value)) { + } else if (typeof (value) === 'string' && value.trim() !== '' && !isNaN(value)) { value = parseFloat(value); }