mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 07:06:36 +01:00
updated web interface design
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -8,15 +8,419 @@
|
||||
<title>Open EPaper Link Access Point</title>
|
||||
<link rel="stylesheet" href="main.css" type="text/css" />
|
||||
<link rel="icon" type="image/vnd.icon" href="favicon.ico">
|
||||
<link rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<div class="logo">Open EPaper Link Access Point</div>
|
||||
<nav>
|
||||
<div>
|
||||
<!-- tabs -->
|
||||
<div class="tab-container">
|
||||
<div class="tablinks material-symbols-outlined" data-target="hometab" title="Dashboard">home</div>
|
||||
<div class="tablinks material-symbols-outlined" data-target="tagtab" title="Tags">sell</div>
|
||||
<div class="tablinks material-symbols-outlined" data-target="aptab" title="Access Points">cell_tower
|
||||
</div>
|
||||
<!--<div class="tablinks material-symbols-outlined" data-target="templatetab" title="Templates">browse
|
||||
</div>-->
|
||||
<div class="tablinks material-symbols-outlined" data-target="configtab" title="Settings">settings
|
||||
</div>
|
||||
<div class="tablinks material-symbols-outlined" data-target="logtab" title="Logging">text_snippet
|
||||
</div>
|
||||
</div>
|
||||
<!-- /tabs -->
|
||||
<div><span id="runstate"></div>
|
||||
<div><span id="apstatecolor">⬤</span> <span id="apstate">loading</span></div>
|
||||
<div><a href="/edit" target="littlefs" class="filebutton material-symbols-outlined">folder_open</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<div id="configbox">
|
||||
<div class="closebtn">✖</div>
|
||||
<form>
|
||||
<div class="container">
|
||||
|
||||
<div class="window">
|
||||
|
||||
<div id="hometab" class="tabcontent">
|
||||
<table>
|
||||
<tr onclick="setFilterAndShow('')">
|
||||
<td class="material-symbols-outlined" style="color:#239f26" id="dashboardStatusIcon">
|
||||
check_circle
|
||||
</td>
|
||||
<td id="dashboardStatus" style="color:#239f26" colspan="2">
|
||||
initialising...
|
||||
</td>
|
||||
</tr>
|
||||
<tr onclick="setFilterAndShow('')">
|
||||
<td class="material-symbols-outlined" style="color:#77239e">
|
||||
sell
|
||||
</td>
|
||||
<td>
|
||||
tags
|
||||
</td>
|
||||
<td id="dashboardTagCount" style="color:#77239e">
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr onclick="setFilterAndShow('pending')">
|
||||
<td class="material-symbols-outlined" style="color:#235f9e">
|
||||
hourglass_empty
|
||||
</td>
|
||||
<td>
|
||||
pending data
|
||||
</td>
|
||||
<td id="dashboardPending" style="color:#235f9e">
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr onclick="setFilterAndShow('lowbatt')">
|
||||
<td class="material-symbols-outlined" style="color:#9e9223">
|
||||
battery_low
|
||||
</td>
|
||||
<td>
|
||||
low battery
|
||||
</td>
|
||||
<td id="dashboardLowBatt" style="color:#9e9223">
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr onclick="setFilterAndShow('inactive')">
|
||||
<td class="material-symbols-outlined" style="color:#9e2323">
|
||||
signal_disconnected
|
||||
</td>
|
||||
<td>
|
||||
timeout
|
||||
</td>
|
||||
<td id="dashboardTimeout" style="color:#9e2323">
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<!--
|
||||
<tr onclick="$(`[data-target='aptab']`).click()">
|
||||
<td class="material-symbols-outlined" style="color:#239f26">
|
||||
cell_tower
|
||||
</td>
|
||||
<td>
|
||||
access points
|
||||
</td>
|
||||
<td id="dashboardApCount" style="color:#239f26">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
-->
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="tagtab" class="tabcontent">
|
||||
<div class="tagheader">
|
||||
<h3>Currently active tags</h3>
|
||||
<div id="activefilter"></div><button class="material-symbols-outlined"
|
||||
id="toggleFilters">filter_alt</button>
|
||||
</div>
|
||||
<div id="filterOptions">
|
||||
<div>
|
||||
<div>group by</div>
|
||||
<div>
|
||||
<input type="radio" name="group" value="" id="rnone" checked><label
|
||||
for="rnone">None</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="group" value="model" id="rtagtype"><label for="rtagtype">Tag
|
||||
model</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="group" value="contentmode" id="rcontent"><label
|
||||
for="rcontent">Content</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="group" value="data-channel" id="rchannel"><label
|
||||
for="rchannel">Channel</label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>sort by</div>
|
||||
<div>
|
||||
<input type="radio" name="sort" value="alias" id="ralias" checked><label
|
||||
for="ralias">Alias</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="sort" value="mac" id="rmac"><label for="rmac">Mac</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="sort" value="data-lastseen" id="rlastseen"><label
|
||||
for="rlastseen">Last seen</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="sort" value="data-nextupdate" id="rnext"><label
|
||||
for="rnext">Next update</label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>filter</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="local" id="rlocal"><label
|
||||
for="rlocal">local</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="remote" id="rremote"><label
|
||||
for="rremote">remote</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="inactive" id="rinactive"><label
|
||||
for="rinactive">timed out</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="pending" id="rpending"><label
|
||||
for="rpending">pending</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="lowbatt" id="rlowbatt"><label
|
||||
for="rlowbatt">low battery</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="taglist" class="taglist">
|
||||
<div class="tagcard" id="tagtemplate">
|
||||
<div class="currimg"><canvas class="tagimg"></div>
|
||||
<div class="mac"></div>
|
||||
<div class="alias"></div>
|
||||
<div class="model"></div>
|
||||
<div class="received"></div>
|
||||
<div class="contentmode"></div>
|
||||
<div class="lastseen"></div>
|
||||
<div class="nextcheckin"></div>
|
||||
<div class="nextupdate"></div>
|
||||
<div class="corner">
|
||||
<div class="pendingicon" title="A new message is waiting for the tag to pick up">
|
||||
↻</div>
|
||||
<div class="warningicon" title="This tag has not been seen for a long time">⚠
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="logtab" class="tabcontent">
|
||||
<div class="tabheader">
|
||||
<div><img id="clearlog" src="data:image/gif;base64,R0lGODlhEAAQAPMAANXV1e3t7d/f39HR0dvb2/Hx8dTU1OLi4urq6mZmZpmZmf///wAAAAAAAAAAAAAAACH5BAEAAAwALAAAAAAQABAAAARBkMlJq71Yrp3ZXkr4WWCYnOZSgQVyEMYwJCq1nHhe20qgCAoA7QLyAYU7njE4JPV+zOSkCEUSFbmTVPPpbjvgTAQAOw==
|
||||
"></div>
|
||||
<div><input type="checkbox" id="showdebug" value="1"><label for="showdebug">Show all websocket
|
||||
traffic</label></div>
|
||||
</div>
|
||||
<ul id="messages" class="messages">
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="aptab" class="tabcontent">
|
||||
<h3>Active access points</h3>
|
||||
|
||||
<div id="aplist">
|
||||
<div id="apcard" class="apcard">
|
||||
<p class="apip">194.109.6.66</p>
|
||||
<p class="apalias">AP kitchen</p>
|
||||
<div>
|
||||
<span class="material-symbols-outlined">
|
||||
sell
|
||||
</span>
|
||||
<span class="aptagcount">13</span>
|
||||
<span class="material-symbols-outlined space">
|
||||
cell_tower
|
||||
</span>
|
||||
<span class="apchannel">25</span>
|
||||
</div>
|
||||
<p class="apswversion">
|
||||
fetching software version...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="templatetab" class="tabcontent">
|
||||
Work in progress...
|
||||
</div>
|
||||
|
||||
<div id="configtab" class="tabcontent">
|
||||
<h3>Access Point config</h3>
|
||||
<p>
|
||||
<label for="apcfgalias">Alias</label>
|
||||
<input id="apcfgalias" type="text">
|
||||
</p>
|
||||
<p>
|
||||
<label for="apcfgchid">Channel</label>
|
||||
<select id="apcfgchid">
|
||||
<option value="0" selected>auto</option>
|
||||
<option value="11">11</option>
|
||||
<option value="15">15</option>
|
||||
<option value="20">20</option>
|
||||
<option value="25">25</option>
|
||||
<option value="26">26</option>
|
||||
<option value="27">27</option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label for="apcfgledbrightness">LED brightness</label>
|
||||
<select id="apcfgledbrightness">
|
||||
<option value="-1">off</option>
|
||||
<option value="20">10%</option>
|
||||
<option value="64">25%</option>
|
||||
<option value="128" selected>50%</option>
|
||||
<option value="192">75%</option>
|
||||
<option value="255">100%</option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label for="apcfglanguage">Content language</label>
|
||||
<select id="apcfglanguage">
|
||||
<option value="0" selected>EN English</option>
|
||||
<option value="1">NL Nederlands</option>
|
||||
<option value="2">DE Deutsch</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="Depending on the content, a tag can sleep for
|
||||
longer periods when no updates are expected
|
||||
(like a date display). This setting specifies
|
||||
the maximum sleep time.">
|
||||
<label for="apclatency">Maximum sleep</label>
|
||||
<select id="apclatency">
|
||||
<option value="0" selected>shortest (40 sec)</option>
|
||||
<option value="5">5 minutes</option>
|
||||
<option value="10">10 minute</option>
|
||||
<option value="30">30 minutes</option>
|
||||
<option value="60">1 hour</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="If connected to the website, don't sleep extra.
|
||||
Latency will be around 40 seconds.">
|
||||
<label for="apcpreventsleep">Shorten latency during config</label>
|
||||
<select id="apcpreventsleep">
|
||||
<option value="0">no</option>
|
||||
<option value="1" selected>yes</option>
|
||||
</select>
|
||||
</p>
|
||||
<p
|
||||
title="Stops updates at night, and put the tags to sleep. During the configured night time, this overrides the maximum sleep time.">
|
||||
<label for="apcnight1">No updates between</label>
|
||||
<select id="apcnight1"></select>
|
||||
<span style="align-self:center;">and</span>
|
||||
<select id="apcnight2"></select>
|
||||
</p>
|
||||
<p title="Turn off preview images on the webpage if you want to manage many tags,
|
||||
to save file system space">
|
||||
<label for="apcpreview">Preview images</label>
|
||||
<select id="apcpreview">
|
||||
<option value="1" selected>yes</option>
|
||||
<option value="0">no</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="Wifi transmit power">
|
||||
<label for="apcwifipower">Wifi power</label>
|
||||
<select id="apcwifipower">
|
||||
<option value="78">19.5 dBm</option>
|
||||
<option value="76">19.0 dBm</option>
|
||||
<option value="74">18.5 dBm</option>
|
||||
<option value="68">17.0 dBm</option>
|
||||
<option value="60">15.0 dBm</option>
|
||||
<option value="52">13.0 dBm</option>
|
||||
<option value="44">11.0 dBm</option>
|
||||
<option value="34" selected>8.5 dBm</option>
|
||||
<option value="28">7.0 dBm</option>
|
||||
<option value="20">5.0 dBm</option>
|
||||
<option value="8">2.0 dBm</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="Your local time zone">
|
||||
<label for="apctimezone">Local time zone</label>
|
||||
<select id="apctimezone">
|
||||
<optgroup label="Europe">
|
||||
<option value="CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00" selected>Central European
|
||||
Time</option>
|
||||
<option value="EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00">Athens, Greece</option>
|
||||
<option value="GMT+0IST-1,M3.5.0/01:00:00,M10.5.0/02:00:00">Dublin, Ireland</option>
|
||||
<option value="EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00">Helsinki, Finland</option>
|
||||
<option value="WET-0WEST-1,M3.5.0/01:00:00,M10.5.0/02:00:00">Lisbon, Portugal</option>
|
||||
<option value="GMT+0BST-1,M3.5.0/01:00:00,M10.5.0/02:00:00">London, Great Britain
|
||||
</option>
|
||||
<option value="EET-2EEST,M3.5.0/3,M10.5.0/4">Kyiv, Ukraine</option>
|
||||
</optgroup>
|
||||
<optgroup label="USA / Canada">
|
||||
<option value="HAW10">Hawaii Time</option>
|
||||
<option value="AKST9AKDT">Alaska Time</option>
|
||||
<option value="PST8PDT">Pacific Time</option>
|
||||
<option value="MST7MDT">Mountain Time</option>
|
||||
<option value="MST7">Arizona, no DST</option>
|
||||
<option value="CST6CDT">Central Time</option>
|
||||
<option value="EST5EDT">Eastern Time</option>
|
||||
</optgroup>
|
||||
<optgroup label="Australia / New Zealand">
|
||||
<option value="EST-10EDT-11,M10.5.0/02:00:00,M3.5.0/03:00:00">Melbourne, Sydney</option>
|
||||
<option value="WST-8">Perth</option>
|
||||
<option value="EST-10">Brisbane</option>
|
||||
<option value="CST-9:30CDT-10:30,M10.5.0/02:00:00,M3.5.0/03:00:00">Adelaide</option>
|
||||
<option value="CST-9:30">Darwin</option>
|
||||
<option value="EST-10EDT-11,M10.1.0/02:00:00,M3.5.0/03:00:00">Hobart</option>
|
||||
<option value="NZST-12NZDT-13,M9.4.0/02:00:00,M4.1.0/03:00:00">New Zealand</option>
|
||||
</optgroup>
|
||||
<optgroup label="Asia">
|
||||
<option value="JST-9">Tokyo</option>
|
||||
<option value="WIB-7">Jakarta</option>
|
||||
<option value="GMT+2">Jerusalem</option>
|
||||
<option value="SGT-8">Singapore</option>
|
||||
<option value="ULAT-8ULAST,M3.5.0/2,M9.5.0/2">Ulaanbaatar, Mongolia</option>
|
||||
</optgroup>
|
||||
<optgroup label="Central and South America">
|
||||
<option value="BRST+3BRDT+2,M10.3.0,M2.3.0">Brazil, Sao Paulo</option>
|
||||
<option value="UTC+3">Argentina</option>
|
||||
<option value="CST+6">Central America</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<input type="button" value="Save" id="apcfgsave"><span id="apcfgmsg"></span>
|
||||
</p>
|
||||
<h3>Manage</h3>
|
||||
<p>
|
||||
<button id="rebootbutton">Reboot AP</button> Saves the tagDB and instantly reboots the Access
|
||||
Point
|
||||
</p>
|
||||
<p>
|
||||
<a href="/backup_db" id="downloadDBbutton">Download tagDB</a>
|
||||
</p>
|
||||
<p>
|
||||
<button id="updatebutton">Update</button> Manage firmware of the ESP32
|
||||
</p>
|
||||
<p>
|
||||
<a href="/setup" target="setup" class="wifibutton">WiFi config</a> Opens a new window with WiFi
|
||||
config options
|
||||
</p>
|
||||
<p>
|
||||
<br>
|
||||
<a href="https://github.com/jjwbruijn/OpenEPaperLink" target="_new">Github
|
||||
OpenEPaperLink</a><br>
|
||||
<a href="https://github.com/jjwbruijn/OpenEPaperLink/wiki" target="_new">OpenEPaperLink
|
||||
Wiki</a><br>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<footer class="logbox">
|
||||
<p>
|
||||
<span> </span>
|
||||
<span id="sysinfo"></span>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<!-- -->
|
||||
|
||||
<dialog id="configbox">
|
||||
<div class="closebtn2">✖</div>
|
||||
<h3 id="cfgmac">00000000</h3>
|
||||
<p>
|
||||
<label for="cfgalias">Alias</label>
|
||||
@@ -50,183 +454,33 @@
|
||||
<button id="cfgscan">scan</button>
|
||||
<button id="cfgdeepsleep">deep sleep</button>
|
||||
<button id="cfgreset">reset settings</button>
|
||||
<button id="cfgdelete" title="remove"><img src="data:image/gif;base64,R0lGODlhEAAQAPMAANXV1e3t7d/f39HR0dvb2/Hx8dTU1OLi4urq6mZmZpmZmf///wAAAAAAAAAAAAAAACH5BAEAAAwALAAAAAAQABAAAARBkMlJq71Yrp3ZXkr4WWCYnOZSgQVyEMYwJCq1nHhe20qgCAoA7QLyAYU7njE4JPV+zOSkCEUSFbmTVPPpbjvgTAQAOw== "></button>
|
||||
<button id="cfgdelete" title="remove"><img
|
||||
src="data:image/gif;base64,R0lGODlhEAAQAPMAANXV1e3t7d/f39HR0dvb2/Hx8dTU1OLi4urq6mZmZpmZmf///wAAAAAAAAAAAAAAACH5BAEAAAwALAAAAAAQABAAAARBkMlJq71Yrp3ZXkr4WWCYnOZSgQVyEMYwJCq1nHhe20qgCAoA7QLyAYU7njE4JPV+zOSkCEUSFbmTVPPpbjvgTAQAOw== "></button>
|
||||
</p>
|
||||
</div>
|
||||
<p id="savebar">
|
||||
<span><input type="button" value="Save" id="cfgsave"></span>
|
||||
<span id="cfgmore" title="advanced options">▼</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="apconfigbox">
|
||||
<div class="closebtn">✖</div>
|
||||
<h3>Access Point config</h3>
|
||||
<p>
|
||||
<label for="apcfgalias">Alias</label>
|
||||
<input id="apcfgalias" type="text">
|
||||
</p>
|
||||
<p>
|
||||
<label for="apcfgchid">Channel</label>
|
||||
<select id="apcfgchid">
|
||||
<option value="0" selected>auto</option>
|
||||
<option value="11">11</option>
|
||||
<option value="15">15</option>
|
||||
<option value="20">20</option>
|
||||
<option value="25">25</option>
|
||||
<option value="26">26</option>
|
||||
<option value="27">27</option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label for="apcfgledbrightness">LED brightness</label>
|
||||
<select id="apcfgledbrightness">
|
||||
<option value="-1">off</option>
|
||||
<option value="20">10%</option>
|
||||
<option value="64">25%</option>
|
||||
<option value="128" selected>50%</option>
|
||||
<option value="192">75%</option>
|
||||
<option value="255">100%</option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label for="apcfglanguage">Content language</label>
|
||||
<select id="apcfglanguage">
|
||||
<option value="0" selected>EN English</option>
|
||||
<option value="1">NL Nederlands</option>
|
||||
<option value="2">DE Deutsch</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="Depending on the content, a tag can sleep for
|
||||
longer periods when no updates are expected
|
||||
(like a date display). This setting specifies
|
||||
the maximum sleep time.">
|
||||
<label for="apclatency">Maximum sleep</label>
|
||||
<select id="apclatency">
|
||||
<option value="0" selected>shortest (40 sec)</option>
|
||||
<option value="5">5 minutes</option>
|
||||
<option value="10">10 minute</option>
|
||||
<option value="30">30 minutes</option>
|
||||
<option value="60">1 hour</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="If connected to the website, don't sleep extra.
|
||||
Latency will be around 40 seconds.">
|
||||
<label for="apcpreventsleep">Shorten latency during config</label>
|
||||
<select id="apcpreventsleep">
|
||||
<option value="0">no</option>
|
||||
<option value="1" selected>yes</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="Stops updates at night, and put the tags to sleep. During the configured night time, this overrides the maximum sleep time.">
|
||||
<label for="apcnight1">No updates between</label>
|
||||
<select id="apcnight1"></select>
|
||||
<span style="align-self:center;">and</span>
|
||||
<select id="apcnight2"></select>
|
||||
</p>
|
||||
<p title="Turn off preview images on the webpage if you want to manage many tags,
|
||||
to save file system space">
|
||||
<label for="apcpreview">Preview images</label>
|
||||
<select id="apcpreview">
|
||||
<option value="1" selected>yes</option>
|
||||
<option value="0">no</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="Wifi transmit power">
|
||||
<label for="apcwifipower">Wifi power</label>
|
||||
<select id="apcwifipower">
|
||||
<option value="78">19.5 dBm</option>
|
||||
<option value="76">19.0 dBm</option>
|
||||
<option value="74">18.5 dBm</option>
|
||||
<option value="68">17.0 dBm</option>
|
||||
<option value="60">15.0 dBm</option>
|
||||
<option value="52">13.0 dBm</option>
|
||||
<option value="44">11.0 dBm</option>
|
||||
<option value="34" selected>8.5 dBm</option>
|
||||
<option value="28">7.0 dBm</option>
|
||||
<option value="20">5.0 dBm</option>
|
||||
<option value="8">2.0 dBm</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="Your local time zone">
|
||||
<label for="apctimezone">Local time zone</label>
|
||||
<select id="apctimezone">
|
||||
<optgroup label="Europe">
|
||||
<option value="CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00" selected>Central European Time</option>
|
||||
<option value="EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00">Athens, Greece</option>
|
||||
<option value="GMT+0IST-1,M3.5.0/01:00:00,M10.5.0/02:00:00">Dublin, Ireland</option>
|
||||
<option value="EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00">Helsinki, Finland</option>
|
||||
<option value="WET-0WEST-1,M3.5.0/01:00:00,M10.5.0/02:00:00">Lisbon, Portugal</option>
|
||||
<option value="GMT+0BST-1,M3.5.0/01:00:00,M10.5.0/02:00:00">London, Great Britain</option>
|
||||
<option value="EET-2EEST,M3.5.0/3,M10.5.0/4">Kyiv, Ukraine</option>
|
||||
</optgroup>
|
||||
<optgroup label="USA / Canada">
|
||||
<option value="HAW10">Hawaii Time</option>
|
||||
<option value="AKST9AKDT">Alaska Time</option>
|
||||
<option value="PST8PDT">Pacific Time</option>
|
||||
<option value="MST7MDT">Mountain Time</option>
|
||||
<option value="MST7">Arizona, no DST</option>
|
||||
<option value="CST6CDT">Central Time</option>
|
||||
<option value="EST5EDT">Eastern Time</option>
|
||||
</optgroup>
|
||||
<optgroup label="Australia / New Zealand">
|
||||
<option value="EST-10EDT-11,M10.5.0/02:00:00,M3.5.0/03:00:00">Melbourne, Sydney</option>
|
||||
<option value="WST-8">Perth</option>
|
||||
<option value="EST-10">Brisbane</option>
|
||||
<option value="CST-9:30CDT-10:30,M10.5.0/02:00:00,M3.5.0/03:00:00">Adelaide</option>
|
||||
<option value="CST-9:30">Darwin</option>
|
||||
<option value="EST-10EDT-11,M10.1.0/02:00:00,M3.5.0/03:00:00">Hobart</option>
|
||||
<option value="NZST-12NZDT-13,M9.4.0/02:00:00,M4.1.0/03:00:00">New Zealand</option>
|
||||
</optgroup>
|
||||
<optgroup label="Asia">
|
||||
<option value="JST-9">Tokyo</option>
|
||||
<option value="WIB-7">Jakarta</option>
|
||||
<option value="GMT+2">Jerusalem</option>
|
||||
<option value="SGT-8">Singapore</option>
|
||||
<option value="ULAT-8ULAST,M3.5.0/2,M9.5.0/2">Ulaanbaatar, Mongolia</option>
|
||||
</optgroup>
|
||||
<optgroup label="Central and South America">
|
||||
<option value="BRST+3BRDT+2,M10.3.0,M2.3.0">Brazil, Sao Paulo</option>
|
||||
<option value="UTC+3">Argentina</option>
|
||||
<option value="CST+6">Central America</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<input type="button" value="Save" id="apcfgsave">
|
||||
</p>
|
||||
<p>
|
||||
Active access points:<br>
|
||||
<table id="aptable">
|
||||
<tr>
|
||||
<th>ip</th>
|
||||
<th>alias</th>
|
||||
<th>tags</th>
|
||||
<th>ch</th>
|
||||
<th>AP ver</th>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
<p>
|
||||
<span id="rebootbutton">reboot AP</span>
|
||||
<a href="/backup_db" id="downloadDBbutton">download tagDB</a>
|
||||
<span id="updatebutton">update</span>
|
||||
<a href="/setup" target="setup" class="filebutton">WiFi config</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://github.com/jjwbruijn/OpenEPaperLink" target="_new">Github OpenEPaperLink</a>
|
||||
</p>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<div id="apupdatebox">
|
||||
<div class="closebtn">✖</div>
|
||||
<h3>Update dashboard</h3>
|
||||
<div id="easyupdate"></div>
|
||||
<div id="advanceddiv">
|
||||
<!--<div>
|
||||
repo: <input type="text" name="repo"> <button id="switchRepo">Switch</button><br>
|
||||
environment: <span id="environment">environment</span>
|
||||
</div>-->
|
||||
<div id="releasetable"></div>
|
||||
<div>
|
||||
<div id="rollbackOption" style="display:none"><button id="rollbackBtn">Rollback to previous firmware</button></div>
|
||||
<span id="c6Option"><div id="updateC6Option"><button id="updateC6Btn">Update ESP32-C6</button> <input type="checkbox" value="1" checked id="c6download"> download latest version</div></span>
|
||||
<div id="rollbackOption" style="display:none"><button id="rollbackBtn">Rollback to previous
|
||||
firmware</button></div>
|
||||
<span id="c6Option">
|
||||
<div id="updateC6Option"><button id="updateC6Btn">Update ESP32-C6</button> <input type="checkbox"
|
||||
value="1" checked id="c6download"> download latest version</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -235,84 +489,8 @@ to save file system space">
|
||||
style="display: none; position: absolute; background: white; border: 1px solid gray; padding: 0; list-style: none;">
|
||||
</ul>
|
||||
|
||||
<form>
|
||||
<div class="container">
|
||||
|
||||
<div class="window">
|
||||
|
||||
<div class="actionbox">
|
||||
<div>
|
||||
<div>Currently active tags: <button class="filebutton" id="toggleFilters">arrange</button></div>
|
||||
<div><span id="temp"></div>
|
||||
<div><span id="runstate"></div>
|
||||
<div><span id="apstatecolor">⬤</span> <span id="apstate">loading</span></div>
|
||||
<div><span id="apconfigbutton">AP config</span></div>
|
||||
<div><a href="/edit" target="littlefs" class="filebutton">File System</a></div>
|
||||
</div>
|
||||
<div id="filterOptions">
|
||||
<div>
|
||||
<div>group by</div>
|
||||
<div><input type="radio" name="group" value="" id="rnone" checked><label for="rnone">None</label></div>
|
||||
<div><input type="radio" name="group" value="model" id="rtagtype"><label for="rtagtype">Tag model</label></div>
|
||||
<div><input type="radio" name="group" value="contentmode" id="rcontent"><label for="rcontent">Content</label></div>
|
||||
<div><input type="radio" name="group" value="data-channel" id="rchannel"><label for="rchannel">Channel</label></div>
|
||||
</div>
|
||||
<div>
|
||||
<div>sort by</div>
|
||||
<div><input type="radio" name="sort" value="alias" id="ralias" checked><label for="ralias">Alias</label></div>
|
||||
<div><input type="radio" name="sort" value="mac" id="rmac"><label for="rmac">Mac</label></div>
|
||||
<div><input type="radio" name="sort" value="data-lastseen" id="rlastseen"><label for="rlastseen">Last seen</label></div>
|
||||
<div><input type="radio" name="sort" value="data-nextupdate" id="rnext"><label for="rnext">Next update</label></div>
|
||||
</div>
|
||||
<div>
|
||||
<div>filter</div>
|
||||
<div><input type="checkbox" name="filter" value="local" id="rlocal"><label for="rlocal">only local</label></div>
|
||||
<div><input type="checkbox" name="filter" value="remote" id="rremote"><label for="rremote">only remote</label></div>
|
||||
<div><input type="checkbox" name="filter" value="inactive" id="rinactive"><label for="rinactive">only inactive</label></div>
|
||||
<div><input type="checkbox" name="filter" value="pending" id="rpending"><label for="rpending">only pending</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="taglist" class="taglist">
|
||||
<div class="tagcard" id="tagtemplate">
|
||||
<div class="currimg"><canvas class="tagimg"></div>
|
||||
<div class="mac"></div>
|
||||
<div class="alias"></div>
|
||||
<div class="model"></div>
|
||||
|
||||
<div class="received"></div>
|
||||
|
||||
<div class="contentmode"></div>
|
||||
<div class="lastseen"></div>
|
||||
<div class="nextcheckin"></div>
|
||||
<div class="nextupdate"></div>
|
||||
<div class="corner">
|
||||
<div class="pendingicon" title="A new message is waiting for the tag to pick up">↻</div>
|
||||
<div class="warningicon" title="This tag has not been seen for a long time">⚠</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="logbox">
|
||||
<p>
|
||||
<span>logging</span>
|
||||
<span><img id="clearlog" src="data:image/gif;base64,R0lGODlhEAAQAPMAANXV1e3t7d/f39HR0dvb2/Hx8dTU1OLi4urq6mZmZpmZmf///wAAAAAAAAAAAAAAACH5BAEAAAwALAAAAAAQABAAAARBkMlJq71Yrp3ZXkr4WWCYnOZSgQVyEMYwJCq1nHhe20qgCAoA7QLyAYU7njE4JPV+zOSkCEUSFbmTVPPpbjvgTAQAOw==
|
||||
"></span>
|
||||
<span id="sysinfo"></span>
|
||||
</p>
|
||||
<ul id="messages" class="messages">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script src="main.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
@@ -1,7 +1,7 @@
|
||||
* {
|
||||
margin:0;
|
||||
padding:0;
|
||||
border:0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
list-style-type: none;
|
||||
outline: none;
|
||||
font-weight: 400;
|
||||
@@ -12,7 +12,8 @@
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
html, body {
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -24,60 +25,263 @@ body {
|
||||
}
|
||||
|
||||
header {
|
||||
height: 50px;
|
||||
background-color: #646260;
|
||||
z-index: 999;
|
||||
position: sticky;
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
label {
|
||||
width: 120px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding: 3px 0px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
margin: 0 auto;
|
||||
height: 50px;
|
||||
text-indent: 50px;
|
||||
overflow:hidden;
|
||||
font-size: 2.5em;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.window {
|
||||
margin: 0 auto;
|
||||
max-width: 94%;
|
||||
}
|
||||
|
||||
.actionbox {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.actionbox>div:first-child>div:first-child {
|
||||
nav>div:first-child>div:first-child {
|
||||
flex-grow: 2;
|
||||
}
|
||||
|
||||
.actionbox>div {
|
||||
display:flex;
|
||||
nav>div {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
padding: 10px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.actionbox label {
|
||||
nav label {
|
||||
padding: 0px 5px;
|
||||
vertical-align: text-bottom;
|
||||
width: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#rebootbutton, #updatebutton, #downloadDBbutton, #apconfigbutton, .filebutton {
|
||||
padding: 2px 5px;
|
||||
background-color: #cccccc;
|
||||
footer {
|
||||
padding: 5px;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
background-color: white;
|
||||
|
||||
#sysinfo {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
margin: 0 auto;
|
||||
height: 50px;
|
||||
text-indent: 50px;
|
||||
overflow: hidden;
|
||||
font-size: 2.5em;
|
||||
color: white;
|
||||
}
|
||||
|
||||
h3 {
|
||||
padding-bottom: 10px;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
/* tabs */
|
||||
|
||||
.tab-container {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.tablinks {
|
||||
background-color: #f2f2f2;
|
||||
padding: 5px 10px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-container .active {
|
||||
background-color: #ccc;
|
||||
margin-top: 10px;
|
||||
margin-bottom: -10px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.tabcontent {
|
||||
display: none;
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
|
||||
|
||||
label {
|
||||
width: 200px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding: 4px 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding-bottom: 20px;
|
||||
;
|
||||
}
|
||||
|
||||
#hometab {
|
||||
font-size: 24px;
|
||||
|
||||
& table {
|
||||
margin: 20px;
|
||||
background: #fff;
|
||||
padding: 5px 20px;
|
||||
border-spacing: 0px;
|
||||
}
|
||||
|
||||
& td {
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
& td:nth-child(3) {
|
||||
text-align: right;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
& tr:hover {
|
||||
background-color: #ccc;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
& .material-symbols-outlined {
|
||||
font-size: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.tagheader {
|
||||
width: 100%;
|
||||
padding: 10px 10px;
|
||||
display: flex;
|
||||
gap: 2em;
|
||||
justify-content: space-between;
|
||||
|
||||
& #toggleFilters {
|
||||
padding: 0px 10px;
|
||||
}
|
||||
|
||||
& h3 {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
& #activefilter {
|
||||
flex-grow: 2;
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
|
||||
.tabheader {
|
||||
background-color: white;
|
||||
padding: 5px 10px;
|
||||
display: flex;
|
||||
gap: 2em;
|
||||
}
|
||||
|
||||
#filterOptions {
|
||||
background-color: white;
|
||||
max-height: 0;
|
||||
padding: 0px 10px;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease-in-out;
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
|
||||
&.active {
|
||||
padding: 10px 10px;
|
||||
max-height: 100px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
& label {
|
||||
width: inherit;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding: 0px 5px;
|
||||
}
|
||||
}
|
||||
|
||||
#aptab,
|
||||
#configtab {
|
||||
padding: 10px;
|
||||
|
||||
& p {
|
||||
padding: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
#aplist {
|
||||
display: flex;
|
||||
gap: 1em;
|
||||
flex-flow: wrap;
|
||||
}
|
||||
|
||||
.apcard {
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
width: 300px;
|
||||
|
||||
& .apalias {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
& .space {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
& div {
|
||||
display: flex;
|
||||
font-size: 2.0em;
|
||||
align-items: center;
|
||||
gap: 0.2em;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#apcard {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#apcfgsave {
|
||||
margin: 20px 205px;
|
||||
}
|
||||
|
||||
.filebutton {
|
||||
width: inherit;
|
||||
padding: 5px 10px;
|
||||
margin-bottom: 0px;
|
||||
margin-top: -1px;
|
||||
background-color: #ccc;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
|
||||
&:hover {
|
||||
background-color: #aaa;
|
||||
}
|
||||
}
|
||||
|
||||
#rebootbutton,
|
||||
#updatebutton,
|
||||
#downloadDBbutton,
|
||||
.wifibutton {
|
||||
padding: 4px 5px;
|
||||
background-color: #ccc;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
width: 120px;
|
||||
margin: 2px 5px 2px 20px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
|
||||
&:hover {
|
||||
background-color: #aaa;
|
||||
}
|
||||
}
|
||||
|
||||
.columns div {
|
||||
@@ -100,15 +304,17 @@ input {
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
input[type=button], button {
|
||||
input[type=button],
|
||||
button {
|
||||
border: 0px;
|
||||
padding: 4px 10px;
|
||||
cursor:pointer;
|
||||
cursor: pointer;
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
input[type=button]:hover,
|
||||
button:hover {
|
||||
background-color:#aaaaaa;
|
||||
background-color: #aaaaaa;
|
||||
}
|
||||
|
||||
select {
|
||||
@@ -117,7 +323,8 @@ select {
|
||||
border: solid 1px #cccccc;
|
||||
}
|
||||
|
||||
#configbox, #apconfigbox, #apupdatebox {
|
||||
#apconfigbox,
|
||||
#apupdatebox {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 65px;
|
||||
@@ -131,19 +338,35 @@ select {
|
||||
max-height: calc(100vh - 75px);
|
||||
}
|
||||
|
||||
#configbox p, #apconfigbox p, #apupdatebox p {
|
||||
#configbox {
|
||||
margin: auto;
|
||||
min-width: 380px;
|
||||
padding: 15px;
|
||||
background-color: #f0e6d3;
|
||||
z-index: 999;
|
||||
box-shadow: 7px 10px 52px -19px rgba(0, 0, 0, 0.63);
|
||||
overflow: auto;
|
||||
max-height: calc(100vh - 75px);
|
||||
}
|
||||
|
||||
#configbox p,
|
||||
#apconfigbox p,
|
||||
#apupdatebox p {
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
#configbox h3, #apconfigbox h3, #apupdatebox h3 {
|
||||
#configbox h3,
|
||||
#apconfigbox h3,
|
||||
#apupdatebox h3 {
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#configbox input, #apconfigbox input {
|
||||
#configbox input,
|
||||
#apconfigbox input {
|
||||
border: solid 1px #cccccc;
|
||||
}
|
||||
|
||||
@@ -191,31 +414,6 @@ select {
|
||||
background-color: #e6f0d3;
|
||||
}
|
||||
|
||||
#aptable {
|
||||
width: 100%;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
#aptable th {
|
||||
text-align: left;
|
||||
background-color: #00000020;
|
||||
padding: 0px 3px;
|
||||
}
|
||||
|
||||
#aptable th, #aptable td {
|
||||
border-right: 1px solid #000010;
|
||||
padding: 0px 3px;
|
||||
}
|
||||
|
||||
#aptable td:nth-child(1), #aptable th:nth-child(1) {
|
||||
border-left: 1px solid #000010;
|
||||
}
|
||||
|
||||
#aptable td:nth-child(3),
|
||||
#aptable td:nth-child(4) {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#apupdatebox {
|
||||
background-color: #f0d0c8;
|
||||
width: 700px;
|
||||
@@ -228,7 +426,8 @@ select {
|
||||
padding: 2px 10px;
|
||||
}
|
||||
|
||||
.closebtn {
|
||||
.closebtn,
|
||||
.closebtn2 {
|
||||
border: 1px solid black;
|
||||
float: right;
|
||||
width: 19px;
|
||||
@@ -239,22 +438,21 @@ select {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.logbox {
|
||||
margin: 5px;
|
||||
}
|
||||
#logtab {
|
||||
& img {
|
||||
vertical-align: bottom;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.logbox p {
|
||||
background-color: #ffffff;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
& label {
|
||||
width: inherit;
|
||||
vertical-align: top;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
|
||||
.logbox img {
|
||||
vertical-align: bottom;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.logbox #sysinfo {
|
||||
float: right;
|
||||
& input {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
}
|
||||
|
||||
.blink-red {
|
||||
@@ -265,10 +463,11 @@ select {
|
||||
.taglist {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 0px 10px 30px 10px;
|
||||
}
|
||||
|
||||
#tagtemplate {
|
||||
display:none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tagcard {
|
||||
@@ -280,12 +479,12 @@ select {
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #cccccc;
|
||||
transition: box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.tagcard:hover {
|
||||
cursor:pointer;
|
||||
box-shadow: 7px 10px 52px -19px rgba(0, 0, 0, 0.63);
|
||||
filter: brightness(1.02);
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
box-shadow: 7px 10px 52px -19px rgba(0, 0, 0, 0.63);
|
||||
filter: brightness(1.02);
|
||||
}
|
||||
}
|
||||
|
||||
.tagflash {
|
||||
@@ -305,30 +504,19 @@ select {
|
||||
margin: 0px 5px;
|
||||
}
|
||||
|
||||
#filterOptions {
|
||||
max-height: 0;
|
||||
padding: 0 10px;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease-in-out, padding 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
#filterOptions.active {
|
||||
max-height: 100px;
|
||||
padding: 10px 10px;
|
||||
}
|
||||
|
||||
.currimg {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.currimg img, .currimg canvas {
|
||||
.currimg img,
|
||||
.currimg canvas {
|
||||
max-width: 50px;
|
||||
border: 1px solid #c0c0c0;
|
||||
}
|
||||
|
||||
.mac {
|
||||
font-size: 0.9em;
|
||||
cursor:pointer;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.alias {
|
||||
@@ -344,6 +532,7 @@ select {
|
||||
font-size: .85em;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.received div {
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -354,16 +543,19 @@ select {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.lastseen, .nextcheckin, .nextupdate {
|
||||
.lastseen,
|
||||
.nextcheckin,
|
||||
.nextupdate {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.lastseen span,
|
||||
.nextcheckin span,
|
||||
.nextupdate span {
|
||||
width:105px;
|
||||
display:inline-block;
|
||||
width: 105px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.corner {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
@@ -383,7 +575,7 @@ select {
|
||||
}
|
||||
|
||||
.warningicon {
|
||||
display:none;
|
||||
display: none;
|
||||
font-size: 1.3em;
|
||||
background-color: yellow;
|
||||
color: black;
|
||||
@@ -412,12 +604,24 @@ ul.messages li.new {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.mono {
|
||||
font-family: monospace;
|
||||
word-break: break-all;
|
||||
background-color: #666;
|
||||
color: #ccc;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.quote {
|
||||
color: white;
|
||||
}
|
||||
|
||||
#paintbutton {
|
||||
padding: 1px 3px;
|
||||
border: 1px solid black;
|
||||
font-size: 1.3em;
|
||||
vertical-align: top;
|
||||
margin-left:12px;
|
||||
margin-left: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -472,6 +676,7 @@ ul.messages li.new {
|
||||
background-color: #dddddd;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
#buttonbar button {
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
@@ -513,7 +718,7 @@ ul.messages li.new {
|
||||
|
||||
/* updatescreens */
|
||||
|
||||
#easyupdate{
|
||||
#easyupdate {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
@@ -578,7 +783,7 @@ ul.messages li.new {
|
||||
.console {
|
||||
width: 100%;
|
||||
background-color: black;
|
||||
font-family: 'lucida console','ui-monospace';
|
||||
font-family: 'lucida console', 'ui-monospace';
|
||||
color: white;
|
||||
padding: 5px 10px;
|
||||
margin: 20px 0px;
|
||||
@@ -587,6 +792,7 @@ ul.messages li.new {
|
||||
overflow-y: scroll;
|
||||
white-space: break-spaces;
|
||||
}
|
||||
|
||||
.console div {
|
||||
word-break: break-all;
|
||||
}
|
||||
@@ -594,36 +800,62 @@ ul.messages li.new {
|
||||
/* media */
|
||||
|
||||
@media(max-width: 460px) {
|
||||
.messages li div, ul.messages li div.date, ul.messages li div.message {
|
||||
display:block;
|
||||
position:relative;
|
||||
|
||||
.messages li div,
|
||||
ul.messages li div.date,
|
||||
ul.messages li div.message {
|
||||
display: block;
|
||||
position: relative;
|
||||
padding: 0;
|
||||
left: auto;
|
||||
}
|
||||
.messages li div.message, li.pending {
|
||||
|
||||
.messages li div.message,
|
||||
li.pending {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
ul.messages {
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes new {
|
||||
0% { background-color: rgba(255, 255, 204, 1); }
|
||||
50% { background-color: rgba(255, 255, 204, .5); }
|
||||
100% { background-color: rgba(255, 255, 204, 0); }
|
||||
0% {
|
||||
background-color: rgba(255, 255, 204, 1);
|
||||
}
|
||||
|
||||
50% {
|
||||
background-color: rgba(255, 255, 204, .5);
|
||||
}
|
||||
|
||||
100% {
|
||||
background-color: rgba(255, 255, 204, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes tagflash {
|
||||
0% { opacity: 1; }
|
||||
50% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pending {
|
||||
0% { }
|
||||
50% { background-color: #d4d4f5;}
|
||||
100% { }
|
||||
0% {}
|
||||
|
||||
50% {
|
||||
background-color: #d4d4f5;
|
||||
}
|
||||
|
||||
100% {}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
@@ -638,7 +870,7 @@ ul.messages li.new {
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.logbox #sysinfo {
|
||||
footer #sysinfo {
|
||||
float: none;
|
||||
display: block;
|
||||
}
|
||||
@@ -682,4 +914,4 @@ ul.messages li.new {
|
||||
padding: 1px 1px;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ let finishedInitialLoading = false;
|
||||
let getTagtypeBusy = false;
|
||||
|
||||
const loadConfig = new Event("loadConfig");
|
||||
window.addEventListener("loadConfig", function() {
|
||||
window.addEventListener("loadConfig", function () {
|
||||
fetch("/get_ap_config")
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
@@ -55,6 +55,7 @@ window.addEventListener("loadConfig", function() {
|
||||
});
|
||||
|
||||
window.addEventListener("load", function () {
|
||||
initTabs();
|
||||
fetch('/content_cards.json')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
@@ -69,12 +70,36 @@ window.addEventListener("load", function () {
|
||||
});
|
||||
|
||||
window.dispatchEvent(loadConfig);
|
||||
|
||||
|
||||
dropUpload();
|
||||
populateTimes($('#apcnight1'));
|
||||
populateTimes($('#apcnight2'));
|
||||
});
|
||||
|
||||
/* tabs */
|
||||
let activeTab = '';
|
||||
function initTabs() {
|
||||
const tabLinks = document.querySelectorAll(".tablinks");
|
||||
const tabContents = document.querySelectorAll(".tabcontent");
|
||||
|
||||
tabLinks.forEach(tabLink => {
|
||||
tabLink.addEventListener("click", function () {
|
||||
const targetId = this.getAttribute("data-target");
|
||||
const loadTabEvent = new CustomEvent('loadTab', { detail: targetId });
|
||||
document.dispatchEvent(loadTabEvent);
|
||||
tabContents.forEach(tabContent => {
|
||||
tabContent.style.display = "none";
|
||||
});
|
||||
tabLinks.forEach(link => {
|
||||
link.classList.remove("active");
|
||||
});
|
||||
document.getElementById(targetId).style.display = "block";
|
||||
this.classList.add("active");
|
||||
});
|
||||
});
|
||||
tabLinks[0].click();
|
||||
};
|
||||
|
||||
function loadTags(pos) {
|
||||
fetch("/get_db?pos=" + pos)
|
||||
.then(response => response.json())
|
||||
@@ -94,7 +119,10 @@ function connect() {
|
||||
});
|
||||
|
||||
socket.addEventListener("message", (event) => {
|
||||
console.log(event.data)
|
||||
if ($('#showdebug').checked) {
|
||||
showMessage(event.data);
|
||||
console.log(event.data);
|
||||
}
|
||||
const msg = JSON.parse(event.data);
|
||||
if (msg.logMsg) {
|
||||
showMessage(msg.logMsg, false);
|
||||
@@ -115,17 +143,12 @@ function connect() {
|
||||
$("#apstatecolor").style.color = apstate[msg.sys.apstate].color;
|
||||
$("#apstate").innerHTML = apstate[msg.sys.apstate].state;
|
||||
$("#runstate").innerHTML = runstate[msg.sys.runstate].state;
|
||||
if (msg.sys.temp) $("#temp").innerHTML = msg.sys.temp.toFixed(1) + '°C';
|
||||
$('#dashboardStatus').innerHTML = apstate[msg.sys.apstate].state;
|
||||
}
|
||||
servertimediff = (Date.now() / 1000) - msg.sys.currtime;
|
||||
}
|
||||
if (msg.apitem) {
|
||||
let row = $("#aptable").insertRow();
|
||||
row.insertCell(0).innerHTML = "<a href=\"http://" + msg.apitem.ip + "\" target=\"_new\">" + msg.apitem.ip + "</a>";
|
||||
row.insertCell(1).innerHTML = msg.apitem.alias;
|
||||
row.insertCell(2).innerHTML = msg.apitem.count;
|
||||
row.insertCell(3).innerHTML = msg.apitem.channel;
|
||||
row.insertCell(4).innerHTML = msg.apitem.version;
|
||||
populateAPCard(msg.apitem);
|
||||
}
|
||||
if (msg.console) {
|
||||
if (otamodule && typeof (otamodule.print) === "function") {
|
||||
@@ -301,9 +324,16 @@ function processTags(tagArray) {
|
||||
|
||||
function updatecards() {
|
||||
if (servertimediff > 1000000000) servertimediff = 0;
|
||||
let tagcount = 0;
|
||||
let pendingcount = 0;
|
||||
let timeoutcount = 0;
|
||||
let lowbattcount = 0;
|
||||
|
||||
$('#taglist').querySelectorAll('[data-mac]').forEach(item => {
|
||||
let tagmac = item.dataset.mac;
|
||||
|
||||
tagcount++;
|
||||
if (tagDB[tagmac].pending) pendingcount++;
|
||||
if (tagDB[tagmac].batteryMv < 2400 && tagDB[tagmac].batteryMv != 0 && tagDB[tagmac].batteryMv != 1337) lowbattcount++;
|
||||
if (item.dataset.lastseen && item.dataset.lastseen > (Date.now() / 1000) - servertimediff - 30 * 24 * 3600 * 60) {
|
||||
let idletime = (Date.now() / 1000) - servertimediff - item.dataset.lastseen;
|
||||
$('#tag' + tagmac + ' .lastseen').innerHTML = "<span>last seen</span>" + displayTime(Math.floor(idletime)) + " ago";
|
||||
@@ -311,6 +341,7 @@ function updatecards() {
|
||||
$('#tag' + tagmac + ' .warningicon').style.display = 'inline-block';
|
||||
$('#tag' + tagmac).classList.remove("tagpending")
|
||||
$('#tag' + tagmac).style.background = '#e0e0a0';
|
||||
timeoutcount++;
|
||||
}
|
||||
if (idletime > 24 * 3600) {
|
||||
$('#tag' + tagmac).style.opacity = '.5';
|
||||
@@ -331,6 +362,11 @@ function updatecards() {
|
||||
$('#tag' + tagmac + ' .nextcheckin').innerHTML = "";
|
||||
}
|
||||
})
|
||||
|
||||
$('#dashboardTagCount').innerHTML = tagcount;
|
||||
$('#dashboardPending').innerHTML = pendingcount;
|
||||
$('#dashboardLowBatt').innerHTML = lowbattcount;
|
||||
$('#dashboardTimeout').innerHTML = timeoutcount;
|
||||
}
|
||||
|
||||
$('#clearlog').onclick = function () {
|
||||
@@ -344,6 +380,13 @@ document.querySelectorAll('.closebtn').forEach(button => {
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.closebtn2').forEach(button => {
|
||||
button.addEventListener('click', (event) => {
|
||||
event.target.parentNode.close();
|
||||
$('#advancedoptions').style.height = '0px';
|
||||
});
|
||||
});
|
||||
|
||||
//clicking on a tag: load config dialog for tag
|
||||
$('#taglist').addEventListener("click", (event) => {
|
||||
let currentElement = event.target;
|
||||
@@ -382,7 +425,7 @@ function loadContentCard(mac) {
|
||||
$('#cfgrotate').value = tagdata.rotate;
|
||||
$('#cfglut').value = tagdata.lut;
|
||||
$('#cfgmore').innerHTML = '▼';
|
||||
$('#configbox').style.display = 'block';
|
||||
$('#configbox').showModal();
|
||||
})
|
||||
}
|
||||
|
||||
@@ -444,7 +487,7 @@ $('#cfgsave').onclick = function () {
|
||||
.catch(error => showMessage('Error: ' + error));
|
||||
|
||||
$('#advancedoptions').style.height = '0px';
|
||||
$('#configbox').style.display = 'none';
|
||||
$('#configbox').close();
|
||||
}
|
||||
|
||||
function sendCmd(mac, cmd) {
|
||||
@@ -463,7 +506,7 @@ function sendCmd(mac, cmd) {
|
||||
})
|
||||
.catch(error => showMessage('Error: ' + error));
|
||||
$('#advancedoptions').style.height = '0px';
|
||||
$('#configbox').style.display = 'none';
|
||||
$('#configbox').close();
|
||||
}
|
||||
|
||||
$('#cfgdelete').onclick = function () {
|
||||
@@ -494,7 +537,8 @@ $('#cfgreset').onclick = function () {
|
||||
sendCmd($('#cfgmac').dataset.mac, "reset");
|
||||
}
|
||||
|
||||
$('#rebootbutton').onclick = function () {
|
||||
$('#rebootbutton').onclick = function (event) {
|
||||
event.preventDefault();
|
||||
showMessage("rebooting AP....", true);
|
||||
fetch("/reboot", {
|
||||
method: "POST"
|
||||
@@ -502,30 +546,37 @@ $('#rebootbutton').onclick = function () {
|
||||
socket.close();
|
||||
}
|
||||
|
||||
$('#apconfigbutton').onclick = function () {
|
||||
let table = document.getElementById("aptable");
|
||||
const rowCount = table.rows.length;
|
||||
for (let i = rowCount - 1; i > 0; i--) {
|
||||
table.deleteRow(i);
|
||||
$('#configbox').addEventListener('click', (event) => {
|
||||
if (event.target.nodeName === 'DIALOG') {
|
||||
$('#configbox').close();
|
||||
}
|
||||
fetch("/get_ap_config")
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
apConfig = data;
|
||||
$('#apcfgalias').value = data.alias;
|
||||
$('#apcfgchid').value = data.channel;
|
||||
$("#apcfgledbrightness").value = data.led;
|
||||
$("#apcfglanguage").value = data.language;
|
||||
$("#apclatency").value = data.maxsleep;
|
||||
$("#apcpreventsleep").value = data.stopsleep;
|
||||
$("#apcpreview").value = data.preview;
|
||||
$("#apcwifipower").value = data.wifipower;
|
||||
$("#apctimezone").value = data.timezone;
|
||||
$("#apcnight1").value = data.sleeptime1;
|
||||
$("#apcnight2").value = data.sleeptime2;
|
||||
})
|
||||
$('#apconfigbox').style.display = 'block'
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener("loadTab", function (event) {
|
||||
activeTab = event.detail;
|
||||
switch (event.detail) {
|
||||
case 'configtab':
|
||||
case 'aptab':
|
||||
fetch("/get_ap_config")
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
apConfig = data;
|
||||
$('#apcfgalias').value = data.alias;
|
||||
$('#apcfgchid').value = data.channel;
|
||||
$("#apcfgledbrightness").value = data.led;
|
||||
$("#apcfglanguage").value = data.language;
|
||||
$("#apclatency").value = data.maxsleep;
|
||||
$("#apcpreventsleep").value = data.stopsleep;
|
||||
$("#apcpreview").value = data.preview;
|
||||
$("#apcwifipower").value = data.wifipower;
|
||||
$("#apctimezone").value = data.timezone;
|
||||
$("#apcnight1").value = data.sleeptime1;
|
||||
$("#apcnight2").value = data.sleeptime2;
|
||||
})
|
||||
$('#apcfgmsg').innerHTML = '';
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
$('#apcfgsave').onclick = function () {
|
||||
let formData = new FormData();
|
||||
@@ -549,14 +600,13 @@ $('#apcfgsave').onclick = function () {
|
||||
.then(data => {
|
||||
showMessage(data);
|
||||
window.dispatchEvent(loadConfig);
|
||||
$('#apcfgmsg').innerHTML = 'OK, Saved';
|
||||
})
|
||||
.catch(error => showMessage('Error: ' + error));
|
||||
|
||||
$('#apconfigbox').style.display = 'none';
|
||||
}
|
||||
|
||||
$('#updatebutton').onclick = function () {
|
||||
$('#apconfigbox').style.display = 'none';
|
||||
$('#updatebutton').onclick = function (event) {
|
||||
event.preventDefault();
|
||||
$('#apupdatebox').style.display = 'block';
|
||||
loadOTA();
|
||||
}
|
||||
@@ -720,7 +770,9 @@ function showMessage(message, iserr) {
|
||||
const messages = $('#messages');
|
||||
const date = new Date();
|
||||
const time = date.toLocaleTimeString('nl-NL', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
||||
if (iserr) {
|
||||
if (message.startsWith('{')) {
|
||||
messages.insertAdjacentHTML("afterbegin", '<li class="new">' + htmlEncode(time) + ' <span class="mono">' + message.replace(/"([^"]+)"/g, '"<span class="quote">$1</span>"') + '</span></li>');
|
||||
} else if (iserr) {
|
||||
messages.insertAdjacentHTML("afterbegin", '<li class="new error">' + htmlEncode(time + ' ' + message) + '</li>');
|
||||
} else {
|
||||
messages.insertAdjacentHTML("afterbegin", '<li class="new">' + htmlEncode(time + ' ' + message) + '</li>');
|
||||
@@ -887,12 +939,18 @@ function GroupSortFilter() {
|
||||
}
|
||||
|
||||
let show = true;
|
||||
let batteryMv = tagDB[item.dataset.mac].batteryMv;
|
||||
if ($('input[name="filter"][value="remote"]').checked && item.dataset.isexternal == "false") show = false;
|
||||
if ($('input[name="filter"][value="local"]').checked && item.dataset.isexternal == "true") show = false;
|
||||
if ($('input[name="filter"][value="inactive"]').checked && item.querySelector('.warningicon').style.display != 'inline-block') show = false;
|
||||
if ($('input[name="filter"][value="pending"]').checked && !item.classList.contains("tagpending")) show = false;
|
||||
if ($('input[name="filter"][value="lowbatt"]').checked && (batteryMv >= 2400 || batteryMv == 0 || batteryMv == 1337)) show = false;
|
||||
if (!show) item.style.display = 'none'; else item.style.display = 'block';
|
||||
item.style.order = order++;
|
||||
const checkedValues = Array.from(document.querySelectorAll('input[name="filter"]:checked'))
|
||||
.map(checkbox => checkbox.value)
|
||||
.join(', ');
|
||||
$('#activefilter').innerHTML = (checkedValues ? 'filtered by ' + checkedValues : '');
|
||||
});
|
||||
|
||||
headItems = Array.from($('#taglist').getElementsByClassName('taggroup'));
|
||||
@@ -901,7 +959,7 @@ function GroupSortFilter() {
|
||||
})
|
||||
}
|
||||
|
||||
$('#toggleFilters').addEventListener('click', () => {
|
||||
$('#toggleFilters').addEventListener('click', (event) => {
|
||||
event.preventDefault();
|
||||
const filterOptions = $('#filterOptions');
|
||||
filterOptions.classList.toggle('active');
|
||||
@@ -912,6 +970,13 @@ $('#toggleFilters').addEventListener('click', () => {
|
||||
}
|
||||
});
|
||||
|
||||
$('#activefilter').addEventListener('click', (event) => {
|
||||
event.preventDefault();
|
||||
const filterOptions = $('#filterOptions');
|
||||
filterOptions.classList.add('active');
|
||||
filterOptions.style.maxHeight = filterOptions.scrollHeight + 20 + 'px';
|
||||
});
|
||||
|
||||
async function getTagtype(hwtype) {
|
||||
if (tagTypes[hwtype]) {
|
||||
return tagTypes[hwtype];
|
||||
@@ -1156,4 +1221,83 @@ function populateTimes(element) {
|
||||
option.text = i.toString().padStart(2, "0") + ":00";
|
||||
element.appendChild(option);
|
||||
}
|
||||
}
|
||||
|
||||
function populateAPCard(msg) {
|
||||
let apip = msg.ip;
|
||||
let apid = apip.replace(/\./g, "-");
|
||||
if (!$('#ap' + apid)) {
|
||||
div = $('#apcard').cloneNode(true);
|
||||
div.setAttribute('id', 'ap' + apid);
|
||||
$('#aplist').appendChild(div);
|
||||
}
|
||||
let alias = msg.alias;
|
||||
if (!alias) alias = apip;
|
||||
$('#ap' + apid + ' .apip').innerHTML = "<a href=\"http://" + apip + "\" target=\"_new\">" + apip + "</a>";
|
||||
$('#ap' + apid + ' .apalias').innerHTML = alias;
|
||||
$('#ap' + apid + ' .aptagcount').innerHTML = msg.count;
|
||||
$('#ap' + apid + ' .apchannel').innerHTML = msg.channel;
|
||||
|
||||
const elements = document.querySelectorAll('.apchannel');
|
||||
Array.from(elements).forEach(element => {
|
||||
if (element.textContent === msg.channel && element.id !== 'ap' + apid) {
|
||||
$('#ap' + apid + ' .apchannel').style.color = 'red';
|
||||
$('#ap' + apid + ' .apchannel').innerHTML += ' conflict';
|
||||
}
|
||||
});
|
||||
|
||||
// $('#ap' + apid + ' .apversion').innerHTML = msg.version;
|
||||
if (activeTab == 'aptab') {
|
||||
populateAPInfo(apip);
|
||||
}
|
||||
}
|
||||
|
||||
function populateAPInfo(apip) {
|
||||
let apid = apip.replace(/\./g, "-");
|
||||
fetch('http://' + apip + '/sysinfo')
|
||||
.then(response => {
|
||||
if (response.status != 200) {
|
||||
$('#ap' + apid + ' .apswversion').innerHTML = "Error fetching sysinfo: " + response.status;
|
||||
return {};
|
||||
} else {
|
||||
return response.json();
|
||||
}
|
||||
})
|
||||
.then(data => {
|
||||
if (data.env) {
|
||||
let version = '';
|
||||
version += `env: ${data.env}<br>`;
|
||||
version += `build date: ${formatEpoch(data.buildtime)}<br>`;
|
||||
version += `esp32 version: ${data.buildversion}<br>`;
|
||||
version += `psram size: ${data.psramsize}<br>`;
|
||||
version += `flash size: ${data.flashsize}<br>`;
|
||||
$('#ap' + apid + ' .apswversion').innerHTML = version;
|
||||
// if (data.env == 'ESP32_S3_16_8_YELLOW_AP') $("#c6Option").style.display = 'block';
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
$('#ap' + apid + ' .apswversion').innerHTML = "Error fetching sysinfo: " + error;
|
||||
});
|
||||
}
|
||||
|
||||
function formatEpoch(epochTime) {
|
||||
const date = new Date(epochTime * 1000); // Convert seconds to milliseconds
|
||||
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0'); // Months are zero-based
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
||||
}
|
||||
|
||||
function setFilterAndShow(filter) {
|
||||
$('input[name="filter"][value="remote"]').checked = false;
|
||||
$('input[name="filter"][value="local"]').checked = false;
|
||||
$('input[name="filter"][value="inactive"]').checked = (filter == 'inactive');
|
||||
$('input[name="filter"][value="pending"]').checked = (filter == 'pending');
|
||||
$('input[name="filter"][value="lowbatt"]').checked = (filter == 'lowbatt');
|
||||
GroupSortFilter();
|
||||
$(`[data-target='tagtab']`).click();
|
||||
}
|
||||
Reference in New Issue
Block a user