1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter-feeds.git synced 2025-03-09 15:40:03 +00:00

Update luci-base and luci-mod-admin-full to latest upstream version

This commit is contained in:
Ycarus 2018-07-23 17:36:03 +02:00
parent 7a86a163f5
commit 602a83668e
74 changed files with 7498 additions and 3067 deletions

View file

@ -23,6 +23,22 @@ IFACE_PATTERNS_VIRTUAL = { }
IFACE_PATTERNS_IGNORE = { "^wmaster%d", "^wifi%d", "^hwsim%d", "^imq%d", "^ifb%d", "^mon%.wlan%d", "^sit%d", "^gre%d", "^gretap%d", "^ip6gre%d", "^ip6tnl%d", "^tunl%d", "^lo$" }
IFACE_PATTERNS_WIRELESS = { "^wlan%d", "^wl%d", "^ath%d", "^%w+%.network%d" }
IFACE_ERRORS = {
CONNECT_FAILED = lng.translate("Connection attempt failed"),
INVALID_ADDRESS = lng.translate("IP address in invalid"),
INVALID_GATEWAY = lng.translate("Gateway address is invalid"),
INVALID_LOCAL_ADDRESS = lng.translate("Local IP address is invalid"),
MISSING_ADDRESS = lng.translate("IP address is missing"),
MISSING_PEER_ADDRESS = lng.translate("Peer address is missing"),
NO_DEVICE = lng.translate("Network device is not present"),
NO_IFACE = lng.translate("Unable to determine device name"),
NO_IFNAME = lng.translate("Unable to determine device name"),
NO_WAN_ADDRESS = lng.translate("Unable to determine external IP address"),
NO_WAN_LINK = lng.translate("Unable to determine upstream interface"),
PEER_RESOLVE_FAIL = lng.translate("Unable to resolve peer host name"),
PIN_FAILED = lng.translate("PIN code rejected")
}
protocol = utl.class()
@ -495,6 +511,17 @@ function register_pattern_virtual(self, pat)
IFACE_PATTERNS_VIRTUAL[#IFACE_PATTERNS_VIRTUAL+1] = pat
end
function register_error_code(self, code, message)
if type(code) == "string" and
type(message) == "string" and
not IFACE_ERRORS[code]
then
IFACE_ERRORS[code] = message
return true
end
return false
end
function has_ipv6(self)
return nfs.access("/proc/net/ipv6_route")
@ -520,6 +547,13 @@ end
function get_network(self, n)
if n and _uci:get("network", n) == "interface" then
return network(n)
elseif n then
local stat = utl.ubus("network.interface", "status", { interface = n })
if type(stat) == "table" and
type(stat.proto) == "string"
then
return network(n, stat.proto)
end
end
end
@ -532,6 +566,23 @@ function get_networks(self)
nls[s['.name']] = network(s['.name'])
end)
local dump = utl.ubus("network.interface", "dump", { })
if type(dump) == "table" and
type(dump.interface) == "table"
then
local _, net
for _, net in ipairs(dump.interface) do
if type(net) == "table" and
type(net.proto) == "string" and
type(net.interface) == "string"
then
if not nls[net.interface] then
nls[net.interface] = network(net.interface, net.proto)
end
end
end
end
local n
for n in utl.kspairs(nls) do
nets[#nets+1] = nls[n]
@ -929,6 +980,16 @@ function protocol.metric(self)
return self:_ubus("metric") or 0
end
function protocol.zonename(self)
local d = self:_ubus("data")
if type(d) == "table" and type(d.zone) == "string" then
return d.zone
end
return nil
end
function protocol.ipaddr(self)
local addrs = self:_ubus("ipv4-address")
return addrs and #addrs > 0 and addrs[1].address
@ -1043,6 +1104,22 @@ function protocol.ip6prefix(self)
end
end
function protocol.errors(self)
local _, err, rv
local errors = self:_ubus("errors")
if type(errors) == "table" then
for _, err in ipairs(errors) do
if type(err) == "table" and
type(err.code) == "string"
then
rv = rv or { }
rv[#rv+1] = IFACE_ERRORS[err.code] or lng.translatef("Unknown error (%s)", err.code)
end
end
end
return rv
end
function protocol.is_bridge(self)
return (not self:is_virtual() and self:type() == "bridge")
end
@ -1063,6 +1140,24 @@ function protocol.is_floating(self)
return false
end
function protocol.is_dynamic(self)
return (self:_ubus("dynamic") == true)
end
function protocol.is_alias(self)
local ifn, parent = nil, nil
for ifn in utl.imatch(_uci:get("network", self.sid, "ifname")) do
if #ifn > 1 and ifn:byte(1) == 64 then
parent = ifn:sub(2)
elseif parent ~= nil then
parent = nil
end
end
return parent
end
function protocol.is_empty(self)
if self:is_floating() then
return false
@ -1081,6 +1176,10 @@ function protocol.is_empty(self)
end
end
function protocol.is_up(self)
return (self:_ubus("up") == true)
end
function protocol.add_interface(self, ifname)
ifname = _M:ifnameof(ifname)
if ifname and not self:is_floating() then
@ -1116,12 +1215,16 @@ function protocol.get_interface(self)
_bridge["br-" .. self.sid] = true
return interface("br-" .. self.sid, self)
else
local ifn = nil
local num = { }
local ifn = self:_ubus("l3_device") or self:_ubus("device")
if ifn then
return interface(ifn, self)
end
for ifn in utl.imatch(_uci:get("network", self.sid, "ifname")) do
ifn = ifn:match("^[^:/]+")
return ifn and interface(ifn, self)
end
ifn = _wifi_netid_by_netname(self.sid)
return ifn and interface(ifn, self)
end
@ -1245,7 +1348,9 @@ function interface.ip6addrs(self)
end
function interface.type(self)
if self.wif or _wifi_iface(self.ifname) then
if self.ifname and self.ifname:byte(1) == 64 then
return "alias"
elseif self.wif or _wifi_iface(self.ifname) then
return "wifi"
elseif _bridge[self.ifname] then
return "bridge"
@ -1282,7 +1387,9 @@ end
function interface.get_type_i18n(self)
local x = self:type()
if x == "wifi" then
if x == "alias" then
return lng.translate("Alias Interface")
elseif x == "wifi" then
return lng.translate("Wireless Adapter")
elseif x == "bridge" then
return lng.translate("Bridge")
@ -1335,7 +1442,11 @@ function interface.bridge_stp(self)
end
function interface.is_up(self)
return self:_ubus("up") or false
local up = self:_ubus("up")
if up == nil then
up = (self:type() == "alias")
end
return up or false
end
function interface.is_bridge(self)
@ -1601,7 +1712,7 @@ end
function wifinet.ifname(self)
local ifname = self:ubus("net", "ifname") or self.iwinfo.ifname
if not ifname or ifname:match("^wifi%d") or ifname:match("^radio%d") then
ifname = self.wdev
ifname = self.netid
end
return ifname
end

View file

@ -1,9 +1,5 @@
<% export("cbi_apply_widget", function(redirect_ok) -%>
<style type="text/css">
.alert-message.notice {
background: linear-gradient(#fff 0%, #eee 100%);
}
#cbi_apply_overlay {
position: absolute;
top: 0;
@ -47,14 +43,15 @@
}
</style>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<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%>' },
uci_apply_rollback = <%=math.max(luci.config and luci.config.apply and luci.config.apply.rollback or 30, 30)%>,
uci_apply_holdoff = <%=math.max(luci.config and luci.config.apply and luci.config.apply.holdoff or 4, 1)%>,
uci_apply_timeout = <%=math.max(luci.config and luci.config.apply and luci.config.apply.timeout or 5, 1)%>,
uci_apply_display = <%=math.max(luci.config and luci.config.apply and luci.config.apply.display or 1.5, 1)%>;
uci_apply_display = <%=math.max(luci.config and luci.config.apply and luci.config.apply.display or 1.5, 1)%>,
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>')),
@ -71,9 +68,17 @@
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');
if (was_xhr_poll_running)
XHR.run();
}
}
@ -83,21 +88,24 @@
'<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> ' +
'<%:Failed to confirm apply within %ds, waiting for rollback…%>'.format(uci_apply_rollback));
var call = function(r) {
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) +
'<div class="right">' +
'<input type="button" class="btn" onclick="uci_status_message(false)" value="<%:Dismiss%>" /> ' +
'<input type="button" class="btn" onclick="uci_revert()" value="<%:Revert changes%>" /> ' +
'<input type="button" class="btn danger" onclick="uci_apply(false)" value="<%:Apply unchecked%>" />' +
'<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%>" />' +
'</div>');
return;
}
xhr.post('<%=url("admin/uci/confirm")%>', uci_apply_auth, call, uci_apply_timeout * 1000);
var delay = isNaN(duration) ? 0 : Math.max(1000 - duration, 0);
window.setTimeout(function() {
xhr.post('<%=url("admin/uci/confirm")%>', uci_apply_auth, call, uci_apply_timeout * 1000);
}, delay);
};
call({ status: 0 });
@ -115,7 +123,7 @@
uci_status_message('notice');
var call = function(r) {
var call = function(r, data, duration) {
if (Date.now() >= deadline) {
uci_rollback(checked);
return;
@ -138,7 +146,10 @@
return;
}
xhr.post('<%=url("admin/uci/confirm")%>', uci_apply_auth, call, uci_apply_timeout * 1000);
var delay = isNaN(duration) ? 0 : Math.max(1000 - duration, 0);
window.setTimeout(function() {
xhr.post('<%=url("admin/uci/confirm")%>', uci_apply_auth, call, uci_apply_timeout * 1000);
}, delay);
};
var tick = function() {

View file

@ -1,23 +1,39 @@
<%- if pageaction then -%>
<div class="cbi-page-actions">
<% if redirect and not flow.hidebackbtn then %>
<input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" />
<% end %>
<%
local display_back = (redirect and not flow.hidebackbtn)
local display_skip = (flow.skip)
local display_apply = (not autoapply and not flow.hideapplybtn)
local display_save = (not flow.hidesavebtn)
local display_reset = (not flow.hideresetbtn)
if pageaction and
(display_back or display_skip or display_apply or display_save or display_reset)
then
%><div class="cbi-page-actions"><%
if display_back then
%><input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" /> <%
end
if display_skip then
%><input class="cbi-button cbi-button-skip" type="button" value="<%:Skip%>" onclick="cbi_submit(this, 'cbi.skip')" /> <%
end
if display_apply then
%><input class="cbi-button cbi-button-apply" type="button" value="<%:Save & Apply%>" onclick="cbi_submit(this, 'cbi.apply')" /> <%
end
if display_save then
%><input class="cbi-button cbi-button-save" type="submit" value="<%:Save%>" /> <%
end
if display_reset then
%><input class="cbi-button cbi-button-reset" type="button" value="<%:Reset%>" onclick="location.href='<%=REQUEST_URI%>'" /> <%
end
%></div><%
end
%>
<% if flow.skip then %>
<input class="cbi-button cbi-button-skip" type="submit" name="cbi.skip" value="<%:Skip%>" />
<% end %>
<% if not autoapply and not flow.hideapplybtn then %>
<input class="cbi-button cbi-button-apply" type="submit" name="cbi.apply" value="<%:Save & Apply%>" />
<% end %>
<% if not flow.hidesavebtn then %>
<input class="cbi-button cbi-button-save" type="submit" value="<%:Save%>" />
<% end %>
<% if not flow.hideresetbtn then %>
<input class="cbi-button cbi-button-reset" type="button" value="<%:Reset%>" onclick="location.href='<%=REQUEST_URI%>'" />
<% end %>
</div>
<%- end -%>
</form>
<script type="text/javascript">cbi_init();</script>

View file

@ -1,18 +1,17 @@
<%+header%>
<form method="post" name="cbi" action="<%=REQUEST_URI%>" enctype="multipart/form-data" onreset="return cbi_validate_reset(this)" onsubmit="return cbi_validate_form(this, '<%:Some fields are invalid, cannot save values!%>')">
<form method="post" name="cbi" action="<%=REQUEST_URI%>" enctype="multipart/form-data" onreset="return cbi_validate_reset(this)" onsubmit="return cbi_validate_form(this, '<%:Some fields are invalid, cannot save values!%>')"<%=
attr("data-strings", luci.util.serialize_json({
label = {
choose = translate('-- Please choose --'),
custom = translate('-- custom --'),
},
path = {
resource = resource,
browser = url("admin/filebrowser")
}
}))
%>>
<div>
<script type="text/javascript" src="<%=resource%>/cbi.js"<%=
attr("data-strings", luci.util.serialize_json({
label = {
choose = translate('-- Please choose --'),
custom = translate('-- custom --'),
},
path = {
resource = resource,
browser = url("admin/filebrowser")
}
}))
%>></script>
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="cbi.submit" value="1" />
<input type="submit" value="<%:Save%>" class="hidden" />

View file

@ -26,9 +26,14 @@
else
local n = self.network and net:get_network(self.network)
if n then
local i
for _, i in ipairs(n:get_interfaces() or { n:get_interface() }) do
checked[i:name()] = true
local a = n:is_alias()
if a then
checked['@' .. a] = true
else
local i
for _, i in ipairs(n:get_interfaces() or { n:get_interface() }) do
checked[i:name()] = true
end
end
end
end
@ -50,7 +55,8 @@
--></script>
<ul>
<% for _, iface in ipairs(ifaces) do
if (not self.nobridges or not iface:is_bridge()) and
if (not self.noaliases or iface:type() ~= "alias") and
(not self.nobridges or not iface:is_bridge()) and
(not self.noinactive or iface:is_up()) and
iface:name() ~= self.exclude
then %>

View file

@ -1,56 +1,77 @@
<% if not self.embedded then %>
<form method="post" enctype="multipart/form-data" action="<%=REQUEST_URI%>">
<div>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="cbi.submit" value="1" />
</div>
<% 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 %>
<% self:render_children() %>
</div>
<%- if self.message then %>
<div><%=self.message%></div>
<%- end %>
<%- if self.errmessage then %>
<div class="error"><%=self.errmessage%></div>
<%- end %>
<% if not self.embedded then %>
<div class="cbi-page-actions">
<%-
if type(self.hidden) == "table" then
for k, v in pairs(self.hidden) do
-%>
<input type="hidden" id="<%=k%>" name="<%=k%>" value="<%=pcdata(v)%>" />
<%-
<%
if not self.embedded then
%><form method="post" enctype="multipart/form-data" action="<%=REQUEST_URI%>">
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="cbi.submit" value="1" /><%
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
self:render_children()
%></div><%
if self.message then
%><div class="alert-message notice"><%=self.message%></div><%
end
if self.errmessage then
%><div class="alert-message warning"><%=self.errmessage%></div><%
end
if not self.embedded then
if type(self.hidden) == "table" then
local k, v
for k, v in pairs(self.hidden) do
%><input type="hidden" id="<%=k%>" name="<%=k%>" value="<%=pcdata(v)%>" /><%
end
end
local display_back = (redirect)
local display_cancel = (self.cancel ~= false and self.on_cancel)
local display_skip = (self.flow and self.flow.skip)
local display_submit = (self.submit ~= false)
local display_reset = (self.reset ~= false)
if display_back or display_cancel or display_skip or display_submit or display_reset then
%><div class="cbi-page-actions"><%
if display_back then
%><input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" /> <%
end
if display_cancel then
local label = pcdata(self.cancel or translate("Cancel"))
%><input class="cbi-button cbi-button-link" type="button" value="<%=label%>" onclick="cbi_submit(this, 'cbi.cancel')" /> <%
end
if display_skip then
%><input class="cbi-button cbi-button-neutral" type="button" value="<%:Skip%>" onclick="cbi_submit(this, 'cbi.skip')" /> <%
end
if display_submit then
local label = pcdata(self.submit or translate("Submit"))
%><input class="cbi-button cbi-button-save" type="submit" value="<%=label%>" /> <%
end
if display_reset then
local label = pcdata(self.reset or translate("Reset"))
%><input class="cbi-button cbi-button-reset" type="reset" value="<%=label%>" /> <%
end
%></div><%
end
%></form><%
end
%>
<% if redirect then %>
<input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" />
<% end %>
<%- if self.cancel ~= false and self.on_cancel then %>
<input class="cbi-button cbi-button-link" type="submit" name="cbi.cancel" value="
<%- if not self.cancel then -%><%-:Cancel-%><%-else-%><%=self.cancel%><%end-%>
" />
<% end %>
<%- if self.flow and self.flow.skip then %>
<input class="cbi-button cbi-button-skip" type="submit" name="cbi.skip" value="<%:Skip%>" />
<% end %>
<%- if self.submit ~= false then %>
<input class="cbi-button cbi-button-save" type="submit" value="
<%- if not self.submit then -%><%-:Submit-%><%-else-%><%=self.submit%><%end-%>
" />
<% end %>
<%- if self.reset ~= false then %>
<input class="cbi-button cbi-button-reset" type="reset" value="
<%- if not self.reset then -%><%-:Reset-%><%-else-%><%=self.reset%><%end-%>
" />
<% end %>
</div>
</form>
<% end %>
<script type="text/javascript">cbi_init();</script>

View file

@ -1,8 +1,13 @@
<%-
local rowcnt = 1
local rowcnt = 0
function rowstyle()
rowcnt = rowcnt + 1
return (rowcnt % 2) + 1
if rowcnt % 2 == 0 then
return " cbi-rowstyle-1"
else
return " cbi-rowstyle-2"
end
end
function width(o)
@ -15,54 +20,115 @@ function width(o)
return ''
end
local has_titles = false
local has_descriptions = false
local anonclass = (not self.anonymous or self.sectiontitle) and "named" or "anonymous"
local titlename = ifattr(not self.anonymous or self.sectiontitle, "data-title", translate("Name"))
local i, k
for i, k in pairs(self.children) do
if not k.typename then
k.typename = k.template and k.template:gsub("^.+/", "") or ""
end
if not has_titles and k.title and #k.title > 0 then
has_titles = true
end
if not has_descriptions and k.description and #k.description > 0 then
has_descriptions = true
end
end
function render_titles()
if not has_titles then
return
end
%><div class="tr cbi-section-table-titles <%=anonclass%>"<%=titlename%>><%
local i, k
for i, k in ipairs(self.children) do
if not k.optional then
%><div class="th cbi-section-table-cell"<%=
width(k) .. attr('data-type', k.typename) %>><%
if k.titleref then
%><a title="<%=self.titledesc or translate('Go to relevant configuration page')%>" class="cbi-title-ref" href="<%=k.titleref%>"><%
end
write(k.title)
if k.titleref then
%></a><%
end
%></div><%
end
end
if self.sortable or self.extedit or self.addremove then
%><div class="th cbi-section-table-cell cbi-section-actions"></div><%
end
%></div><%
rowcnt = rowcnt + 1
end
function render_descriptions()
if not has_descriptions then
return
end
%><div class="tr cbi-section-table-descr <%=anonclass%>"><%
local i, k
for i, k in ipairs(self.children) do
if not k.optional then
%><div class="th cbi-section-table-cell"<%=
width(k) .. attr("data-type", k.typename) %>><%
write(k.description)
%></div><%
end
end
if self.sortable or self.extedit or self.addremove then
%><div class="th cbi-section-table-cell cbi-section-actions"></div><%
end
%></div><%
rowcnt = rowcnt + 1
end
-%>
<!-- tblsection -->
<div class="cbi-section cbi-tblsection" id="cbi-<%=self.config%>-<%=self.sectiontype%>">
<% if self.title and #self.title > 0 then -%>
<legend><%=self.title%></legend>
<h3><%=self.title%></h3>
<%- end %>
<%- if self.sortable then -%>
<input type="hidden" id="cbi.sts.<%=self.config%>.<%=self.sectiontype%>" name="cbi.sts.<%=self.config%>.<%=self.sectiontype%>" value="" />
<%- end -%>
<div class="cbi-section-descr"><%=self.description%></div>
<%- local count = 0 -%>
<div class="table cbi-section-table">
<div class="tr cbi-section-table-titles <%=anonclass%>"<%=titlename%>>
<%- for i, k in pairs(self.children) do if not k.optional then -%>
<div class="th cbi-section-table-cell"<%=
width(k) ..
attr("data-type", k.template and k.template:gsub("^.+/", "") or "")
%>>
<%- if k.titleref then -%><a title="<%=self.titledesc or translate('Go to relevant configuration page')%>" class="cbi-title-ref" href="<%=k.titleref%>"><%- end -%>
<%-=k.title-%>
<%- if k.titleref then -%></a><%- end -%>
</div>
<%- count = count + 1; end; end; if self.sortable or self.extedit or self.addremove then -%>
<div class="th cbi-section-table-cell cbi-section-actions"></div>
<%- count = count + 1; end -%>
</div>
<div class="tr cbi-section-table-descr <%=anonclass%>">
<%- for i, k in pairs(self.children) do if not k.optional then -%>
<div class="th cbi-section-table-cell"<%=
width(k) ..
attr("data-type", k.template and k.template:gsub("^.+/", "") or "")
%>><%=k.description%></div>
<%- end; end; if self.sortable or self.extedit or self.addremove then -%>
<div class="th cbi-section-table-cell cbi-section-actions"></div>
<%- end -%>
</div>
<%- local isempty, i, k = true, nil, nil
<%-
render_titles()
render_descriptions()
local isempty, section, i, k = true, nil, nil
for i, k in ipairs(self:cfgsections()) do
isempty = false
section = k
local 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 colorclass = (self.extedit or self.rowcolors) and " cbi-rowstyle-%d" % rowstyle() or ""
local colorclass = (self.extedit or self.rowcolors) and rowstyle() or ""
local scope = {
valueheader = "cbi/cell_valueheader",
valuefooter = "cbi/cell_valuefooter"
@ -80,20 +146,22 @@ local titlename = ifattr(not self.anonymous or self.sectiontitle, "data-title",
<%- if self.sortable or self.extedit or self.addremove then -%>
<div class="td cbi-section-table-cell nowrap cbi-section-actions">
<%- if self.sortable then -%>
<input class="cbi-button cbi-button-up" type="button" value="<%:Up%>" onclick="return cbi_row_swap(this, true, 'cbi.sts.<%=self.config%>.<%=self.sectiontype%>')" title="<%:Move up%>" />
<input class="cbi-button cbi-button-down" type="button" value="<%:Down%>" onclick="return cbi_row_swap(this, false, 'cbi.sts.<%=self.config%>.<%=self.sectiontype%>')" title="<%:Move down%>" />
<% end; if self.extedit then -%>
<input class="cbi-button cbi-button-edit" type="button" value="<%:Edit%>"
<%- if type(self.extedit) == "string" then
%> onclick="location.href='<%=self.extedit:format(section)%>'"
<%- elseif type(self.extedit) == "function" then
%> onclick="location.href='<%=self:extedit(section)%>'"
<%- end
%> alt="<%:Edit%>" title="<%:Edit%>" />
<% end; if self.addremove then %>
<input class="cbi-button cbi-button-remove" type="submit" value="<%:Delete%>" onclick="this.form.cbi_state='del-section'; return true" name="cbi.rts.<%=self.config%>.<%=k%>" alt="<%:Delete%>" title="<%:Delete%>" />
<%- end -%>
<div>
<%- if self.sortable then -%>
<input class="cbi-button cbi-button-up" type="button" value="<%:Up%>" onclick="return cbi_row_swap(this, true, 'cbi.sts.<%=self.config%>.<%=self.sectiontype%>')" title="<%:Move up%>" />
<input class="cbi-button cbi-button-down" type="button" value="<%:Down%>" onclick="return cbi_row_swap(this, false, 'cbi.sts.<%=self.config%>.<%=self.sectiontype%>')" title="<%:Move down%>" />
<% end; if self.extedit then -%>
<input class="cbi-button cbi-button-edit" type="button" value="<%:Edit%>"
<%- if type(self.extedit) == "string" then
%> onclick="location.href='<%=self.extedit:format(section)%>'"
<%- elseif type(self.extedit) == "function" then
%> onclick="location.href='<%=self:extedit(section)%>'"
<%- end
%> alt="<%:Edit%>" title="<%:Edit%>" />
<% end; if self.addremove then %>
<input class="cbi-button cbi-button-remove" type="submit" value="<%:Delete%>" onclick="this.form.cbi_state='del-section'; return true" name="cbi.rts.<%=self.config%>.<%=k%>" alt="<%:Delete%>" title="<%:Delete%>" />
<%- end -%>
</div>
</div>
<%- end -%>
</div>
@ -124,7 +192,7 @@ local titlename = ifattr(not self.anonymous or self.sectiontitle, "data-title",
<div class="cbi-section-error"><%:Invalid%></div>
<%- end %>
<div>
<input type="text" class="cbi-section-create-name" id="cbi.cts.<%=self.config%>.<%=self.sectiontype%>." name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>." data-type="uciname" data-optional="true" />
<input type="text" class="cbi-section-create-name" id="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" data-type="uciname" data-optional="true" />
</div>
<input class="cbi-button cbi-button-add" type="submit" onclick="this.form.cbi_state='add-section'; return true" value="<%:Add%>" title="<%:Add%>" />
<% end %>