Merge pull request #1895 from jow-/master

Responsive OpenWrt theme
This commit is contained in:
Jo-Philipp Wich 2018-06-25 08:49:44 +02:00 committed by GitHub
commit 483c9d35b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 2321 additions and 1573 deletions

View file

@ -18,95 +18,91 @@
vals[#vals+1] = '%s (%s)' %{ ip, name } vals[#vals+1] = '%s (%s)' %{ ip, name }
end) end)
-%> -%>
<div class="cbi-section-create cbi-tblsection-create">
<br /> <h4><%:New port forward%></h4>
<div class="table cbi-section-table" style="width:810px; margin-left:5px"> <div class="table">
<div class="tr cbi-section-table-titles"> <div class="tr table-titles">
<div class="th cbi-section-table-cell" colspan="8"><%:New port forward%>:</div> <div class="th"><%:Name%></div>
<div class="th"><%:Protocol%></div>
<div class="th"><%:External zone%></div>
<div class="th"><%:External port%></div>
<div class="th"><%:Internal zone%></div>
<div class="th"><%:Internal IP address%></div>
<div class="th"><%:Internal port%></div>
<div class="th"></div>
</div>
<div class="tr">
<div class="td">
<input type="text" class="cbi-input-text" id="_newfwd.name" name="_newfwd.name" placeholder="<%:New port forward%>" />
</div> </div>
<div class="tr cbi-section-table-descr"> <div class="td">
<div class="th cbi-section-table-cell"><%:Name%></div> <select class="cbi-input-select" id="_newfwd.proto" name="_newfwd.proto">
<div class="th cbi-section-table-cell"><%:Protocol%></div> <option value="tcp udp">TCP+UDP</option>
<div class="th cbi-section-table-cell"><%:External zone%></div> <option value="tcp">TCP</option>
<div class="th cbi-section-table-cell"><%:External port%></div> <option value="udp">UDP</option>
<div class="th cbi-section-table-cell"><%:Internal zone%></div> <option value="other"><%:Other...%></option>
<div class="th cbi-section-table-cell"><%:Internal IP address%></div> </select>
<div class="th cbi-section-table-cell"><%:Internal port%></div>
<div class="th cbi-section-table-cell"></div>
</div> </div>
<div class="tr cbi-section-table-row"> <div class="td">
<div class="td cbi-section-table-cell"> <select class="cbi-input-select" id="_newfwd.extzone" name="_newfwd.extzone">
<input type="text" class="cbi-input-text" id="_newfwd.name" name="_newfwd.name" placeholder="<%:New port forward%>" /> <% for _, z in ipairs(ezl) do -%><option value="<%=z:name()%>"><%=z:name()%></option><%- end %>
</div> </select>
<div class="td cbi-section-table-cell" style="width:110px"> </div>
<select class="cbi-input-select" id="_newfwd.proto" name="_newfwd.proto"> <div class="td">
<option value="tcp udp">TCP+UDP</option> <input type="text" class="cbi-input-text" id="_newfwd.extport" name="_newfwd.extport" data-type="portrange" data-optional="true" />
<option value="tcp">TCP</option> </div>
<option value="udp">UDP</option> <div class="td">
<option value="other"><%:Other...%></option> <select class="cbi-input-select" id="_newfwd.intzone" name="_newfwd.intzone">
</select> <% for _, z in ipairs(izl) do -%><option value="<%=z:name()%>"><%=z:name()%></option><%- end %>
</div> </select>
<div class="td cbi-section-table-cell" style="width:55px"> </div>
<select class="cbi-input-select" id="_newfwd.extzone" name="_newfwd.extzone"> <div class="td">
<% for _, z in ipairs(ezl) do -%><option value="<%=z:name()%>"><%=z:name()%></option><%- end %> <input type="text" class="cbi-input-text" id="_newfwd.intaddr" name="_newfwd.intaddr" data-type="host" data-optional="true"<%=
</select> ifattr(#keys > 0, "data-choices", {keys, vals})
</div> %>/>
<div class="td cbi-section-table-cell" style="width:110px"> </div>
<input type="text" class="cbi-input-text" id="_newfwd.extport" name="_newfwd.extport" data-type="portrange" data-optional="true" /> <div class="td">
</div> <input type="text" class="cbi-input-text" id="_newfwd.intport" name="_newfwd.intport" data-type="portrange" data-optional="true" />
<div class="td cbi-section-table-cell" style="width:55px"> </div>
<select class="cbi-input-select" id="_newfwd.intzone" name="_newfwd.intzone"> <div class="td bottom">
<% for _, z in ipairs(izl) do -%><option value="<%=z:name()%>"><%=z:name()%></option><%- end %> <input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" />
</select>
</div>
<div class="td cbi-section-table-cell" style="width:110px">
<input type="text" class="cbi-input-text" id="_newfwd.intaddr" name="_newfwd.intaddr" data-type="host" data-optional="true"<%=
ifattr(#keys > 0, "data-choices", {keys, vals})
%>/>
</div>
<div class="td cbi-section-table-cell" style="width:110px">
<input type="text" class="cbi-input-text" id="_newfwd.intport" name="_newfwd.intport" data-type="portrange" data-optional="true" />
</div>
<div class="td cbi-section-table-cell">
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" />
</div>
</div> </div>
</div> </div>
<script type="text/javascript">//<![CDATA[
cbi_bind(document.getElementById('_newfwd.extport'), 'blur',
function() {
var n = document.getElementById('_newfwd.name');
var p = document.getElementById('_newfwd.proto');
var i = document.getElementById('_newfwd.intport');
var hints = {
/* port name 0=both, 1=tcp, 2=udp, 3=other */
21: [ 'FTP', 1 ],
22: [ 'SSH', 1 ],
53: [ 'DNS', 0 ],
80: [ 'HTTP', 1 ],
443: [ 'HTTPS', 1 ],
3389: [ 'RDP', 1 ],
5900: [ 'VNC', 1 ],
};
if (!this.className.match(/invalid/))
{
if (!i.value) i.value = this.value;
var hint = hints[this.value || 0] || hints[i.value || 0];
if (hint)
{
p.selectedIndex = hint[1];
if (!n.value)
n.value = hint[0];
}
else if (!n.value)
{
n.value = 'Forward' + this.value;
}
}
});
//]]></script>
</div> </div>
<script type="text/javascript">//<![CDATA[
cbi_bind(document.getElementById('_newfwd.extport'), 'blur',
function() {
var n = document.getElementById('_newfwd.name');
var p = document.getElementById('_newfwd.proto');
var i = document.getElementById('_newfwd.intport');
var hints = {
/* port name 0=both, 1=tcp, 2=udp, 3=other */
21: [ 'FTP', 1 ],
22: [ 'SSH', 1 ],
53: [ 'DNS', 0 ],
80: [ 'HTTP', 1 ],
443: [ 'HTTPS', 1 ],
3389: [ 'RDP', 1 ],
5900: [ 'VNC', 1 ],
};
if (!this.className.match(/invalid/))
{
if (!i.value) i.value = this.value;
var hint = hints[this.value || 0] || hints[i.value || 0];
if (hint)
{
p.selectedIndex = hint[1];
if (!n.value)
n.value = hint[0];
}
else if (!n.value)
{
n.value = 'Forward' + this.value;
}
}
});
//]]></script>

View file

@ -5,112 +5,105 @@
local zones = fw:get_zones() local zones = fw:get_zones()
%> %>
<div class="cbi-section-create cbi-tblsection-create"> <% if wz then %>
<% if wz then %> <h4><%:Open ports on router%></h4>
<br /> <div class="table">
<div class="table cbi-section-table" style="margin-left:5px"> <div class="tr cbi-section-table-titles">
<div class="tr cbi-section-table-titles"> <div class="th"><%:Name%></div>
<div class="th cbi-section-table-cell left" colspan="4"><%:Open ports on router%>:</div> <div class="th"><%:Protocol%></div>
<div class="th"><%:External port%></div>
<div class="th"></div>
</div>
<div class="tr">
<div class="td">
<input type="text" class="cbi-input-text" id="_newopen.name" name="_newopen.name" placeholder="<%:New input rule%>" />
</div> </div>
<div class="tr cbi-section-table-descr"> <div class="td">
<div class="th cbi-section-table-cell"><%:Name%></div> <select class="cbi-input-select" id="_newopen.proto" name="_newopen.proto">
<div class="th cbi-section-table-cell"><%:Protocol%></div> <option value="tcp udp">TCP+UDP</option>
<div class="th cbi-section-table-cell"><%:External port%></div> <option value="tcp">TCP</option>
<div class="th cbi-section-table-cell"></div> <option value="udp">UDP</option>
<option value="other"><%:Other...%></option>
</select>
</div> </div>
<div class="tr cbi-section-table-row"> <div class="td">
<div class="td cbi-section-table-cell" style="width:130px"> <input type="text" class="cbi-input-text" id="_newopen.extport" name="_newopen.extport" />
<input type="text" class="cbi-input-text" id="_newopen.name" name="_newopen.name" placeholder="<%:New input rule%>" /> </div>
</div> <div class="td bottom">
<div class="td cbi-section-table-cell" style="width:110px"> <input type="submit" class="cbi-button cbi-button-add" name="_newopen.submit" value="<%:Add%>" />
<select class="cbi-input-select" id="_newopen.proto" name="_newopen.proto">
<option value="tcp udp">TCP+UDP</option>
<option value="tcp">TCP</option>
<option value="udp">UDP</option>
<option value="other"><%:Other...%></option>
</select>
</div>
<div class="td cbi-section-table-cell" style="width:110px">
<input type="text" class="cbi-input-text" id="_newopen.extport" name="_newopen.extport" />
</div>
<div class="td cbi-section-table-cell left">
<input type="submit" class="cbi-button cbi-button-add" name="_newopen.submit" value="<%:Add%>" />
</div>
</div> </div>
</div> </div>
<% end %> </div>
<% if #zones > 1 then %> <% end %>
<div class="table cbi-section-table" style="margin-left:5px"> <% if #zones > 1 then %>
<div class="tr cbi-section-table-titles"> <h4><%:New forward rule%></h4>
<div class="th cbi-section-table-cell left" colspan="6"><br /><%:New forward rule%>:</div> <div class="table">
<div class="tr cbi-section-table-titles">
<div class="th"><%:Name%></div>
<div class="th"><%:Source zone%></div>
<div class="th"><%:Destination zone%></div>
<div class="th"></div>
</div>
<div class="tr">
<div class="td">
<input type="text" class="cbi-input-text" id="_newfwd.name" name="_newfwd.name" placeholder="<%:New forward rule%>" />
</div> </div>
<div class="tr cbi-section-table-descr"> <div class="td">
<div class="th cbi-section-table-cell"><%:Name%></div> <select class="cbi-input-text" id="_newfwd.src" name="_newfwd.src">
<div class="th cbi-section-table-cell"><%:Source zone%></div> <% local k, v; for k, v in ipairs(fw:get_zones()) do -%>
<div class="th cbi-section-table-cell"><%:Destination zone%></div> <option<%=ifattr(v:name() == "wan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option>
<div class="th cbi-section-table-cell"></div> <%- end %>
</select>
</div> </div>
<div class="tr cbi-section-table-row"> <div class="td">
<div class="td cbi-section-table-cell" style="width:130px"> <select class="cbi-input-text" id="_newfwd.dest" name="_newfwd.dest">
<input type="text" class="cbi-input-text" id="_newfwd.name" name="_newfwd.name" placeholder="<%:New forward rule%>" /> <% local k, v; for k, v in ipairs(fw:get_zones()) do -%>
</div> <option<%=ifattr(v:name() == "lan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option>
<div class="td cbi-section-table-cell" style="width:110px"> <%- end %>
<select class="cbi-input-text" id="_newfwd.src" name="_newfwd.src"> </select>
<% local k, v; for k, v in ipairs(fw:get_zones()) do -%> </div>
<option<%=ifattr(v:name() == "wan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option> <div class="td bottom">
<%- end %> <input type="submit" class="cbi-button cbi-button-link" name="_newfwd.submit" value="<%:Add and edit...%>" />
</select>
</div>
<div class="td cbi-section-table-cell" style="width:110px">
<select class="cbi-input-text" id="_newfwd.dest" name="_newfwd.dest">
<% local k, v; for k, v in ipairs(fw:get_zones()) do -%>
<option<%=ifattr(v:name() == "lan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option>
<%- end %>
</select>
</div>
<div class="td cbi-section-table-cell left">
<input type="submit" class="cbi-button cbi-button-link" name="_newfwd.submit" value="<%:Add and edit...%>" />
</div>
</div> </div>
</div> </div>
<% else %> </div>
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" /> <% else %>
<% end %> <input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" />
<% end %>
<% if wz then %> <% if wz then %>
<script type="text/javascript">//<![CDATA[ <script type="text/javascript">//<![CDATA[
cbi_validate_field('_newopen.extport', true, 'list(neg(portrange))'); cbi_validate_field('_newopen.extport', true, 'list(neg(portrange))');
cbi_bind(document.getElementById('_newopen.extport'), 'blur', cbi_bind(document.getElementById('_newopen.extport'), 'blur',
function() { function() {
var n = document.getElementById('_newopen.name'); var n = document.getElementById('_newopen.name');
var p = document.getElementById('_newopen.proto'); var p = document.getElementById('_newopen.proto');
var hints = { var hints = {
/* port name 0=both, 1=tcp, 2=udp, 3=other */ /* port name 0=both, 1=tcp, 2=udp, 3=other */
22: [ 'SSH', 1 ], 22: [ 'SSH', 1 ],
53: [ 'DNS', 0 ], 53: [ 'DNS', 0 ],
80: [ 'HTTP', 1 ], 80: [ 'HTTP', 1 ],
443: [ 'HTTPS', 1 ], 443: [ 'HTTPS', 1 ],
}; };
if (!this.className.match(/invalid/)) if (!this.className.match(/invalid/))
{
var hint = hints[this.value || 0];
if (hint)
{ {
var hint = hints[this.value || 0]; p.selectedIndex = hint[1];
if (hint)
{
p.selectedIndex = hint[1];
if (!n.value) if (!n.value)
n.value = hint[0]; n.value = hint[0];
}
else if (!n.value && this.value)
{
n.value = 'Open' + this.value;
}
} }
}); else if (!n.value && this.value)
{
n.value = 'Open' + this.value;
}
}
});
cbi_validate_field('cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>', true, 'uciname'); cbi_validate_field('cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>', true, 'uciname');
//]]></script> //]]></script>
<% end %> <% end %>
</div>

View file

@ -12,53 +12,48 @@
end end
%> %>
<div class="cbi-section-create cbi-tblsection-create"> <% if #zones > 1 then %>
<% if #zones > 1 then %> <h4><%:New source NAT%></h4>
<br /> <div class="table">
<div class="table cbi-section-table" style="width:700px; margin-left:5px"> <div class="tr cbi-section-table-titles">
<div class="tr cbi-section-table-titles"> <div class="th"><%:Name%></div>
<div class="th cbi-section-table-cell left" colspan="6"><%:New source NAT%>:</div> <div class="th"><%:Source zone%></div>
<div class="th"><%:Destination zone%></div>
<div class="th"><%:To source IP%></div>
<div class="th"><%:To source port%></div>
<div class="th"></div>
</div>
<div class="tr">
<div class="td">
<input type="text" class="cbi-input-text" id="_newsnat.name" name="_newsnat.name" placeholder="<%:New SNAT rule%>" />
</div> </div>
<div class="tr cbi-section-table-descr"> <div class="td">
<div class="th cbi-section-table-cell"><%:Name%></div> <select class="cbi-input-text" id="_newsnat.src" name="_newsnat.src">
<div class="th cbi-section-table-cell"><%:Source zone%></div> <% local k, v; for k, v in ipairs(fw:get_zones()) do -%>
<div class="th cbi-section-table-cell"><%:Destination zone%></div> <option<%=ifattr(v:name() == "lan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option>
<div class="th cbi-section-table-cell"><%:To source IP%></div> <%- end %>
<div class="th cbi-section-table-cell"><%:To source port%></div> </select>
<div class="th cbi-section-table-cell"></div>
</div> </div>
<div class="tr cbi-section-table-row"> <div class="td">
<div class="td cbi-section-table-cell"> <select class="cbi-input-text" id="_newsnat.dest" name="_newsnat.dest">
<input type="text" class="cbi-input-text" id="_newsnat.name" name="_newsnat.name" placeholder="<%:New SNAT rule%>" /> <% local k, v; for k, v in ipairs(fw:get_zones()) do -%>
</div> <option<%=ifattr(v:name() == "wan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option>
<div class="td cbi-section-table-cell" style="width:110px"> <%- end %>
<select class="cbi-input-text" id="_newsnat.src" name="_newsnat.src"> </select>
<% local k, v; for k, v in ipairs(fw:get_zones()) do -%> </div>
<option<%=ifattr(v:name() == "lan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option> <div class="td">
<%- end %> <input type="text" class="cbi-input-text" id="_newsnat.dip" name="_newsnat.dip" placeholder="<%:Do not rewrite%>" data-type="ip4addr" data-optional="true"<%=
</select> ifattr(#keys > 0, "data-choices", { keys, vals })
</div> %> />
<div class="td cbi-section-table-cell" style="width:110px"> </div>
<select class="cbi-input-text" id="_newsnat.dest" name="_newsnat.dest"> <div class="td">
<% local k, v; for k, v in ipairs(fw:get_zones()) do -%> <input type="text" class="cbi-input-text" id="_newsnat.dport" name="_newsnat.dport" placeholder="<%:Do not rewrite%>" data-type="portrange" data-optional="true" />
<option<%=ifattr(v:name() == "wan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option> </div>
<%- end %> <div class="td bottom">
</select> <input type="submit" class="cbi-button cbi-button-link" name="_newsnat.submit" value="<%:Add and edit...%>" />
</div>
<div class="td cbi-section-table-cell" style="width:110px">
<input type="text" class="cbi-input-text" id="_newsnat.dip" name="_newsnat.dip" placeholder="<%:Do not rewrite%>" data-type="ip4addr" data-optional="true"<%=
ifattr(#keys > 0, "data-choices", { keys, vals })
%> />
</div>
<div class="td cbi-section-table-cell" style="width:110px">
<input type="text" class="cbi-input-text" id="_newsnat.dport" name="_newsnat.dport" placeholder="<%:Do not rewrite%>" data-type="portrange" data-optional="true" />
</div>
<div class="td cbi-section-table-cell">
<input type="submit" class="cbi-button cbi-button-link" name="_newsnat.submit" value="<%:Add and edit...%>" />
</div>
</div> </div>
</div> </div>
<% else %> </div>
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" /> <% else %>
<% end %> <input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" />
</div> <% end %>

View file

@ -1,24 +1,17 @@
<div class="cbi-section-create cbi-tblsection-create"> <div class="cbi-section-create cbi-tblsection-create">
<br /> <div>
<div class="table cbi-section-table"> <select class="cbi-input-select" id="_newinst.type" name="_newinst.type">
<div class="tr cbi-section-table-row"> <option value="_dummy">-- instance type --</option>
<div class="td cbi-section-table-cell" style="width:140px"> <option value="ss_local">ss-local</option>
<select class="cbi-input-select" id="_newinst.type" name="_newinst.type"> <option value="ss_tunnel">ss-tunnel</option>
<option value="_dummy">-- instance type --</option> <option value="ss_redir">ss-redir</option>
<option value="ss_local">ss-local</option> <option value="ss_server">ss-server</option>
<option value="ss_tunnel">ss-tunnel</option> </select>
<option value="ss_redir">ss-redir</option>
<option value="ss_server">ss-server</option>
</select>
</div>
<div class="td cbi-section-table-cell" style="width:110px">
<input type="text" class="cbi-input-text" id="_newinst.name" name="_newinst.name" placeholder="<%:Name%>"/>
</div>
<div class="td cbi-section-table-cell left">
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>" value="<%:Add%>" />
</div>
</div>
</div> </div>
<div>
<input type="text" class="cbi-input-text" id="_newinst.name" name="_newinst.name" placeholder="<%:Name%>"/>
</div>
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>" value="<%:Add%>" />
</div> </div>
<script type="text/javascript">//<![CDATA[ <script type="text/javascript">//<![CDATA[
XHR.poll(5, '<%=url('admin/services/shadowsocks-libev/status')%>', null, XHR.poll(5, '<%=url('admin/services/shadowsocks-libev/status')%>', null,

View file

@ -6,10 +6,10 @@ This is free software, licensed under the Apache License, Version 2.0
<%+header%> <%+header%>
<div class="cbi-map"> <div class="cbi-map">
<fieldset class="cbi-section"> <div class="cbi-section">
<div class="cbi-section-descr"><%:This form shows the syslog output, pre-filtered for travelmate related messages only.%></div> <div class="cbi-section-descr"><%:This form shows the syslog output, pre-filtered for travelmate related messages only.%></div>
<textarea id="logread_id" style="width: 100%; height: 450px; border: 1px solid #cccccc; padding: 5px; font-size: 12px; font-family: monospace; resize: none;" readonly="readonly" wrap="off" rows="<%=content:cmatch("\n")+2%>"><%=content:pcdata()%></textarea> <textarea id="logread_id" style="width: 100%; height: 450px; border: 1px solid #cccccc; padding: 5px; font-size: 12px; font-family: monospace; resize: none;" readonly="readonly" wrap="off" rows="<%=content:cmatch("\n")+2%>"><%=content:pcdata()%></textarea>
</fieldset> </div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">

View file

@ -11,19 +11,21 @@ This is free software, licensed under the Apache License, Version 2.0
<%+header%> <%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<div class="cbi-map"> <div class="cbi-map">
<div class="cbi-map-descr"> <div class="cbi-map-descr">
<%=translatef("Provides an overview of all configured uplinks for the travelmate interface (%s). You can edit, delete or re-order existing uplinks or scan for a new one. The currently used uplink is emphasized in blue.", trmiface)%> <%=translatef("Provides an overview of all configured uplinks for the travelmate interface (%s). You can edit, delete or re-order existing uplinks or scan for a new one. The currently used uplink is emphasized in blue.", trmiface)%>
</div> </div>
<fieldset class="cbi-section"> <div class="cbi-section">
<div class="table cbi-section-table" style="empty-cells:hide"> <div class="table cbi-section-table">
<div class="tr cbi-section-table-titles"> <div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell" style="text-align:left"><%:Device%></div> <div class="th left"><%:Device%></div>
<div class="th cbi-section-table-cell" style="text-align:left"><%:SSID%></div> <div class="th left"><%:SSID%></div>
<div class="th cbi-section-table-cell" style="text-align:left"><%:BSSID%></div> <div class="th left"><%:BSSID%></div>
<div class="th cbi-section-table-cell" style="text-align:left"><%:Encryption%></div> <div class="th left"><%:Encryption%></div>
<div class="th cbi-section-table-cell" style="text-align:center" colspan="2"><%:Actions%></div> <div class="th center">&#160;</div>
</div> </div>
<% <%
uci:foreach("wireless", "wifi-iface", function(s) uci:foreach("wireless", "wifi-iface", function(s)
@ -45,11 +47,9 @@ This is free software, licensed under the Apache License, Version 2.0
<div class="td" style="<%=style%>"><%=ssid%></div> <div class="td" style="<%=style%>"><%=ssid%></div>
<div class="td" style="<%=style%>"><%=bssid%></div> <div class="td" style="<%=style%>"><%=bssid%></div>
<div class="td" style="<%=style%>"><%=encryption%></div> <div class="td" style="<%=style%>"><%=encryption%></div>
<div class="td cbi-value-field" style="width:80px"> <div class="td cbi-section-actions">
<input class="cbi-button cbi-button-up" type="button" value="" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&amp;dir=up'" alt="<%:Move up%>" title="<%:Move up%>"/> <input class="cbi-button cbi-button-up" type="button" value="<%:Up%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&amp;dir=up'" alt="<%:Move up%>" title="<%:Move up%>"/>
<input class="cbi-button cbi-button-down" type="button" value="" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&amp;dir=down'" alt="<%:Move down%>" title="<%:Move down%>"/> <input class="cbi-button cbi-button-down" type="button" value="<%:Down%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&amp;dir=down'" alt="<%:Move down%>" title="<%:Move down%>"/>
</div>
<div class="td cbi-value-field" style="width:150px">
<input type="button" class="cbi-button cbi-button-edit" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiedit')%>?cfg=<%=section%>'" title="<%:Edit this Uplink%>" value="<%:Edit%>"/> <input type="button" class="cbi-button cbi-button-edit" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiedit')%>?cfg=<%=section%>'" title="<%:Edit this Uplink%>" value="<%:Edit%>"/>
<input type="button" class="cbi-button cbi-button-remove" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifidelete')%>?cfg=<%=section%>'" title="<%:Delete this Uplink%>" value="<%:Delete%>"/> <input type="button" class="cbi-button cbi-button-remove" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifidelete')%>?cfg=<%=section%>'" title="<%:Delete this Uplink%>" value="<%:Delete%>"/>
</div> </div>
@ -59,7 +59,7 @@ This is free software, licensed under the Apache License, Version 2.0
end) end)
%> %>
</div> </div>
</fieldset> </div>
<div class="cbi-page-actions right"> <div class="cbi-page-actions right">
<% <%
uci:foreach("wireless", "wifi-device", function(s) uci:foreach("wireless", "wifi-device", function(s)
@ -68,7 +68,7 @@ This is free software, licensed under the Apache License, Version 2.0
<form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiscan')%>" method="post"> <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiscan')%>" method="post">
<input type="hidden" name="device" value="<%=device%>"/> <input type="hidden" name="device" value="<%=device%>"/>
<input type="hidden" name="token" value="<%=token%>"/> <input type="hidden" name="token" value="<%=token%>"/>
<input type="submit" class="cbi-button cbi-button-find" title="<%:Find and join network on%> <%=device%>" value="<%:Scan%> <%=device%>"/> <input type="submit" class="cbi-button cbi-button-action important" title="<%:Find and join network on%> <%=device%>" value="<%:Scan%> <%=device%>"/>
</form> </form>
<% <%
end) end)

View file

@ -39,31 +39,33 @@ This is free software, licensed under the Apache License, Version 2.0
<%+header%> <%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<div class="cbi-map"> <div class="cbi-map">
<h2 name="content"><%:Wireless Scan%></h2> <h2 name="content"><%:Wireless Scan%></h2>
<fieldset class="cbi-section"> <div class="cbi-section">
<div class="table cbi-section-table" style="empty-cells:hide"> <div class="table cbi-section-table">
<div class="tr cbi-section-table-titles"> <div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell" style="text-align:left"><%:Uplink SSID%></div> <div class="th left"><%:Uplink SSID%></div>
<div class="th cbi-section-table-cell" style="text-align:left"><%:Uplink BSSID%></div> <div class="th left"><%:Uplink BSSID%></div>
<div class="th cbi-section-table-cell" style="text-align:left"><%:Encryption%></div> <div class="th left"><%:Encryption%></div>
<div class="th cbi-section-table-cell" style="text-align:left" colspan="2"><%:Signal strength%></div> <div class="th left"><%:Signal strength%></div>
</div> </div>
<% for i, net in ipairs(iw.scanlist or { }) do %> <% for i, net in ipairs(iw.scanlist or { }) do %>
<div class="tr cbi-section-table-row cbi-rowstyle-1"> <div class="tr cbi-section-table-row cbi-rowstyle-1">
<div class="td cbi-value-field" style="text-align:left"> <div class="td left">
<%=net.ssid and utl.pcdata(net.ssid) or "<em>%s</em>" % translate("hidden")%> <%=net.ssid and utl.pcdata(net.ssid) or "<em>%s</em>" % translate("hidden")%>
</div> </div>
<div class="td cbi-value-field" style="text-align:left"> <div class="td left">
<%=net.bssid and utl.pcdata(net.bssid)%> <%=net.bssid and utl.pcdata(net.bssid)%>
</div> </div>
<div class="td cbi-value-field" style="text-align:left"> <div class="td left">
<%=format_wifi_encryption(net.encryption)%> <%=format_wifi_encryption(net.encryption)%>
</div> </div>
<div class="td cbi-value-field" style="text-align:left"> <div class="td left">
<%=percent_wifi_signal(net)%> % <%=percent_wifi_signal(net)%> %
</div> </div>
<div class="td cbi-value-field" style="width:100px;text-align:right"> <div class="td cbi-section-actions">
<form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiadd')%>" method="post"> <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiadd')%>" method="post">
<input type="hidden" name="token" value="<%=token%>"/> <input type="hidden" name="token" value="<%=token%>"/>
<input type="hidden" name="device" value="<%=utl.pcdata(dev)%>"/> <input type="hidden" name="device" value="<%=utl.pcdata(dev)%>"/>
@ -80,16 +82,16 @@ This is free software, licensed under the Apache License, Version 2.0
</div> </div>
<% end %> <% end %>
</div> </div>
</fieldset> </div>
<div class="cbi-page-actions right"> <div class="cbi-page-actions right">
<form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/stations')%>" method="get">
<input class="cbi-button cbi-button-reset" type="submit" value="<%:Back to overview%>"/>
</form>
<form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiscan')%>" method="post"> <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiscan')%>" method="post">
<input type="hidden" name="token" value="<%=token%>"/> <input type="hidden" name="token" value="<%=token%>"/>
<input type="hidden" name="device" value="<%=utl.pcdata(dev)%>"/> <input type="hidden" name="device" value="<%=utl.pcdata(dev)%>"/>
<input class="cbi-button cbi-input-find" type="submit" value="<%:Repeat scan%>"/> <input class="cbi-button cbi-input-find" type="submit" value="<%:Repeat scan%>"/>
</form> </form>
<form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/stations')%>" method="post">
<input class="cbi-button cbi-button-reset" type="submit" value="<%:Back to overview%>"/>
</form>
</div> </div>
</div> </div>

View file

@ -16,40 +16,39 @@
var tb = document.getElementById('upnp_status_table'); var tb = document.getElementById('upnp_status_table');
if (st && tb) if (st && tb)
{ {
/* clear all rows */ var rows = [];
while (tb.firstElementChild !== tb.lastElementChild)
tb.removeChild(tb.lastElementChild);
for (var i = 0; i < st.length; i++) for (var i = 0; i < st.length; i++)
tb.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-%d">'.format((i % 2) + 1), [ rows.push([
E('<div class="td">', st[i].proto), st[i].proto,
E('<div class="td">', st[i].extport), st[i].extport,
E('<div class="td">', st[i].intaddr), st[i].intaddr,
E('<div class="td">', st[i].intport), st[i].intport,
E('<div class="td">', st[i].descr), st[i].descr,
E('<input class="cbi-button cbi-input-remove" type="button" value="<%:Delete%>" onclick="upnp_delete_fwd(%d)" />'.format(st[i].num)) E('<input class="cbi-button cbi-button-remove" type="button" value="<%:Delete%>" onclick="upnp_delete_fwd(%d)" />'.format(st[i].num))
])); ]);
if (tb.firstElementChild === tb.lastElementChild) cbi_update_table(tb, rows, '<em><%:There are no active redirects.%></em>');
tb.appendChild(E('<div class="tr cbi-section-table-row"><div class="td"><em><br /><%:There are no active redirects.%></em></div></div>'));
} }
} }
); );
//]]></script> //]]></script>
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%:Active UPnP Redirects%></legend> <legend><%:Active UPnP Redirects%></legend>
<div class="table cbi-section-table" id="upnp_status_table"> <div class="cbi-section-node">
<div class="tr cbi-section-table-titles"> <div class="table" id="upnp_status_table">
<div class="th cbi-section-table-cell"><%:Protocol%></div> <div class="tr table-titles">
<div class="th cbi-section-table-cell"><%:External Port%></div> <div class="th"><%:Protocol%></div>
<div class="th cbi-section-table-cell"><%:Client Address%></div> <div class="th"><%:External Port%></div>
<div class="th cbi-section-table-cell"><%:Client Port%></div> <div class="th"><%:Client Address%></div>
<div class="th cbi-section-table-cell"><%:Description%></div> <div class="th"><%:Client Port%></div>
<div class="th cbi-section-table-cell">&#160;</div> <div class="th"><%:Description%></div>
</div> <div class="th cbi-section-actions">&#160;</div>
<div class="tr cbi-section-table-row"> </div>
<div class="td" colspan="5"><em><br /><%:Collecting data...%></em></div> <div class="tr">
<div class="td" colspan="5"><em><%:Collecting data...%></em></div>
</div>
</div> </div>
</div> </div>
</fieldset> </div>

View file

@ -620,7 +620,11 @@ function cbi_init() {
} }
document.querySelectorAll('.cbi-dropdown').forEach(function(s) { document.querySelectorAll('.cbi-dropdown').forEach(function(s) {
cbi_dropdown_init(s); cbi_dropdown_init(s);
});
document.querySelectorAll('.cbi-tooltip:not(:empty)').forEach(function(s) {
s.parentNode.classList.add('cbi-tooltip-container');
}); });
cbi_d_update(); cbi_d_update();
@ -1232,14 +1236,13 @@ function cbi_validate_field(cbid, optional, type)
function cbi_row_swap(elem, up, store) function cbi_row_swap(elem, up, store)
{ {
var tr = elem.parentNode; var tr = findParent(elem.parentNode, '.cbi-section-table-row');
while (tr && !tr.classList.contains('cbi-section-table-row'))
tr = tr.parentNode;
if (!tr) if (!tr)
return false; return false;
tr.classList.remove('flash');
if (up) { if (up) {
var prev = tr.previousElementSibling; var prev = tr.previousElementSibling;
@ -1277,6 +1280,9 @@ function cbi_row_swap(elem, up, store)
if (input) if (input)
input.value = ids.join(' '); input.value = ids.join(' ');
window.scrollTo(0, tr.offsetTop);
window.setTimeout(function() { tr.classList.add('flash'); }, 1);
return false; return false;
} }
@ -1522,6 +1528,19 @@ function toElem(s)
return elem || null; return elem || null;
} }
function findParent(node, selector)
{
while (node)
if (node.msMatchesSelector && node.msMatchesSelector(selector))
return node;
else if (node.matches && node.matches(selector))
return node;
else
node = node.parentNode;
return null;
}
function E() function E()
{ {
var html = arguments[0], var html = arguments[0],
@ -1541,7 +1560,7 @@ function E()
if (attr) if (attr)
for (var key in attr) for (var key in attr)
if (attr.hasOwnProperty(key)) if (attr.hasOwnProperty(key) && attr[key] !== null && attr[key] !== undefined)
elem.setAttribute(key, attr[key]); elem.setAttribute(key, attr[key]);
if (typeof(data) === 'function') if (typeof(data) === 'function')
@ -1818,18 +1837,6 @@ CBIDropdown = {
document.querySelectorAll('.cbi-dropdown[open]').forEach(function(s) { document.querySelectorAll('.cbi-dropdown[open]').forEach(function(s) {
s.dispatchEvent(new CustomEvent('cbi-dropdown-close', {})); s.dispatchEvent(new CustomEvent('cbi-dropdown-close', {}));
}); });
},
findParent: function(node, selector) {
while (node)
if (node.msMatchesSelector && node.msMatchesSelector(selector))
return node;
else if (node.matches && node.matches(selector))
return node;
else
node = node.parentNode;
return null;
} }
}; };
@ -1908,7 +1915,7 @@ function cbi_dropdown_init(sb) {
sbox.openDropdown(this); sbox.openDropdown(this);
} }
else { else {
var li = sbox.findParent(ev.target, 'li'); var li = findParent(ev.target, 'li');
if (li && li.parentNode.classList.contains('dropdown')) if (li && li.parentNode.classList.contains('dropdown'))
sbox.toggleItem(this, li); sbox.toggleItem(this, li);
} }
@ -1933,7 +1940,7 @@ function cbi_dropdown_init(sb) {
} }
else else
{ {
var active = sbox.findParent(document.activeElement, 'li'); var active = findParent(document.activeElement, 'li');
switch (ev.keyCode) { switch (ev.keyCode) {
case 27: case 27:
@ -1986,7 +1993,7 @@ function cbi_dropdown_init(sb) {
if (!this.hasAttribute('open')) if (!this.hasAttribute('open'))
return; return;
var li = sbox.findParent(ev.target, 'li'); var li = findParent(ev.target, 'li');
if (li) { if (li) {
if (li.parentNode.classList.contains('dropdown')) if (li.parentNode.classList.contains('dropdown'))
sbox.setFocus(this, li); sbox.setFocus(this, li);
@ -2023,18 +2030,18 @@ function cbi_dropdown_init(sb) {
}); });
create.addEventListener('focus', function(ev) { create.addEventListener('focus', function(ev) {
var cbox = sbox.findParent(this, 'li').querySelector('input[type="checkbox"]'); var cbox = findParent(this, 'li').querySelector('input[type="checkbox"]');
if (cbox) cbox.checked = true; if (cbox) cbox.checked = true;
sb.setAttribute('locked-in', ''); sb.setAttribute('locked-in', '');
}); });
create.addEventListener('blur', function(ev) { create.addEventListener('blur', function(ev) {
var cbox = sbox.findParent(this, 'li').querySelector('input[type="checkbox"]'); var cbox = findParent(this, 'li').querySelector('input[type="checkbox"]');
if (cbox) cbox.checked = false; if (cbox) cbox.checked = false;
sb.removeAttribute('locked-in'); sb.removeAttribute('locked-in');
}); });
var li = sbox.findParent(create, 'li'); var li = findParent(create, 'li');
li.setAttribute('unselectable', ''); li.setAttribute('unselectable', '');
li.addEventListener('click', function(ev) { li.addEventListener('click', function(ev) {
@ -2044,3 +2051,77 @@ function cbi_dropdown_init(sb) {
} }
cbi_dropdown_init.prototype = CBIDropdown; cbi_dropdown_init.prototype = CBIDropdown;
function cbi_update_table(table, data, placeholder) {
target = isElem(table) ? table : document.querySelector(table);
if (!isElem(target))
return;
target.querySelectorAll('.tr.table-titles, .cbi-section-table-titles').forEach(function(thead) {
var titles = [];
thead.querySelectorAll('.th').forEach(function(th) {
titles.push(th);
});
if (Array.isArray(data)) {
var n = 0, rows = target.querySelectorAll('.tr');
data.forEach(function(row) {
var trow = E('div', { 'class': 'tr' });
for (var i = 0; i < titles.length; i++) {
var text = titles[i].innerText;
var td = trow.appendChild(E('div', {
'class': titles[i].className,
'data-title': text ? text.trim() : null
}, row[i] || ''));
td.classList.remove('th');
td.classList.add('td');
}
trow.classList.add('cbi-rowstyle-%d'.format((n++ % 2) ? 2 : 1));
if (rows[n])
target.replaceChild(trow, rows[n]);
else
target.appendChild(trow);
});
while (rows[++n])
target.removeChild(rows[n]);
if (placeholder && target.firstElementChild === target.lastElementChild) {
var trow = target.appendChild(E('div', { 'class': 'tr placeholder' }));
var td = trow.appendChild(E('div', { 'class': titles[0].className }, placeholder));
td.classList.remove('th');
td.classList.add('td');
}
}
else {
thead.parentNode.style.display = 'none';
thead.parentNode.querySelectorAll('.tr, .cbi-section-table-row').forEach(function(trow) {
if (trow !== thead) {
var n = 0;
trow.querySelectorAll('.th, .td').forEach(function(td) {
if (n < titles.length) {
var text = (titles[n++].innerText || '').trim();
if (text !== '')
td.setAttribute('data-title', text);
}
});
}
});
thead.parentNode.style.display = '';
}
});
}
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.table').forEach(cbi_update_table);
});

View file

@ -47,7 +47,7 @@
} }
</style> </style>
<script type="text/javascript" src="<%=resource%>/cbi.js?v=git-18.138.59467-72fe5dd"></script> <script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[ <script type="text/javascript">//<![CDATA[
var xhr = new XHR(), var xhr = new XHR(),
uci_apply_auth = { sid: '<%=luci.dispatcher.context.authsession%>', token: '<%=token%>' }, uci_apply_auth = { sid: '<%=luci.dispatcher.context.authsession%>', token: '<%=token%>' },

View file

@ -1,6 +1,6 @@
<%+cbi/valueheader%> <%+cbi/valueheader%>
<% if self:cfgvalue(section) ~= false then %> <% if self:cfgvalue(section) ~= false then %>
<input class="cbi-button cbi-input-<%=self.inputstyle or "button" %>" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> /> <input class="cbi-button cbi-button-<%=self.inputstyle or "button" %>" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> />
<% else %> <% else %>
- -
<% end %> <% end %>

View file

@ -1,2 +1,10 @@
<div class="td cbi-value-field<% if self.error and self.error[section] then %> cbi-value-error<% end %>"> <%-
local title = luci.util.trim(striptags(self.title))
local ftype = self.template and self.template:gsub("^.+/", "")
-%>
<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)
%>>
<div id="cbi-<%=self.config.."-"..section.."-"..self.option%>" data-index="<%=self.index%>" data-depends="<%=pcdata(self:deplist2json(section))%>"> <div id="cbi-<%=self.config.."-"..section.."-"..self.option%>" data-index="<%=self.index%>" data-depends="<%=pcdata(self:deplist2json(section))%>">

View file

@ -36,6 +36,18 @@
<%=pcdata(self.vallist[i])%> <%=pcdata(self.vallist[i])%>
</li> </li>
<% end %> <% end %>
<% if self.custom then %>
<li>
<input type="password" style="display:none" />
<input class="create-item-input" type="text"<%=
attr("placeholder", self.custom ~= true and
self.custom or
(self.multiple and
translate("Enter custom values") or
translate("Enter custom value")))
%> />
</li>
<% end %>
</ul> </ul>
</div> </div>

View file

@ -14,46 +14,59 @@
local def = fwm:get_defaults() local def = fwm:get_defaults()
local zone = fwm:get_zone(value) local zone = fwm:get_zone(value)
local empty = true local empty = true
local function render_zone(zone)
-%>
<label class="zonebadge" style="background-color:<%=zone:get_color()%>">
<strong><%=zone:name()%></strong>
<div class="cbi-tooltip">
<%-
local zempty = true
for _, net in ipairs(zone:get_networks()) do
net = nwm:get_network(net)
if net then
zempty = false
-%>
<span class="ifacebadge<% if net:name() == self.network then %> ifacebadge-active<% end %>"><%=net:name()%>:&#160;
<%
local nempty = true
for _, iface in ipairs(net:is_bridge() and net:get_interfaces() or { net:get_interface() }) do
nempty = false
%>
<img<%=attr("title", iface:get_i18n())%> src="<%=resource%>/icons/<%=iface:type()%><%=iface:is_up() and "" or "_disabled"%>.png" />
<% end %>
<% if nempty then %><em><%:(empty)%></em><% end %>
</span>
<%- end end -%>
<% if zempty then %><span class="ifacebadge"><em><%:(empty)%></em></span><% end %>
</div>
</label>
<%-
end
-%> -%>
<% if zone then %> <% if zone then %>
<div style="white-space:nowrap"> <div class="zone-forwards">
<label class="zonebadge" style="background-color:<%=zone:get_color()%>"> <div class="zone-src">
<strong><%=zone:name()%>:</strong> <%=render_zone(zone)%>
<%- </div>
local zempty = true <span>&#8658;</span>
for _, net in ipairs(zone:get_networks()) do <div class="zone-dest">
net = nwm:get_network(net) <%
if net then for _, fwd in ipairs(zone:get_forwardings_by("src")) do
zempty = false fz = fwd:dest_zone()
-%> if fz then
<span class="ifacebadge<% if net:name() == self.network then %> ifacebadge-active<% end %>"><%=net:name()%>: empty = false
<% render_zone(fz)
local nempty = true end
for _, iface in ipairs(net:is_bridge() and net:get_interfaces() or { net:get_interface() }) do end
nempty = false if empty then
%> %>
<img<%=attr("title", iface:get_i18n())%> style="width:16px; height:16px; vertical-align:middle" src="<%=resource%>/icons/<%=iface:type()%><%=iface:is_up() and "" or "_disabled"%>.png" />
<% end %>
<% if nempty then %><em><%:(empty)%></em><% end %>
</span>
<%- end end -%>
<%- if zempty then %><em><%:(empty)%></em><% end -%>
</label>
&#160;&#8658;&#160;
<% for _, fwd in ipairs(zone:get_forwardings_by("src")) do
fz = fwd:dest_zone()
if fz then
empty = false %>
<label class="zonebadge" style="background-color:<%=fz:get_color()%>">
<strong><%=fz:name()%></strong>
</label>&#160;
<% end end %>
<% if empty then %>
<label class="zonebadge zonebadge-empty"> <label class="zonebadge zonebadge-empty">
<strong><%=zone:forward():upper()%></strong> <strong><%=zone:forward():upper()%></strong>
</label> </label>
<% end %> <% end %>
</div>
</div> </div>
<% end %> <% end %>

View file

@ -1,9 +1,7 @@
<%- if pageaction then -%> <%- if pageaction then -%>
<div class="cbi-page-actions"> <div class="cbi-page-actions">
<% if redirect and not flow.hidebackbtn then %> <% if redirect and not flow.hidebackbtn then %>
<div style="float:left">
<input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" /> <input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" />
</div>
<% end %> <% end %>
<% if flow.skip then %> <% if flow.skip then %>

View file

@ -3,7 +3,6 @@
<br /> <br />
<%- end %> <%- end %>
<div class="cbi-value-description"> <div class="cbi-value-description">
<span class="cbi-value-helpicon"><img src="<%=resource%>/cbi/help.gif" alt="<%:help%>" /></span>
<%=self.description%> <%=self.description%>
</div> </div>
<%- end %> <%- end %>

View file

@ -31,7 +31,6 @@
</li> </li>
<% end %> <% end %>
</ul> </ul>
<br />
<% for i, section in ipairs(self.children) do %> <% 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 %>> <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() %> <% section:render() %>
@ -53,6 +52,4 @@
<% else %> <% else %>
<%- self:render_children() %> <%- self:render_children() %>
<% end %> <% end %>
<br />
</div> </div>

View file

@ -1,5 +1,5 @@
<% if self:cfgvalue(self.section) then section = self.section %> <% if self:cfgvalue(self.section) then section = self.section %>
<fieldset class="cbi-section"> <div class="cbi-section">
<% if self.title and #self.title > 0 then -%> <% if self.title and #self.title > 0 then -%>
<legend><%=self.title%></legend> <legend><%=self.title%></legend>
<%- end %> <%- end %>
@ -15,17 +15,16 @@
<div class="cbi-section-node<% if self.tabs then %> cbi-section-node-tabbed<% end %>" id="cbi-<%=self.config%>-<%=section%>"> <div class="cbi-section-node<% if self.tabs then %> cbi-section-node-tabbed<% end %>" id="cbi-<%=self.config%>-<%=section%>">
<%+cbi/ucisection%> <%+cbi/ucisection%>
</div> </div>
<br /> </div>
</fieldset>
<% elseif self.addremove then %> <% elseif self.addremove then %>
<% if self.template_addremove then include(self.template_addremove) else -%> <% if self.template_addremove then include(self.template_addremove) else -%>
<fieldset class="cbi-section" id="cbi-<%=self.config%>-<%=self.section%>"> <div class="cbi-section" id="cbi-<%=self.config%>-<%=self.section%>">
<% if self.title and #self.title > 0 then -%> <% if self.title and #self.title > 0 then -%>
<legend><%=self.title%></legend> <legend><%=self.title%></legend>
<%- end %> <%- end %>
<div class="cbi-section-descr"><%=self.description%></div> <div class="cbi-section-descr"><%=self.description%></div>
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cns.<%=self.config%>.<%=self.section%>" value="<%:Add%>" /> <input type="submit" class="cbi-button cbi-button-add" name="cbi.cns.<%=self.config%>.<%=self.section%>" value="<%:Add%>" />
</fieldset> </div>
<%- end %> <%- end %>
<% end %> <% end %>
<!-- /nsection --> <!-- /nsection -->

View file

@ -1,4 +1,4 @@
<fieldset class="cbi-section"> <div class="cbi-section">
<% if self.title and #self.title > 0 then -%> <% if self.title and #self.title > 0 then -%>
<legend><%=self.title%></legend> <legend><%=self.title%></legend>
<%- end %> <%- end %>
@ -25,8 +25,7 @@
</div> </div>
<%- end %> <%- end %>
</div> </div>
<br /> </div>
</fieldset>
<%- <%-
if type(self.hidden) == "table" then if type(self.hidden) == "table" then
for k, v in pairs(self.hidden) do for k, v in pairs(self.hidden) do

View file

@ -10,7 +10,6 @@
<% if self.title and #self.title > 0 then %><h2 name="content"><%=self.title%></h2><% 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.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %>
<% self:render_children() %> <% self:render_children() %>
<br />
</div> </div>
<%- if self.message then %> <%- if self.message then %>
<div><%=self.message%></div> <div><%=self.message%></div>
@ -30,9 +29,12 @@
end end
%> %>
<% if redirect then %> <% if redirect then %>
<div style="float:left"> <input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" />
<input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" /> <% end %>
</div> <%- 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 %> <% end %>
<%- if self.flow and self.flow.skip then %> <%- if self.flow and self.flow.skip then %>
<input class="cbi-button cbi-button-skip" type="submit" name="cbi.skip" value="<%:Skip%>" /> <input class="cbi-button cbi-button-skip" type="submit" name="cbi.skip" value="<%:Skip%>" />
@ -46,11 +48,6 @@
<input class="cbi-button cbi-button-reset" type="reset" value=" <input class="cbi-button cbi-button-reset" type="reset" value="
<%- if not self.reset then -%><%-:Reset-%><%-else-%><%=self.reset%><%end-%> <%- if not self.reset then -%><%-:Reset-%><%-else-%><%=self.reset%><%end-%>
" /> " />
<% end %>
<%- if self.cancel ~= false and self.on_cancel then %>
<input class="cbi-button cbi-button-reset" type="submit" name="cbi.cancel" value="
<%- if not self.cancel then -%><%-:Cancel-%><%-else-%><%=self.cancel%><%end-%>
" />
<% end %> <% end %>
</div> </div>
</form> </form>

View file

@ -14,10 +14,11 @@ function width(o)
end end
return '' return ''
end end
-%> -%>
<!-- tblsection --> <!-- tblsection -->
<fieldset class="cbi-section" id="cbi-<%=self.config%>-<%=self.sectiontype%>"> <div class="cbi-section cbi-tblsection" id="cbi-<%=self.config%>-<%=self.sectiontype%>">
<% if self.title and #self.title > 0 then -%> <% if self.title and #self.title > 0 then -%>
<legend><%=self.title%></legend> <legend><%=self.title%></legend>
<%- end %> <%- end %>
@ -25,121 +26,103 @@ end
<input type="hidden" id="cbi.sts.<%=self.config%>.<%=self.sectiontype%>" name="cbi.sts.<%=self.config%>.<%=self.sectiontype%>" value="" /> <input type="hidden" id="cbi.sts.<%=self.config%>.<%=self.sectiontype%>" name="cbi.sts.<%=self.config%>.<%=self.sectiontype%>" value="" />
<%- end -%> <%- end -%>
<div class="cbi-section-descr"><%=self.description%></div> <div class="cbi-section-descr"><%=self.description%></div>
<div class="cbi-section-node"> <%- local count = 0 -%>
<%- local count = 0 -%> <div class="table cbi-section-table">
<div class="table cbi-section-table"> <div class="tr cbi-section-table-titles <%=(not self.anonymous or self.sectiontitle) and "named" or "anonymous"%>">
<div class="tr cbi-section-table-titles"> <%- for i, k in pairs(self.children) do if not k.optional then -%>
<%- if not self.anonymous then -%> <div class="th cbi-section-table-cell"<%=
<%- if self.sectionhead then -%> width(k) ..
<div class="th cbi-section-table-cell"><%=self.sectionhead%></div> attr("data-type", k.template and k.template:gsub("^.+/", "") or "")
<%- else -%> %>>
<div class="th">&#160;</div> <%- if k.titleref then -%><a title="<%=self.titledesc or translate('Go to relevant configuration page')%>" class="cbi-title-ref" href="<%=k.titleref%>"><%- end -%>
<%- end -%> <%-=k.title-%>
<%- count = count +1; end -%> <%- if k.titleref then -%></a><%- end -%>
<%- for i, k in pairs(self.children) do if not k.optional then -%>
<div class="th cbi-section-table-cell"<%=width(k)%>>
<%- 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 then -%>
<div class="th cbi-section-table-cell"><%:Sort%></div>
<%- count = count + 1; end; if self.extedit or self.addremove then -%>
<div class="th cbi-section-table-cell">&#160;</div>
<%- count = count + 1; end -%>
</div> </div>
<div class="tr cbi-section-table-descr"> <%- count = count + 1; end; end; if self.sortable or self.extedit or self.addremove then -%>
<%- if not self.anonymous then -%> <div class="th cbi-section-table-cell cbi-section-actions"></div>
<%- if self.sectiondesc then -%> <%- count = count + 1; end -%>
<div class="th cbi-section-table-cell"><%=self.sectiondesc%></div> </div>
<%- else -%> <div class="tr cbi-section-table-descr">
<div class="th"></div> <%- for i, k in pairs(self.children) do if not k.optional then -%>
<%- end -%> <div class="th cbi-section-table-cell"<%=
<%- end -%> width(k) ..
<%- for i, k in pairs(self.children) do if not k.optional then -%> attr("data-type", k.template and k.template:gsub("^.+/", "") or "")
<div class="th cbi-section-table-cell"<%=width(k)%>><%=k.description%></div> %>><%=k.description%></div>
<%- end; end; if self.sortable then -%> <%- end; end; if self.sortable or self.extedit or self.addremove then -%>
<div class="th cbi-section-table-cell"></div> <div class="th cbi-section-table-cell cbi-section-actions"></div>
<%- end; if self.extedit or self.addremove then -%> <%- end -%>
<div class="th cbi-section-table-cell"></div> </div>
<%- end -%> <%- local isempty = true
</div> for i, k in ipairs(self:cfgsections()) do
<%- local isempty = true section = k
for i, k in ipairs(self:cfgsections()) do isempty = false
section = k title = striptags((type(self.sectiontitle) == "function") and self:sectiontitle(section) or k)
isempty = false scope = {
scope = { valueheader = "cbi/cell_valueheader", valuefooter = "cbi/cell_valuefooter" } valueheader = "cbi/cell_valueheader",
-%> valuefooter = "cbi/cell_valuefooter"
<div class="tr cbi-section-table-row<% if self.extedit or self.rowcolors then %> cbi-rowstyle-<%=rowstyle()%><% end %>" id="cbi-<%=self.config%>-<%=section%>"> }
<% if not self.anonymous then -%> -%>
<div class="th"><h3><%=(type(self.sectiontitle) == "function") and self:sectiontitle(section) or k%></h3></div> <div class="tr cbi-section-table-row<% if self.extedit or self.rowcolors then %> cbi-rowstyle-<%=rowstyle()%><% end %>" id="cbi-<%=self.config%>-<%=section%>"<%=ifattr(title and (not self.anonymous or self.sectiontitle), "data-title", striptags((type(self.sectiontitle) == "function") and self:sectiontitle(section) or k))%>>
<%- end %> <%-
for k, node in ipairs(self.children) do
if not node.optional then
<%- node:render(section, scope or {})
for k, node in ipairs(self.children) do
if not node.optional then
node:render(section, scope or {})
end
end end
-%> end
-%>
<%- if self.sortable then -%> <%- if self.sortable or self.extedit or self.addremove then -%>
<div class="td cbi-section-table-cell"> <div class="td cbi-section-table-cell nowrap cbi-section-actions">
<input class="cbi-button cbi-button-up" type="button" value="" onclick="return cbi_row_swap(this, true, 'cbi.sts.<%=self.config%>.<%=self.sectiontype%>')" alt="<%:Move up%>" title="<%:Move up%>" /> <%- if self.sortable then -%>
<input class="cbi-button cbi-button-down" type="button" value="" onclick="return cbi_row_swap(this, false, 'cbi.sts.<%=self.config%>.<%=self.sectiontype%>')" alt="<%:Move down%>" title="<%:Move down%>" /> <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%>" />
</div> <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 -%> <% end; if self.extedit then -%>
<input class="cbi-button cbi-button-edit" type="button" value="<%:Edit%>"
<%- if self.extedit or self.addremove then -%> <%- if type(self.extedit) == "string" then
<div class="td cbi-section-table-cell"> %> onclick="location.href='<%=self.extedit:format(section)%>'"
<%- if self.extedit then -%> <%- elseif type(self.extedit) == "function" then
<input class="cbi-button cbi-button-edit" type="button" value="<%:Edit%>" %> onclick="location.href='<%=self:extedit(section)%>'"
<%- if type(self.extedit) == "string" then <%- end
%> onclick="location.href='<%=self.extedit:format(section)%>'" %> alt="<%:Edit%>" title="<%:Edit%>" />
<%- elseif type(self.extedit) == "function" then <% end; if self.addremove then %>
%> onclick="location.href='<%=self:extedit(section)%>'" <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 <%- end -%>
%> alt="<%:Edit%>" title="<%:Edit%>" /> </div>
<%- 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>
<%- end -%>
</div>
<%- end -%>
<%- if isempty then -%>
<div class="tr cbi-section-table-row">
<div class="td" colspan="<%=count%>"><em><br /><%:This section contains no values yet%></em></div>
</div>
<%- end -%> <%- end -%>
</div> </div>
<%- end -%>
<% if self.error then %> <%- if isempty then -%>
<div class="cbi-section-error"> <div class="tr cbi-section-table-row placeholder">
<ul><% for _, c in pairs(self.error) do for _, e in ipairs(c) do -%> <div class="td"><em><%:This section contains no values yet%></em></div>
<li><%=pcdata(e):gsub("\n","<br />")%></li> </div>
<%- end end %></ul>
</div>
<% end %>
<%- if self.addremove then -%>
<% if self.template_addremove then include(self.template_addremove) else -%>
<div class="cbi-section-create cbi-tblsection-create">
<% if self.anonymous then %>
<input class="cbi-button cbi-button-add" type="submit" value="<%:Add%>" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" title="<%:Add%>" />
<% else %>
<% if self.invalid_cts then -%><div class="cbi-section-error"><% end %>
<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" />
<input class="cbi-button cbi-button-add" type="submit" onclick="this.form.cbi_state='add-section'; return true" value="<%:Add%>" title="<%:Add%>" />
<% if self.invalid_cts then -%>
<br /><%:Invalid%></div>
<%- end %>
<% end %>
</div>
<%- end %>
<%- end -%> <%- end -%>
</div> </div>
</fieldset>
<% if self.error then %>
<div class="cbi-section-error">
<ul><% for _, c in pairs(self.error) do for _, e in ipairs(c) do -%>
<li><%=pcdata(e):gsub("\n","<br />")%></li>
<%- end end %></ul>
</div>
<% end %>
<%- if self.addremove then -%>
<% if self.template_addremove then include(self.template_addremove) else -%>
<div class="cbi-section-create cbi-tblsection-create">
<% if self.anonymous then %>
<input class="cbi-button cbi-button-add" type="submit" value="<%:Add%>" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" title="<%:Add%>" />
<% else %>
<% if self.invalid_cts then -%>
<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" />
</div>
<input class="cbi-button cbi-button-add" type="submit" onclick="this.form.cbi_state='add-section'; return true" value="<%:Add%>" title="<%:Add%>" />
<% end %>
</div>
<%- end %>
<%- end -%>
</div>
<!-- /tblsection --> <!-- /tblsection -->

View file

@ -1,4 +1,4 @@
<fieldset class="cbi-section" id="cbi-<%=self.config%>-<%=self.sectiontype%>"> <div class="cbi-section" id="cbi-<%=self.config%>-<%=self.sectiontype%>">
<% if self.title and #self.title > 0 then -%> <% if self.title and #self.title > 0 then -%>
<legend><%=self.title%></legend> <legend><%=self.title%></legend>
<%- end %> <%- end %>
@ -20,10 +20,9 @@
<%+cbi/tabmenu%> <%+cbi/tabmenu%>
<fieldset class="cbi-section-node<% if self.tabs then %> cbi-section-node-tabbed<% end %>" id="cbi-<%=self.config%>-<%=section%>"> <div class="cbi-section-node<% if self.tabs then %> cbi-section-node-tabbed<% end %>" id="cbi-<%=self.config%>-<%=section%>">
<%+cbi/ucisection%> <%+cbi/ucisection%>
</fieldset> </div>
<br />
<%- end %> <%- end %>
<% if isempty then -%> <% if isempty then -%>
@ -36,14 +35,15 @@
<% if self.anonymous then -%> <% if self.anonymous then -%>
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" /> <input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" />
<%- else -%> <%- else -%>
<% if self.invalid_cts then -%><div class="cbi-section-error"><% end %>
<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" />
<input type="submit" class="cbi-button cbi-button-add" onclick="this.form.cbi_state='add-section'; return true" value="<%:Add%>" />
<% if self.invalid_cts then -%> <% if self.invalid_cts then -%>
<br /><%:Invalid%></div> <div class="cbi-section-error"><%:Invalid%></div>
<%- end %> <%- 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" />
</div>
<input class="cbi-button cbi-button-add" type="submit" onclick="this.form.cbi_state='add-section'; return true" value="<%:Add%>" title="<%:Add%>" />
<%- end %> <%- end %>
</div> </div>
<%- end %> <%- end %>
<%- end %> <%- end %>
</fieldset> </div>

View file

@ -8,7 +8,7 @@
<%:Uploaded File%> (<%=t.byte_format(s.size)%>) <%:Uploaded File%> (<%=t.byte_format(s.size)%>)
<% if self.unsafeupload then %> <% if self.unsafeupload then %>
<input type="hidden"<%= attr("value", v) .. attr("name", cbid) .. attr("id", cbid) %> /> <input type="hidden"<%= attr("value", v) .. attr("name", cbid) .. attr("id", cbid) %> />
<input class="cbi-button cbi-input-image" type="image" value="<%:Replace entry%>" name="cbi.rlf.<%=section .. "." .. self.option%>" alt="<%:Replace entry%>" title="<%:Replace entry%>" src="<%=resource%>/cbi/reload.gif" /> <input class="cbi-button cbi-button-image" type="image" value="<%:Replace entry%>" name="cbi.rlf.<%=section .. "." .. self.option%>" alt="<%:Replace entry%>" title="<%:Replace entry%>" src="<%=resource%>/cbi/reload.gif" />
<% end %> <% end %>
<% end %> <% end %>

View file

@ -18,23 +18,23 @@
<div class="cbi-map-descr"> <div class="cbi-map-descr">
<%:Please enter your username and password.%> <%:Please enter your username and password.%>
</div> </div>
<fieldset class="cbi-section"><fieldset class="cbi-section-node"> <div class="cbi-section"><div class="cbi-section-node">
<div class="cbi-value"> <div class="cbi-value">
<label class="cbi-value-title"><%:Username%></label> <label class="cbi-value-title"><%:Username%></label>
<div class="cbi-value-field"> <div class="cbi-value-field">
<input class="cbi-input-user" type="text" name="luci_username" value="<%=duser%>" /> <input class="cbi-input-text" type="text" name="luci_username" value="<%=duser%>" />
</div> </div>
</div> </div>
<div class="cbi-value cbi-value-last"> <div class="cbi-value cbi-value-last">
<label class="cbi-value-title"><%:Password%></label> <label class="cbi-value-title"><%:Password%></label>
<div class="cbi-value-field"> <div class="cbi-value-field">
<input class="cbi-input-password" type="password" name="luci_password" /> <input class="cbi-input-text" type="password" name="luci_password" />
</div> </div>
</div> </div>
</fieldset></fieldset> </div></div>
</div> </div>
<div> <div class="cbi-page-actions">
<input type="submit" value="<%:Login%>" class="cbi-button cbi-button-apply" /> <input type="submit" value="<%:Login%>" class="cbi-button cbi-button-apply" />
<input type="reset" value="<%:Reset%>" class="cbi-button cbi-button-reset" /> <input type="reset" value="<%:Reset%>" class="cbi-button cbi-button-reset" />
</div> </div>

View file

@ -74,7 +74,7 @@ function action_packages()
local out, err local out, err
-- Display -- Display
local display = luci.http.formvalue("display") or "installed" local display = luci.http.formvalue("display") or "available"
-- Letter -- Letter
local letter = string.byte(luci.http.formvalue("letter") or "A", 1) local letter = string.byte(luci.http.formvalue("letter") or "A", 1)

View file

@ -61,55 +61,54 @@ local route_host = luci.config.diag and luci.config.diag.route or "dev.openwrt.o
<div class="cbi-map"> <div class="cbi-map">
<h2 name="content"><%:Diagnostics%></h2> <h2 name="content"><%:Diagnostics%></h2>
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%:Network Utilities%></legend> <legend><%:Network Utilities%></legend>
<br /> <div class="table">
<div class="tr">
<div class="td left">
<input style="margin: 5px 0" type="text" value="<%=ping_host%>" name="ping" /><br />
<% if has_ping6 then %>
<select name="ping_proto" style="width:auto">
<option value="" selected="selected"><%:IPv4%></option>
<option value="6"><%:IPv6%></option>
</select>
<input type="button" value="<%:Ping%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.ping, this.form.ping_proto.selectedIndex)" />
<% else %>
<input type="button" value="<%:Ping%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.ping)" />
<% end %>
</div>
<div style="width:30%; float:left"> <div class="td left">
<input style="margin: 5px 0" type="text" value="<%=ping_host%>" name="ping" /><br /> <input style="margin: 5px 0" type="text" value="<%=route_host%>" name="traceroute" /><br />
<% if has_ping6 then %> <% if has_traceroute6 then %>
<select name="ping_proto" style="width:auto"> <select name="traceroute_proto" style="width:auto">
<option value="" selected="selected"><%:IPv4%></option> <option value="" selected="selected"><%:IPv4%></option>
<option value="6"><%:IPv6%></option> <option value="6"><%:IPv6%></option>
</select> </select>
<input type="button" value="<%:Ping%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.ping, this.form.ping_proto.selectedIndex)" /> <input type="button" value="<%:Traceroute%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.traceroute, this.form.traceroute_proto.selectedIndex)" />
<% else %> <% else %>
<input type="button" value="<%:Ping%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.ping)" /> <input type="button" value="<%:Traceroute%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.traceroute)" />
<% end %> <% end %>
<% if not has_traceroute6 then %>
<p>&#160;</p>
<p><%:Install iputils-traceroute6 for IPv6 traceroute%></p>
<% end %>
</div>
<div class="td left">
<input style="margin: 5px 0" type="text" value="<%=dns_host%>" name="nslookup" /><br />
<input type="button" value="<%:Nslookup%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.nslookup)" />
</div>
</div>
</div> </div>
</div>
<div style="width:33%; float:left">
<input style="margin: 5px 0" type="text" value="<%=route_host%>" name="traceroute" /><br />
<% if has_traceroute6 then %>
<select name="traceroute_proto" style="width:auto">
<option value="" selected="selected"><%:IPv4%></option>
<option value="6"><%:IPv6%></option>
</select>
<input type="button" value="<%:Traceroute%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.traceroute, this.form.traceroute_proto.selectedIndex)" />
<% else %>
<input type="button" value="<%:Traceroute%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.traceroute)" />
<% end %>
<% if not has_traceroute6 then %>
<p>&#160;</p>
<p><%:Install iputils-traceroute6 for IPv6 traceroute%></p>
<% end %>
</div>
<div style="width:33%; float:left;">
<input style="margin: 5px 0" type="text" value="<%=dns_host%>" name="nslookup" /><br />
<input type="button" value="<%:Nslookup%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.nslookup)" />
</div>
<br style="clear:both" /><br />
</fieldset>
</div> </div>
<fieldset class="cbi-section" style="display:none"> <div class="cbi-section" style="display:none">
<legend id="diag-rc-legend"><%:Collecting data...%></legend> <strong id="diag-rc-legend"></strong>
<span id="diag-rc-output"></span> <span id="diag-rc-output"></span>
</fieldset> </div>
</form> </form>
<%+footer%> <%+footer%>

View file

@ -67,7 +67,7 @@
} }
function iface_delete(id) { function iface_delete(id) {
if (!confirm(<%=luci.http.write_json(translate('Really delete this interface? The deletion cannot be undone! You might lose access to this device if you are connected via this interface.'))%>)) if (!confirm(<%=luci.http.write_json(translate('Really delete this interface? The deletion cannot be undone! You might lose access to this device if you are connected via this interface'))%>))
return; return;
(new XHR()).post('<%=url('admin/network/iface_delete')%>/' + id, { token: '<%=token%>' }, (new XHR()).post('<%=url('admin/network/iface_delete')%>/' + id, { token: '<%=token%>' },
@ -141,8 +141,8 @@
} }
html += String.format( html += String.format(
'<strong><%:RX%></strong>: %.2mB (%d <%:Pkts.%>)<br />' + '<strong><%:RX%>:</strong> %.2mB (%d <%:Pkts.%>)<br />' +
'<strong><%:TX%></strong>: %.2mB (%d <%:Pkts.%>)<br />', '<strong><%:TX%>:</strong> %.2mB (%d <%:Pkts.%>)<br />',
ifc.rx_bytes, ifc.rx_packets, ifc.rx_bytes, ifc.rx_packets,
ifc.tx_bytes, ifc.tx_packets ifc.tx_bytes, ifc.tx_packets
); );
@ -209,46 +209,43 @@
</fieldset> </fieldset>
<div class="cbi-map"> <div class="cbi-map">
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%:Interface Overview%></legend> <legend><%:Interface Overview%></legend>
<div class="table cbi-section-table" style="margin:10px; empty-cells:hide"> <div class="cbi-section-node">
<div class="tr cbi-section-table-titles"> <div class="table">
<div class="th"><%:Network%></div> <%
<div class="th left"><%:Status%></div> for i, net in ipairs(netlist) do
<div class="th"><%:Actions%></div> local z = net[3]
</div> local c = z and z:get_color() or "#EEEEEE"
<% local t = z and translate("Part of zone %q" % z:name()) or translate("No zone assigned")
for i, net in ipairs(netlist) do %>
local z = net[3] <div class="tr cbi-rowstyle-<%=i % 2 + 1%>">
local c = z and z:get_color() or "#EEEEEE" <div class="td col-3 center middle">
local t = z and translate("Part of zone %q" % z:name()) or translate("No zone assigned") <div class="ifacebox">
%> <div class="ifacebox-head" style="background-color:<%=c%>" title="<%=pcdata(t)%>">
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i % 2 + 1%>"> <strong><%=net[1]:upper()%></strong>
<div class="td"> </div>
<div class="ifacebox"> <div class="ifacebox-body" id="<%=net[1]%>-ifc-devices">
<div class="ifacebox-head" style="background-color:<%=c%>" title="<%=pcdata(t)%>"> <img src="<%=resource%>/icons/ethernet_disabled.png" style="width:16px; height:16px" /><br />
<strong><%=net[1]:upper()%></strong> <small>?</small>
</div> </div>
<div class="ifacebox-body" id="<%=net[1]%>-ifc-devices">
<img src="<%=resource%>/icons/ethernet_disabled.png" style="width:16px; height:16px" /><br />
<small>?</small>
</div> </div>
</div> </div>
<div class="td col-5 left" id="<%=net[1]%>-ifc-description">
<em><%:Collecting data...%></em>
</div>
<div class="td cbi-section-actions">
<input type="button" class="cbi-button cbi-button-neutral" onclick="iface_shutdown('<%=net[1]%>', true)" title="<%:Reconnect this interface%>" value="<%:Connect%>" />
<input type="button" class="cbi-button cbi-button-neutral" onclick="iface_shutdown('<%=net[1]%>', false)" title="<%:Shutdown this interface%>" value="<%:Stop%>" />
<input type="button" class="cbi-button cbi-button-action important" onclick="location.href='<%=url("admin/network/network", net[1])%>'" title="<%:Edit this interface%>" value="<%:Edit%>" id="<%=net[1]%>-ifc-edit" />
<input type="button" class="cbi-button cbi-button-negative" onclick="iface_delete('<%=net[1]%>')" value="<%:Delete%>" />
</div>
</div> </div>
<div class="td left" id="<%=net[1]%>-ifc-description"> <% end %>
<em><%:Collecting data...%></em> </div>
</div>
<div class="td">
<input type="button" class="cbi-button cbi-button-reload" style="width:100px" onclick="iface_shutdown('<%=net[1]%>', true)" title="<%:Reconnect this interface%>" value="<%:Connect%>" />
<input type="button" class="cbi-button cbi-button-reset" style="width:100px" onclick="iface_shutdown('<%=net[1]%>', false)" title="<%:Shutdown this interface%>" value="<%:Stop%>" />
<input type="button" class="cbi-button cbi-button-edit" style="width:100px" onclick="location.href='<%=url("admin/network/network", net[1])%>'" title="<%:Edit this interface%>" value="<%:Edit%>" id="<%=net[1]%>-ifc-edit" />
<input type="button" class="cbi-button cbi-button-remove" style="width:100px" onclick="iface_delete('<%=net[1]%>')" value="<%:Delete%>" />
</div>
</div>
<% end %>
</div> </div>
<input type="button" class="cbi-button cbi-button-add" value="<%:Add new interface...%>" onclick="location.href='<%=url("admin/network/iface_add")%>'" /> <input type="button" class="cbi-button cbi-button-add" value="<%:Add new interface...%>" onclick="location.href='<%=url("admin/network/iface_add")%>'" />
</fieldset> </div>
</div> </div>

View file

@ -6,29 +6,18 @@
{ {
if (ifc && (ifc = ifc[0])) if (ifc && (ifc = ifc[0]))
{ {
var html = ''; var s = document.getElementById('<%=self.option%>-ifc-status'),
img = s.querySelector('img'),
info = s.querySelector('span'),
html = '<strong><%:Device%>:</strong> %h<br />'.format(ifc.ifname);
var s = document.getElementById('<%=self.option%>-ifc-signal'); if (ifc.ifname)
if (s)
s.innerHTML = String.format(
'<img src="<%=resource%>/icons/%s%s.png" style="width:16px; height:16px" />' +
'<br /><small>%s</small>',
ifc.type, ifc.is_up ? '' : '_disabled',
ifc.name
);
var d = document.getElementById('<%=self.option%>-ifc-description');
if (d && ifc.ifname)
{ {
if (ifc.is_up) if (ifc.is_up)
{
html += String.format('<strong><%:Uptime%>:</strong> %t<br />', ifc.uptime); html += String.format('<strong><%:Uptime%>:</strong> %t<br />', ifc.uptime);
}
if (ifc.macaddr) if (ifc.macaddr)
{
html += String.format('<strong><%:MAC-Address%>:</strong> %s<br />', ifc.macaddr); html += String.format('<strong><%:MAC-Address%>:</strong> %s<br />', ifc.macaddr);
}
html += String.format( html += String.format(
'<strong><%:RX%></strong>: %.2mB (%d <%:Pkts.%>)<br />' + '<strong><%:RX%></strong>: %.2mB (%d <%:Pkts.%>)<br />' +
@ -38,50 +27,40 @@
); );
if (ifc.ipaddrs && ifc.ipaddrs.length) if (ifc.ipaddrs && ifc.ipaddrs.length)
{
for (var i = 0; i < ifc.ipaddrs.length; i++) for (var i = 0; i < ifc.ipaddrs.length; i++)
html += String.format( html += String.format(
'<strong><%:IPv4%>:</strong> %s<br />', '<strong><%:IPv4%>:</strong> %s<br />',
ifc.ipaddrs[i] ifc.ipaddrs[i]
); );
}
if (ifc.ip6addrs && ifc.ip6addrs.length) if (ifc.ip6addrs && ifc.ip6addrs.length)
{
for (var i = 0; i < ifc.ip6addrs.length; i++) for (var i = 0; i < ifc.ip6addrs.length; i++)
html += String.format( html += String.format(
'<strong><%:IPv6%>:</strong> %s<br />', '<strong><%:IPv6%>:</strong> %s<br />',
ifc.ip6addrs[i] ifc.ip6addrs[i]
); );
}
if (ifc.ip6prefix)
{
html += String.format('<strong><%:IPv6-PD%>:</strong> %s<br />', ifc.ip6prefix);
}
d.innerHTML = html; if (ifc.ip6prefix)
html += String.format('<strong><%:IPv6-PD%>:</strong> %s<br />', ifc.ip6prefix);
info.innerHTML = html;
} }
else if (d) else
{ {
d.innerHTML = '<em><%:Interface not present or not connected yet.%></em>'; info.innerHTML = '<em><%:Interface not present or not connected yet.%></em>';
} }
img.src = '<%=resource%>/icons/%s%s.png'.format(ifc.type, ifc.is_up ? '' : '_disabled');
} }
} }
); );
//]]></script> //]]></script>
<div class="table"> <span class="ifacebadge large" id="<%=self.option%>-ifc-status">
<div class="tr cbi-section-table"> <img src="<%=resource%>/icons/ethernet_disabled.png" />
<div class="td"></div> <span>
<div class="td cbi-value-field" style="min-width:16px; padding:3px; text-align:center" id="<%=self.option%>-ifc-signal"> <em><%:Collecting data...%></em>
<img src="<%=resource%>/icons/ethernet_disabled.png" style="width:16px; height:16px" /><br /> </span>
<small>?</small> </span>
</div>
<div class="td cbi-value-field" style="vertical-align:middle; text-align:left; padding:3px" id="<%=self.option%>-ifc-description">
<em><%:Collecting data...%></em>
</div>
</div>
</div>
<%+cbi/valuefooter%> <%+cbi/valuefooter%>

View file

@ -34,7 +34,7 @@
else else
timestr = String.format('%t', st[0][i].expires); timestr = String.format('%t', st[0][i].expires);
tb.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-%d">'.format((i % 2) + 1), [ tb.appendChild(E('<div class="tr cbi-rowstyle-%d">'.format((i % 2) + 1), [
E('<div class="td">', st[0][i].hostname || '?'), E('<div class="td">', st[0][i].hostname || '?'),
E('<div class="td">', st[0][i].ipaddr), E('<div class="td">', st[0][i].ipaddr),
E('<div class="td">', st[0][i].macaddr), E('<div class="td">', st[0][i].macaddr),
@ -43,7 +43,7 @@
} }
if (tb.firstElementChild === tb.lastElementChild) if (tb.firstElementChild === tb.lastElementChild)
tb.appendChild(E('<div class="tr cbi-section-table-row"><div class="td"><em><br /><%:There are no active leases.%></em></div></div>')); tb.appendChild(E('<div class="tr"><div class="td"><em><br /><%:There are no active leases.%></em></div></div>'));
} }
var tb6 = document.getElementById('lease6_status_table'); var tb6 = document.getElementById('lease6_status_table');
@ -79,8 +79,8 @@
hint = host.name; hint = host.name;
} }
tb6.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-%d" style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space: nowrap">'.format((i % 2) + 1), [ tb6.appendChild(E('<div class="tr cbi-rowstyle-%d">'.format((i % 2) + 1), [
E('<div class="td">', hint ? '<div style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space: nowrap">%h (%h)</div>'.format(name || '?', hint) : (name || '?')), E('<div class="td nowrap">', hint ? '%h (%h)'.format(name || '?', hint) : (name || '?')),
E('<div class="td">', st[1][i].ip6addr), E('<div class="td">', st[1][i].ip6addr),
E('<div class="td">', st[1][i].duid), E('<div class="td">', st[1][i].duid),
E('<div class="td">', timestr) E('<div class="td">', timestr)
@ -88,7 +88,7 @@
} }
if (tb6.firstElementChild === tb6.lastElementChild) if (tb6.firstElementChild === tb6.lastElementChild)
tb6.appendChild(E('<div class="tr cbi-section-table-row"><div class="td"><em><br /><%:There are no active leases.%></em></div></div>')); tb6.appendChild(E('<div class="tr"><div class="td"><em><br /><%:There are no active leases.%></em></div></div>'));
} }
} }
); );
@ -96,14 +96,14 @@
<fieldset class="cbi-section"> <fieldset class="cbi-section">
<legend><%:Active DHCP Leases%></legend> <legend><%:Active DHCP Leases%></legend>
<div class="table cbi-section-table" id="lease_status_table"> <div class="table" id="lease_status_table">
<div class="tr cbi-section-table-titles"> <div class="tr">
<div class="th cbi-section-table-cell"><%:Hostname%></div> <div class="th"><%:Hostname%></div>
<div class="th cbi-section-table-cell"><%:IPv4-Address%></div> <div class="th"><%:IPv4-Address%></div>
<div class="th cbi-section-table-cell"><%:MAC-Address%></div> <div class="th"><%:MAC-Address%></div>
<div class="th cbi-section-table-cell"><%:Leasetime remaining%></div> <div class="th"><%:Leasetime remaining%></div>
</div> </div>
<div class="tr cbi-section-table-row"> <div class="tr">
<div class="td" colspan="4"><em><br /><%:Collecting data...%></em></div> <div class="td" colspan="4"><em><br /><%:Collecting data...%></em></div>
</div> </div>
</div> </div>
@ -111,14 +111,14 @@
<fieldset class="cbi-section" style="display:none"> <fieldset class="cbi-section" style="display:none">
<legend><%:Active DHCPv6 Leases%></legend> <legend><%:Active DHCPv6 Leases%></legend>
<div class="table cbi-section-table" id="lease6_status_table"> <div class="table" id="lease6_status_table">
<div class="tr cbi-section-table-titles"> <div class="tr">
<div class="th cbi-section-table-cell"><%:Host%></div> <div class="th"><%:Host%></div>
<div class="th cbi-section-table-cell"><%:IPv6-Address%></div> <div class="th"><%:IPv6-Address%></div>
<div class="th cbi-section-table-cell"><%:DUID%></div> <div class="th"><%:DUID%></div>
<div class="th cbi-section-table-cell"><%:Leasetime remaining%></div> <div class="th"><%:Leasetime remaining%></div>
</div> </div>
<div class="tr cbi-section-table-row"> <div class="tr">
<div class="td" colspan="4"><em><br /><%:Collecting data...%></em></div> <div class="td" colspan="4"><em><br /><%:Collecting data...%></em></div>
</div> </div>
</div> </div>

View file

@ -1,21 +1,39 @@
<script type="text/javascript">//<![CDATA[ <script type="text/javascript">//<![CDATA[
var switches = [ '<%=table.concat(self.switches, "', '")%>' ]; var switches = [ '<%=table.concat(self.switches, "', '")%>' ],
tables = document.querySelectorAll('.cbi-section-table');
function add_status_row(table) {
var first_row = table.querySelector('.cbi-section-table-row');
if (first_row.classList.contains('port-status'))
return first_row;
var status_row = first_row.parentNode.insertBefore(
E('div', { 'class': first_row.className }), first_row);
first_row.querySelectorAll('.td').forEach(function(td) {
status_row.appendChild(td.cloneNode(false));
status_row.lastElementChild.removeAttribute('data-title');
});
status_row.firstElementChild.innerHTML = '<%:Port status:%>';
status_row.classList.add('port-status') ;
return status_row;
}
XHR.poll(5, '<%=url('admin/network/switch_status')%>/' + switches.join(','), null, XHR.poll(5, '<%=url('admin/network/switch_status')%>/' + switches.join(','), null,
function(x, st) function(x, st)
{ {
for (var i = 0; i < switches.length; i++) for (var i = 0; i < switches.length; i++)
{ {
var ports = st[switches[i]]; var ports = st[switches[i]];
var th0 = document.getElementById('portstatus-' + switches[i]); var tr = add_status_row(tables[i]);
if (th0 && ports && ports.length) if (tr && ports && ports.length)
{ {
if (!th0.innerHTML)
th0.innerHTML = '<%:Port status:%>';
for (var j = 0; j < ports.length; j++) for (var j = 0; j < ports.length; j++)
{ {
var th = document.getElementById('portstatus-' + switches[i] + '-' + j); var th = tr.childNodes[j+1];
if (!th) if (!th)
continue; continue;

View file

@ -90,25 +90,43 @@
<h2 name="content"><%:Join Network: Wireless Scan%></h2> <h2 name="content"><%:Join Network: Wireless Scan%></h2>
<div class="cbi-map"> <div class="cbi-map">
<fieldset class="cbi-section"> <div class="cbi-section">
<div class="table cbi-section-table" style="empty-cells:hide"> <div class="table">
<div class="tr table-titles">
<div class="th col-1 center"><%:Signal%></div>
<div class="th col-5 left"><%:SSID%></div>
<div class="th col-2 center"><%:Channel%></div>
<div class="th col-2 left"><%:Mode%></div>
<div class="th col-3 left"><%:BSSID%></div>
<div class="th col-2 left"><%:Encryption%></div>
<div class="th cbi-section-actions">&#160;</div>
</div>
<!-- scan list --> <!-- scan list -->
<% for i, net in ipairs(scanlist(3)) do net.encryption = net.encryption or { } %> <% for i, net in ipairs(scanlist(3)) do net.encryption = net.encryption or { } %>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=1 + ((i-1) % 2)%>"> <div class="tr cbi-rowstyle-<%=1 + ((i-1) % 2)%>">
<div class="td cbi-value-field" style="width:16px; padding:3px"> <div class="td col-1 center">
<abbr title="<%:Signal%>: <%=net.signal%> <%:dB%> / <%:Quality%>: <%=net.quality%>/<%=net.quality_max%>"> <abbr title="<%:Signal%>: <%=net.signal%> <%:dB%> / <%:Quality%>: <%=net.quality%>/<%=net.quality_max%>">
<img src="<%=guess_wifi_signal(net)%>" /><br /> <img src="<%=guess_wifi_signal(net)%>" /><br />
<small><%=percent_wifi_signal(net)%>%</small> <small><%=percent_wifi_signal(net)%>%</small>
</abbr> </abbr>
</div> </div>
<div class="td cbi-value-field" style="vertical-align:middle; text-align:left; padding:3px"> <div class="td col-5 left" data-title="<%:SSID%>">
<big><strong><%=net.ssid and utl.pcdata(net.ssid) or "<em>%s</em>" % translate("hidden")%></strong></big><br /> <strong><%=net.ssid and utl.pcdata(net.ssid) or "<em>%s</em>" % translate("hidden")%></strong>
<strong>Channel:</strong> <%=net.channel%> |
<strong>Mode:</strong> <%=net.mode%> |
<strong>BSSID:</strong> <%=net.bssid%> |
<strong>Encryption:</strong> <%=format_wifi_encryption(net.encryption)%>
</div> </div>
<div class="td cbi-value-field" style="width:40px"> <div class="td col-2 center" data-title="<%:Channel%>">
<%=net.channel%>
</div>
<div class="td col-2 left" data-title="<%:Mode%>">
<%=net.mode%>
</div>
<div class="td col-3 left" data-title="<%:BSSID%>">
<%=net.bssid%>
</div>
<div class="td col-2 left" data-title="<%:Encryption%>">
<%=format_wifi_encryption(net.encryption)%>
</div>
<div class="td cbi-section-actions">
<form action="<%=url('admin/network/wireless_join')%>" method="post"> <form action="<%=url('admin/network/wireless_join')%>" method="post">
<input type="hidden" name="token" value="<%=token%>" /> <input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="device" value="<%=utl.pcdata(dev)%>" /> <input type="hidden" name="device" value="<%=utl.pcdata(dev)%>" />
@ -126,23 +144,23 @@
<input type="hidden" name="clbridge" value="<%=iw.type == "wl" and 1 or 0%>" /> <input type="hidden" name="clbridge" value="<%=iw.type == "wl" and 1 or 0%>" />
<input class="cbi-button cbi-button-apply" type="submit" value="<%:Join Network%>" /> <input class="cbi-button cbi-button-action important" type="submit" value="<%:Join Network%>" />
</form> </form>
</div> </div>
</div> </div>
<% end %> <% end %>
<!-- /scan list --> <!-- /scan list -->
</div> </div>
</fieldset> </div>
</div> </div>
<div class="cbi-page-actions right"> <div class="cbi-page-actions right">
<form class="inline" action="<%=url("admin/network/wireless")%>" method="get"> <form class="inline" action="<%=url("admin/network/wireless")%>" method="get">
<input class="cbi-button cbi-button-reset" type="submit" value="<%:Back to overview%>" /> <input class="cbi-button cbi-button-neutral" type="submit" value="<%:Back to overview%>" />
</form> </form>
<form class="inline" action="<%=url('admin/network/wireless_join')%>" method="post"> <form class="inline" action="<%=url('admin/network/wireless_join')%>" method="post">
<input type="hidden" name="token" value="<%=token%>" /> <input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="device" value="<%=utl.pcdata(dev)%>" /> <input type="hidden" name="device" value="<%=utl.pcdata(dev)%>" />
<input class="cbi-button cbi-input-find" type="submit" value="<%:Repeat scan%>" /> <input class="cbi-button cbi-button-action" type="submit" value="<%:Repeat scan%>" />
</form> </form>
</div> </div>

View file

@ -138,7 +138,7 @@
function wifi_shutdown(id, toggle) { function wifi_shutdown(id, toggle) {
var reconnect = (toggle.getAttribute('active') == 'false'); var reconnect = (toggle.getAttribute('active') == 'false');
if (!reconnect && !confirm(<%=luci.http.write_json(translate('Really shut down network? You might lose access to this device if you are connected via this interface.'))%>)) if (!reconnect && !confirm(<%=luci.http.write_json(translate('Really shut down network? You might lose access to this device if you are connected via this interface'))%>))
return; return;
is_reconnecting = true; is_reconnecting = true;
@ -237,13 +237,13 @@
{ {
if (!iw.disabled) if (!iw.disabled)
{ {
toggle.className = 'cbi-button cbi-button-reset'; toggle.className = 'cbi-button cbi-button-neutral';
toggle.value = '<%:Disable%>'; toggle.value = '<%:Disable%>';
toggle.title = '<%:Shutdown this network%>'; toggle.title = '<%:Shutdown this network%>';
} }
else else
{ {
toggle.className = 'cbi-button cbi-button-reload'; toggle.className = 'cbi-button cbi-button-neutral';
toggle.value = '<%:Enable%>'; toggle.value = '<%:Enable%>';
toggle.title = '<%:Activate this network%>'; toggle.title = '<%:Activate this network%>';
} }
@ -320,7 +320,7 @@
name = host ? (host.name || host.ipv4 || host.ipv6) : null, name = host ? (host.name || host.ipv4 || host.ipv6) : null,
hint = (host && host.name && (host.ipv4 || host.ipv6)) ? (host.ipv4 || host.ipv6) : null; hint = (host && host.name && (host.ipv4 || host.ipv6)) ? (host.ipv4 || host.ipv6) : null;
assoctable.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-%d">'.format(rowstyle), [ assoctable.appendChild(E('<div class="tr cbi-rowstyle-%d">'.format(rowstyle), [
E('<div class="td"><span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> %h</span></div>' E('<div class="td"><span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> %h</span></div>'
.format(iw.device.name, iw.ifname)), .format(iw.device.name, iw.ifname)),
E('<div class="td" style="white-space:nowrap">%h</div>' E('<div class="td" style="white-space:nowrap">%h</div>'
@ -350,7 +350,7 @@
{ {
var img = document.getElementById(dev + '-iw-upstate'); var img = document.getElementById(dev + '-iw-upstate');
if (img) if (img)
img.src = '<%=resource%>/icons/wifi_big' + (devup[dev] ? '' : '_disabled') + '.png'; img.src = '<%=resource%>/icons/wifi' + (devup[dev] ? '' : '_disabled') + '.png';
} }
} }
} }
@ -359,37 +359,37 @@
<h2 name="content"><%:Wireless Overview%></h2> <h2 name="content"><%:Wireless Overview%></h2>
<fieldset class="cbi-section" style="display:none"> <div class="cbi-section" style="display:none">
<legend><%:Reconnecting interface%></legend> <legend><%:Reconnecting interface%></legend>
<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" />
<span id="iw-rc-status"><%:Waiting for changes to be applied...%></span> <span id="iw-rc-status"><%:Waiting for changes to be applied...%></span>
</fieldset> </div>
<div class="cbi-map"> <div id="cbi-wireless-overview" class="cbi-map">
<% for _, dev in ipairs(devices) do local nets = dev:get_wifinets() %> <% for _, dev in ipairs(devices) do local nets = dev:get_wifinets() %>
<!-- device <%=dev:name()%> --> <!-- device <%=dev:name()%> -->
<fieldset class="cbi-section"> <div class="cbi-section-node">
<div class="table cbi-section-table" style="margin:10px; empty-cells:hide"> <div class="table">
<!-- physical device --> <!-- physical device -->
<div class="tr"> <div class="tr">
<div class="td"> <div class="td col-2 center">
<img src="<%=resource%>/icons/wifi_big_disabled.png" id="<%=dev:name()%>-iw-upstate" /> <span class="ifacebadge"><img src="<%=resource%>/icons/wifi_disabled.png" id="<%=dev:name()%>-iw-upstate" /> <%=dev:name()%></span>
</div> </div>
<div class="td left"> <div class="td col-7 left">
<big><strong><%=guess_wifi_hw(dev)%> (<%=dev:name()%>)</strong></big><br /> <big><strong><%=guess_wifi_hw(dev)%></strong></big><br />
<span id="<%=dev:name()%>-iw-devinfo"></span> <span id="<%=dev:name()%>-iw-devinfo"></span>
</div> </div>
<div class="td right"> <div class="td cbi-section-actions">
<form action="<%=url('admin/network/wireless_join')%>" method="post" class="inline"> <form action="<%=url('admin/network/wireless_join')%>" method="post" class="inline">
<input type="hidden" name="device" value="<%=dev:name()%>" /> <input type="hidden" name="device" value="<%=dev:name()%>" />
<input type="hidden" name="token" value="<%=token%>" /> <input type="hidden" name="token" value="<%=token%>" />
<input type="submit" class="cbi-button cbi-button-find" style="width:100px" title="<%:Find and join network%>" value="<%:Scan%>" /> <input type="submit" class="cbi-button cbi-button-action" title="<%:Find and join network%>" value="<%:Scan%>" />
</form> </form>
<form action="<%=url('admin/network/wireless_add')%>" method="post" class="inline"> <form action="<%=url('admin/network/wireless_add')%>" method="post" class="inline">
<input type="hidden" name="device" value="<%=dev:name()%>" /> <input type="hidden" name="device" value="<%=dev:name()%>" />
<input type="hidden" name="token" value="<%=token%>" /> <input type="hidden" name="token" value="<%=token%>" />
<input type="submit" class="cbi-button cbi-button-add" style="width:100px" title="<%:Provide new network%>" value="<%:Add%>" /> <input type="submit" class="cbi-button cbi-button-add" title="<%:Provide new network%>" value="<%:Add%>" />
</form> </form>
</div> </div>
</div> </div>
@ -398,22 +398,22 @@
<!-- network list --> <!-- network list -->
<% if #nets > 0 then %> <% if #nets > 0 then %>
<% for i, net in ipairs(nets) do %> <% for i, net in ipairs(nets) do %>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=1 + ((i-1) % 2)%>"> <div class="tr cbi-rowstyle-<%=1 + ((i-1) % 2)%>">
<div class="td" id="<%=net:id()%>-iw-signal"> <div class="td col-2 center" id="<%=net:id()%>-iw-signal">
<span class="ifacebadge" title="<%:Not associated%>"><img src="<%=resource%>/icons/signal-none.png" /> 0%</span> <span class="ifacebadge" title="<%:Not associated%>"><img src="<%=resource%>/icons/signal-none.png" /> 0%</span>
</div> </div>
<div class="td left" id="<%=net:id()%>-iw-status"> <div class="td col-7 left" id="<%=net:id()%>-iw-status">
<em><%:Collecting data...%></em> <em><%:Collecting data...%></em>
</div> </div>
<div class="td right"> <div class="td cbi-section-actions">
<input id="<%=net:id()%>-iw-toggle" type="button" class="cbi-button cbi-button-reload" style="width:100px" onclick="wifi_shutdown('<%=net:id()%>', this)" title="<%:Delete this network%>" value="<%:Enable%>" /> <input id="<%=net:id()%>-iw-toggle" type="button" class="cbi-button cbi-button-neutral" onclick="wifi_shutdown('<%=net:id()%>', this)" title="<%:Enable this network%>" value="<%:Enable%>" />
<input type="button" class="cbi-button cbi-button-edit" style="width:100px" onclick="location.href='<%=net:adminlink()%>'" title="<%:Edit this network%>" value="<%:Edit%>" /> <input type="button" class="cbi-button cbi-button-action important" onclick="location.href='<%=net:adminlink()%>'" title="<%:Edit this network%>" value="<%:Edit%>" />
<input type="button" class="cbi-button cbi-button-remove" style="width:100px" onclick="wifi_delete('<%=net:id()%>')" title="<%:Delete this network%>" value="<%:Remove%>" /> <input type="button" class="cbi-button cbi-button-negative" onclick="wifi_delete('<%=net:id()%>')" title="<%:Delete this network%>" value="<%:Remove%>" />
</div> </div>
</div> </div>
<% end %> <% end %>
<% else %> <% else %>
<div class="tr cbi-section-table-row cbi-rowstyle-2"> <div class="tr cbi-rowstyle-2">
<div class="td left"> <div class="td left">
<em><%:No network configured on this device%></em> <em><%:No network configured on this device%></em>
</div> </div>
@ -421,30 +421,30 @@
<% end %> <% end %>
<!-- /network list --> <!-- /network list -->
</div> </div>
</fieldset> </div>
<!-- /device <%=dev:name()%> --> <!-- /device <%=dev:name()%> -->
<% end %> <% end %>
<h2><%:Associated Stations%></h2> <h2><%:Associated Stations%></h2>
<fieldset class="cbi-section"> <div class="cbi-section-node">
<div class="table cbi-section-table valign-middle" style="margin:10px" id="iw-assoclist"> <div class="table" id="iw-assoclist">
<div class="tr cbi-section-table-titles"> <div class="tr">
<div class="th cbi-section-table-cell"></div> <div class="th"><%:Interface%></div>
<div class="th cbi-section-table-cell"><%:SSID%></div> <div class="th"><%:SSID%></div>
<div class="th cbi-section-table-cell"><%:MAC-Address%></div> <div class="th"><%:MAC-Address%></div>
<div class="th cbi-section-table-cell"><%:Host%></div> <div class="th"><%:Host%></div>
<div class="th cbi-section-table-cell"><%:Signal%> / <%:Noise%></div> <div class="th"><%:Signal%> / <%:Noise%></div>
<div class="th cbi-section-table-cell"><%:RX Rate%> / <%:TX Rate%></div> <div class="th"><%:RX Rate%> / <%:TX Rate%></div>
</div> </div>
<div class="tr cbi-section-table-row cbi-rowstyle-2"> <div class="tr cbi-rowstyle-2">
<div class="td"> <div class="td">
<em><%:Collecting data...%></em> <em><%:Collecting data...%></em>
</div> </div>
</div> </div>
</div> </div>
</fieldset> </div>
</div> </div>
<%+footer%> <%+footer%>

View file

@ -130,7 +130,7 @@
var pc = Math.floor((100 / mn) * vn); var pc = Math.floor((100 / mn) * vn);
return String.format( return String.format(
'<div style="width:200px; position:relative; border:1px solid #999999">' + '<div style="width:100%%; max-width:200px; position:relative; border:1px solid #999999">' +
'<div style="background-color:#CCCCCC; width:%d%%; height:15px">' + '<div style="background-color:#CCCCCC; width:%d%%; height:15px">' +
'<div style="position:absolute; left:0; top:0; text-align:center; width:100%%; color:#000000">' + '<div style="position:absolute; left:0; top:0; text-align:center; width:100%%; color:#000000">' +
'<small>%s / %s (%d%%)</small>' + '<small>%s / %s (%d%%)</small>' +
@ -205,7 +205,7 @@
return E('div', { class: 'ifacebox' }, [ return E('div', { class: 'ifacebox' }, [
E('div', { class: 'ifacebox-head center ' + (active ? 'active' : '') }, E('div', { class: 'ifacebox-head center ' + (active ? 'active' : '') },
E('strong', title)), E('strong', title)),
E('div', { class: 'ifacebox-body' }, childs) E('div', { class: 'ifacebox-body left' }, childs)
]); ]);
} }
@ -334,9 +334,7 @@
var ls = document.getElementById('lease_status_table'); var ls = document.getElementById('lease_status_table');
if (ls) if (ls)
{ {
/* clear all rows */ var rows = [];
while (ls.firstElementChild !== ls.lastElementChild)
ls.removeChild(ls.lastElementChild);
for (var i = 0; i < info.leases.length; i++) for (var i = 0; i < info.leases.length; i++)
{ {
@ -349,26 +347,23 @@
else else
timestr = String.format('%t', info.leases[i].expires); timestr = String.format('%t', info.leases[i].expires);
ls.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-%d">'.format((i % 2) + 1), [ rows.push([
E('<div class="td">', info.leases[i].hostname ? info.leases[i].hostname : '?'), info.leases[i].hostname ? info.leases[i].hostname : '?',
E('<div class="td">', info.leases[i].ipaddr), info.leases[i].ipaddr,
E('<div class="td">', info.leases[i].macaddr), info.leases[i].macaddr,
E('<div class="td">', timestr) timestr
])); ]);
} }
if (ls.firstElementChild === ls.lastElementChild) cbi_update_table(ls, rows, '<em><%:There are no active leases.%></em>');
ls.appendChild(E('<div class="tr cbi-section-table-row"><div class="td"><em><br /><%:There are no active leases.%></em></div></div>'));
} }
var ls6 = document.getElementById('lease6_status_table'); var ls6 = document.getElementById('lease6_status_table');
if (ls6 && info.leases6) if (ls6 && info.leases6)
{ {
ls6.parentNode.style.display = 'block'; ls6.parentNode.parentNode.style.display = 'block';
/* clear all rows */ var rows = [];
while (ls6.firstElementChild !== ls6.lastElementChild)
ls6.removeChild(ls6.lastElementChild);
for (var i = 0; i < info.leases6.length; i++) for (var i = 0; i < info.leases6.length; i++)
{ {
@ -394,16 +389,15 @@
hint = host.name; hint = host.name;
} }
ls6.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-%d">'.format((i % 2) + 1), [ rows.push([
E('<div class="td nowrap">', hint ? '<div>%h (%h)</div>'.format(name || '?', hint) : (name || '?')), hint ? '%h (%h)'.format(name || '?', hint) : (name || '?'),
E('<div class="td nowrap">', info.leases6[i].ip6addr), info.leases6[i].ip6addr,
E('<div class="td nowrap">', info.leases6[i].duid), info.leases6[i].duid,
E('<div class="td nowrap">', timestr) timestr
])); ]);
} }
if (ls6.firstElementChild === ls6.lastElementChild) cbi_update_table(ls6, rows, '<em><%:There are no active leases.%></em>');
ls6.appendChild(E('<div class="tr cbi-section-table-row"><div class="td"><em><br /><%:There are no active leases.%></em></div></div>'));
} }
<% end %> <% end %>
@ -482,9 +476,7 @@
var ac = document.getElementById('wifi_assoc_table'); var ac = document.getElementById('wifi_assoc_table');
if (ac) if (ac)
{ {
/* clear all rows */ var rows = [];
while (ac.firstElementChild !== ac.lastElementChild)
ac.removeChild(ac.lastElementChild);
assoclist.sort(function(a, b) { assoclist.sort(function(a, b) {
return (a.name == b.name) return (a.name == b.name)
@ -512,27 +504,30 @@
name = host ? (host.name || host.ipv4 || host.ipv6) : null, name = host ? (host.name || host.ipv4 || host.ipv6) : null,
hint = (host && host.name && (host.ipv4 || host.ipv6)) ? (host.ipv4 || host.ipv6) : null; hint = (host && host.name && (host.ipv4 || host.ipv6)) ? (host.ipv4 || host.ipv6) : null;
ac.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-%d">'.format(1 + (i % 2)), [ rows.push([
E('<div class="td"><span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> %h</span></div>' '<span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> <a href="%s">%h</a><small>&#160;(%h)</small></span>'.format(
.format(assoclist[i].radio, assoclist[i].ifname)), assoclist[i].radio,
E('<div class="td"><a href="%s" style="white-space:nowrap">%h</a></div>' assoclist[i].link,
.format(assoclist[i].link, assoclist[i].name)), assoclist[i].name,
E('<div class="td">', assoclist[i].ifname),
assoclist[i].bssid), assoclist[i].bssid,
E('<div class="td nowrap">', hint ? '%h (%h)'.format(name || '?', hint) : (name || '?'),
hint ? '<div>%h (%h)</div>'.format(name || '?', hint) : (name || '?')), '<span class="ifacebadge" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%> / <%:SNR%>: %d"><img src="%s" /> %d / %d <%:dBm%></span>'.format(
E('<div class="td"><span class="ifacebadge" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%> / <%:SNR%>: %d"><img src="%s" /> %d / %d <%:dBm%></span></div>' assoclist[i].signal,
.format(assoclist[i].signal, assoclist[i].noise, assoclist[i].signal - assoclist[i].noise, icon, assoclist[i].signal, assoclist[i].noise)), assoclist[i].noise,
E('<div class="td nowrap">', [ assoclist[i].signal - assoclist[i].noise,
E('<span style="white-space:nowrap">', wifirate(assoclist[i], true)), icon,
E('<br />'), assoclist[i].signal,
E('<span style="white-space:nowrap">', wifirate(assoclist[i], false)) assoclist[i].noise),
E('span', {}, [
E('span', wifirate(assoclist[i], true)),
E('br'),
E('span', wifirate(assoclist[i], false))
]) ])
])); ]);
} }
if (ac.firstElementChild === ac.lastElementChild) cbi_update_table(ac, rows, '<em><%:No information available%></em>');
ac.appendChild(E('<div class="tr cbi-section-table-row"><div class="td"><em><br /><%:No information available%></em></div></div>'));
} }
<% end %> <% end %>
@ -591,7 +586,7 @@
<h2 name="content"><%:Status%></h2> <h2 name="content"><%:Status%></h2>
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%:System%></legend> <legend><%:System%></legend>
<div class="table" width="100%"> <div class="table" width="100%">
@ -607,9 +602,9 @@
<div class="tr"><div class="td left" width="33%"><%:Uptime%></div><div class="td left" id="uptime">-</div></div> <div class="tr"><div class="td left" width="33%"><%:Uptime%></div><div class="td left" id="uptime">-</div></div>
<div class="tr"><div class="td left" width="33%"><%:Load Average%></div><div class="td left" id="loadavg">-</div></div> <div class="tr"><div class="td left" width="33%"><%:Load Average%></div><div class="td left" id="loadavg">-</div></div>
</div> </div>
</fieldset> </div>
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%:Memory%></legend> <legend><%:Memory%></legend>
<div class="table" width="100%"> <div class="table" width="100%">
@ -617,20 +612,20 @@
<div class="tr"><div class="td left" width="33%"><%:Free%></div><div class="td left" id="memfree">-</div></div> <div class="tr"><div class="td left" width="33%"><%:Free%></div><div class="td left" id="memfree">-</div></div>
<div class="tr"><div class="td left" width="33%"><%:Buffered%></div><div class="td left" id="membuff">-</div></div> <div class="tr"><div class="td left" width="33%"><%:Buffered%></div><div class="td left" id="membuff">-</div></div>
</div> </div>
</fieldset> </div>
<% if swapinfo.total > 0 then %> <% if swapinfo.total > 0 then %>
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%:Swap%></legend> <legend><%:Swap%></legend>
<div class="table" width="100%"> <div class="table" width="100%">
<div class="tr"><div class="td left" width="33%"><%:Total Available%></div><div class="td left" id="swaptotal">-</div></div> <div class="tr"><div class="td left" width="33%"><%:Total Available%></div><div class="td left" id="swaptotal">-</div></div>
<div class="tr"><div class="td left" width="33%"><%:Free%></div><div class="td left" id="swapfree">-</div></div> <div class="tr"><div class="td left" width="33%"><%:Free%></div><div class="td left" id="swapfree">-</div></div>
</div> </div>
</fieldset> </div>
<% end %> <% end %>
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%:Network%></legend> <legend><%:Network%></legend>
<div id="upstream_status_table" class="network-status-table"> <div id="upstream_status_table" class="network-status-table">
@ -640,87 +635,95 @@
<div class="table" width="100%"> <div class="table" width="100%">
<div class="tr"><div class="td left" width="33%"><%:Active Connections%></div><div class="td left" id="conns">-</div></div> <div class="tr"><div class="td left" width="33%"><%:Active Connections%></div><div class="td left" id="conns">-</div></div>
</div> </div>
</fieldset> </div>
<% if has_dhcp then %> <% if has_dhcp then %>
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%:DHCP Leases%></legend> <legend><%:DHCP Leases%></legend>
<div class="table cbi-section-table" id="lease_status_table"> <div class="cbi-section-node">
<div class="tr cbi-section-table-titles"> <div class="table" id="lease_status_table">
<div class="th"><%:Hostname%></div> <div class="tr table-titles">
<div class="th"><%:IPv4-Address%></div> <div class="th"><%:Hostname%></div>
<div class="th"><%:MAC-Address%></div> <div class="th"><%:IPv4-Address%></div>
<div class="th"><%:Leasetime remaining%></div> <div class="th"><%:MAC-Address%></div>
</div> <div class="th"><%:Leasetime remaining%></div>
<div class="tr cbi-section-table-row"> </div>
<div class="td" colspan="4"><em><br /><%:Collecting data...%></em></div> <div class="tr cbi-section-table-row">
<div class="td" colspan="4"><em><br /><%:Collecting data...%></em></div>
</div>
</div> </div>
</div> </div>
</fieldset> </div>
<fieldset class="cbi-section" style="display:none"> <div class="cbi-section" style="display:none">
<legend><%:DHCPv6 Leases%></legend> <legend><%:DHCPv6 Leases%></legend>
<div class="table cbi-section-table" id="lease6_status_table"> <div class="cbi-section-node">
<div class="tr cbi-section-table-titles"> <div class="table" id="lease6_status_table">
<div class="th"><%:Host%></div> <div class="tr table-titles">
<div class="th"><%:IPv6-Address%></div> <div class="th"><%:Host%></div>
<div class="th"><%:DUID%></div> <div class="th"><%:IPv6-Address%></div>
<div class="th"><%:Leasetime remaining%></div> <div class="th"><%:DUID%></div>
</div> <div class="th"><%:Leasetime remaining%></div>
<div class="tr cbi-section-table-row"> </div>
<div class="td" colspan="4"><em><br /><%:Collecting data...%></em></div> <div class="tr cbi-section-table-row">
<div class="td" colspan="4"><em><br /><%:Collecting data...%></em></div>
</div>
</div> </div>
</div> </div>
</fieldset> </div>
<% end %> <% end %>
<% if has_dsl then %> <% if has_dsl then %>
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%:DSL%></legend> <legend><%:DSL%></legend>
<div class="table" width="100%">
<div class="tr"> <div class="cbi-section-node">
<div class="td left" width="33%" style="vertical-align:top"><%:DSL Status%></div> <div class="table" width="100%">
<div class="td"> <div class="tr">
<div class="table"> <div class="td left" width="33%" style="vertical-align:top"><%:DSL Status%></div>
<div class="tr"> <div class="td">
<div class="td" id="dsl_i" style="width:16px; text-align:center; padding:3px"><img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small></div> <div class="table">
<div class="td left" id="dsl_s" style="vertical-align:middle; padding: 3px"><em><%:Collecting data...%></em></div> <div class="tr">
<div class="td" id="dsl_i" style="width:16px; text-align:center; padding:3px"><img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small></div>
<div class="td left" id="dsl_s" style="vertical-align:middle; padding: 3px"><em><%:Collecting data...%></em></div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</fieldset> </div>
<% end %> <% end %>
<% if has_wifi then %> <% if has_wifi then %>
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%:Wireless%></legend> <legend><%:Wireless%></legend>
<div id="wifi_status_table" class="network-status-table"> <div id="wifi_status_table" class="network-status-table">
<em><%:Collecting data...%></em> <em><%:Collecting data...%></em>
</div> </div>
</fieldset> </div>
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%:Associated Stations%></legend> <legend><%:Associated Stations%></legend>
<div class="table cbi-section-table valign-middle" id="wifi_assoc_table"> <div class="cbi-section-node">
<div class="tr cbi-section-table-titles"> <div class="table" id="wifi_assoc_table">
<div class="th">&#160;</div> <div class="tr table-titles">
<div class="th"><%:Network%></div> <div class="th nowrap"><%:Network%></div>
<div class="th"><%:MAC-Address%></div> <div class="th hide-xs"><%:MAC-Address%></div>
<div class="th"><%:Host%></div> <div class="th nowrap"><%:Host%></div>
<div class="th"><%:Signal%> / <%:Noise%></div> <div class="th nowrap"><%:Signal%> / <%:Noise%></div>
<div class="th"><%:RX Rate%> / <%:TX Rate%></div> <div class="th nowrap"><%:RX Rate%> / <%:TX Rate%></div>
</div> </div>
<div class="tr cbi-section-table-row"> <div class="tr">
<div class="td" colspan="6"><em><br /><%:Collecting data...%></em></div> <div class="td" colspan="6"><em><br /><%:Collecting data...%></em></div>
</div>
</div> </div>
</div> </div>
</fieldset> </div>
<% end %> <% end %>
<%- <%-

View file

@ -62,6 +62,7 @@
<%+header%> <%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<style type="text/css"> <style type="text/css">
span:target { span:target {
color: blue; color: blue;
@ -70,7 +71,6 @@
</style> </style>
<h2 name="content"><%:Firewall Status%></h2> <h2 name="content"><%:Firewall Status%></h2>
<br />
<% if has_ip6tables then %> <% if has_ip6tables then %>
<ul class="cbi-tabmenu"> <ul class="cbi-tabmenu">
@ -88,69 +88,69 @@
<input type="submit" class="cbi-button" name="restart" value="<%:Restart Firewall%>" /> <input type="submit" class="cbi-button" name="restart" value="<%:Restart Firewall%>" />
</form> </form>
<fieldset class="cbi-section"> <div class="cbi-section">
<% for _, tbl in ipairs(tables) do chaincnt = 0 %> <% for _, tbl in ipairs(tables) do chaincnt = 0 %>
<h3><%:Table%>: <%=tbl%></h3> <h3><%:Table%>: <%=tbl%></h3>
<div class="table cbi-section-table" style="font-size:90%">
<% for _, chain in ipairs(ipt:chains(tbl)) do
rowcnt = 0
chaincnt = chaincnt + 1
chaininfo = ipt:chain(tbl, chain)
%>
<div class="tr cbi-section-table-titles cbi-rowstyle-<%=rowstyle()%>">
<div class="th cbi-section-table-cell" style="text-align:left" colspan="11">
<br /><span id="rule_<%=tbl:lower()%>_<%=chain%>">
<%:Chain%> <em><%=chain%></em>
(<%- if chaininfo.policy then -%>
<%:Policy%>: <em><%=chaininfo.policy%></em>, <%:Packets%>: <%=chaininfo.packets%>, <%:Traffic%>: <%=wba.byte_format(chaininfo.bytes)-%>
<%- else -%>
<%:References%>: <%=chaininfo.references-%>
<%- end -%>)</span>
</div>
</div>
<div class="tr cbi-section-table-descr">
<div class="th cbi-section-table-cell"><%:Pkts.%></div>
<div class="th cbi-section-table-cell"><%:Traffic%></div>
<div class="th cbi-section-table-cell"><%:Target%></div>
<div class="th cbi-section-table-cell"><%:Prot.%></div>
<div class="th cbi-section-table-cell"><%:In%></div>
<div class="th cbi-section-table-cell"><%:Out%></div>
<div class="th cbi-section-table-cell"><%:Source%></div>
<div class="th cbi-section-table-cell"><%:Destination%></div>
<div class="th cbi-section-table-cell" style="width:30%"><%:Options%></div>
</div>
<% for _, rule in ipairs(ipt:find({table=tbl, chain=chain})) do %> <% for _, chain in ipairs(ipt:chains(tbl)) do
<div class="tr cbi-section-table-row cbi-rowstyle-<%=rowstyle()%>"> rowcnt = 0
<div class="td"><%=rule.packets%></div> chaincnt = chaincnt + 1
<div class="td" style="white-space: nowrap"><%=wba.byte_format(rule.bytes)%></div> chaininfo = ipt:chain(tbl, chain)
<div class="td"><%=rule.target and link_target(tbl, rule.target) or "-"%></div> %>
<div class="td"><%=rule.protocol%></div> <h4 id="rule_<%=tbl:lower()%>_<%=chain%>">
<div class="td"><%=link_iface(rule.inputif)%></div> <%:Chain%> <em><%=chain%></em>
<div class="td"><%=link_iface(rule.outputif)%></div> (<%- if chaininfo.policy then -%>
<div class="td"><%=rule.source%></div> <%:Policy%>: <em><%=chaininfo.policy%></em>, <%:Packets%>: <%=chaininfo.packets%>, <%:Traffic%>: <%=wba.byte_format(chaininfo.bytes)-%>
<div class="td"><%=rule.destination%></div> <%- else -%>
<div class="td" style="width:30%"><small><%=#rule.options > 0 and luci.util.pcdata(table.concat(rule.options, " ")) or "-"%></small></div> <%:References%>: <%=chaininfo.references-%>
</div> <%- end -%>)
<% end %> </h4>
<% if rowcnt == 1 then %> <div class="cbi-section-node">
<div class="tr cbi-section-table-titles cbi-rowstyle-<%=rowstyle()%>"> <div class="table" style="font-size:90%">
<div class="td" colspan="9"><em><%:No rules in this chain%></em></div> <div class="tr table-titles cbi-rowstyle-<%=rowstyle()%>">
<div class="th hide-xs"><%:Pkts.%></div>
<div class="th nowrap"><%:Traffic%></div>
<div class="th col-5"><%:Target%></div>
<div class="th"><%:Prot.%></div>
<div class="th"><%:In%></div>
<div class="th"><%:Out%></div>
<div class="th"><%:Source%></div>
<div class="th"><%:Destination%></div>
<div class="th col-9 hide-xs"><%:Options%></div>
</div> </div>
<% end %>
<% end %>
<% if chaincnt == 0 then %> <% for _, rule in ipairs(ipt:find({table=tbl, chain=chain})) do %>
<div class="tr cbi-section-table-titles cbi-rowstyle-<%=rowstyle()%>"> <div class="tr cbi-rowstyle-<%=rowstyle()%>">
<div class="td" colspan="9"><em><%:No chains in this table%></em></div> <div class="td"><%=rule.packets%></div>
<div class="td nowrap"><%=wba.byte_format(rule.bytes)%></div>
<div class="td col-5"><%=rule.target and link_target(tbl, rule.target) or "-"%></div>
<div class="td"><%=rule.protocol%></div>
<div class="td"><%=link_iface(rule.inputif)%></div>
<div class="td"><%=link_iface(rule.outputif)%></div>
<div class="td"><%=rule.source%></div>
<div class="td"><%=rule.destination%></div>
<div class="td col-9 hide-xs"><%=#rule.options > 0 and luci.util.pcdata(table.concat(rule.options, " ")) or "-"%></div>
</div>
<% end %>
<% if rowcnt == 1 then %>
<div class="tr cbi-rowstyle-<%=rowstyle()%>">
<div class="td" colspan="9"><em><%:No rules in this chain%></em></div>
</div>
<% end %>
</div> </div>
<% end %> </div>
</div> <% end %>
<% if chaincnt == 0 then %>
<em><%:No chains in this table%></em>
<% end %>
<br /><br /> <br /><br />
<% end %> <% end %>
</fieldset> </div>
</div> </div>
<%+footer%> <%+footer%>

View file

@ -32,28 +32,30 @@
<%+header%> <%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<div class="cbi-map" id="cbi-network"> <div class="cbi-map" id="cbi-network">
<h2 name="content"><%:Routes%></h2> <h2 name="content"><%:Routes%></h2>
<div class="cbi-map-descr"><%:The following rules are currently active on this system.%></div> <div class="cbi-map-descr"><%:The following rules are currently active on this system.%></div>
<fieldset class="cbi-section"> <div class="cbi-section">
<legend>ARP</legend> <legend>ARP</legend>
<div class="cbi-section-node"> <div class="cbi-section-node">
<div class="table cbi-section-table"> <div class="table">
<div class="tr cbi-section-table-titles"> <div class="tr table-titles">
<div class="th cbi-section-table-cell"><%_<abbr title="Internet Protocol Version 4">IPv4</abbr>-Address%></div> <div class="th"><%_<abbr title="Internet Protocol Version 4">IPv4</abbr>-Address%></div>
<div class="th cbi-section-table-cell"><%_<abbr title="Media Access Control">MAC</abbr>-Address%></div> <div class="th"><%_<abbr title="Media Access Control">MAC</abbr>-Address%></div>
<div class="th cbi-section-table-cell"><%:Interface%></div> <div class="th"><%:Interface%></div>
</div> </div>
<% <%
for _, v in ipairs(ip.neighbors({ family = 4 })) do for _, v in ipairs(ip.neighbors({ family = 4 })) do
if v.mac then if v.mac then
%> %>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>"> <div class="tr cbi-rowstyle-<%=(style and 1 or 2)%>">
<div class="td cbi-value-field"><%=v.dest%></div> <div class="td"><%=v.dest%></div>
<div class="td cbi-value-field"><%=v.mac%></div> <div class="td"><%=v.mac%></div>
<div class="td cbi-value-field"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div> <div class="td"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div>
</div> </div>
<% <%
style = not style style = not style
@ -62,61 +64,57 @@
%> %>
</div> </div>
</div> </div>
</fieldset> </div>
<br />
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%_Active <abbr title="Internet Protocol Version 4">IPv4</abbr>-Routes%></legend> <legend><%_Active <abbr title="Internet Protocol Version 4">IPv4</abbr>-Routes%></legend>
<div class="cbi-section-node"> <div class="cbi-section-node">
<div class="table cbi-section-table"> <div class="table">
<div class="tr cbi-section-table-titles"> <div class="tr table-titles">
<div class="th cbi-section-table-cell"><%:Network%></div> <div class="th"><%:Network%></div>
<div class="th cbi-section-table-cell"><%:Target%></div> <div class="th"><%:Target%></div>
<div class="th cbi-section-table-cell"><%_<abbr title="Internet Protocol Version 4">IPv4</abbr>-Gateway%></div> <div class="th"><%_<abbr title="Internet Protocol Version 4">IPv4</abbr>-Gateway%></div>
<div class="th cbi-section-table-cell"><%:Metric%></div> <div class="th"><%:Metric%></div>
<div class="th cbi-section-table-cell"><%:Table%></div> <div class="th"><%:Table%></div>
</div> </div>
<% for _, v in ipairs(ip.routes({ family = 4, type = 1 })) do %> <% for _, v in ipairs(ip.routes({ family = 4, type = 1 })) do %>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>"> <div class="tr cbi-rowstyle-<%=(style and 1 or 2)%>">
<div class="td cbi-value-field"><%=luci.tools.webadmin.iface_get_network(v.dev) or v.dev%></div> <div class="td"><%=luci.tools.webadmin.iface_get_network(v.dev) or v.dev%></div>
<div class="td cbi-value-field"><%=v.dest%></div> <div class="td"><%=v.dest%></div>
<div class="td cbi-value-field"><%=v.gw%></div> <div class="td"><%=v.gw or "-"%></div>
<div class="td cbi-value-field"><%=v.metric or 0%></div> <div class="td"><%=v.metric or 0%></div>
<div class="td cbi-value-field"><%=rtn[v.table] or v.table%></div> <div class="td"><%=rtn[v.table] or v.table%></div>
</div> </div>
<% style = not style end %> <% style = not style end %>
</div> </div>
</div> </div>
</fieldset> </div>
<br />
<% <%
if nixio.fs.access("/proc/net/ipv6_route") then if nixio.fs.access("/proc/net/ipv6_route") then
style = true style = true
%> %>
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%_Active <abbr title="Internet Protocol Version 6">IPv6</abbr>-Routes%></legend> <legend><%_Active <abbr title="Internet Protocol Version 6">IPv6</abbr>-Routes%></legend>
<div class="cbi-section-node"> <div class="cbi-section-node">
<div class="table cbi-section-table"> <div class="table">
<div class="tr cbi-section-table-titles"> <div class="tr table-titles">
<div class="th cbi-section-table-cell"><%:Network%></div> <div class="th"><%:Network%></div>
<div class="th cbi-section-table-cell"><%:Target%></div> <div class="th"><%:Target%></div>
<div class="th cbi-section-table-cell"><%:Source%></div> <div class="th"><%:Source%></div>
<div class="th cbi-section-table-cell"><%:Metric%></div> <div class="th"><%:Metric%></div>
<div class="th cbi-section-table-cell"><%:Table%></div> <div class="th"><%:Table%></div>
</div> </div>
<% <%
for _, v in ipairs(ip.routes({ family = 6, type = 1 })) do for _, v in ipairs(ip.routes({ family = 6, type = 1 })) do
if v.dest and not v.dest:is6linklocal() then if v.dest and not v.dest:is6linklocal() then
%> %>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>"> <div class="tr cbi-rowstyle-<%=(style and 1 or 2)%>">
<div class="td cbi-value-field"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div> <div class="td"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div>
<div class="td cbi-value-field"><%=v.dest%></div> <div class="td"><%=v.dest%></div>
<div class="td cbi-value-field"><%=v.from%></div> <div class="td"><%=v.from%></div>
<div class="td cbi-value-field"><%=v.metric or 0%></div> <div class="td"><%=v.metric or 0%></div>
<div class="td cbi-value-field"><%=rtn[v.table] or v.table%></div> <div class="td"><%=rtn[v.table] or v.table%></div>
</div> </div>
<% <%
style = not style style = not style
@ -125,27 +123,25 @@
%> %>
</div> </div>
</div> </div>
</fieldset> </div>
<br />
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%:IPv6 Neighbours%></legend> <legend><%:IPv6 Neighbours%></legend>
<div class="cbi-section-node"> <div class="cbi-section-node">
<div class="table cbi-section-table"> <div class="table">
<div class="tr cbi-section-table-titles"> <div class="tr table-titles">
<div class="th cbi-section-table-cell"><%:IPv6-Address%></div> <div class="th"><%:IPv6-Address%></div>
<div class="th cbi-section-table-cell"><%:MAC-Address%></div> <div class="th"><%:MAC-Address%></div>
<div class="th cbi-section-table-cell"><%:Interface%></div> <div class="th"><%:Interface%></div>
</div> </div>
<% <%
for _, v in ipairs(ip.neighbors({ family = 6 })) do for _, v in ipairs(ip.neighbors({ family = 6 })) do
if v.dest and not v.dest:is6linklocal() and v.mac then if v.dest and not v.dest:is6linklocal() and v.mac then
%> %>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>"> <div class="tr cbi-rowstyle-<%=(style and 1 or 2)%>">
<div class="td cbi-value-field"><%=v.dest%></div> <div class="td"><%=v.dest%></div>
<div class="td cbi-value-field"><%=v.mac%></div> <div class="td"><%=v.mac%></div>
<div class="td cbi-value-field"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div> <div class="td"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div>
</div> </div>
<% <%
style = not style style = not style
@ -154,8 +150,7 @@
%> %>
</div> </div>
</div> </div>
</fieldset> </div>
<br />
<% end %> <% end %>
</div> </div>

View file

@ -13,84 +13,78 @@
<li class="cbi-tab-disabled"><a href="<%=REQUEST_URI%>/backupfiles"><%:Configuration%></a></li> <li class="cbi-tab-disabled"><a href="<%=REQUEST_URI%>/backupfiles"><%:Configuration%></a></li>
</ul> </ul>
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%:Backup / Restore%></legend>
<fieldset class="cbi-section"> <div class="cbi-section-descr"><%:Click "Generate archive" to download a tar archive of the current configuration files. To reset the firmware to its initial state, click "Perform reset" (only possible with squashfs images).%></div>
<legend><%:Backup / Restore%></legend> <div class="cbi-section-node">
<div class="cbi-section-descr"><%:Click "Generate archive" to download a tar archive of the current configuration files. To reset the firmware to its initial state, click "Perform reset" (only possible with squashfs images).%></div> <form class="inline" method="post" action="<%=url('admin/system/flashops/backup')%>">
<div class="cbi-section-node"> <input type="hidden" name="token" value="<%=token%>" />
<form class="inline" method="post" action="<%=url('admin/system/flashops/backup')%>"> <div class="cbi-value<% if not reset_avail then %> cbi-value-last<% end %>">
<input type="hidden" name="token" value="<%=token%>" /> <label class="cbi-value-title" for="image"><%:Download backup%>:</label>
<div class="cbi-value<% if not reset_avail then %> cbi-value-last<% end %>"> <div class="cbi-value-field">
<label class="cbi-value-title" for="image"><%:Download backup%>:</label> <input class="cbi-button cbi-button-action important" type="submit" name="backup" value="<%:Generate archive%>" />
<div class="cbi-value-field">
<input class="cbi-button cbi-button-apply" type="submit" name="backup" value="<%:Generate archive%>" />
</div>
</div> </div>
</form> </div>
<% if reset_avail then %> </form>
<form class="inline" method="post" action="<%=url('admin/system/flashops/reset')%>">
<input type="hidden" name="token" value="<%=token%>" />
<div class="cbi-value cbi-value-last">
<label class="cbi-value-title"><%:Reset to defaults%>:</label>
<div class="cbi-value-field">
<input onclick="return confirm('<%:Really reset all changes?%>')" class="cbi-button cbi-button-reset" type="submit" name="reset" value="<%:Perform reset%>" />
</div>
</div>
</form>
<% end %>
</div>
<br />
<div class="cbi-section-descr"><%:To restore configuration files, you can upload a previously generated backup archive here.%></div>
<div class="cbi-section-node">
<form class="inline" method="post" action="<%=url('admin/system/flashops/restore')%>" enctype="multipart/form-data">
<div class="cbi-value cbi-value-last">
<label class="cbi-value-title" for="archive"><%:Restore backup%>:</label>
<div class="cbi-value-field">
<input type="hidden" name="token" value="<%=token%>" />
<input type="file" name="archive" id="archive" />
<input type="submit" class="cbi-button cbi-input-apply" name="restore" value="<%:Upload archive...%>" />
</div>
</div>
</form>
</div>
<% if reset_avail then %> <% if reset_avail then %>
<div class="alert-message warning"><%:Custom files (certificates, scripts) may remain on the system. To prevent this, perform a factory-reset first.%></div> <form class="inline" method="post" action="<%=url('admin/system/flashops/reset')%>">
<input type="hidden" name="token" value="<%=token%>" />
<div class="cbi-value cbi-value-last">
<label class="cbi-value-title"><%:Reset to defaults%>:</label>
<div class="cbi-value-field">
<input onclick="return confirm('<%:Really reset all changes?%>')" class="cbi-button cbi-button-reset" type="submit" name="reset" value="<%:Perform reset%>" />
</div>
</div>
</form>
<% end %> <% end %>
</fieldset> </div>
<br /> <br />
<div class="cbi-section-descr"><%:To restore configuration files, you can upload a previously generated backup archive here.%></div>
<div class="cbi-section-node">
<form class="inline" method="post" action="<%=url('admin/system/flashops/restore')%>" enctype="multipart/form-data">
<div class="cbi-value cbi-value-last">
<label class="cbi-value-title" for="archive"><%:Restore backup%>:</label>
<div class="cbi-value-field">
<input type="hidden" name="token" value="<%=token%>" />
<input type="file" name="archive" id="archive" />
<input type="submit" class="cbi-button cbi-button-action important" name="restore" value="<%:Upload archive...%>" />
</div>
</div>
</form>
</div>
<% if reset_avail then %>
<div class="alert-message warning"><%:Custom files (certificates, scripts) may remain on the system. To prevent this, perform a factory-reset first.%></div>
<% end %>
</div>
<fieldset class="cbi-section"> <div class="cbi-section">
<legend><%:Flash new firmware image%></legend> <legend><%:Flash new firmware image%></legend>
<% if upgrade_avail then %> <% if upgrade_avail then %>
<form method="post" action="<%=url('admin/system/flashops/sysupgrade')%>" enctype="multipart/form-data"> <form method="post" action="<%=url('admin/system/flashops/sysupgrade')%>" enctype="multipart/form-data">
<input type="hidden" name="token" value="<%=token%>" /> <input type="hidden" name="token" value="<%=token%>" />
<div class="cbi-section-descr"><%:Upload a sysupgrade-compatible image here to replace the running firmware. Check "Keep settings" to retain the current configuration (requires a compatible firmware image).%></div> <div class="cbi-section-descr"><%:Upload a sysupgrade-compatible image here to replace the running firmware. Check "Keep settings" to retain the current configuration (requires a compatible firmware image).%></div>
<div class="cbi-section-node"> <div class="cbi-section-node">
<div class="cbi-value"> <div class="cbi-value">
<label class="cbi-value-title" for="keep"><%:Keep settings%>:</label> <label class="cbi-value-title" for="keep"><%:Keep settings%>:</label>
<div class="cbi-value-field"> <div class="cbi-value-field">
<input type="checkbox" name="keep" id="keep" checked="checked" /> <input type="checkbox" name="keep" id="keep" checked="checked" />
</div>
</div>
<div class="cbi-value cbi-value-last<% if image_invalid then %> cbi-value-error<% end %>">
<label class="cbi-value-title" for="image"><%:Image%>:</label>
<div class="cbi-value-field">
<input type="file" name="image" id="image" />
<input type="submit" class="cbi-button cbi-input-apply" value="<%:Flash image...%>" />
</div>
</div> </div>
</div> </div>
<% if image_invalid then %> <div class="cbi-value cbi-value-last<% if image_invalid then %> cbi-value-error<% end %>">
<div class="cbi-section-error"><%:The uploaded image file does not contain a supported format. Make sure that you choose the generic image format for your platform. %></div> <label class="cbi-value-title" for="image"><%:Image%>:</label>
<% end %> <div class="cbi-value-field">
</form> <input type="file" name="image" id="image" />
<% else %> <input type="submit" class="cbi-button cbi-button-action important" value="<%:Flash image...%>" />
<div class="cbi-section-descr"><%:Sorry, there is no sysupgrade support present; a new firmware image must be flashed manually. Please refer to the wiki for device specific install instructions.%></div> </div>
<% end %> </div>
</fieldset> </div>
<% if image_invalid then %>
</fieldset> <div class="cbi-section-error"><%:The uploaded image file does not contain a supported format. Make sure that you choose the generic image format for your platform. %></div>
<% end %>
</form>
<% else %>
<div class="cbi-section-descr"><%:Sorry, there is no sysupgrade support present; a new firmware image must be flashed manually. Please refer to the wiki for device specific install instructions.%></div>
<% end %>
</div>
<%+footer%> <%+footer%>

View file

@ -44,6 +44,8 @@ end
<%+header%> <%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<h2 name="content"><%:Software%></h2> <h2 name="content"><%:Software%></h2>
<div class="cbi-map"> <div class="cbi-map">
@ -57,8 +59,8 @@ end
<input type="hidden" name="exec" value="1" /> <input type="hidden" name="exec" value="1" />
<input type="hidden" name="token" value="<%=token%>" /> <input type="hidden" name="token" value="<%=token%>" />
<fieldset class="cbi-section"> <div class="cbi-section">
<fieldset class="cbi-section-node"> <div class="cbi-section-node">
<% if (install and next(install)) or (remove and next(remove)) or update or upgrade then %> <% if (install and next(install)) or (remove and next(remove)) or update or upgrade then %>
<div class="cbi-value"> <div class="cbi-value">
<% if #stdout > 0 then %><pre><%=pcdata(stdout)%></pre><% end %> <% if #stdout > 0 then %><pre><%=pcdata(stdout)%></pre><% end %>
@ -91,18 +93,18 @@ end
<div style="background-color:#F08080; border-right:1px solid #000000; height:100%; width:<%=used_perc%>%">&#160;</div> <div style="background-color:#F08080; border-right:1px solid #000000; height:100%; width:<%=used_perc%>%">&#160;</div>
</div> </div>
</div> </div>
</fieldset> </div>
<br /> <br />
<fieldset class="cbi-section-node"> <div class="cbi-section-node">
<input type="hidden" name="display" value="<%=pcdata(display)%>" /> <input type="hidden" name="display" value="<%=pcdata(display)%>" />
<div class="cbi-value"> <div class="cbi-value">
<label class="cbi-value-title"><%:Download and install package%>:</label> <label class="cbi-value-title"><%:Download and install package%>:</label>
<div class="cbi-value-field"> <div class="cbi-value-field">
<input type="text" name="url" size="30" value="" /> <input type="text" name="url" size="30" value="" />
<input class="cbi-button cbi-input-save" type="submit" name="go" value="<%:OK%>" /> <input class="cbi-button cbi-button-save" type="submit" name="go" value="<%:OK%>" />
</div> </div>
</div> </div>
@ -110,11 +112,11 @@ end
<label class="cbi-value-title"><%:Filter%>:</label> <label class="cbi-value-title"><%:Filter%>:</label>
<div class="cbi-value-field"> <div class="cbi-value-field">
<input type="text" name="query" size="20" value="<%=pcdata(query)%>" /> <input type="text" name="query" size="20" value="<%=pcdata(query)%>" />
<input type="submit" class="cbi-button cbi-input-find" name="search" value="<%:Find package%>" /> <input type="submit" class="cbi-button cbi-button-action" name="search" value="<%:Find package%>" />
</div> </div>
</div> </div>
</fieldset> </div>
</fieldset> </div>
</form> </form>
@ -122,90 +124,90 @@ end
<ul class="cbi-tabmenu"> <ul class="cbi-tabmenu">
<li class="cbi-tab<% if display ~= "installed" then %>-disabled<% end %>"><a href="?display=installed&amp;query=<%=pcdata(query)%>"><%:Installed packages%><% if query then %> (<%=pcdata(query)%>)<% end %></a></li>
<li class="cbi-tab<% if display ~= "available" then %>-disabled<% end %>"><a href="?display=available&amp;query=<%=pcdata(query)%>"><%:Available packages%><% if query then %> (<%=pcdata(query)%>)<% end %></a></li> <li class="cbi-tab<% if display ~= "available" then %>-disabled<% end %>"><a href="?display=available&amp;query=<%=pcdata(query)%>"><%:Available packages%><% if query then %> (<%=pcdata(query)%>)<% end %></a></li>
<li class="cbi-tab<% if display ~= "installed" then %>-disabled<% end %>"><a href="?display=installed&amp;query=<%=pcdata(query)%>"><%:Installed packages%><% if query then %> (<%=pcdata(query)%>)<% end %></a></li>
</ul> </ul>
<% if display ~= "available" then %> <% if display ~= "available" then %>
<fieldset class="cbi-section"> <div class="cbi-section">
<div class="table cbi-section-table" style="width:100%"> <div class="cbi-section-node">
<div class="tr cbi-section-table-titles"> <div class="table">
<div class="th cbi-section-table-cell" style="text-align:left">&#160;</div> <div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell" style="text-align:left"><%:Package name%></div> <div class="th left"><%:Package name%></div>
<div class="th cbi-section-table-cell" style="text-align:left"><%:Version%></div> <div class="th left"><%:Version%></div>
</div> <div class="th cbi-section-actions">&#160;</div>
<% local empty = true; luci.model.ipkg.list_installed(querypat, function(n, v, s, d) empty = false; filter[n] = true %>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=rowstyle()%>">
<div class="td" style="text-align:left; width:10%">
<form method="post" class="inline" action="<%=REQUEST_URI%>">
<input type="hidden" name="exec" value="1" />
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="remove" value="<%=pcdata(n)%>" />
<a onclick="window.confirm('<%:Remove%> &quot;<%=luci.util.pcdata(n)%>&quot; ?') &#38;&#38; this.parentNode.submit(); return false" href="#"><%:Remove%></a>
</form>
</div> </div>
<div class="td" style="text-align:left"><%=luci.util.pcdata(n)%></div> <% local empty = true; luci.model.ipkg.list_installed(querypat, function(n, v, s, d) empty = false; filter[n] = true %>
<div class="td" style="text-align:left"><%=luci.util.pcdata(v)%></div> <div class="tr cbi-rowstyle-<%=rowstyle()%>">
<div class="td left"><%=luci.util.pcdata(n)%></div>
<div class="td left"><%=luci.util.pcdata(v)%></div>
<div class="td cbi-section-actions">
<form method="post" class="inline" action="<%=REQUEST_URI%>">
<input type="hidden" name="exec" value="1" />
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="remove" value="<%=pcdata(n)%>" />
<input class="cbi-button cbi-button-remove" type="submit" onclick="window.confirm('<%:Remove%> &quot;<%=luci.util.pcdata(n)%>&quot; ?') &#38;&#38; this.parentNode.submit(); return false" value="<%:Remove%>" />
</form>
</div>
</div>
<% end) %>
<% if empty then %>
<div class="tr cbi-section-table-row">
<div class="td left">&#160;</div>
<div class="td left"><em><%:none%></em></div>
<div class="td left"><em><%:none%></em></div>
</div>
<% end %>
</div> </div>
<% end) %>
<% if empty then %>
<div class="tr cbi-section-table-row">
<div class="td" style="text-align:left">&#160;</div>
<div class="td" style="text-align:left"><em><%:none%></em></div>
<div class="td" style="text-align:left"><em><%:none%></em></div>
</div>
<% end %>
</div> </div>
</fieldset> </div>
<% else %> <% else %>
<fieldset class="cbi-section"> <div class="cbi-section">
<% if not querypat then %> <% if not querypat then %>
<ul class="cbi-tabmenu"> <ul class="cbi-tabmenu" style="flex-wrap:wrap">
<% local i; for i = 65, 90 do %> <% local i; for i = 65, 90 do %>
<li class="cbi-tab<% if letter ~= i then %>-disabled<% end %>"><a href="?display=available&amp;letter=<%=string.char(i)%>"><%=string.char(i)%></a></li> <li class="cbi-tab<% if letter ~= i then %>-disabled<% end %>"><a href="?display=available&amp;letter=<%=string.char(i)%>"><%=string.char(i)%></a></li>
<% end %> <% end %>
<li class="cbi-tab<% if letter ~= 35 then %>-disabled<% end %>"><a href="?display=available&amp;letter=%23">#</a></li> <li class="cbi-tab<% if letter ~= 35 then %>-disabled<% end %>"><a href="?display=available&amp;letter=%23">#</a></li>
</ul> </ul>
<div class="cbi-section-node">
<% end %> <% end %>
<div class="table cbi-section-table" style="width:100%"> <div class="cbi-section-node cbi-section-node-tabbed">
<div class="tr cbi-section-table-titles"> <div class="table">
<div class="th cbi-section-table-cell" style="text-align:left">&#160;</div> <div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell" style="text-align:left"><%:Package name%></div> <div class="th col-2 left"><%:Package name%></div>
<div class="th cbi-section-table-cell" style="text-align:left"><%:Version%></div> <div class="th col-2 left"><%:Version%></div>
<div class="th cbi-section-table-cell" style="text-align:right"><%:Size (.ipk)%></div> <div class="th col-1 center"><%:Size (.ipk)%></div>
<div class="th cbi-section-table-cell" style="text-align:left"><%:Description%></div> <div class="th col-10 left"><%:Description%></div>
</div> <div class="th cbi-section-actions">&#160;</div>
<% local empty = true; opkg_list(querypat or letterpat, function(n, v, s, d) if filter[n] then return end; empty = false %>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=rowstyle()%>">
<div class="td" style="text-align:left; width:10%">
<form method="post" class="inline" action="<%=REQUEST_URI%>">
<input type="hidden" name="exec" value="1" />
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="install" value="<%=pcdata(n)%>" />
<a onclick="window.confirm('<%:Install%> &quot;<%=luci.util.pcdata(n)%>&quot; ?') &#38;&#38; this.parentNode.submit(); return false" href="#"><%:Install%></a>
</form>
</div> </div>
<div class="td" style="text-align:left"><%=luci.util.pcdata(n)%></div> <% local empty = true; opkg_list(querypat or letterpat, function(n, v, s, d) if filter[n] then return end; empty = false %>
<div class="td" style="text-align:left"><%=luci.util.pcdata(v)%></div> <div class="tr cbi-rowstyle-<%=rowstyle()%>">
<div class="td" style="text-align:right"><%=luci.util.pcdata(s)%></div> <div class="td col-2 left"><%=luci.util.pcdata(n)%></div>
<div class="td" style="text-align:left"><%=luci.util.pcdata(d)%></div> <div class="td col-2 left"><%=luci.util.pcdata(v)%></div>
<div class="td col-1 center"><%=luci.util.pcdata(s)%></div>
<div class="td col-10 left"><%=luci.util.pcdata(d)%></div>
<div class="td cbi-section-actions">
<form method="post" class="inline" action="<%=REQUEST_URI%>">
<input type="hidden" name="exec" value="1" />
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="install" value="<%=pcdata(n)%>" />
<input class="cbi-button cbi-button-apply" type="submit" onclick="window.confirm('<%:Install%> &quot;<%=luci.util.pcdata(n)%>&quot; ?') &#38;&#38; this.parentNode.submit(); return false" value="<%:Install%>" />
</form>
</div>
</div>
<% end) %>
<% if empty then %>
<div class="tr">
<div class="td left">&#160;</div>
<div class="td left"><em><%:none%></em></div>
<div class="td left"><em><%:none%></em></div>
<div class="td right"><em><%:none%></em></div>
<div class="td left"><em><%:none%></em></div>
</div>
<% end %>
</div> </div>
<% end) %>
<% if empty then %>
<div class="tr cbi-section-table-row">
<div class="td" style="text-align:left">&#160;</div>
<div class="td" style="text-align:left"><em><%:none%></em></div>
<div class="td" style="text-align:left"><em><%:none%></em></div>
<div class="td" style="text-align:right"><em><%:none%></em></div>
<div class="td" style="text-align:left"><em><%:none%></em></div>
</div>
<% end %>
</div> </div>
<% if not querypat then %> </div>
</div>
<% end %>
</fieldset>
<% end %> <% end %>
</div> </div>

View file

@ -7,7 +7,6 @@
<%+header%> <%+header%>
<h2 name="content"><%:Reboot%></h2> <h2 name="content"><%:Reboot%></h2>
<br />
<p><%:Reboots the operating system of your device%></p> <p><%:Reboots the operating system of your device%></p>
@ -49,7 +48,7 @@
} }
//]]></script> //]]></script>
<input class="cbi-button cbi-button-apply" type="button" value="<%:Perform reboot%>" onclick="reboot(this)" /> <input class="cbi-button cbi-button-action important" type="button" value="<%:Perform reboot%>" onclick="reboot(this)" />
<p class="alert-message" style="display:none"> <p class="alert-message" style="display:none">
<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" />

View file

@ -4,7 +4,7 @@
-%> -%>
<% export("uci_changelog", function(changes) -%> <% export("uci_changelog", function(changes) -%>
<fieldset class="cbi-section"> <div class="cbi-section">
<strong><%:Legend:%></strong> <strong><%:Legend:%></strong>
<div class="uci-change-legend"> <div class="uci-change-legend">
<div class="uci-change-legend-label"><ins>&#160;</ins> <%:Section added%></div> <div class="uci-change-legend-label"><ins>&#160;</ins> <%:Section added%></div>
@ -32,9 +32,11 @@
ret[#ret+1] = "<br />%s.%s.%s+=<strong>%s</strong>" ret[#ret+1] = "<br />%s.%s.%s+=<strong>%s</strong>"
%{ r, s, o, util.pcdata(v[i]) } %{ r, s, o, util.pcdata(v[i]) }
end end
else elseif v ~= "" then
ret[#ret+1] = "<br />%s.%s.%s=<strong>%s</strong>" ret[#ret+1] = "<br />%s.%s.%s=<strong>%s</strong>"
%{ r, s, o, util.pcdata(v) } %{ r, s, o, util.pcdata(v) }
else
ret[#ret+1] = "<br /><del>%s.%s.<strong>%s</strong></del>" %{ r, s, o }
end end
end end
end end
@ -57,7 +59,7 @@
ret[#ret+1] = "%s.%s.%s+=<strong>%s</strong><br />" ret[#ret+1] = "%s.%s.%s+=<strong>%s</strong><br />"
%{ r, s, o, util.pcdata(v[i]) } %{ r, s, o, util.pcdata(v[i]) }
end end
else else
ret[#ret+1] = "%s.%s.%s=<strong>%s</strong><br />" ret[#ret+1] = "%s.%s.%s=<strong>%s</strong><br />"
%{ r, s, o, util.pcdata(v) } %{ r, s, o, util.pcdata(v) }
@ -75,5 +77,5 @@
write(table.concat(ret)) write(table.concat(ret))
%></div> %></div>
</fieldset> </div>
<%- end) %> <%- end) %>

View file

@ -27,21 +27,17 @@
<div class="cbi-page-actions"> <div class="cbi-page-actions">
<% if redir_url then %> <% if redir_url then %>
<div style="float:left"> <form method="get" action="<%=luci.util.pcdata(redir_url)%>">
<form class="inline" method="get" action="<%=luci.util.pcdata(redir_url)%>"> <input class="cbi-button cbi-button-link" type="submit" value="<%:Back%>" />
<input class="cbi-button cbi-button-link" style="float:left; margin:0" type="submit" value="<%:Back%>" /> </form>
</form>
</div>
<% end %> <% end %>
<div style="text-align:right"> <input class="cbi-button cbi-button-save" type="button" id="apply_button" value="<%:Save & Apply%>" onclick="uci_apply(true); this.blur()" />
<input class="cbi-button cbi-button-save" type="button" id="apply_button" value="<%:Save & Apply%>" onclick="uci_apply(true); this.blur()" /> <form method="post" action="<%=url("admin/uci/revert")%>">
<form class="inline" method="post" action="<%=url("admin/uci/revert")%>"> <input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="token" value="<%=token%>" /> <input type="hidden" name="redir" value="<%=pcdata(luci.http.formvalue("redir"))%>" />
<input type="hidden" name="redir" value="<%=pcdata(luci.http.formvalue("redir"))%>" /> <input class="cbi-button cbi-button-reset" type="submit" value="<%:Revert%>" />
<input class="cbi-button cbi-button-reset" type="submit" value="<%:Revert%>" /> </form>
</form>
</div>
</div> </div>
<%+footer%> <%+footer%>

View file

@ -215,7 +215,8 @@ a:hover {
* ---------------------------------------------------------------------------------------- */ * ---------------------------------------------------------------------------------------- */
p, p,
.cbi-map-descr, .cbi-map-descr,
.cbi-section-descr { .cbi-section-descr,
.table .tr.cbi-section-table-descr .th {
font-size: 13px; font-size: 13px;
font-weight: normal; font-weight: normal;
line-height: 18px; line-height: 18px;
@ -229,7 +230,7 @@ p small {
h1, h1,
h2, h2,
h3, h3, legend,
h4, h4,
h5, h5,
h6 { h6 {
@ -265,14 +266,14 @@ h2 small {
font-size: 14px; font-size: 14px;
} }
h3, h3, legend,
h4, h4,
h5, h5,
h6 { h6 {
line-height: 36px; line-height: 36px;
} }
h3 { h3, legend {
font-size: 18px; font-size: 18px;
} }
@ -645,6 +646,26 @@ textarea[readonly] {
border-color: #ddd; border-color: #ddd;
} }
.cbi-optionals,
.cbi-section-create {
padding: 0 0 10px 10px;
}
.cbi-section-create {
margin: -3px;
display: inline-flex;
align-items: center;
}
.cbi-section-create > * {
margin: 3px;
flex: 1 1 auto;
}
.cbi-section-create > * > input {
width: 100%;
}
.actions, .actions,
.cbi-page-actions { .cbi-page-actions {
background: #f5f5f5; background: #f5f5f5;
@ -706,6 +727,7 @@ textarea[readonly] {
padding: 0; padding: 0;
font-size: 13px; font-size: 13px;
border-collapse: collapse; border-collapse: collapse;
position: relative;
} }
.table .th, .table .td { .table .th, .table .td {
@ -732,6 +754,19 @@ textarea[readonly] {
vertical-align: top; vertical-align: top;
} }
.tr.placeholder {
height: calc(3em + 20px);
}
.tr.placeholder > .td {
position: absolute;
left: 0;
right: 0;
bottom: 0;
text-align: center;
line-height: 3em;
}
/* Patterns.less /* Patterns.less
* Repeatable UI elements outside the base styles provided from the scaffolding * Repeatable UI elements outside the base styles provided from the scaffolding
* ---------------------------------------------------------------------------- */ * ---------------------------------------------------------------------------- */
@ -1244,99 +1279,67 @@ footer {
outline: 1px dotted #666; outline: 1px dotted #666;
} }
.btn.primary,
.cbi-page-actions .cbi-button-apply,
.cbi-page-actions .cbi-button-save,
.cbi-page-actions .cbi-button-reset {
color: #ffffff;
padding: 5px 14px 6px;
background-color: #0064cd;
background-repeat: repeat-x;
background-image: linear-gradient(to bottom, #049cdb, #0064cd);
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
border-color: #0064cd #0064cd #003f81;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
}
.cbi-input-invalid, .cbi-input-invalid,
.cbi-value-error input { .cbi-value-error input {
color: #FF0000; color: #FF0000;
border-color: #FF0000; border-color: #FF0000;
} }
.cbi-button-up, .cbi-button-positive,
.cbi-input-up { .cbi-button-fieldadd,
background-position: center center;
background-image: url('../resources/cbi/up.gif'), linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
}
.cbi-button-down,
.cbi-input-down {
background-position: center center;
background-image: url('../resources/cbi/down.gif'), linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
}
.cbi-button-find,
.cbi-input-find {
background-position: 6px center, left top;
padding-left: 28px;
background-image: url('../resources/cbi/find.gif'), linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
}
.cbi-button-add, .cbi-button-add,
.cbi-input-add { .cbi-button-save {
background-position: 6px center, left top; border-color: #4a4;
padding-left: 28px; color: #4a4;
background-image: url('../resources/cbi/add.gif'), linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
}
.cbi-button-apply,
.cbi-input-apply {
background-position: 6px center, left top;
padding-left: 28px;
background-image: url('../resources/cbi/apply.gif'), linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
}
.cbi-button-reset,
.cbi-input-reset {
background-position: 6px center, left top;
padding-left: 28px;
background-image: url('../resources/cbi/reset.gif'), linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
}
.cbi-button-edit,
.cbi-input-edit {
background-position: 6px center, left top;
padding-left: 28px;
background-image: url('../resources/cbi/edit.gif'), linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
}
.cbi-button-remove,
.cbi-input-remove {
background-position: 6px center, left top;
padding-left: 28px;
background-image: url('../resources/cbi/remove.gif'), linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
}
.cbi-button-reload,
.cbi-input-reload {
background-position: 6px center, left top;
padding-left: 28px;
background-image: url('../resources/cbi/reload.gif'), linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
}
.cbi-button-link,
.cbi-input-link {
background-position: 6px center, left top;
padding-left: 28px;
background-image: url('../resources/cbi/link.gif'), linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
} }
.cbi-button-neutral,
.cbi-button-download, .cbi-button-download,
.cbi-input-download { .cbi-button-find,
background-position: 6px center, left top; .cbi-button-link,
padding-left: 28px; .cbi-button-up,
background-image: url('../resources/cbi/download.gif'), linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); .cbi-button-down {
border-color: #444;
color: #444;
}
.btn.primary,
.cbi-button-action,
.cbi-button-apply,
.cbi-button-reload,
.cbi-button-edit {
border-color: #0069d6;
color: #0069d6;
}
.cbi-button-negative,
.cbi-section-remove .cbi-button,
.cbi-button-reset,
.cbi-button-remove {
border-color: #c44;
color: #c44;
}
.btn.primary,
.cbi-button-action.important,
.cbi-page-actions .cbi-button-apply,
.cbi-section-actions .cbi-button-edit {
color: #fff;
background: #0069d6;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.cbi-button-positive.important,
.cbi-page-actions .cbi-button-save {
color: #fff;
background: #4a4;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.cbi-page-actions .cbi-button-apply + .cbi-button-save {
background: linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
text-shadow: 0 -1px 0 rgba(255, 255, 255, 0.75);
color: #4a4;
} }
.cbi-dropdown { .cbi-dropdown {
@ -1492,6 +1495,58 @@ footer {
opacity: .6; opacity: .6;
} }
.cbi-tooltip-container {
cursor: help;
}
.cbi-tooltip {
position: absolute;
z-index: 1000;
left: -1000px;
opacity: 0;
transition: opacity .25s ease-out;
}
.cbi-tooltip-container:hover .cbi-tooltip:not(:empty) {
left: auto;
opacity: 1;
transition: opacity .25s ease-in;
}
.zonebadge .cbi-tooltip {
padding: 1px;
background: inherit;
margin: -1.6em 0 0 -5px;
border-radius: 3px;
pointer-events: none;
box-shadow: 0 0 3px #444;
}
.zonebadge .cbi-tooltip > * {
margin: 1px;
}
.zone-forwards {
display: flex;
flex-wrap: wrap;
}
.zone-forwards > * {
flex: 1 1 40%;
padding: 1px;
}
.zone-forwards > span {
flex-basis: 10%;
text-align: center;
}
.zone-forwards .zone-src,
.zone-forwards .zone-dest {
display: flex;
flex-direction: column;
}
.btn.active, .btn:active { .btn.active, .btn:active {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
} }
@ -1751,9 +1806,13 @@ table table td,
vertical-align: middle; vertical-align: middle;
} }
.cbi-value-description { display: inline; } .cbi-value-description {
background-image: url(/luci-static/resources/cbi/help.gif);
.cbi-value-description img { vertical-align: middle; } background-position: .25em .2em;
background-repeat: no-repeat;
margin: .25em 0 0 0;
padding: 0 0 0 1.7em;
}
.cbi-section-error { .cbi-section-error {
border: 1px solid #FF0000; border: 1px solid #FF0000;
@ -1852,6 +1911,7 @@ table table td,
flex-wrap: wrap; flex-wrap: wrap;
} }
.ifacebadge.large,
.network-status-table .ifacebox-body .ifacebadge { .network-status-table .ifacebox-body .ifacebadge {
flex: 1; flex: 1;
margin: .5em .25em 0 .25em; margin: .5em .25em 0 .25em;
@ -1866,7 +1926,6 @@ table table td,
white-space: nowrap; white-space: nowrap;
color: #666666; color: #666666;
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
cursor: pointer;
} }
.zonebadge > em, .zonebadge > em,

View file

@ -32,8 +32,8 @@
font-style: normal; font-style: normal;
} }
.table { display: table; } .table { display: table; position: relative; }
.tr { display: table-row; } .tr { display: table-row; }
.thead { display: table-header-group; } .thead { display: table-header-group; }
.tbody { display: table-row-group; } .tbody { display: table-row-group; }
.tfoot { display: table-footer-group; } .tfoot { display: table-footer-group; }
@ -48,6 +48,19 @@
font-weight: bold; font-weight: bold;
} }
.tr.placeholder {
height: 4em;
}
.tr.placeholder > .td {
position: absolute;
left: 0;
right: 0;
bottom: 0;
text-align: center;
line-height: 3em;
}
.table[width="33%"], .th[width="33%"], .td[width="33%"] { width: 33%; } .table[width="33%"], .th[width="33%"], .td[width="33%"] { width: 33%; }
.table[width="100%"], .th[width="100%"], .td[width="100%"] { width: 100%; } .table[width="100%"], .th[width="100%"], .td[width="100%"] { width: 100%; }
@ -442,10 +455,12 @@ h3 {
} }
h4 { h4 {
margin: 2rem 0 0 0;
font-size: 1.2rem;
padding-bottom: 10px;
} }
fieldset { .cbi-section {
margin: 2rem 0 0 0; margin: 2rem 0 0 0;
padding: 2rem; padding: 2rem;
border: 0; border: 0;
@ -465,7 +480,7 @@ fieldset {
margin-top: 1rem; margin-top: 1rem;
} }
fieldset > legend { .cbi-section > legend {
display: none !important; display: none !important;
} }
@ -486,10 +501,12 @@ fieldset > fieldset {
border-bottom: 1px solid #eee; border-bottom: 1px solid #eee;
} }
table, table {
.table {
border-spacing: 0; border-spacing: 0;
border-collapse: collapse; border-collapse: collapse;
}
table, .table {
width: 100%; width: 100%;
border: 1px solid #eee; border: 1px solid #eee;
} }
@ -501,21 +518,75 @@ table > tbody > tr > td, table > tbody > tr > th, table > tfoot > tr > td, table
white-space: nowrap; white-space: nowrap;
} }
.td.cbi-value-field,
.cbi-section-table-cell { .cbi-section-table-cell {
text-align: center; text-align: center;
display: inline-block;
flex: 10;
}
.cbi-section-table-cell {
white-space: nowrap;
align-self: flex-end;
flex: 1;
}
.td.cbi-value-field[data-title]::before {
content: attr(data-title);
padding: .5rem;
display: block;
white-space: nowrap;
}
.cbi-section-table {
border: none;
}
.cbi-section-table-titles,
.cbi-section-table-descr {
display: none;
} }
.cbi-section-table-row { .cbi-section-table-row {
text-align: center; text-align: center;
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: space-between;
margin-bottom: 1rem;
background: #f4f4f4;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
} }
fieldset > table > tbody > tr:nth-of-type(2n), .cbi-section-table-row:last-child {
fieldset > .table > .tbody > .tr:nth-of-type(2n) { margin-bottom: 0;
}
.cbi-section-table-row[data-title]::before {
content: attr(data-title);
display: block;
width: 100%;
margin: .25rem;
padding: .25rem .25rem .5rem .25rem;
border-bottom: 1px solid rgba(0, 0, 0, .26);
text-align: center;
font-size: 1rem;
}
.cbi-section-table-row > .cbi-value-field .cbi-input-select,
.cbi-section-table-row > .cbi-value-field .cbi-input-text,
.cbi-section-table-row > .cbi-value-field .cbi-input-password,
.cbi-section-table-row > .cbi-value-field .cbi-dropdown {
width: 100%;
}
div > table > tbody > tr:nth-of-type(2n),
div > .table > .tbody > .tr:nth-of-type(2n) {
background-color: #f9f9f9; background-color: #f9f9f9;
} }
fieldset > table > tbody > tr:nth-of-type(2n), div > table > tbody > tr:nth-of-type(2n),
fieldset > .table > .tbody > .tr:nth-of-type(2n) { div > .table > .tbody > .tr:nth-of-type(2n) {
background-color: #f9f9f9; background-color: #f9f9f9;
} }
@ -1029,7 +1100,7 @@ td > .ifacebadge,
.ifacebadge > img { .ifacebadge > img {
display: inline-block; display: inline-block;
margin: 0 .2rem; margin: 0 .2rem;
align-self: start; align-self: flex-start;
} }
.ifacebadge > img + img { .ifacebadge > img + img {
@ -1206,10 +1277,9 @@ td > .ifacebadge,
.zonebadge { .zonebadge {
padding: 0.2rem 0.5rem; padding: 0.2rem 0.5rem;
display: inline-block; display: inline-block;
cursor: pointer;
} }
.zonebadge > .ifacebadge { .zonebadge .ifacebadge {
padding: .2rem .3rem; padding: .2rem .3rem;
margin: 0.1rem 0.2rem; margin: 0.1rem 0.2rem;
border: 1px solid #6C6C6C; border: 1px solid #6C6C6C;
@ -1255,11 +1325,13 @@ td > .ifacebadge,
min-width: 7rem; min-width: 7rem;
} }
.cbi-section-table-row > .cbi-value-field .cbi-input-select { .cbi-section-create {
width: 7rem; margin: .5rem -3px;
display: inline-flex;
align-items: center;
} }
.cbi-section-create > .cbi-button-add { .cbi-section-create > * {
margin: 0.5rem; margin: 0.5rem;
} }
@ -1291,6 +1363,62 @@ small {
border-top: 1px solid #CCC; border-top: 1px solid #CCC;
} }
.cbi-dropdown-container {
position: relative;
}
.cbi-tooltip-container {
cursor: help;
}
.cbi-tooltip {
position: absolute;
z-index: 1000;
left: -1000px;
opacity: 0;
transition: opacity .25s ease-out;
pointer-events: none;
box-shadow: 0 0 2px #444;
}
.cbi-tooltip-container:hover .cbi-tooltip {
left: auto;
opacity: 1;
transition: opacity .25s ease-in;
}
.zonebadge .cbi-tooltip {
padding: .25rem;
background: inherit;
margin: -1.5rem 0 0 -.5rem;
}
.zonebadge-empty {
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);
color: #404040;
}
.zone-forwards {
display: flex;
min-width: 10rem;
}
.zone-forwards > * {
flex: 1 1 45%;
}
.zone-forwards > span {
flex-basis: 10%;
text-align: center;
padding: 0 .25rem;
}
.zone-forwards .zone-src,
.zone-forwards .zone-dest {
display: flex;
flex-direction: column;
}
#diag-rc-output > pre { #diag-rc-output > pre {
background-color: #f5f5f5; background-color: #f5f5f5;
display: block; display: block;
@ -1475,11 +1603,6 @@ header > .container > .pull-right > * {
margin-top: 0; margin-top: 0;
} }
/* fix network firewall*/
.node-network-firewall > .main .cbi-section-table-row > .cbi-value-field .cbi-input-select {
min-width: 4rem;
}
.node-status-iptables fieldset, .node-status-iptables fieldset,
.node-system-packages fieldset, .node-system-packages fieldset,
.node-system-flashops fieldset { .node-system-flashops fieldset {
@ -1669,6 +1792,26 @@ body.lang_pl.node-main-login .cbi-value-title {
.node-main-login > .main .cbi-value-title { .node-main-login > .main .cbi-value-title {
text-align: left; text-align: left;
} }
.tr {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.th, .td {
flex: 1;
flex-basis: 33%;
overflow: hidden;
text-overflow: ellipsis;
}
.th.cbi-value-field,
.td.cbi-value-field,
.th.cbi-section-table-cell,
.td.cbi-section-table-cell {
flex-basis: auto;
}
} }
@media screen and (max-width: 480px) { @media screen and (max-width: 480px) {
@ -1803,6 +1946,14 @@ body.lang_pl.node-main-login .cbi-value-title {
.node-status-iptables > .main div > .cbi-map > form input[type="submit"] + input[type="submit"] { .node-status-iptables > .main div > .cbi-map > form input[type="submit"] + input[type="submit"] {
margin-top: 1rem; margin-top: 1rem;
} }
.th, .td {
flex-basis: 50%;
}
.td.cbi-value-field {
flex-basis: 100%;
}
} }
@media screen and (min-width: 992px) { @media screen and (min-width: 992px) {

View file

@ -56,9 +56,39 @@
local childs = disp.node_childs(node) local childs = disp.node_childs(node)
if #childs > 0 then if #childs > 0 then
write('<div class="tabmenu%d"><ul class="tabmenu l%d">' %{ write('<ul class="mainmenu l%d">' % level)
level, level
}) local i, v
for i, v in ipairs(childs) do
local nnode = node.nodes[v]
write('<li class="mainmenu-item-%s %s"><a href="%s">%s</a>' %{
v, (nnode._menu_selected or (node.leaf and v == leaf)) and 'selected' or '',
nodeurl(prefix, v, nnode.query),
striptags(translate(nnode.title))
})
if level < 2 then
render_menu(prefix .. "/" .. v, nnode, level + 1)
end
write('</li>')
end
write('</ul>')
end
end
local function render_tabmenu(prefix, node, level)
if not level then
level = 1
end
local childs = disp.node_childs(node)
if #childs > 0 then
if level > 2 then
write('<ul class="cbi-tabmenu">')
end
local selected_node local selected_node
local selected_name local selected_name
@ -71,20 +101,22 @@
selected_name = v selected_name = v
end end
write('<li class="tabmenu-item-%s %s"><a href="%s">%s</a></li>' %{ if level > 2 then
v, (nnode._menu_selected or (node.leaf and v == leaf)) and 'active' or '', write('<li class="tabmenu-item-%s %s"><a href="%s">%s</a></li>' %{
nodeurl(prefix, v, nnode.query), v, (nnode._menu_selected or (node.leaf and v == leaf)) and 'cbi-tab' or '',
striptags(translate(nnode.title)) nodeurl(prefix, v, nnode.query),
}) striptags(translate(nnode.title))
})
end
end end
write('</ul><br style="clear:both" />') if level > 2 then
write('</ul>')
end
if selected_node then if selected_node then
render_menu(prefix .. "/" .. selected_name, selected_node, level + 1) render_tabmenu(prefix .. "/" .. selected_name, selected_node, level + 1)
end end
write('</div>')
end end
end end
@ -116,6 +148,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%=luci.i18n.context.lang%>" lang="<%=luci.i18n.context.lang%>"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%=luci.i18n.context.lang%>" lang="<%=luci.i18n.context.lang%>">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="Content-Script-Type" content="text/javascript" /> <meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" /> <link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" />
<% if node and node.css then %><link rel="stylesheet" type="text/css" media="screen" href="<%=resource%>/<%=node.css%>" /> <% if node and node.css then %><link rel="stylesheet" type="text/css" media="screen" href="<%=resource%>/<%=node.css%>" />
@ -125,6 +158,47 @@
</style> </style>
<% end -%> <% end -%>
<script type="text/javascript" src="<%=resource%>/xhr.js"></script> <script type="text/javascript" src="<%=resource%>/xhr.js"></script>
<script type="text/javascript">//<![CDATA[
document.addEventListener('DOMContentLoaded', function() {
var event = ('ontouchstart' in window) ? 'touchstart' : 'click';
document.querySelectorAll('ul.mainmenu.l1 > li > a').forEach(function(a) {
a.addEventListener(event, function(ev) {
var a = ev.target, ul1 = a.parentNode.parentNode, ul2 = a.nextElementSibling;
document.querySelectorAll('ul.mainmenu.l1 > li.active').forEach(function(li) {
if (li !== a.parentNode)
li.classList.remove('active');
});
if (!ul2)
return;
if (ul2.parentNode.offsetLeft + ul2.offsetWidth <= ul1.offsetLeft + ul1.offsetWidth)
ul2.classList.add('align-left');
ul1.classList.add('active');
a.parentNode.classList.add('active');
a.blur();
ev.preventDefault();
ev.stopPropagation();
});
});
document.addEventListener(event, function(ev) {
var t = ev.target;
while (t && t.id != 'mainmenu')
t = t.parentNode;
if (!t)
document.querySelectorAll('ul.mainmenu > li.active').forEach(function(li) {
li.classList.remove('active');
});
});
});
//]]></script>
<title><%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI</title> <title><%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI</title>
</head> </head>
<body class="lang_<%=luci.i18n.context.lang%>"> <body class="lang_<%=luci.i18n.context.lang%>">
@ -161,11 +235,15 @@
</div> </div>
<div id="maincontainer"> <div id="maincontainer">
<div id="tabmenu"> <div id="mainmenu">
<% if category then render_menu(category, cattree) end %> <% if category then render_menu(category, cattree) end %>
</div> </div>
<div id="maincontent"> <div id="maincontent">
<div id="tabmenu">
<% if category then render_tabmenu(category, cattree) end %>
</div>
<noscript> <noscript>
<div class="alert-message warning"> <div class="alert-message warning">
<h4><%:JavaScript required!%></h4> <h4><%:JavaScript required!%></h4>