mirror of
https://github.com/Ysurac/openmptcprouter-feeds.git
synced 2025-03-09 15:40:03 +00:00
Update luci and theme
This commit is contained in:
parent
fe03553aae
commit
4d7962337f
165 changed files with 74180 additions and 13802 deletions
66
luci-base/luasrc/view/admin_uci/changelog.htm
Normal file
66
luci-base/luasrc/view/admin_uci/changelog.htm
Normal file
|
@ -0,0 +1,66 @@
|
|||
<%#
|
||||
Copyright 2010 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<% export("uci_changelog", function(changes) -%>
|
||||
<div class="cbi-section">
|
||||
<strong><%:Legend:%></strong>
|
||||
<div class="uci-change-legend">
|
||||
<div class="uci-change-legend-label"><ins> </ins> <%:Section added%></div>
|
||||
<div class="uci-change-legend-label"><del> </del> <%:Section removed%></div>
|
||||
<div class="uci-change-legend-label"><var><ins> </ins></var> <%:Option changed%></div>
|
||||
<div class="uci-change-legend-label"><var><del> </del></var> <%:Option removed%></div>
|
||||
<br style="clear:both" />
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<div class="uci-change-list"><%
|
||||
local util = luci.util
|
||||
local tpl = {
|
||||
["add-3"] = "<ins>uci add %0 <strong>%3</strong> # =%2</ins>",
|
||||
["set-3"] = "<ins>uci set %0.<strong>%2</strong>=%3</ins>",
|
||||
["set-4"] = "<var><ins>uci set %0.%2.%3=<strong>%4</strong></ins></var>",
|
||||
["remove-2"] = "<del>uci del %0.<strong>%2</strong></del>",
|
||||
["remove-3"] = "<var><del>uci del %0.%2.<strong>%3</strong></del></var>",
|
||||
["order-3"] = "<var>uci reorder %0.%2=<strong>%3</strong></var>",
|
||||
["list-add-4"] = "<var><ins>uci add_list %0.%2.%3=<strong>%4</strong></ins></var>",
|
||||
["list-del-4"] = "<var><del>uci del_list %0.%2.%3=<strong>%4</strong></del></var>",
|
||||
["rename-3"] = "<var>uci rename %0.%2=<strong>%3</strong></var>",
|
||||
["rename-4"] = "<var>uci rename %0.%2.%3=<strong>%4</strong></var>"
|
||||
}
|
||||
|
||||
local conf, deltas
|
||||
for conf, deltas in util.kspairs(changes) do
|
||||
write("<h3># /etc/config/%s</h3>" % conf)
|
||||
|
||||
local _, delta, added
|
||||
for _, delta in pairs(deltas) do
|
||||
local t = tpl["%s-%d" %{ delta[1], #delta }]
|
||||
|
||||
write(t:gsub("%%(%d)", function(n)
|
||||
if n == "0" then
|
||||
return conf
|
||||
elseif n == "2" then
|
||||
if added and delta[2] == added[1] then
|
||||
return "@%s[-1]" % added[2]
|
||||
else
|
||||
return delta[2]
|
||||
end
|
||||
elseif n == "4" then
|
||||
return util.shellquote(delta[4])
|
||||
else
|
||||
return delta[tonumber(n)]
|
||||
end
|
||||
end))
|
||||
|
||||
if delta[1] == "add" then
|
||||
added = { delta[2], delta[3] }
|
||||
end
|
||||
end
|
||||
|
||||
write("<br />")
|
||||
end
|
||||
%></div>
|
||||
</div>
|
||||
<%- end) %>
|
45
luci-base/luasrc/view/admin_uci/changes.htm
Normal file
45
luci-base/luasrc/view/admin_uci/changes.htm
Normal file
|
@ -0,0 +1,45 @@
|
|||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
|
||||
<%-
|
||||
local node, redir_url = luci.dispatcher.lookup(luci.http.formvalue("redir"))
|
||||
export("redirect", redir_url or url("admin/uci/changes"))
|
||||
|
||||
include("admin_uci/changelog")
|
||||
-%>
|
||||
|
||||
<h2 name="content"><%:Configuration%> / <%:Changes%></h2>
|
||||
|
||||
<% if changes then %>
|
||||
<%- uci_changelog(changes) -%>
|
||||
<% else %>
|
||||
<p><strong><%:There are no pending changes!%></strong></p>
|
||||
<% end %>
|
||||
|
||||
<div class="alert-message" id="cbi_apply_status" style="display:none"></div>
|
||||
|
||||
<div class="cbi-page-actions">
|
||||
<% if redir_url then %>
|
||||
<form method="get" action="<%=luci.util.pcdata(redir_url)%>">
|
||||
<input class="cbi-button cbi-button-link" type="submit" value="<%:Back%>" />
|
||||
</form>
|
||||
<% end %>
|
||||
|
||||
<form method="post" action="<%=url("admin/uci/changes")%>">
|
||||
<input type="hidden" name="token" value="<%=token%>" />
|
||||
<input type="hidden" name="redir" value="<%=pcdata(luci.http.formvalue("redir"))%>" />
|
||||
<input class="cbi-button cbi-button-save" type="submit" name="trigger_apply" value="<%:Save & Apply%>" />
|
||||
</form>
|
||||
<form method="post" action="<%=url("admin/uci/revert")%>">
|
||||
<input type="hidden" name="token" value="<%=token%>" />
|
||||
<input type="hidden" name="redir" value="<%=pcdata(luci.http.formvalue("redir"))%>" />
|
||||
<input class="cbi-button cbi-button-reset" type="submit" value="<%:Revert%>" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<%+footer%>
|
33
luci-base/luasrc/view/admin_uci/revert.htm
Normal file
33
luci-base/luasrc/view/admin_uci/revert.htm
Normal file
|
@ -0,0 +1,33 @@
|
|||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
|
||||
<%-
|
||||
local node, redir_url = luci.dispatcher.lookup(luci.http.formvalue("redir"))
|
||||
export("redirect", redir_url or url("admin/uci/changes"))
|
||||
|
||||
include("admin_uci/changelog")
|
||||
-%>
|
||||
|
||||
<h2 name="content"><%:Configuration%> / <%:Revert%></h2>
|
||||
|
||||
<% if changes then %>
|
||||
<p><strong><%:The following changes have been reverted%>:</strong></p>
|
||||
<%- uci_changelog(changes) -%>
|
||||
<% else %>
|
||||
<p><strong><%:There are no pending changes to revert!%></strong></p>
|
||||
<% end %>
|
||||
|
||||
<% if redir_url then %>
|
||||
<div class="cbi-page-actions">
|
||||
<form class="inline" method="get" action="<%=luci.util.pcdata(redir_url)%>">
|
||||
<input class="cbi-button cbi-button-link" style="margin:0" type="submit" value="<%:Back%>" />
|
||||
</form>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%+footer%>
|
|
@ -1,49 +1,4 @@
|
|||
<% export("cbi_apply_widget", function(redirect_ok, rollback_token) -%>
|
||||
<style type="text/css">
|
||||
#cbi_apply_overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
display: none;
|
||||
z-index: 20000;
|
||||
}
|
||||
|
||||
#cbi_apply_overlay .alert-message {
|
||||
position: relative;
|
||||
top: 10%;
|
||||
width: 60%;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
min-height: 32px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#cbi_apply_overlay .alert-message > h4,
|
||||
#cbi_apply_overlay .alert-message > p,
|
||||
#cbi_apply_overlay .alert-message > div {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
#cbi_apply_overlay .alert-message > img {
|
||||
margin-right: 1em;
|
||||
flex-basis: 32px;
|
||||
}
|
||||
|
||||
body.apply-overlay-active {
|
||||
overflow: hidden;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
body.apply-overlay-active #cbi_apply_overlay {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" src="<%=resource%>/cbi.js?v=git-18.138.59467-72fe5dd"></script>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var xhr = new XHR(),
|
||||
uci_apply_auth = { sid: '<%=luci.dispatcher.context.authsession%>', token: '<%=token%>' },
|
||||
|
@ -55,28 +10,22 @@
|
|||
was_xhr_poll_running = false;
|
||||
|
||||
function uci_status_message(type, content) {
|
||||
var overlay = document.getElementById('cbi_apply_overlay') || document.body.appendChild(E('<div id="cbi_apply_overlay"><div class="alert-message"></div></div>')),
|
||||
message = overlay.querySelector('.alert-message');
|
||||
if (type) {
|
||||
var message = showModal('', '');
|
||||
|
||||
if (message && type) {
|
||||
if (!message.classList.contains(type)) {
|
||||
message.classList.remove('notice');
|
||||
message.classList.remove('warning');
|
||||
message.classList.add(type);
|
||||
}
|
||||
message.classList.add('alert-message');
|
||||
DOMTokenList.prototype.add.apply(message.classList, type.split(/\s+/));
|
||||
|
||||
if (content)
|
||||
message.innerHTML = content;
|
||||
|
||||
document.body.classList.add('apply-overlay-active');
|
||||
|
||||
if (!was_xhr_poll_running) {
|
||||
was_xhr_poll_running = XHR.running();
|
||||
XHR.halt();
|
||||
}
|
||||
}
|
||||
else {
|
||||
document.body.classList.remove('apply-overlay-active');
|
||||
hideModal();
|
||||
|
||||
if (was_xhr_poll_running)
|
||||
XHR.run();
|
||||
|
@ -85,19 +34,18 @@
|
|||
|
||||
function uci_rollback(checked) {
|
||||
if (checked) {
|
||||
uci_status_message('warning',
|
||||
'<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> ' +
|
||||
'<%:Failed to confirm apply within %ds, waiting for rollback…%>'.format(uci_apply_rollback));
|
||||
uci_status_message('warning spinning',
|
||||
'<p><%:Failed to confirm apply within %ds, waiting for rollback…%></p>'.format(uci_apply_rollback));
|
||||
|
||||
var call = function(r, data, duration) {
|
||||
if (r.status === 204) {
|
||||
uci_status_message('warning',
|
||||
'<h4><%:Configuration has been rolled back!%></h4>' +
|
||||
'<p><%:The device could not be reached within %d seconds after applying the pending changes, which caused the configuration to be rolled back for safety reasons. If you believe that the configuration changes are correct nonetheless, perform an unchecked configuration apply. Alternatively, you can dismiss this warning and edit changes before attempting to apply again, or revert all pending changes to keep the currently working configuration state.%></p>'.format(uci_apply_rollback) +
|
||||
'<p><%:The device could not be reached within %d seconds after applying the pending changes, which caused the configuration to be rolled back for safety reasons. If you believe that the configuration changes are correct nonetheless, proceed by applying anyway. Alternatively, you can dismiss this warning and edit changes before attempting to apply again, or revert all pending changes to keep the currently working configuration state.%></p>'.format(uci_apply_rollback) +
|
||||
'<div class="right">' +
|
||||
'<input type="button" class="btn" onclick="uci_status_message(false)" value="<%:Dismiss%>" /> ' +
|
||||
'<input type="button" class="btn cbi-button-action important" onclick="uci_revert()" value="<%:Revert changes%>" /> ' +
|
||||
'<input type="button" class="btn cbi-button-negative important" onclick="uci_apply(false)" value="<%:Apply unchecked%>" />' +
|
||||
'<input type="button" class="btn cbi-button-negative important" onclick="uci_apply(false)" value="<%:Apply anyway%>" />' +
|
||||
'</div>');
|
||||
|
||||
return;
|
||||
|
@ -126,6 +74,7 @@
|
|||
|
||||
var call = function(r, data, duration) {
|
||||
if (Date.now() >= deadline) {
|
||||
window.clearTimeout(tt);
|
||||
uci_rollback(checked);
|
||||
return;
|
||||
}
|
||||
|
@ -133,7 +82,7 @@
|
|||
var indicator = document.querySelector('.uci_change_indicator');
|
||||
if (indicator) indicator.style.display = 'none';
|
||||
|
||||
uci_status_message('notice', '<%:Configuration has been applied.%>');
|
||||
uci_status_message('notice', '<p><%:Configuration has been applied.%></p>');
|
||||
|
||||
window.clearTimeout(tt);
|
||||
window.setTimeout(function() {
|
||||
|
@ -156,9 +105,8 @@
|
|||
var tick = function() {
|
||||
var now = Date.now();
|
||||
|
||||
uci_status_message('notice',
|
||||
'<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> ' +
|
||||
'<%:Waiting for configuration to get applied… %ds%>'.format(Math.max(Math.floor((deadline - Date.now()) / 1000), 0)));
|
||||
uci_status_message('notice spinning',
|
||||
'<p><%:Waiting for configuration to be applied… %ds%></p>'.format(Math.max(Math.floor((deadline - Date.now()) / 1000), 0)));
|
||||
|
||||
if (now >= deadline)
|
||||
return;
|
||||
|
@ -174,9 +122,7 @@
|
|||
}
|
||||
|
||||
function uci_apply(checked) {
|
||||
uci_status_message('notice',
|
||||
'<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> ' +
|
||||
'<%:Starting configuration apply…%>');
|
||||
uci_status_message('notice spinning', '<p><%:Starting configuration apply…%></p>');
|
||||
|
||||
xhr.post('<%=url("admin/uci")%>/' + (checked ? 'apply_rollback' : 'apply_unchecked'), uci_apply_auth, function(r, tok) {
|
||||
if (r.status === (checked ? 200 : 204)) {
|
||||
|
@ -186,7 +132,7 @@
|
|||
uci_confirm(checked, Date.now() + uci_apply_rollback * 1000);
|
||||
}
|
||||
else if (checked && r.status === 204) {
|
||||
uci_status_message('notice', '<%:There are no changes to apply.%>');
|
||||
uci_status_message('notice', '<p><%:There are no changes to apply.%></p>');
|
||||
window.setTimeout(function() {
|
||||
<% if redirect_ok then -%>
|
||||
location.href = decodeURIComponent('<%=luci.util.urlencode(redirect_ok)%>');
|
||||
|
@ -196,20 +142,18 @@
|
|||
}, uci_apply_display * 1000);
|
||||
}
|
||||
else {
|
||||
uci_status_message('warning', '<%_Apply request failed with status <code>%h</code>%>'.format(r.responseText || r.statusText || r.status));
|
||||
uci_status_message('warning', '<p><%_Apply request failed with status <code>%h</code>%></p>'.format(r.responseText || r.statusText || r.status));
|
||||
window.setTimeout(function() { uci_status_message(false); }, uci_apply_display * 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function uci_revert() {
|
||||
uci_status_message('notice',
|
||||
'<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> ' +
|
||||
'<%:Reverting configuration…%>');
|
||||
uci_status_message('notice spinning', '<p><%:Reverting configuration…%></p>');
|
||||
|
||||
xhr.post('<%=url("admin/uci/revert")%>', uci_apply_auth, function(r) {
|
||||
if (r.status === 200) {
|
||||
uci_status_message('notice', '<%:Changes have been reverted.%>');
|
||||
uci_status_message('notice', '<p><%:Changes have been reverted.%></p>');
|
||||
window.setTimeout(function() {
|
||||
<% if redirect_ok then -%>
|
||||
location.href = decodeURIComponent('<%=luci.util.urlencode(redirect_ok)%>');
|
||||
|
@ -219,7 +163,7 @@
|
|||
}, uci_apply_display * 1000);
|
||||
}
|
||||
else {
|
||||
uci_status_message('warning', '<%_Revert request failed with status <code>%h</code>%>'.format(r.statusText || r.status));
|
||||
uci_status_message('warning', '<p><%_Revert request failed with status <code>%h</code>%></p>'.format(r.statusText || r.status));
|
||||
window.setTimeout(function() { uci_status_message(false); }, uci_apply_display * 1000);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<% local v = self:cfgvalue(section) -%>
|
||||
<%+cbi/valueheader%>
|
||||
<input class="cbi-input-text" type="text"<%= attr("value", v) .. attr("name", cbid) .. attr("id", cbid) %> />
|
||||
<script type="text/javascript">
|
||||
cbi_init()
|
||||
cbi_browser_init('<%=cbid%>', '<%=resource%>', '<%=url('admin/filebrowser')%>'<%=self.default_path and ", '"..self.default_path.."'"%>);
|
||||
</script>
|
||||
|
||||
<input class="cbi-input-text" type="text"<%=
|
||||
attr("id", cbid) ..
|
||||
attr("name", cbid) ..
|
||||
attr("value", self:cfgvalue(section) or self.default) ..
|
||||
attr("data-browser", self.default_path or "")
|
||||
%> />
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<div class="td cbi-value-field<% if self.error and self.error[section] then %> cbi-value-error<% end %>"<%=
|
||||
attr("data-name", self.option) ..
|
||||
ifattr(ftype and #ftype > 0, "data-type", ftype) ..
|
||||
ifattr(title and #title > 0, "data-title", title) ..
|
||||
ifattr(descr and #descr > 0, "data-description", descr)
|
||||
ifattr(title and #title > 0, "data-title", title, true) ..
|
||||
ifattr(descr and #descr > 0, "data-description", descr, true)
|
||||
%>>
|
||||
<div id="cbi-<%=self.config.."-"..section.."-"..self.option%>" data-index="<%=self.index%>" data-depends="<%=pcdata(self:deplist2json(section))%>">
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<li<%=
|
||||
attr("data-index", i) ..
|
||||
attr("data-depends", self:deplist2json(section, self.deplist[i])) ..
|
||||
attr("value", key) ..
|
||||
attr("data-value", key) ..
|
||||
ifattr(selected[key], "selected", "selected")
|
||||
%>>
|
||||
<%=pcdata(self.vallist[i])%>
|
||||
|
|
|
@ -6,22 +6,8 @@
|
|||
self.keylist, self.vallist,
|
||||
self.datatype, self.optional or self.rmempty
|
||||
})) ..
|
||||
|
||||
attr("data-values", luci.util.serialize_json(self:cfgvalue(section))) ..
|
||||
ifattr(self.size, "data-size", self.size) ..
|
||||
ifattr(self.placeholder, "data-placeholder", self.placeholder)
|
||||
%>>
|
||||
<%
|
||||
local vals = self:cfgvalue(section) or {}
|
||||
for i=1, #vals + 1 do
|
||||
local val = vals[i]
|
||||
if (val and #val > 0) or (i == 1) then
|
||||
%>
|
||||
<input class="cbi-input-text" value="<%=pcdata(val)%>" data-update="change" type="text"<%=
|
||||
attr("id", cbid .. "." .. i) ..
|
||||
attr("name", cbid) ..
|
||||
ifattr(self.size, "size") ..
|
||||
ifattr(i == 1 and self.placeholder, "placeholder", self.placeholder)
|
||||
%> /><br />
|
||||
<% end end %>
|
||||
</div>
|
||||
%>></div>
|
||||
<%+cbi/valuefooter%>
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
if empty then
|
||||
%>
|
||||
<label class="zonebadge zonebadge-empty">
|
||||
<strong><%=zone:forward():upper()%></strong>
|
||||
<strong><%=def:forward():upper()%></strong>
|
||||
</label>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
ifattr(self.rmempty or self.optional, "optional", "optional")
|
||||
%>>
|
||||
<script type="item-template"><!--
|
||||
<li value="{{value}}">
|
||||
<li data-value="{{value}}">
|
||||
<span class="zonebadge" style="background:repeating-linear-gradient(45deg,rgba(204,204,204,0.5),rgba(204,204,204,0.5) 5px,rgba(255,255,255,0.5) 5px,rgba(255,255,255,0.5) 10px)">
|
||||
<strong>{{value}}:</strong><em>(<%:create%>)</em>
|
||||
</span>
|
||||
|
@ -38,7 +38,7 @@
|
|||
--></script>
|
||||
<ul>
|
||||
<% if self.allowlocal then %>
|
||||
<li value=""<%=ifattr(checked[""], "selected", "selected")%>>
|
||||
<li data-value=""<%=ifattr(checked[""], "selected", "selected")%>>
|
||||
<span style="background-color:<%=fwm.zone.get_color()%>" class="zonebadge">
|
||||
<strong><%:Device%></strong>
|
||||
<% if self.allowany and self.allowlocal then -%>
|
||||
|
@ -48,14 +48,14 @@
|
|||
</span>
|
||||
</li>
|
||||
<% elseif self.widget ~= "checkbox" and (self.rmempty or self.optional) then %>
|
||||
<li value=""<%=ifattr(checked[""], "selected", "selected")%>>
|
||||
<li data-value=""<%=ifattr(checked[""], "selected", "selected")%>>
|
||||
<span class="zonebadge">
|
||||
<em><%:unspecified%></em>
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if self.allowany then %>
|
||||
<li value="*"<%=ifattr(checked["*"], "selected", "selected")%>>
|
||||
<li data-value="*"<%=ifattr(checked["*"], "selected", "selected")%>>
|
||||
<span style="background-color:<%=fwm.zone.get_color()%>" class="zonebadge">
|
||||
<strong><%:Any zone%></strong>
|
||||
<% if self.allowany and self.allowlocal then %>(<%:forward%>)<% end %>
|
||||
|
@ -67,7 +67,7 @@
|
|||
if zone:name() ~= self.exclude then
|
||||
selected = selected or (value == zone:name())
|
||||
%>
|
||||
<li<%=attr("value", zone:name()) .. ifattr(checked[zone:name()], "selected", "selected")%>>
|
||||
<li<%=attr("data-value", zone:name()) .. ifattr(checked[zone:name()], "selected", "selected")%>>
|
||||
<span style="background-color:<%=zone:get_color()%>" class="zonebadge">
|
||||
<strong><%=zone:name()%>:</strong>
|
||||
<%-
|
||||
|
@ -94,11 +94,11 @@
|
|||
<% end end %>
|
||||
|
||||
<% if self.widget ~= "checkbox" and not self.nocreate then %>
|
||||
<li value="-">
|
||||
<li data-value="-">
|
||||
<span class="zonebadge">
|
||||
<em><%:create%>:</em>
|
||||
<input type="password" style="display:none" />
|
||||
<input class="create-item-input" type="text" />
|
||||
<input class="create-item-input" type="text" data-type="and(uciname,maxlength(11))" data-optional="true" />
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
|
|
27
luci-base/luasrc/view/cbi/ipaddr.htm
Normal file
27
luci-base/luasrc/view/cbi/ipaddr.htm
Normal file
|
@ -0,0 +1,27 @@
|
|||
<%+cbi/valueheader%>
|
||||
<script type="text/javascript">
|
||||
function switchToCIDRList(ev) {
|
||||
var input = ev.target.previousElementSibling,
|
||||
usecidr = document.getElementById(input.id + '_usecidr');
|
||||
|
||||
ev.preventDefault();
|
||||
|
||||
usecidr.value = '1';
|
||||
cbi_d_update();
|
||||
}
|
||||
</script>
|
||||
<input data-update="change"<%=
|
||||
attr("id", cbid) ..
|
||||
attr("name", cbid) ..
|
||||
attr("type", "text") ..
|
||||
attr("class", "cbi-input-text") ..
|
||||
attr("value", self:cfgvalue(section) or self.default) ..
|
||||
ifattr(self.size, "size") ..
|
||||
ifattr(self.placeholder, "placeholder") ..
|
||||
ifattr(self.datatype, "data-type", self.datatype) ..
|
||||
ifattr(self.datatype, "data-optional", self.optional or self.rmempty) ..
|
||||
ifattr(self.combobox_manual, "data-manual", self.combobox_manual) ..
|
||||
ifattr(#self.keylist > 0, "data-choices", { self.keylist, self.vallist })
|
||||
%> /><!--
|
||||
--><button class="cbi-button cbi-button-neutral" title="<%:Switch to CIDR list notation%>" aria-label="<%:Switch to CIDR list notation%>" onclick="switchToCIDRList(event)">…</button>
|
||||
<%+cbi/valuefooter%>
|
|
@ -3,25 +3,25 @@
|
|||
<%- end end -%>
|
||||
|
||||
<div class="cbi-map" id="cbi-<%=self.config%>">
|
||||
<% if self.title and #self.title > 0 then %><h2 name="content"><%=self.title%></h2><% end %>
|
||||
<% if self.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %>
|
||||
<% if self.title and #self.title > 0 then %>
|
||||
<h2 name="content"><%=self.title%></h2>
|
||||
<% end %>
|
||||
<% if self.description and #self.description > 0 then %>
|
||||
<div class="cbi-map-descr"><%=self.description%></div>
|
||||
<% end %>
|
||||
<% if self.tabbed then %>
|
||||
<ul class="cbi-tabmenu map">
|
||||
<%- self.selected_tab = luci.http.formvalue("tab.m-" .. self.config) %>
|
||||
<% for i, section in ipairs(self.children) do %>
|
||||
<%- if not self.selected_tab then self.selected_tab = section.sectiontype end %>
|
||||
<li id="tab.m-<%=self.config%>.<%=section.section or section.sectiontype%>" class="cbi-tab<%=(section.sectiontype == self.selected_tab) and '' or '-disabled'%>">
|
||||
<a onclick="this.blur(); return cbi_t_switch('m-<%=self.config%>', '<%=section.section or section.sectiontype%>')" href="<%=REQUEST_URI%>?tab.m-<%=self.config%>=<%=section.section or section.sectiontype%>"><%=section.title or section.section or section.sectiontype %></a>
|
||||
<% if section.sectiontype == self.selected_tab then %><input type="hidden" id="tab.m-<%=self.config%>" name="tab.m-<%=self.config%>" value="<%=section.section or section.sectiontype%>" /><% end %>
|
||||
</li>
|
||||
<div>
|
||||
<% for i, section in ipairs(self.children) do
|
||||
tab = section.section or section.sectiontype %>
|
||||
<div class="cbi-tabcontainer"<%=
|
||||
attr("id", "container.m-%s.%s" %{ self.config, tab }) ..
|
||||
attr("data-tab", tab) ..
|
||||
attr("data-tab-title", section.title or tab)
|
||||
%>>
|
||||
<% section:render() %>
|
||||
</div>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% for i, section in ipairs(self.children) do %>
|
||||
<div class="cbi-tabcontainer" id="container.m-<%=self.config%>.<%=section.section or section.sectiontype%>"<% if section.sectiontype ~= self.selected_tab then %> style="display:none"<% end %>>
|
||||
<% section:render() %>
|
||||
</div>
|
||||
<script type="text/javascript">cbi_t_add('m-<%=self.config%>', '<%=section.section or section.sectiontype%>')</script>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% if not self.save then -%>
|
||||
<div class="cbi-section-error">
|
||||
|
|
|
@ -41,13 +41,13 @@
|
|||
|
||||
<input type="hidden" name="<%=cbeid%>" value="1" />
|
||||
|
||||
<div class="cbi-dropdown" display-items="5" placeholder="<%:-- please select -- %>"<%=
|
||||
<div class="cbi-dropdown" display-items="10" placeholder="<%:-- please select -- %>"<%=
|
||||
attr("name", cbid) ..
|
||||
ifattr(self.widget == "checkbox", "multiple", "multiple") ..
|
||||
ifattr(self.widget == "checkbox", "optional", "optional")
|
||||
%>>
|
||||
<script type="item-template"><!--
|
||||
<li value="{{value}}">
|
||||
<li data-value="{{value}}">
|
||||
<img title="<%:Custom Interface%>: "{{value}}"" src="<%=resource%>/icons/ethernet_disabled.png" />
|
||||
<span class="hide-open">{{value}}</span>
|
||||
<span class="hide-close"><%:Custom Interface%>: "{{value}}"</span>
|
||||
|
@ -61,7 +61,7 @@
|
|||
iface:name() ~= self.exclude
|
||||
then %>
|
||||
<li<%=
|
||||
attr("value", iface:name()) ..
|
||||
attr("data-value", iface:name()) ..
|
||||
ifattr(checked[iface:name()], "selected", "selected")
|
||||
%>>
|
||||
<img<%=attr("title", iface:get_i18n())%> src="<%=resource%>/icons/<%=iface:type()%><%=iface:is_up() and "" or "_disabled"%>.png" />
|
||||
|
@ -78,7 +78,7 @@
|
|||
</li>
|
||||
<% end end %>
|
||||
<% if not self.nocreate then %>
|
||||
<li value="">
|
||||
<li data-value="">
|
||||
<img title="<%:Custom Interface%>" src="<%=resource%>/icons/ethernet_disabled.png" />
|
||||
<span><%:Custom Interface%>:</span>
|
||||
<input type="password" style="display:none" />
|
||||
|
|
|
@ -20,13 +20,13 @@
|
|||
end
|
||||
-%>
|
||||
|
||||
<div class="cbi-dropdown" display-items="5" placeholder="<%:-- please select -- %>"<%=
|
||||
<div class="cbi-dropdown" display-items="10" placeholder="<%:-- please select -- %>"<%=
|
||||
attr("name", cbid) ..
|
||||
ifattr(self.widget == "checkbox", "multiple", "multiple") ..
|
||||
ifattr(self.widget == "checkbox", "optional", "optional")
|
||||
%>>
|
||||
<script type="item-template"><!--
|
||||
<li value="{{value}}">
|
||||
<li data-value="{{value}}">
|
||||
<span class="ifacebadge" style="background:repeating-linear-gradient(45deg,rgba(204,204,204,0.5),rgba(204,204,204,0.5) 5px,rgba(255,255,255,0.5) 5px,rgba(255,255,255,0.5) 10px)">
|
||||
{{value}}: <em>(<%:create%>)</em>
|
||||
</span>
|
||||
|
@ -34,7 +34,7 @@
|
|||
--></script>
|
||||
<ul>
|
||||
<% if self.widget ~= "checkbox" then %>
|
||||
<li value=""<%= ifattr(not value, "selected", "selected") %>>
|
||||
<li data-value=""<%= ifattr(not value, "selected", "selected") %>>
|
||||
<em><%:unspecified%></em>
|
||||
</li>
|
||||
<% end %>
|
||||
|
@ -44,7 +44,7 @@
|
|||
(net:name() ~= self.exclude) and
|
||||
(not self.novirtual or not net:is_virtual())
|
||||
then %>
|
||||
<li<%= attr("value", net:name()) .. ifattr(checked[net:name()], "selected", "selected") %>>
|
||||
<li<%= attr("data-value", net:name()) .. ifattr(checked[net:name()], "selected", "selected") %>>
|
||||
<span class="ifacebadge"><%=net:name()%>:
|
||||
<%
|
||||
local empty = true
|
||||
|
@ -63,7 +63,7 @@
|
|||
<% end end %>
|
||||
|
||||
<% if not self.nocreate then %>
|
||||
<li value="-"<%= ifattr(not value and self.widget ~= "checkbox", "selected", "selected") %>>
|
||||
<li data-value="-"<%= ifattr(not value and self.widget ~= "checkbox", "selected", "selected") %>>
|
||||
<em>
|
||||
<%- if self.widget == "checkbox" then -%>
|
||||
<%:create:%>
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
<input type="submit" class="cbi-button" name="cbi.rns.<%=self.config%>.<%=section%>" value="<%:Delete%>" />
|
||||
</div>
|
||||
<%- end %>
|
||||
<%+cbi/tabmenu%>
|
||||
<div class="cbi-section-node<% if self.tabs then %> cbi-section-node-tabbed<% end %>" id="cbi-<%=self.config%>-<%=section%>">
|
||||
<%+cbi/ucisection%>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
<% for tab, data in pairs(self.tabs) do %>
|
||||
<div class="cbi-tabcontainer" id="container.<%=self.config%>.<%=section%>.<%=tab%>"<% if tab ~= self.selected_tab then %> style="display:none"<% end %>>
|
||||
<% if data.description then %><div class="cbi-tab-descr"><%=data.description%></div><% end %>
|
||||
<% for _, tab in ipairs(self.tab_names) do data = self.tabs[tab] %>
|
||||
<div class="cbi-tabcontainer"<%=
|
||||
attr("id", "container.%s.%s.%s" %{ self.config, section, tab }) ..
|
||||
attr("data-tab", tab) ..
|
||||
attr("data-tab-title", data.title) ..
|
||||
attr("data-tab-active", tostring(tab == self.selected_tab))
|
||||
%>>
|
||||
<% if data.description then %>
|
||||
<div class="cbi-tab-descr"><%=data.description%></div>
|
||||
<% end %>
|
||||
|
||||
<% self:render_tab(tab, section, scope or {}) %>
|
||||
</div>
|
||||
<script type="text/javascript">cbi_t_add('<%=self.config%>.<%=section%>', '<%=tab%>')</script>
|
||||
<% end %>
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
<%- if self.tabs then %>
|
||||
<ul class="cbi-tabmenu">
|
||||
<%- self.selected_tab = luci.http.formvalue("tab." .. self.config .. "." .. section) %>
|
||||
<%- for _, tab in ipairs(self.tab_names) do if #self.tabs[tab].childs > 0 then %>
|
||||
<%- if not self.selected_tab then self.selected_tab = tab end %>
|
||||
<li id="tab.<%=self.config%>.<%=section%>.<%=tab%>" class="cbi-tab<%=(tab == self.selected_tab) and '' or '-disabled'%>">
|
||||
<a onclick="this.blur(); return cbi_t_switch('<%=self.config%>.<%=section%>', '<%=tab%>')" href="<%=REQUEST_URI%>?tab.<%=self.config%>.<%=section%>=<%=tab%>"><%=self.tabs[tab].title%></a>
|
||||
<% if tab == self.selected_tab then %><input type="hidden" id="tab.<%=self.config%>.<%=section%>" name="tab.<%=self.config%>.<%=section%>" value="<%=tab%>" /><% end %>
|
||||
</li>
|
||||
<% end end -%>
|
||||
</ul>
|
||||
<% end -%>
|
|
@ -127,7 +127,7 @@ end
|
|||
section = k
|
||||
|
||||
local sectionname = striptags((type(self.sectiontitle) == "function") and self:sectiontitle(section) or k)
|
||||
local sectiontitle = ifattr(sectionname and (not self.anonymous or self.sectiontitle), "data-title", sectionname)
|
||||
local sectiontitle = ifattr(sectionname and (not self.anonymous or self.sectiontitle), "data-title", sectionname, true)
|
||||
local colorclass = (self.extedit or self.rowcolors) and rowstyle() or ""
|
||||
local scope = {
|
||||
valueheader = "cbi/cell_valueheader",
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
<% if self.title and #self.title > 0 then -%>
|
||||
<legend><%=self.title%></legend>
|
||||
<%- end %>
|
||||
<% if self.error_msg and #self.error_msg > 0 then -%>
|
||||
<div class="cbi-section-error">
|
||||
<%=self.error_msg%>
|
||||
</div>
|
||||
<%- end %>
|
||||
<% if self.description and #self.description > 0 then -%>
|
||||
<div class="cbi-section-descr"><%=self.description%></div>
|
||||
<%- end %>
|
||||
|
@ -18,8 +23,6 @@
|
|||
<h3><%=section:upper()%></h3>
|
||||
<%- end %>
|
||||
|
||||
<%+cbi/tabmenu%>
|
||||
|
||||
<div class="cbi-section-node<% if self.tabs then %> cbi-section-node-tabbed<% end %>" id="cbi-<%=self.config%>-<%=section%>">
|
||||
<%+cbi/ucisection%>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<%+cbi/valueheader%>
|
||||
<%- if self.password then -%>
|
||||
<input type="password" style="position:absolute; left:-4000px"<%=
|
||||
<input type="password" style="position:absolute; left:-1000px" aria-hidden="true" tabindex="-1"<%=
|
||||
attr("name", "password." .. cbid)
|
||||
%> />
|
||||
<%- end -%>
|
||||
|
@ -21,6 +21,6 @@
|
|||
ifattr(#self.keylist > 0, "data-choices", { self.keylist, self.vallist })
|
||||
%> />
|
||||
<%- if self.password then -%>
|
||||
<div class="cbi-button cbi-button-neutral" title="<%:Reveal/hide password%>" onclick="var e = this.previousElementSibling; e.type = (e.type === 'password') ? 'text' : 'password'">∗</div>
|
||||
<button class="cbi-button cbi-button-neutral" title="<%:Reveal/hide password%>" aria-label="<%:Reveal/hide password%>" onclick="var e = this.previousElementSibling; e.type = (e.type === 'password') ? 'text' : 'password'; event.preventDefault()">∗</button>
|
||||
<% end %>
|
||||
<%+cbi/valuefooter%>
|
||||
|
|
168
luci-base/luasrc/view/cbi/wireless_modefreq.htm
Normal file
168
luci-base/luasrc/view/cbi/wireless_modefreq.htm
Normal file
|
@ -0,0 +1,168 @@
|
|||
<%+cbi/valueheader%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var freqlist = <%= luci.http.write_json(self.iwinfo.freqlist) %>;
|
||||
var hwmodes = <%= luci.http.write_json(self.iwinfo.hwmodelist or {}) %>;
|
||||
var htmodes = <%= luci.http.write_json(self.iwinfo.htmodelist) %>;
|
||||
|
||||
var channels = {
|
||||
'11g': [
|
||||
'auto', 'auto', true
|
||||
],
|
||||
'11a': [
|
||||
'auto', 'auto', true
|
||||
]
|
||||
};
|
||||
|
||||
for (var i = 0; i < freqlist.length; i++)
|
||||
channels[(freqlist[i].mhz > 2484) ? '11a' : '11g'].push(
|
||||
freqlist[i].channel,
|
||||
'%d (%d MHz)'.format(freqlist[i].channel, freqlist[i].mhz),
|
||||
!freqlist[i].restricted
|
||||
);
|
||||
|
||||
var modes = [
|
||||
'', 'Legacy', true,
|
||||
'n', 'N', hwmodes.n,
|
||||
'ac', 'AC', hwmodes.ac
|
||||
];
|
||||
|
||||
var htmodes = {
|
||||
'': [
|
||||
'', '-', true
|
||||
],
|
||||
'n': [
|
||||
'HT20', '20 MHz', htmodes.HT20,
|
||||
'HT40', '40 MHz', htmodes.HT40
|
||||
],
|
||||
'ac': [
|
||||
'VHT20', '20 MHz', htmodes.VHT20,
|
||||
'VHT40', '40 MHz', htmodes.VHT40,
|
||||
'VHT80', '80 MHz', htmodes.VHT80,
|
||||
'VHT160', '160 MHz', htmodes.VHT160
|
||||
]
|
||||
};
|
||||
|
||||
var bands = {
|
||||
'': [
|
||||
'11g', '2.4 GHz', (channels['11g'].length > 3),
|
||||
'11a', '5 GHz', (channels['11a'].length > 3)
|
||||
],
|
||||
'n': [
|
||||
'11g', '2.4 GHz', (channels['11g'].length > 3),
|
||||
'11a', '5 GHz', (channels['11a'].length > 3)
|
||||
],
|
||||
'ac': [
|
||||
'11a', '5 GHz', true
|
||||
]
|
||||
};
|
||||
|
||||
function cbi_set_values(sel, vals)
|
||||
{
|
||||
if (sel.vals)
|
||||
sel.vals.selected = sel.selectedIndex;
|
||||
|
||||
while (sel.options[0])
|
||||
sel.remove(0);
|
||||
|
||||
for (var i = 0; vals && i < vals.length; i += 3)
|
||||
{
|
||||
if (!vals[i+2])
|
||||
continue;
|
||||
|
||||
var opt = document.createElement('option');
|
||||
opt.value = vals[i+0];
|
||||
opt.text = vals[i+1];
|
||||
|
||||
sel.add(opt);
|
||||
}
|
||||
|
||||
if (!isNaN(vals.selected))
|
||||
sel.selectedIndex = vals.selected;
|
||||
|
||||
sel.parentNode.style.display = (sel.options.length <= 1) ? 'none' : '';
|
||||
sel.vals = vals;
|
||||
}
|
||||
|
||||
function cbi_toggle_wifi_mode(id)
|
||||
{
|
||||
cbi_toggle_wifi_htmode(id);
|
||||
cbi_toggle_wifi_band(id);
|
||||
}
|
||||
|
||||
function cbi_toggle_wifi_htmode(id)
|
||||
{
|
||||
var mode = document.getElementById(id + '.mode');
|
||||
var bwdt = document.getElementById(id + '.htmode');
|
||||
|
||||
cbi_set_values(bwdt, htmodes[mode.value]);
|
||||
}
|
||||
|
||||
function cbi_toggle_wifi_band(id)
|
||||
{
|
||||
var mode = document.getElementById(id + '.mode');
|
||||
var band = document.getElementById(id + '.band');
|
||||
|
||||
cbi_set_values(band, bands[mode.value]);
|
||||
cbi_toggle_wifi_channel(id);
|
||||
}
|
||||
|
||||
function cbi_toggle_wifi_channel(id)
|
||||
{
|
||||
var band = document.getElementById(id + '.band');
|
||||
var chan = document.getElementById(id + '.channel');
|
||||
|
||||
cbi_set_values(chan, channels[band.value]);
|
||||
}
|
||||
|
||||
function cbi_init_wifi(id)
|
||||
{
|
||||
var mode = document.getElementById(id + '.mode');
|
||||
var band = document.getElementById(id + '.band');
|
||||
var chan = document.getElementById(id + '.channel');
|
||||
var bwdt = document.getElementById(id + '.htmode');
|
||||
|
||||
cbi_set_values(mode, modes);
|
||||
|
||||
if (/VHT20|VHT40|VHT80|VHT160/.test(<%= luci.http.write_json(self.map:get(section, "htmode")) %>))
|
||||
mode.value = 'ac';
|
||||
else if (/HT20|HT40/.test(<%= luci.http.write_json(self.map:get(section, "htmode")) %>))
|
||||
mode.value = 'n';
|
||||
else
|
||||
mode.value = '';
|
||||
|
||||
cbi_toggle_wifi_mode(id);
|
||||
|
||||
if (/a/.test(<%= luci.http.write_json(self.map:get(section, "hwmode")) %>))
|
||||
band.value = '11a';
|
||||
else
|
||||
band.value = '11g';
|
||||
|
||||
cbi_toggle_wifi_band(id);
|
||||
|
||||
bwdt.value = <%= luci.http.write_json(self.map:get(section, "htmode")) %>;
|
||||
chan.value = <%= luci.http.write_json(self.map:get(section, "channel")) %>;
|
||||
}
|
||||
//]]></script>
|
||||
|
||||
<label style="float:left; margin-right:3px">
|
||||
<%:Mode%><br />
|
||||
<select style="width:auto" id="<%= cbid %>.mode" name="<%= cbid %>.mode" onchange="cbi_toggle_wifi_mode('<%= cbid %>')"></select>
|
||||
</label>
|
||||
<label style="float:left; margin-right:3px">
|
||||
<%:Band%><br />
|
||||
<select style="width:auto" id="<%= cbid %>.band" name="<%= cbid %>.band" onchange="cbi_toggle_wifi_band('<%= cbid %>')"></select>
|
||||
</label>
|
||||
<label style="float:left; margin-right:3px">
|
||||
<%:Channel%><br />
|
||||
<select style="width:auto" id="<%= cbid %>.channel" name="<%= cbid %>.channel"></select>
|
||||
</label>
|
||||
<label style="float:left; margin-right:3px">
|
||||
<%:Width%><br />
|
||||
<select style="width:auto" id="<%= cbid %>.htmode" name="<%= cbid %>.htmode"></select>
|
||||
</label>
|
||||
<br style="clear:left" />
|
||||
|
||||
<script type="text/javascript">cbi_init_wifi('<%= cbid %>');</script>
|
||||
|
||||
<%+cbi/valuefooter%>
|
11
luci-base/luasrc/view/empty_node_placeholder.htm
Normal file
11
luci-base/luasrc/view/empty_node_placeholder.htm
Normal file
|
@ -0,0 +1,11 @@
|
|||
<%#
|
||||
Copyright 2010 Jo-Philipp Wich <jow@openwrt.org>
|
||||
Copyright 2018 Daniel F. Dickinson <cshored@thecshore.com>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
|
||||
<p>Component not present.</p>
|
||||
|
||||
<%+footer%>
|
|
@ -10,3 +10,15 @@
|
|||
luci.dispatcher.context.template_header_sent = true
|
||||
end
|
||||
%>
|
||||
|
||||
<script type="text/javascript" src="<%=resource%>/luci.js"></script>
|
||||
<script type="text/javascript">
|
||||
L = new LuCI(<%= luci.http.write_json({
|
||||
token = token,
|
||||
resource = resource,
|
||||
scriptname = luci.http.getenv("SCRIPT_NAME"),
|
||||
pathinfo = luci.http.getenv("PATH_INFO"),
|
||||
requestpath = luci.dispatcher.context.requestpath,
|
||||
pollinterval = luci.config.main.pollinterval or 5
|
||||
}) %>);
|
||||
</script>
|
||||
|
|
95
luci-base/luasrc/view/lease_status.htm
Normal file
95
luci-base/luasrc/view/lease_status.htm
Normal file
|
@ -0,0 +1,95 @@
|
|||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(-1, '<%=url('admin/dhcplease_status')%>', null,
|
||||
function(x, st)
|
||||
{
|
||||
var tb = document.getElementById('lease_status_table');
|
||||
if (st && st[0] && tb)
|
||||
{
|
||||
var rows = [];
|
||||
|
||||
for (var i = 0; i < st[0].length; i++)
|
||||
{
|
||||
var timestr;
|
||||
|
||||
if (st[0][i].expires === false)
|
||||
timestr = '<em><%:unlimited%></em>';
|
||||
else if (st[0][i].expires <= 0)
|
||||
timestr = '<em><%:expired%></em>';
|
||||
else
|
||||
timestr = String.format('%t', st[0][i].expires);
|
||||
|
||||
rows.push([
|
||||
st[0][i].hostname || '?',
|
||||
st[0][i].ipaddr,
|
||||
st[0][i].macaddr,
|
||||
timestr
|
||||
]);
|
||||
}
|
||||
|
||||
cbi_update_table(tb, rows, '<em><%:There are no active leases.%></em>');
|
||||
}
|
||||
|
||||
var tb6 = document.getElementById('lease6_status_table');
|
||||
if (st && st[1] && tb6)
|
||||
{
|
||||
tb6.parentNode.style.display = 'block';
|
||||
|
||||
var rows = [];
|
||||
|
||||
for (var i = 0; i < st[1].length; i++)
|
||||
{
|
||||
var timestr;
|
||||
|
||||
if (st[1][i].expires === false)
|
||||
timestr = '<em><%:unlimited%></em>';
|
||||
else if (st[1][i].expires <= 0)
|
||||
timestr = '<em><%:expired%></em>';
|
||||
else
|
||||
timestr = String.format('%t', st[1][i].expires);
|
||||
|
||||
var name = st[1][i].hostname,
|
||||
hint = st[1][i].host_hint;
|
||||
|
||||
rows.push([
|
||||
hint ? '%h (%h)'.format(name || '?', hint) : (name || '?'),
|
||||
st[1][i].ip6addr,
|
||||
st[1][i].duid,
|
||||
timestr
|
||||
]);
|
||||
}
|
||||
|
||||
cbi_update_table(tb6, rows, '<em><%:There are no active leases.%></em>');
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]></script>
|
||||
|
||||
<div class="cbi-section">
|
||||
<h3><%:Active DHCP Leases%></h3>
|
||||
<div class="table" id="lease_status_table">
|
||||
<div class="tr table-titles">
|
||||
<div class="th"><%:Hostname%></div>
|
||||
<div class="th"><%:IPv4-Address%></div>
|
||||
<div class="th"><%:MAC-Address%></div>
|
||||
<div class="th"><%:Leasetime remaining%></div>
|
||||
</div>
|
||||
<div class="tr placeholder">
|
||||
<div class="td"><em><%:Collecting data...%></em></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cbi-section" style="display:none">
|
||||
<h3><%:Active DHCPv6 Leases%></h3>
|
||||
<div class="table" id="lease6_status_table">
|
||||
<div class="tr table-titles">
|
||||
<div class="th"><%:Host%></div>
|
||||
<div class="th"><%:IPv6-Address%></div>
|
||||
<div class="th"><%:DUID%></div>
|
||||
<div class="th"><%:Leasetime remaining%></div>
|
||||
</div>
|
||||
<div class="tr placeholder">
|
||||
<div class="td"><em><%:Collecting data...%></em></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
120
luci-base/luasrc/view/wifi_assoclist.htm
Normal file
120
luci-base/luasrc/view/wifi_assoclist.htm
Normal file
|
@ -0,0 +1,120 @@
|
|||
<%
|
||||
local supports_deauth = {}
|
||||
|
||||
local _, v
|
||||
for _, v in ipairs(luci.util.ubus()) do
|
||||
local iface = v:match("^hostapd%.(.+)$")
|
||||
if iface then
|
||||
local funcs = luci.util.ubus(v)
|
||||
if type(funcs) == "table" and funcs.del_client then
|
||||
supports_deauth[iface] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var supports_deauth = <%= luci.http.write_json(supports_deauth) %>;
|
||||
|
||||
function wifirate(bss, rx) {
|
||||
var p = rx ? 'rx_' : 'tx_',
|
||||
s = '%.1f <%:Mbit/s%>, %d<%:MHz%>'
|
||||
.format(bss[p+'rate'] / 1000, bss[p+'mhz']),
|
||||
ht = bss[p+'ht'], vht = bss[p+'vht'],
|
||||
mhz = bss[p+'mhz'], nss = bss[p+'nss'],
|
||||
mcs = bss[p+'mcs'], sgi = bss[p+'short_gi'];
|
||||
|
||||
if (ht || vht) {
|
||||
if (vht) s += ', VHT-MCS %d'.format(mcs);
|
||||
if (nss) s += ', VHT-NSS %d'.format(nss);
|
||||
if (ht) s += ', MCS %s'.format(mcs);
|
||||
if (sgi) s += ', <%:Short GI%>';
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
function handleDeauth(ev) {
|
||||
(new XHR()).post('<%=url('admin/wireless_deauth')%>', {
|
||||
token: '<%=token%>',
|
||||
iface: ev.target.getAttribute('data-iface'),
|
||||
bssid: ev.target.getAttribute('data-bssid')
|
||||
}, function() {
|
||||
ev.target.disabled = true;
|
||||
});
|
||||
}
|
||||
|
||||
XHR.poll(-1, '<%=url('admin/wireless_assoclist')%>', null,
|
||||
function(x, st)
|
||||
{
|
||||
var tb = document.getElementById('wifi_assoclist_table');
|
||||
if (st && tb)
|
||||
{
|
||||
var rows = [];
|
||||
|
||||
st.forEach(function(bss) {
|
||||
var icon;
|
||||
var q = (-1 * (bss.noise - bss.signal)) / 5;
|
||||
if (q < 1)
|
||||
icon = "<%=resource%>/icons/signal-0.png";
|
||||
else if (q < 2)
|
||||
icon = "<%=resource%>/icons/signal-0-25.png";
|
||||
else if (q < 3)
|
||||
icon = "<%=resource%>/icons/signal-25-50.png";
|
||||
else if (q < 4)
|
||||
icon = "<%=resource%>/icons/signal-50-75.png";
|
||||
else
|
||||
icon = "<%=resource%>/icons/signal-75-100.png";
|
||||
|
||||
rows.push([
|
||||
'<span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> <a href="%s">%h</a><small> (%h)</small></span>'.format(
|
||||
bss.radio,
|
||||
bss.link,
|
||||
bss.name,
|
||||
bss.ifname),
|
||||
bss.bssid,
|
||||
bss.host_hint ? '%h (%h)'.format(bss.host_name || '?', bss.host_hint) : (bss.host_name || '?'),
|
||||
'<span class="ifacebadge" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%> / <%:SNR%>: %d"><img src="%s" /> %d / %d <%:dBm%></span>'.format(
|
||||
bss.signal,
|
||||
bss.noise,
|
||||
bss.signal - bss.noise,
|
||||
icon,
|
||||
bss.signal,
|
||||
bss.noise),
|
||||
E('span', {}, [
|
||||
E('span', wifirate(bss, true)),
|
||||
E('br'),
|
||||
E('span', wifirate(bss, false))
|
||||
]),
|
||||
supports_deauth[bss.ifname] ? E('input', {
|
||||
type: 'button',
|
||||
class: 'cbi-button cbi-button-remove',
|
||||
value: '<%:Disconnect%>',
|
||||
'data-bssid': bss.bssid,
|
||||
'data-iface': bss.ifname,
|
||||
click: handleDeauth
|
||||
}) : '-'
|
||||
]);
|
||||
});
|
||||
|
||||
cbi_update_table(tb, rows, '<em><%:No information available%></em>');
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]></script>
|
||||
|
||||
<div class="table" id="wifi_assoclist_table">
|
||||
<div class="tr table-titles">
|
||||
<div class="th nowrap"><%:Network%></div>
|
||||
<div class="th hide-xs"><%:MAC-Address%></div>
|
||||
<div class="th nowrap"><%:Host%></div>
|
||||
<div class="th nowrap"><%:Signal%> / <%:Noise%></div>
|
||||
<div class="th nowrap"><%:RX Rate%> / <%:TX Rate%></div>
|
||||
<% if next(supports_deauth) then %>
|
||||
<div class="th right"><%:Disconnect%></div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="tr placeholder">
|
||||
<div class="td"><em><%:Collecting data...%></em></div>
|
||||
</div>
|
||||
</div>
|
Loading…
Add table
Add a link
Reference in a new issue