diff options
50 files changed, 2459 insertions, 1794 deletions
diff --git a/applications/luci-app-firewall/luasrc/view/firewall/cbi_addforward.htm b/applications/luci-app-firewall/luasrc/view/firewall/cbi_addforward.htm index 279b6e06d6..f48599b505 100644 --- a/applications/luci-app-firewall/luasrc/view/firewall/cbi_addforward.htm +++ b/applications/luci-app-firewall/luasrc/view/firewall/cbi_addforward.htm @@ -18,95 +18,91 @@ vals[#vals+1] = '%s (%s)' %{ ip, name } end) -%> -<div class="cbi-section-create cbi-tblsection-create"> - <br /> - <div class="table cbi-section-table" style="width:810px; margin-left:5px"> - <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell" colspan="8"><%:New port forward%>:</div> + +<h4><%:New port forward%></h4> +<div class="table"> + <div class="tr table-titles"> + <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 class="td"> + <select class="cbi-input-select" id="_newfwd.proto" name="_newfwd.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"> + <select class="cbi-input-select" id="_newfwd.extzone" name="_newfwd.extzone"> + <% for _, z in ipairs(ezl) do -%><option value="<%=z:name()%>"><%=z:name()%></option><%- end %> + </select> + </div> + <div class="td"> + <input type="text" class="cbi-input-text" id="_newfwd.extport" name="_newfwd.extport" data-type="portrange" data-optional="true" /> + </div> + <div class="td"> + <select class="cbi-input-select" id="_newfwd.intzone" name="_newfwd.intzone"> + <% for _, z in ipairs(izl) do -%><option value="<%=z:name()%>"><%=z:name()%></option><%- end %> + </select> + </div> + <div class="td"> + <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="tr cbi-section-table-descr"> - <div class="th cbi-section-table-cell"><%:Name%></div> - <div class="th cbi-section-table-cell"><%:Protocol%></div> - <div class="th cbi-section-table-cell"><%:External zone%></div> - <div class="th cbi-section-table-cell"><%:External port%></div> - <div class="th cbi-section-table-cell"><%:Internal zone%></div> - <div class="th cbi-section-table-cell"><%:Internal IP address%></div> - <div class="th cbi-section-table-cell"><%:Internal port%></div> - <div class="th cbi-section-table-cell"></div> + <div class="td"> + <input type="text" class="cbi-input-text" id="_newfwd.intport" name="_newfwd.intport" data-type="portrange" data-optional="true" /> </div> - <div class="tr cbi-section-table-row"> - <div class="td cbi-section-table-cell"> - <input type="text" class="cbi-input-text" id="_newfwd.name" name="_newfwd.name" placeholder="<%:New port forward%>" /> - </div> - <div class="td cbi-section-table-cell" style="width:110px"> - <select class="cbi-input-select" id="_newfwd.proto" name="_newfwd.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:55px"> - <select class="cbi-input-select" id="_newfwd.extzone" name="_newfwd.extzone"> - <% for _, z in ipairs(ezl) do -%><option value="<%=z:name()%>"><%=z:name()%></option><%- end %> - </select> - </div> - <div class="td cbi-section-table-cell" style="width:110px"> - <input type="text" class="cbi-input-text" id="_newfwd.extport" name="_newfwd.extport" data-type="portrange" data-optional="true" /> - </div> - <div class="td cbi-section-table-cell" style="width:55px"> - <select class="cbi-input-select" id="_newfwd.intzone" name="_newfwd.intzone"> - <% for _, z in ipairs(izl) do -%><option value="<%=z:name()%>"><%=z:name()%></option><%- end %> - </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 class="td bottom"> + <input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" /> </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 ], - }; +<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; + 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]; + 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; - } + if (!n.value) + n.value = hint[0]; } - }); - //]]></script> -</div> + else if (!n.value) + { + n.value = 'Forward' + this.value; + } + } + }); +//]]></script> diff --git a/applications/luci-app-firewall/luasrc/view/firewall/cbi_addrule.htm b/applications/luci-app-firewall/luasrc/view/firewall/cbi_addrule.htm index c99ecaca37..273675cd30 100644 --- a/applications/luci-app-firewall/luasrc/view/firewall/cbi_addrule.htm +++ b/applications/luci-app-firewall/luasrc/view/firewall/cbi_addrule.htm @@ -5,112 +5,105 @@ local zones = fw:get_zones() %> -<div class="cbi-section-create cbi-tblsection-create"> - <% if wz then %> - <br /> - <div class="table cbi-section-table" style="margin-left:5px"> - <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell left" colspan="4"><%:Open ports on router%>:</div> +<% if wz then %> + <h4><%:Open ports on router%></h4> + <div class="table"> + <div class="tr cbi-section-table-titles"> + <div class="th"><%:Name%></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 class="td"> + <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="tr cbi-section-table-descr"> - <div class="th cbi-section-table-cell"><%:Name%></div> - <div class="th cbi-section-table-cell"><%:Protocol%></div> - <div class="th cbi-section-table-cell"><%:External port%></div> - <div class="th cbi-section-table-cell"></div> + <div class="td"> + <input type="text" class="cbi-input-text" id="_newopen.extport" name="_newopen.extport" /> </div> - <div class="tr cbi-section-table-row"> - <div class="td cbi-section-table-cell" style="width:130px"> - <input type="text" class="cbi-input-text" id="_newopen.name" name="_newopen.name" placeholder="<%:New input rule%>" /> - </div> - <div class="td cbi-section-table-cell" style="width:110px"> - <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 class="td bottom"> + <input type="submit" class="cbi-button cbi-button-add" name="_newopen.submit" value="<%:Add%>" /> </div> </div> - <% end %> - <% if #zones > 1 then %> - <div class="table cbi-section-table" style="margin-left:5px"> - <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell left" colspan="6"><br /><%:New forward rule%>:</div> + </div> +<% end %> +<% if #zones > 1 then %> + <h4><%:New forward rule%></h4> + <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 class="tr cbi-section-table-descr"> - <div class="th cbi-section-table-cell"><%:Name%></div> - <div class="th cbi-section-table-cell"><%:Source zone%></div> - <div class="th cbi-section-table-cell"><%:Destination zone%></div> - <div class="th cbi-section-table-cell"></div> + <div class="td"> + <select class="cbi-input-text" id="_newfwd.src" name="_newfwd.src"> + <% local k, v; for k, v in ipairs(fw:get_zones()) do -%> + <option<%=ifattr(v:name() == "wan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option> + <%- end %> + </select> </div> - <div class="tr cbi-section-table-row"> - <div class="td cbi-section-table-cell" style="width:130px"> - <input type="text" class="cbi-input-text" id="_newfwd.name" name="_newfwd.name" placeholder="<%:New forward rule%>" /> - </div> - <div class="td cbi-section-table-cell" style="width:110px"> - <select class="cbi-input-text" id="_newfwd.src" name="_newfwd.src"> - <% local k, v; for k, v in ipairs(fw:get_zones()) do -%> - <option<%=ifattr(v:name() == "wan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option> - <%- end %> - </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 class="td"> + <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 bottom"> + <input type="submit" class="cbi-button cbi-button-link" name="_newfwd.submit" value="<%:Add and edit...%>" /> </div> </div> - <% else %> - <input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" /> - <% end %> + </div> +<% else %> + <input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" /> +<% end %> - <% if wz then %> - <script type="text/javascript">//<![CDATA[ - cbi_validate_field('_newopen.extport', true, 'list(neg(portrange))'); - cbi_bind(document.getElementById('_newopen.extport'), 'blur', - function() { - var n = document.getElementById('_newopen.name'); - var p = document.getElementById('_newopen.proto'); - var hints = { - /* port name 0=both, 1=tcp, 2=udp, 3=other */ - 22: [ 'SSH', 1 ], - 53: [ 'DNS', 0 ], - 80: [ 'HTTP', 1 ], - 443: [ 'HTTPS', 1 ], - }; +<% if wz then %> + <script type="text/javascript">//<![CDATA[ + cbi_validate_field('_newopen.extport', true, 'list(neg(portrange))'); + cbi_bind(document.getElementById('_newopen.extport'), 'blur', + function() { + var n = document.getElementById('_newopen.name'); + var p = document.getElementById('_newopen.proto'); + var hints = { + /* port name 0=both, 1=tcp, 2=udp, 3=other */ + 22: [ 'SSH', 1 ], + 53: [ 'DNS', 0 ], + 80: [ 'HTTP', 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]; - if (hint) - { - p.selectedIndex = hint[1]; + p.selectedIndex = hint[1]; - if (!n.value) - n.value = hint[0]; - } - else if (!n.value && this.value) - { - n.value = 'Open' + this.value; - } + if (!n.value) + n.value = hint[0]; + } + else if (!n.value && this.value) + { + n.value = 'Open' + this.value; } - }); + } + }); - cbi_validate_field('cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>', true, 'uciname'); - //]]></script> - <% end %> -</div> + cbi_validate_field('cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>', true, 'uciname'); + //]]></script> +<% end %> diff --git a/applications/luci-app-firewall/luasrc/view/firewall/cbi_addsnat.htm b/applications/luci-app-firewall/luasrc/view/firewall/cbi_addsnat.htm index b2775cf694..0b4774ccc0 100644 --- a/applications/luci-app-firewall/luasrc/view/firewall/cbi_addsnat.htm +++ b/applications/luci-app-firewall/luasrc/view/firewall/cbi_addsnat.htm @@ -12,53 +12,48 @@ end %> -<div class="cbi-section-create cbi-tblsection-create"> - <% if #zones > 1 then %> - <br /> - <div class="table cbi-section-table" style="width:700px; margin-left:5px"> - <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell left" colspan="6"><%:New source NAT%>:</div> +<% if #zones > 1 then %> + <h4><%:New source NAT%></h4> + <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"><%: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 class="td"> + <select class="cbi-input-text" id="_newsnat.src" name="_newsnat.src"> + <% 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"> + <select class="cbi-input-text" id="_newsnat.dest" name="_newsnat.dest"> + <% local k, v; for k, v in ipairs(fw:get_zones()) do -%> + <option<%=ifattr(v:name() == "wan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option> + <%- end %> + </select> + </div> + <div class="td"> + <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="tr cbi-section-table-descr"> - <div class="th cbi-section-table-cell"><%:Name%></div> - <div class="th cbi-section-table-cell"><%:Source zone%></div> - <div class="th cbi-section-table-cell"><%:Destination zone%></div> - <div class="th cbi-section-table-cell"><%:To source IP%></div> - <div class="th cbi-section-table-cell"><%:To source port%></div> - <div class="th cbi-section-table-cell"></div> + <div class="td"> + <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="tr cbi-section-table-row"> - <div class="td cbi-section-table-cell"> - <input type="text" class="cbi-input-text" id="_newsnat.name" name="_newsnat.name" placeholder="<%:New SNAT rule%>" /> - </div> - <div class="td cbi-section-table-cell" style="width:110px"> - <select class="cbi-input-text" id="_newsnat.src" name="_newsnat.src"> - <% 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" style="width:110px"> - <select class="cbi-input-text" id="_newsnat.dest" name="_newsnat.dest"> - <% local k, v; for k, v in ipairs(fw:get_zones()) do -%> - <option<%=ifattr(v:name() == "wan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option> - <%- end %> - </select> - </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 class="td bottom"> + <input type="submit" class="cbi-button cbi-button-link" name="_newsnat.submit" value="<%:Add and edit...%>" /> </div> </div> - <% else %> - <input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" /> - <% end %> -</div> + </div> +<% else %> + <input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" /> +<% end %> diff --git a/applications/luci-app-shadowsocks-libev/luasrc/view/shadowsocks-libev/add_instance.htm b/applications/luci-app-shadowsocks-libev/luasrc/view/shadowsocks-libev/add_instance.htm index 80b95564dd..f016dd47e6 100644 --- a/applications/luci-app-shadowsocks-libev/luasrc/view/shadowsocks-libev/add_instance.htm +++ b/applications/luci-app-shadowsocks-libev/luasrc/view/shadowsocks-libev/add_instance.htm @@ -1,24 +1,17 @@ <div class="cbi-section-create cbi-tblsection-create"> - <br /> - <div class="table cbi-section-table"> - <div class="tr cbi-section-table-row"> - <div class="td cbi-section-table-cell" style="width:140px"> - <select class="cbi-input-select" id="_newinst.type" name="_newinst.type"> - <option value="_dummy">-- instance type --</option> - <option value="ss_local">ss-local</option> - <option value="ss_tunnel">ss-tunnel</option> - <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> + <select class="cbi-input-select" id="_newinst.type" name="_newinst.type"> + <option value="_dummy">-- instance type --</option> + <option value="ss_local">ss-local</option> + <option value="ss_tunnel">ss-tunnel</option> + <option value="ss_redir">ss-redir</option> + <option value="ss_server">ss-server</option> + </select> </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> <script type="text/javascript">//<![CDATA[ XHR.poll(5, '<%=url('admin/services/shadowsocks-libev/status')%>', null, diff --git a/applications/luci-app-travelmate/luasrc/view/travelmate/logread.htm b/applications/luci-app-travelmate/luasrc/view/travelmate/logread.htm index 6cbeaffde6..c40bdeeb59 100644 --- a/applications/luci-app-travelmate/luasrc/view/travelmate/logread.htm +++ b/applications/luci-app-travelmate/luasrc/view/travelmate/logread.htm @@ -6,10 +6,10 @@ This is free software, licensed under the Apache License, Version 2.0 <%+header%> <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> <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> <script type="text/javascript"> diff --git a/applications/luci-app-travelmate/luasrc/view/travelmate/stations.htm b/applications/luci-app-travelmate/luasrc/view/travelmate/stations.htm index bee6fcb360..ffacc2f6df 100644 --- a/applications/luci-app-travelmate/luasrc/view/travelmate/stations.htm +++ b/applications/luci-app-travelmate/luasrc/view/travelmate/stations.htm @@ -11,19 +11,21 @@ This is free software, licensed under the Apache License, Version 2.0 <%+header%> +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> + <div class="cbi-map"> <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)%> </div> -<fieldset class="cbi-section"> - <div class="table cbi-section-table" style="empty-cells:hide"> +<div class="cbi-section"> + <div class="table cbi-section-table"> <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell" style="text-align:left"><%:Device%></div> - <div class="th cbi-section-table-cell" style="text-align:left"><%:SSID%></div> - <div class="th cbi-section-table-cell" style="text-align:left"><%:BSSID%></div> - <div class="th cbi-section-table-cell" style="text-align:left"><%:Encryption%></div> - <div class="th cbi-section-table-cell" style="text-align:center" colspan="2"><%:Actions%></div> + <div class="th left"><%:Device%></div> + <div class="th left"><%:SSID%></div> + <div class="th left"><%:BSSID%></div> + <div class="th left"><%:Encryption%></div> + <div class="th center"> </div> </div> <% 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%>"><%=bssid%></div> <div class="td" style="<%=style%>"><%=encryption%></div> - <div class="td cbi-value-field" style="width:80px"> - <input class="cbi-button cbi-button-up" type="button" value="" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&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%>&dir=down'" alt="<%:Move down%>" title="<%:Move down%>"/> - </div> - <div class="td cbi-value-field" style="width:150px"> + <div class="td cbi-section-actions"> + <input class="cbi-button cbi-button-up" type="button" value="<%:Up%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&dir=up'" alt="<%:Move up%>" title="<%:Move up%>"/> + <input class="cbi-button cbi-button-down" type="button" value="<%:Down%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&dir=down'" alt="<%:Move down%>" title="<%:Move down%>"/> <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%>"/> </div> @@ -59,7 +59,7 @@ This is free software, licensed under the Apache License, Version 2.0 end) %> </div> -</fieldset> +</div> <div class="cbi-page-actions right"> <% 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"> <input type="hidden" name="device" value="<%=device%>"/> <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> <% end) diff --git a/applications/luci-app-travelmate/luasrc/view/travelmate/wifi_scan.htm b/applications/luci-app-travelmate/luasrc/view/travelmate/wifi_scan.htm index 81182b99b4..57efd97376 100644 --- a/applications/luci-app-travelmate/luasrc/view/travelmate/wifi_scan.htm +++ b/applications/luci-app-travelmate/luasrc/view/travelmate/wifi_scan.htm @@ -39,31 +39,33 @@ This is free software, licensed under the Apache License, Version 2.0 <%+header%> +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> + <div class="cbi-map"> <h2 name="content"><%:Wireless Scan%></h2> - <fieldset class="cbi-section"> - <div class="table cbi-section-table" style="empty-cells:hide"> + <div class="cbi-section"> + <div class="table cbi-section-table"> <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell" style="text-align:left"><%:Uplink SSID%></div> - <div class="th cbi-section-table-cell" style="text-align:left"><%:Uplink BSSID%></div> - <div class="th cbi-section-table-cell" style="text-align:left"><%:Encryption%></div> - <div class="th cbi-section-table-cell" style="text-align:left" colspan="2"><%:Signal strength%></div> + <div class="th left"><%:Uplink SSID%></div> + <div class="th left"><%:Uplink BSSID%></div> + <div class="th left"><%:Encryption%></div> + <div class="th left"><%:Signal strength%></div> </div> <% for i, net in ipairs(iw.scanlist or { }) do %> <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")%> </div> - <div class="td cbi-value-field" style="text-align:left"> + <div class="td left"> <%=net.bssid and utl.pcdata(net.bssid)%> </div> - <div class="td cbi-value-field" style="text-align:left"> + <div class="td left"> <%=format_wifi_encryption(net.encryption)%> </div> - <div class="td cbi-value-field" style="text-align:left"> + <div class="td left"> <%=percent_wifi_signal(net)%> % </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"> <input type="hidden" name="token" value="<%=token%>"/> <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> <% end %> </div> - </fieldset> + </div> <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"> <input type="hidden" name="token" value="<%=token%>"/> <input type="hidden" name="device" value="<%=utl.pcdata(dev)%>"/> <input class="cbi-button cbi-input-find" type="submit" value="<%:Repeat scan%>"/> </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> diff --git a/applications/luci-app-upnp/luasrc/view/upnp_status.htm b/applications/luci-app-upnp/luasrc/view/upnp_status.htm index 1e09225793..459c63c1d7 100644 --- a/applications/luci-app-upnp/luasrc/view/upnp_status.htm +++ b/applications/luci-app-upnp/luasrc/view/upnp_status.htm @@ -16,40 +16,39 @@ var tb = document.getElementById('upnp_status_table'); if (st && tb) { - /* clear all rows */ - while (tb.firstElementChild !== tb.lastElementChild) - tb.removeChild(tb.lastElementChild); + var rows = []; 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), [ - E('<div class="td">', st[i].proto), - E('<div class="td">', st[i].extport), - E('<div class="td">', st[i].intaddr), - E('<div class="td">', st[i].intport), - E('<div class="td">', st[i].descr), - E('<input class="cbi-button cbi-input-remove" type="button" value="<%:Delete%>" onclick="upnp_delete_fwd(%d)" />'.format(st[i].num)) - ])); + rows.push([ + st[i].proto, + st[i].extport, + st[i].intaddr, + st[i].intport, + st[i].descr, + 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) - tb.appendChild(E('<div class="tr cbi-section-table-row"><div class="td"><em><br /><%:There are no active redirects.%></em></div></div>')); + cbi_update_table(tb, rows, '<em><%:There are no active redirects.%></em>'); } } ); //]]></script> -<fieldset class="cbi-section"> +<div class="cbi-section"> <legend><%:Active UPnP Redirects%></legend> - <div class="table cbi-section-table" id="upnp_status_table"> - <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell"><%:Protocol%></div> - <div class="th cbi-section-table-cell"><%:External Port%></div> - <div class="th cbi-section-table-cell"><%:Client Address%></div> - <div class="th cbi-section-table-cell"><%:Client Port%></div> - <div class="th cbi-section-table-cell"><%:Description%></div> - <div class="th cbi-section-table-cell"> </div> - </div> - <div class="tr cbi-section-table-row"> - <div class="td" colspan="5"><em><br /><%:Collecting data...%></em></div> + <div class="cbi-section-node"> + <div class="table" id="upnp_status_table"> + <div class="tr table-titles"> + <div class="th"><%:Protocol%></div> + <div class="th"><%:External Port%></div> + <div class="th"><%:Client Address%></div> + <div class="th"><%:Client Port%></div> + <div class="th"><%:Description%></div> + <div class="th cbi-section-actions"> </div> + </div> + <div class="tr"> + <div class="td" colspan="5"><em><%:Collecting data...%></em></div> + </div> </div> </div> -</fieldset> +</div> diff --git a/modules/luci-base/htdocs/luci-static/resources/cbi.js b/modules/luci-base/htdocs/luci-static/resources/cbi.js index a7f999d876..6a487366f8 100644 --- a/modules/luci-base/htdocs/luci-static/resources/cbi.js +++ b/modules/luci-base/htdocs/luci-static/resources/cbi.js @@ -620,7 +620,11 @@ function cbi_init() { } 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(); @@ -1232,14 +1236,13 @@ function cbi_validate_field(cbid, optional, type) function cbi_row_swap(elem, up, store) { - var tr = elem.parentNode; - - while (tr && !tr.classList.contains('cbi-section-table-row')) - tr = tr.parentNode; + var tr = findParent(elem.parentNode, '.cbi-section-table-row'); if (!tr) return false; + tr.classList.remove('flash'); + if (up) { var prev = tr.previousElementSibling; @@ -1277,6 +1280,9 @@ function cbi_row_swap(elem, up, store) if (input) input.value = ids.join(' '); + window.scrollTo(0, tr.offsetTop); + window.setTimeout(function() { tr.classList.add('flash'); }, 1); + return false; } @@ -1522,6 +1528,19 @@ function toElem(s) 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() { var html = arguments[0], @@ -1541,7 +1560,7 @@ function E() if (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]); if (typeof(data) === 'function') @@ -1818,18 +1837,6 @@ CBIDropdown = { document.querySelectorAll('.cbi-dropdown[open]').forEach(function(s) { 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); } else { - var li = sbox.findParent(ev.target, 'li'); + var li = findParent(ev.target, 'li'); if (li && li.parentNode.classList.contains('dropdown')) sbox.toggleItem(this, li); } @@ -1933,7 +1940,7 @@ function cbi_dropdown_init(sb) { } else { - var active = sbox.findParent(document.activeElement, 'li'); + var active = findParent(document.activeElement, 'li'); switch (ev.keyCode) { case 27: @@ -1986,7 +1993,7 @@ function cbi_dropdown_init(sb) { if (!this.hasAttribute('open')) return; - var li = sbox.findParent(ev.target, 'li'); + var li = findParent(ev.target, 'li'); if (li) { if (li.parentNode.classList.contains('dropdown')) sbox.setFocus(this, li); @@ -2023,18 +2030,18 @@ function cbi_dropdown_init(sb) { }); 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; sb.setAttribute('locked-in', ''); }); 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; sb.removeAttribute('locked-in'); }); - var li = sbox.findParent(create, 'li'); + var li = findParent(create, 'li'); li.setAttribute('unselectable', ''); li.addEventListener('click', function(ev) { @@ -2044,3 +2051,77 @@ function cbi_dropdown_init(sb) { } 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); +}); diff --git a/modules/luci-base/luasrc/tools/status.lua b/modules/luci-base/luasrc/tools/status.lua index 06a9ad4154..0059ccceb0 100644 --- a/modules/luci-base/luasrc/tools/status.lua +++ b/modules/luci-base/luasrc/tools/status.lua @@ -113,6 +113,11 @@ function wifi_networks() local net for _, net in ipairs(dev:get_wifinets()) do + local a, an = nil, 0 + for _, a in pairs(net:assoclist() or {}) do + an = an + 1 + end + rd.networks[#rd.networks+1] = { name = net:shortname(), link = net:adminlink(), @@ -128,10 +133,10 @@ function wifi_networks() noise = net:noise(), bitrate = net:bitrate(), ifname = net:ifname(), - assoclist = net:assoclist(), country = net:country(), txpower = net:txpower(), txpoweroff = net:txpower_offset(), + num_assoc = an, disabled = (dev:get("disabled") == "1" or net:get("disabled") == "1") } @@ -165,7 +170,6 @@ function wifi_network(id) noise = net:noise(), bitrate = net:bitrate(), ifname = net:ifname(), - assoclist = net:assoclist(), country = net:country(), txpower = net:txpower(), txpoweroff = net:txpower_offset(), @@ -182,6 +186,52 @@ function wifi_network(id) return { } end +function wifi_assoclist() + local sys = require "luci.sys" + local ntm = require "luci.model.network".init() + local hosts = sys.net.host_hints() + + local assoc = {} + local _, dev, net, bss + + for _, dev in ipairs(ntm:get_wifidevs()) do + local radioname = dev:get_i18n() + + for _, net in ipairs(dev:get_wifinets()) do + local netname = net:shortname() + local netlink = net:adminlink() + local ifname = net:ifname() + + for _, bss in pairs(net:assoclist() or {}) do + local host = hosts[_] + + bss.bssid = _ + bss.ifname = ifname + bss.radio = radioname + bss.name = netname + bss.link = netlink + + bss.host_name = (host) and (host.name or host.ipv4 or host.ipv6) + bss.host_hint = (host and host.name and (host.ipv4 or host.ipv6)) and (host.ipv4 or host.ipv6) + + assoc[#assoc+1] = bss + end + end + end + + table.sort(assoc, function(a, b) + if a.radio ~= b.radio then + return a.radio < b.radio + elseif a.ifname ~= b.ifname then + return a.ifname < b.ifname + else + return a.bssid < b.bssid + end + end) + + return assoc +end + function switch_status(devs) local dev local switches = { } diff --git a/modules/luci-base/luasrc/view/cbi/apply_widget.htm b/modules/luci-base/luasrc/view/cbi/apply_widget.htm index 702512f495..e3090da656 100644 --- a/modules/luci-base/luasrc/view/cbi/apply_widget.htm +++ b/modules/luci-base/luasrc/view/cbi/apply_widget.htm @@ -47,7 +47,7 @@ } </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[ var xhr = new XHR(), uci_apply_auth = { sid: '<%=luci.dispatcher.context.authsession%>', token: '<%=token%>' }, diff --git a/modules/luci-base/luasrc/view/cbi/button.htm b/modules/luci-base/luasrc/view/cbi/button.htm index 30f8ddfda5..6ccba58f23 100644 --- a/modules/luci-base/luasrc/view/cbi/button.htm +++ b/modules/luci-base/luasrc/view/cbi/button.htm @@ -1,6 +1,6 @@ <%+cbi/valueheader%> <% 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 %> - <% end %> diff --git a/modules/luci-base/luasrc/view/cbi/cell_valueheader.htm b/modules/luci-base/luasrc/view/cbi/cell_valueheader.htm index a4b68cda72..dbb0e1120b 100644 --- a/modules/luci-base/luasrc/view/cbi/cell_valueheader.htm +++ b/modules/luci-base/luasrc/view/cbi/cell_valueheader.htm @@ -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))%>"> diff --git a/modules/luci-base/luasrc/view/cbi/dropdown.htm b/modules/luci-base/luasrc/view/cbi/dropdown.htm index bdf7248375..cf8c03d22c 100644 --- a/modules/luci-base/luasrc/view/cbi/dropdown.htm +++ b/modules/luci-base/luasrc/view/cbi/dropdown.htm @@ -36,6 +36,18 @@ <%=pcdata(self.vallist[i])%> </li> <% 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> </div> diff --git a/modules/luci-base/luasrc/view/cbi/firewall_zoneforwards.htm b/modules/luci-base/luasrc/view/cbi/firewall_zoneforwards.htm index 546fd8e85a..b38e4b13db 100644 --- a/modules/luci-base/luasrc/view/cbi/firewall_zoneforwards.htm +++ b/modules/luci-base/luasrc/view/cbi/firewall_zoneforwards.htm @@ -14,46 +14,59 @@ local def = fwm:get_defaults() local zone = fwm:get_zone(value) 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()%>:  + <% + 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 %> -<div style="white-space:nowrap"> - <label class="zonebadge" style="background-color:<%=zone:get_color()%>"> - <strong><%=zone:name()%>:</strong> - <%- - 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()%>: - <% - 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())%> 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> -  ⇒  - <% 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>  - <% end end %> - <% if empty then %> +<div class="zone-forwards"> + <div class="zone-src"> + <%=render_zone(zone)%> + </div> + <span>⇒</span> + <div class="zone-dest"> + <% + for _, fwd in ipairs(zone:get_forwardings_by("src")) do + fz = fwd:dest_zone() + if fz then + empty = false + render_zone(fz) + end + end + if empty then + %> <label class="zonebadge zonebadge-empty"> <strong><%=zone:forward():upper()%></strong> </label> <% end %> + </div> </div> <% end %> diff --git a/modules/luci-base/luasrc/view/cbi/footer.htm b/modules/luci-base/luasrc/view/cbi/footer.htm index e6acfb0697..5f939b6469 100644 --- a/modules/luci-base/luasrc/view/cbi/footer.htm +++ b/modules/luci-base/luasrc/view/cbi/footer.htm @@ -1,9 +1,7 @@ <%- if pageaction then -%> <div class="cbi-page-actions"> <% 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)%>'" /> - </div> <% end %> <% if flow.skip then %> diff --git a/modules/luci-base/luasrc/view/cbi/full_valuefooter.htm b/modules/luci-base/luasrc/view/cbi/full_valuefooter.htm index f780936766..d4ad093efa 100644 --- a/modules/luci-base/luasrc/view/cbi/full_valuefooter.htm +++ b/modules/luci-base/luasrc/view/cbi/full_valuefooter.htm @@ -3,7 +3,6 @@ <br /> <%- end %> <div class="cbi-value-description"> - <span class="cbi-value-helpicon"><img src="<%=resource%>/cbi/help.gif" alt="<%:help%>" /></span> <%=self.description%> </div> <%- end %> diff --git a/modules/luci-base/luasrc/view/cbi/map.htm b/modules/luci-base/luasrc/view/cbi/map.htm index 02b47f5455..83c3cb2170 100644 --- a/modules/luci-base/luasrc/view/cbi/map.htm +++ b/modules/luci-base/luasrc/view/cbi/map.htm @@ -31,7 +31,6 @@ </li> <% end %> </ul> - <br /> <% for i, section in ipairs(self.children) do %> <div class="cbi-tabcontainer" id="container.m-<%=self.config%>.<%=section.section or section.sectiontype%>"<% if section.sectiontype ~= self.selected_tab then %> style="display:none"<% end %>> <% section:render() %> @@ -53,6 +52,4 @@ <% else %> <%- self:render_children() %> <% end %> - - <br /> </div> diff --git a/modules/luci-base/luasrc/view/cbi/nsection.htm b/modules/luci-base/luasrc/view/cbi/nsection.htm index abf67596f0..63abc57734 100644 --- a/modules/luci-base/luasrc/view/cbi/nsection.htm +++ b/modules/luci-base/luasrc/view/cbi/nsection.htm @@ -1,5 +1,5 @@ <% 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 -%> <legend><%=self.title%></legend> <%- end %> @@ -15,17 +15,16 @@ <div class="cbi-section-node<% if self.tabs then %> cbi-section-node-tabbed<% end %>" id="cbi-<%=self.config%>-<%=section%>"> <%+cbi/ucisection%> </div> - <br /> - </fieldset> + </div> <% elseif self.addremove then %> <% 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 -%> <legend><%=self.title%></legend> <%- end %> <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%>" /> - </fieldset> + </div> <%- end %> <% end %> <!-- /nsection --> diff --git a/modules/luci-base/luasrc/view/cbi/nullsection.htm b/modules/luci-base/luasrc/view/cbi/nullsection.htm index ef169593af..7230719d19 100644 --- a/modules/luci-base/luasrc/view/cbi/nullsection.htm +++ b/modules/luci-base/luasrc/view/cbi/nullsection.htm @@ -1,4 +1,4 @@ -<fieldset class="cbi-section"> +<div class="cbi-section"> <% if self.title and #self.title > 0 then -%> <legend><%=self.title%></legend> <%- end %> @@ -25,8 +25,7 @@ </div> <%- end %> </div> - <br /> -</fieldset> +</div> <%- if type(self.hidden) == "table" then for k, v in pairs(self.hidden) do diff --git a/modules/luci-base/luasrc/view/cbi/simpleform.htm b/modules/luci-base/luasrc/view/cbi/simpleform.htm index 3b758d70ee..c6000d22b3 100644 --- a/modules/luci-base/luasrc/view/cbi/simpleform.htm +++ b/modules/luci-base/luasrc/view/cbi/simpleform.htm @@ -10,7 +10,6 @@ <% if self.title and #self.title > 0 then %><h2 name="content"><%=self.title%></h2><% end %> <% if self.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %> <% self:render_children() %> - <br /> </div> <%- if self.message then %> <div><%=self.message%></div> @@ -30,9 +29,12 @@ end %> <% 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)%>'" /> - </div> + <input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" /> +<% end %> +<%- if self.cancel ~= false and self.on_cancel then %> + <input class="cbi-button cbi-button-link" type="submit" name="cbi.cancel" value=" + <%- if not self.cancel then -%><%-:Cancel-%><%-else-%><%=self.cancel%><%end-%> + " /> <% end %> <%- if self.flow and self.flow.skip then %> <input class="cbi-button cbi-button-skip" type="submit" name="cbi.skip" value="<%:Skip%>" /> @@ -47,11 +49,6 @@ <%- 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 %> </div> </form> <% end %> diff --git a/modules/luci-base/luasrc/view/cbi/tblsection.htm b/modules/luci-base/luasrc/view/cbi/tblsection.htm index bb11cf1c06..ab13922040 100644 --- a/modules/luci-base/luasrc/view/cbi/tblsection.htm +++ b/modules/luci-base/luasrc/view/cbi/tblsection.htm @@ -14,10 +14,14 @@ function width(o) end return '' end + +local anonclass = (not self.anonymous or self.sectiontitle) and "named" or "anonymous" +local titlename = ifattr(not self.anonymous or self.sectiontitle, "data-title", translate("Name")) + -%> <!-- 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 -%> <legend><%=self.title%></legend> <%- end %> @@ -25,121 +29,107 @@ end <input type="hidden" id="cbi.sts.<%=self.config%>.<%=self.sectiontype%>" name="cbi.sts.<%=self.config%>.<%=self.sectiontype%>" value="" /> <%- end -%> <div class="cbi-section-descr"><%=self.description%></div> - <div class="cbi-section-node"> - <%- local count = 0 -%> - <div class="table cbi-section-table"> - <div class="tr cbi-section-table-titles"> - <%- if not self.anonymous then -%> - <%- if self.sectionhead then -%> - <div class="th cbi-section-table-cell"><%=self.sectionhead%></div> - <%- else -%> - <div class="th"> </div> - <%- end -%> - <%- count = count +1; 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"> </div> - <%- count = count + 1; end -%> - </div> - <div class="tr cbi-section-table-descr"> - <%- if not self.anonymous then -%> - <%- if self.sectiondesc then -%> - <div class="th cbi-section-table-cell"><%=self.sectiondesc%></div> - <%- else -%> - <div class="th"></div> - <%- end -%> - <%- end -%> - <%- for i, k in pairs(self.children) do if not k.optional then -%> - <div class="th cbi-section-table-cell"<%=width(k)%>><%=k.description%></div> - <%- end; end; if self.sortable then -%> - <div class="th cbi-section-table-cell"></div> - <%- end; if self.extedit or self.addremove then -%> - <div class="th cbi-section-table-cell"></div> - <%- end -%> + <%- local count = 0 -%> + <div class="table cbi-section-table"> + <div class="tr cbi-section-table-titles <%=anonclass%>"<%=titlename%>> + <%- for i, k in pairs(self.children) do if not k.optional then -%> + <div class="th cbi-section-table-cell"<%= + width(k) .. + attr("data-type", k.template and k.template:gsub("^.+/", "") or "") + %>> + <%- if k.titleref then -%><a title="<%=self.titledesc or translate('Go to relevant configuration page')%>" class="cbi-title-ref" href="<%=k.titleref%>"><%- end -%> + <%-=k.title-%> + <%- if k.titleref then -%></a><%- end -%> </div> - <%- local isempty = true - for i, k in ipairs(self:cfgsections()) do - section = k - isempty = false - scope = { 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> - <%- end %> - + <%- count = count + 1; end; end; if self.sortable or self.extedit or self.addremove then -%> + <div class="th cbi-section-table-cell cbi-section-actions"></div> + <%- count = count + 1; end -%> + </div> + <div class="tr cbi-section-table-descr <%=anonclass%>"> + <%- for i, k in pairs(self.children) do if not k.optional then -%> + <div class="th cbi-section-table-cell"<%= + width(k) .. + attr("data-type", k.template and k.template:gsub("^.+/", "") or "") + %>><%=k.description%></div> + <%- end; end; if self.sortable or self.extedit or self.addremove then -%> + <div class="th cbi-section-table-cell cbi-section-actions"></div> + <%- end -%> + </div> + <%- local isempty, i, k = true, nil, nil + for i, k in ipairs(self:cfgsections()) do + isempty = false - <%- - for k, node in ipairs(self.children) do - if not node.optional then - node:render(section, scope or {}) - end + local section = k + local sectionname = striptags((type(self.sectiontitle) == "function") and self:sectiontitle(section) or k) + local sectiontitle = ifattr(sectionname and (not self.anonymous or self.sectiontitle), "data-title", sectionname) + local colorclass = (self.extedit or self.rowcolors) and " cbi-rowstyle-%d" % rowstyle() or "" + local scope = { + valueheader = "cbi/cell_valueheader", + valuefooter = "cbi/cell_valuefooter" + } + -%> + <div class="tr cbi-section-table-row<%=colorclass%>" id="cbi-<%=self.config%>-<%=section%>"<%=sectiontitle%>> + <%- + local node + for k, node in ipairs(self.children) do + if not node.optional then + node:render(section, scope or {}) end - -%> - - <%- if self.sortable then -%> - <div class="td cbi-section-table-cell"> - <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%>" /> - <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%>" /> - </div> - <%- end -%> - - <%- if self.extedit or self.addremove then -%> - <div class="td cbi-section-table-cell"> - <%- if self.extedit then -%> - <input class="cbi-button cbi-button-edit" type="button" value="<%:Edit%>" - <%- if type(self.extedit) == "string" then - %> onclick="location.href='<%=self.extedit:format(section)%>'" - <%- elseif type(self.extedit) == "function" then - %> onclick="location.href='<%=self:extedit(section)%>'" - <%- end - %> alt="<%:Edit%>" title="<%:Edit%>" /> - <%- end; if self.addremove then %> - <input class="cbi-button cbi-button-remove" type="submit" value="<%:Delete%>" onclick="this.form.cbi_state='del-section'; return true" name="cbi.rts.<%=self.config%>.<%=k%>" alt="<%:Delete%>" title="<%:Delete%>" /> - <%- end -%> - </div> - <%- end -%> - </div> - <%- end -%> + 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> + <%- if self.sortable or self.extedit or self.addremove then -%> + <div class="td cbi-section-table-cell nowrap cbi-section-actions"> + <%- if self.sortable then -%> + <input class="cbi-button cbi-button-up" type="button" value="<%:Up%>" onclick="return cbi_row_swap(this, true, 'cbi.sts.<%=self.config%>.<%=self.sectiontype%>')" title="<%:Move up%>" /> + <input class="cbi-button cbi-button-down" type="button" value="<%:Down%>" onclick="return cbi_row_swap(this, false, 'cbi.sts.<%=self.config%>.<%=self.sectiontype%>')" title="<%:Move down%>" /> + <% end; if self.extedit then -%> + <input class="cbi-button cbi-button-edit" type="button" value="<%:Edit%>" + <%- if type(self.extedit) == "string" then + %> onclick="location.href='<%=self.extedit:format(section)%>'" + <%- elseif type(self.extedit) == "function" then + %> onclick="location.href='<%=self:extedit(section)%>'" + <%- end + %> alt="<%:Edit%>" title="<%:Edit%>" /> + <% end; if self.addremove then %> + <input class="cbi-button cbi-button-remove" type="submit" value="<%:Delete%>" onclick="this.form.cbi_state='del-section'; return true" name="cbi.rts.<%=self.config%>.<%=k%>" alt="<%:Delete%>" title="<%:Delete%>" /> + <%- end -%> + </div> <%- end -%> </div> + <%- end -%> - <% 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"><% 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 %> + <%- if isempty then -%> + <div class="tr cbi-section-table-row placeholder"> + <div class="td"><em><%:This section contains no values yet%></em></div> + </div> <%- end -%> </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 --> diff --git a/modules/luci-base/luasrc/view/cbi/tsection.htm b/modules/luci-base/luasrc/view/cbi/tsection.htm index 726521ae3f..1a13df0c04 100644 --- a/modules/luci-base/luasrc/view/cbi/tsection.htm +++ b/modules/luci-base/luasrc/view/cbi/tsection.htm @@ -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 -%> <legend><%=self.title%></legend> <%- end %> @@ -20,10 +20,9 @@ <%+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%> - </fieldset> - <br /> + </div> <%- end %> <% if isempty then -%> @@ -36,14 +35,15 @@ <% if self.anonymous then -%> <input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%: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 type="submit" class="cbi-button cbi-button-add" onclick="this.form.cbi_state='add-section'; return true" value="<%:Add%>" /> <% if self.invalid_cts then -%> - <br /><%:Invalid%></div> + <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 %> -</fieldset> +</div> diff --git a/modules/luci-base/luasrc/view/cbi/upload.htm b/modules/luci-base/luasrc/view/cbi/upload.htm index 4fb5201aac..3c3d82b653 100644 --- a/modules/luci-base/luasrc/view/cbi/upload.htm +++ b/modules/luci-base/luasrc/view/cbi/upload.htm @@ -8,7 +8,7 @@ <%:Uploaded File%> (<%=t.byte_format(s.size)%>) <% if self.unsafeupload then %> <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 %> diff --git a/modules/luci-base/luasrc/view/sysauth.htm b/modules/luci-base/luasrc/view/sysauth.htm index e7a741aaab..9b0e2de780 100644 --- a/modules/luci-base/luasrc/view/sysauth.htm +++ b/modules/luci-base/luasrc/view/sysauth.htm @@ -18,23 +18,23 @@ <div class="cbi-map-descr"> <%:Please enter your username and password.%> </div> - <fieldset class="cbi-section"><fieldset class="cbi-section-node"> + <div class="cbi-section"><div class="cbi-section-node"> <div class="cbi-value"> <label class="cbi-value-title"><%:Username%></label> <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 class="cbi-value cbi-value-last"> <label class="cbi-value-title"><%:Password%></label> <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> - </fieldset></fieldset> + </div></div> </div> - <div> + <div class="cbi-page-actions"> <input type="submit" value="<%:Login%>" class="cbi-button cbi-button-apply" /> <input type="reset" value="<%:Reset%>" class="cbi-button cbi-button-reset" /> </div> diff --git a/modules/luci-mod-admin-full/luasrc/controller/admin/system.lua b/modules/luci-mod-admin-full/luasrc/controller/admin/system.lua index 6fcd66f441..0c19893cf8 100644 --- a/modules/luci-mod-admin-full/luasrc/controller/admin/system.lua +++ b/modules/luci-mod-admin-full/luasrc/controller/admin/system.lua @@ -74,7 +74,7 @@ function action_packages() local out, err -- Display - local display = luci.http.formvalue("display") or "installed" + local display = luci.http.formvalue("display") or "available" -- Letter local letter = string.byte(luci.http.formvalue("letter") or "A", 1) diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_network/diagnostics.htm b/modules/luci-mod-admin-full/luasrc/view/admin_network/diagnostics.htm index f4adb26069..5607e59dfb 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_network/diagnostics.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_network/diagnostics.htm @@ -61,55 +61,54 @@ local route_host = luci.config.diag and luci.config.diag.route or "dev.openwrt.o <div class="cbi-map"> <h2 name="content"><%:Diagnostics%></h2> - <fieldset class="cbi-section"> + <div class="cbi-section"> <legend><%:Network Utilities%></legend> - <br /> - - <div style="width:30%; float: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 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 class="td 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> </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 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> </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"> - <legend id="diag-rc-legend"><%:Collecting data...%></legend> + <div class="cbi-section" style="display:none"> + <strong id="diag-rc-legend"></strong> <span id="diag-rc-output"></span> - </fieldset> + </div> </form> <%+footer%> diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_network/iface_overview.htm b/modules/luci-mod-admin-full/luasrc/view/admin_network/iface_overview.htm index 420e5879fa..473e2275ce 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_network/iface_overview.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_network/iface_overview.htm @@ -67,7 +67,7 @@ } 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; (new XHR()).post('<%=url('admin/network/iface_delete')%>/' + id, { token: '<%=token%>' }, @@ -141,8 +141,8 @@ } html += String.format( - '<strong><%:RX%></strong>: %.2mB (%d <%:Pkts.%>)<br />' + - '<strong><%:TX%></strong>: %.2mB (%d <%:Pkts.%>)<br />', + '<strong><%:RX%>:</strong> %.2mB (%d <%:Pkts.%>)<br />' + + '<strong><%:TX%>:</strong> %.2mB (%d <%:Pkts.%>)<br />', ifc.rx_bytes, ifc.rx_packets, ifc.tx_bytes, ifc.tx_packets ); @@ -209,46 +209,43 @@ </fieldset> <div class="cbi-map"> - <fieldset class="cbi-section"> + <div class="cbi-section"> <legend><%:Interface Overview%></legend> - <div class="table cbi-section-table" style="margin:10px; empty-cells:hide"> - <div class="tr cbi-section-table-titles"> - <div class="th"><%:Network%></div> - <div class="th left"><%:Status%></div> - <div class="th"><%:Actions%></div> - </div> - <% - for i, net in ipairs(netlist) do - local z = net[3] - 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") - %> - <div class="tr cbi-section-table-row cbi-rowstyle-<%=i % 2 + 1%>"> - <div class="td"> - <div class="ifacebox"> - <div class="ifacebox-head" style="background-color:<%=c%>" title="<%=pcdata(t)%>"> - <strong><%=net[1]:upper()%></strong> - </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 class="cbi-section-node"> + <div class="table"> + <% + for i, net in ipairs(netlist) do + local z = net[3] + 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") + %> + <div class="tr cbi-rowstyle-<%=i % 2 + 1%>"> + <div class="td col-3 center middle"> + <div class="ifacebox"> + <div class="ifacebox-head" style="background-color:<%=c%>" title="<%=pcdata(t)%>"> + <strong><%=net[1]:upper()%></strong> + </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 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 class="td left" id="<%=net[1]%>-ifc-description"> - <em><%:Collecting data...%></em> - </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 %> + <% end %> + </div> </div> <input type="button" class="cbi-button cbi-button-add" value="<%:Add new interface...%>" onclick="location.href='<%=url("admin/network/iface_add")%>'" /> - </fieldset> + </div> </div> diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_network/iface_status.htm b/modules/luci-mod-admin-full/luasrc/view/admin_network/iface_status.htm index 58f5400da7..9c5173dae2 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_network/iface_status.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_network/iface_status.htm @@ -6,29 +6,18 @@ { 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 (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.ifname) { if (ifc.is_up) - { html += String.format('<strong><%:Uptime%>:</strong> %t<br />', ifc.uptime); - } if (ifc.macaddr) - { html += String.format('<strong><%:MAC-Address%>:</strong> %s<br />', ifc.macaddr); - } html += String.format( '<strong><%:RX%></strong>: %.2mB (%d <%:Pkts.%>)<br />' + @@ -38,50 +27,40 @@ ); if (ifc.ipaddrs && ifc.ipaddrs.length) - { for (var i = 0; i < ifc.ipaddrs.length; i++) html += String.format( '<strong><%:IPv4%>:</strong> %s<br />', ifc.ipaddrs[i] ); - } if (ifc.ip6addrs && ifc.ip6addrs.length) - { for (var i = 0; i < ifc.ip6addrs.length; i++) html += String.format( '<strong><%:IPv6%>:</strong> %s<br />', ifc.ip6addrs[i] ); - } - + if (ifc.ip6prefix) - { html += String.format('<strong><%:IPv6-PD%>:</strong> %s<br />', ifc.ip6prefix); - } - d.innerHTML = html; + 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> -<div class="table"> - <div class="tr cbi-section-table"> - <div class="td"></div> - <div class="td cbi-value-field" style="min-width:16px; padding:3px; text-align:center" id="<%=self.option%>-ifc-signal"> - <img src="<%=resource%>/icons/ethernet_disabled.png" style="width:16px; height:16px" /><br /> - <small>?</small> - </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> +<span class="ifacebadge large" id="<%=self.option%>-ifc-status"> + <img src="<%=resource%>/icons/ethernet_disabled.png" /> + <span> + <em><%:Collecting data...%></em> + </span> +</span> <%+cbi/valuefooter%> diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_network/lease_status.htm b/modules/luci-mod-admin-full/luasrc/view/admin_network/lease_status.htm index 9005279a4e..a1b2c8454d 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_network/lease_status.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_network/lease_status.htm @@ -34,7 +34,7 @@ else 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].ipaddr), E('<div class="td">', st[0][i].macaddr), @@ -43,7 +43,7 @@ } 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'); @@ -79,8 +79,8 @@ 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), [ - 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 || '?')), + tb6.appendChild(E('<div class="tr cbi-rowstyle-%d">'.format((i % 2) + 1), [ + 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].duid), E('<div class="td">', timestr) @@ -88,7 +88,7 @@ } 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"> <legend><%:Active DHCP Leases%></legend> - <div class="table cbi-section-table" id="lease_status_table"> - <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell"><%:Hostname%></div> - <div class="th cbi-section-table-cell"><%:IPv4-Address%></div> - <div class="th cbi-section-table-cell"><%:MAC-Address%></div> - <div class="th cbi-section-table-cell"><%:Leasetime remaining%></div> + <div class="table" id="lease_status_table"> + <div class="tr"> + <div class="th"><%:Hostname%></div> + <div class="th"><%:IPv4-Address%></div> + <div class="th"><%:MAC-Address%></div> + <div class="th"><%:Leasetime remaining%></div> </div> - <div class="tr cbi-section-table-row"> + <div class="tr"> <div class="td" colspan="4"><em><br /><%:Collecting data...%></em></div> </div> </div> @@ -111,14 +111,14 @@ <fieldset class="cbi-section" style="display:none"> <legend><%:Active DHCPv6 Leases%></legend> - <div class="table cbi-section-table" id="lease6_status_table"> - <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell"><%:Host%></div> - <div class="th cbi-section-table-cell"><%:IPv6-Address%></div> - <div class="th cbi-section-table-cell"><%:DUID%></div> - <div class="th cbi-section-table-cell"><%:Leasetime remaining%></div> + <div class="table" id="lease6_status_table"> + <div class="tr"> + <div class="th"><%:Host%></div> + <div class="th"><%:IPv6-Address%></div> + <div class="th"><%:DUID%></div> + <div class="th"><%:Leasetime remaining%></div> </div> - <div class="tr cbi-section-table-row"> + <div class="tr"> <div class="td" colspan="4"><em><br /><%:Collecting data...%></em></div> </div> </div> diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_network/switch_status.htm b/modules/luci-mod-admin-full/luasrc/view/admin_network/switch_status.htm index 96fbffdb02..d3d07bead9 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_network/switch_status.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_network/switch_status.htm @@ -1,21 +1,39 @@ <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, function(x, st) { for (var i = 0; i < switches.length; 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++) { - var th = document.getElementById('portstatus-' + switches[i] + '-' + j); + var th = tr.childNodes[j+1]; if (!th) continue; diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_assoclist.htm b/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_assoclist.htm new file mode 100644 index 0000000000..f3e2313ee6 --- /dev/null +++ b/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_assoclist.htm @@ -0,0 +1,84 @@ +<script type="text/javascript">//<![CDATA[ + function wifirate(bss, rx) { + var p = rx ? 'rx_' : 'tx_', + s = '%.1f <%:Mbit/s%>, %d<%:MHz%>' + .format(bss[p+'rate'] / 1000, bss[p+'mhz']), + ht = bss[p+'ht'], vht = bss[p+'vht'], + mhz = bss[p+'mhz'], nss = bss[p+'nss'], + mcs = bss[p+'mcs'], sgi = bss[p+'short_gi']; + + if (ht || vht) { + if (vht) s += ', VHT-MCS %d'.format(mcs); + if (nss) s += ', VHT-NSS %d'.format(nss); + if (ht) s += ', MCS %s'.format(mcs); + if (sgi) s += ', <%:Short GI%>'; + } + + return s; + } + + XHR.poll(5, '<%=url('admin/network/wireless_assoclist')%>', null, + function(x, st) + { + var tb = document.getElementById('wifi_assoclist_table'); + if (st && tb) + { + var rows = []; + + st.forEach(function(bss) { + var icon; + var q = (-1 * (bss.noise - bss.signal)) / 5; + if (q < 1) + icon = "<%=resource%>/icons/signal-0.png"; + else if (q < 2) + icon = "<%=resource%>/icons/signal-0-25.png"; + else if (q < 3) + icon = "<%=resource%>/icons/signal-25-50.png"; + else if (q < 4) + icon = "<%=resource%>/icons/signal-50-75.png"; + else + icon = "<%=resource%>/icons/signal-75-100.png"; + + rows.push([ + '<span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> <a href="%s">%h</a><small> (%h)</small></span>'.format( + bss.radio, + bss.link, + bss.name, + bss.ifname), + bss.bssid, + bss.host_hint ? '%h (%h)'.format(bss.host_name || '?', bss.host_hint) : (bss.host_name || '?'), + '<span class="ifacebadge" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%> / <%:SNR%>: %d"><img src="%s" /> %d / %d <%:dBm%></span>'.format( + bss.signal, + bss.noise, + bss.signal - bss.noise, + icon, + bss.signal, + bss.noise), + E('span', {}, [ + E('span', wifirate(bss, true)), + E('br'), + E('span', wifirate(bss, false)) + ]) + ]); + }); + + cbi_update_table(tb, rows, '<em><%:No information available%></em>'); + } + } + ); +//]]></script> + +<div class="cbi-section-node"> + <div class="table" id="wifi_assoclist_table"> + <div class="tr table-titles"> + <div class="th nowrap"><%:Network%></div> + <div class="th hide-xs"><%:MAC-Address%></div> + <div class="th nowrap"><%:Host%></div> + <div class="th nowrap"><%:Signal%> / <%:Noise%></div> + <div class="th nowrap"><%:RX Rate%> / <%:TX Rate%></div> + </div> + <div class="tr placeholder"> + <div class="td"><em><%:Collecting data...%></em></div> + </div> + </div> +</div> diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_join.htm b/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_join.htm index e9cfb3e85b..9b93942c88 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_join.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_join.htm @@ -90,25 +90,43 @@ <h2 name="content"><%:Join Network: Wireless Scan%></h2> <div class="cbi-map"> - <fieldset class="cbi-section"> - <div class="table cbi-section-table" style="empty-cells:hide"> + <div class="cbi-section"> + <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"> </div> + </div> + <!-- scan list --> <% 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="td cbi-value-field" style="width:16px; padding:3px"> + <div class="tr cbi-rowstyle-<%=1 + ((i-1) % 2)%>"> + <div class="td col-1 center"> <abbr title="<%:Signal%>: <%=net.signal%> <%:dB%> / <%:Quality%>: <%=net.quality%>/<%=net.quality_max%>"> <img src="<%=guess_wifi_signal(net)%>" /><br /> <small><%=percent_wifi_signal(net)%>%</small> </abbr> </div> - <div class="td cbi-value-field" style="vertical-align:middle; text-align:left; padding:3px"> - <big><strong><%=net.ssid and utl.pcdata(net.ssid) or "<em>%s</em>" % translate("hidden")%></strong></big><br /> - <strong>Channel:</strong> <%=net.channel%> | - <strong>Mode:</strong> <%=net.mode%> | - <strong>BSSID:</strong> <%=net.bssid%> | - <strong>Encryption:</strong> <%=format_wifi_encryption(net.encryption)%> + <div class="td col-5 left" data-title="<%:SSID%>"> + <strong><%=net.ssid and utl.pcdata(net.ssid) or "<em>%s</em>" % translate("hidden")%></strong> + </div> + <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-value-field" style="width:40px"> + <div class="td cbi-section-actions"> <form action="<%=url('admin/network/wireless_join')%>" method="post"> <input type="hidden" name="token" value="<%=token%>" /> <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 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> </div> </div> <% end %> <!-- /scan list --> </div> - </fieldset> + </div> </div> <div class="cbi-page-actions right"> <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 class="inline" action="<%=url('admin/network/wireless_join')%>" method="post"> <input type="hidden" name="token" value="<%=token%>" /> <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> </div> diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_overview.htm b/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_overview.htm index ceb810018b..b9602785f4 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_overview.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_overview.htm @@ -113,32 +113,10 @@ var is_reconnecting = false; - function nowrap(s) { - return s.replace(/ /g, ' '); - } - - function wifirate(bss, rx) { - var p = rx ? 'rx_' : 'tx_', - s = '%.1f <%:Mbit/s%>, %d<%:MHz%>' - .format(bss[p+'rate'] / 1000, bss[p+'mhz']), - ht = bss[p+'ht'], vht = bss[p+'vht'], - mhz = bss[p+'mhz'], nss = bss[p+'nss'], - mcs = bss[p+'mcs'], sgi = bss[p+'short_gi']; - - if (ht || vht) { - if (vht) s += ', VHT-MCS %d'.format(mcs); - if (nss) s += ', VHT-NSS %d'.format(nss); - if (ht) s += ', MCS %s'.format(mcs); - if (sgi) s += ', <%:Short GI%>'; - } - - return s; - } - function wifi_shutdown(id, toggle) { 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; is_reconnecting = true; @@ -193,20 +171,25 @@ { if (st) { - var assoctable = document.getElementById('iw-assoclist'); - if (assoctable) - while (assoctable.firstElementChild !== assoctable.lastElementChild) - assoctable.removeChild(assoctable.lastElementChild); - - var devup = { }; var rowstyle = 1; + var radiostate = { }; + + st.forEach(function(s) { + var r = radiostate[wifidevs[s.id]] || (radiostate[wifidevs[s.id]] = {}); + + s.is_assoc = (s.bssid && s.bssid != '00:00:00:00:00:00' && s.channel && s.mode != 'Unknown' && !s.disabled); + + r.up = r.up || s.is_assoc; + r.channel = r.channel || s.channel; + r.bitrate = r.bitrate || s.bitrate; + r.frequency = r.frequency || s.frequency; + }); for( var i = 0; i < st.length; i++ ) { var iw = st[i]; - var is_assoc = (iw.bssid && iw.bssid != '00:00:00:00:00:00' && iw.channel && iw.mode != 'Unknown' && !iw.disabled); var p = iw.quality; - var q = is_assoc ? p : -1; + var q = iw.is_assoc ? p : -1; var icon; if (q < 0) @@ -222,9 +205,6 @@ else icon = "<%=resource%>/icons/signal-75-100.png"; - if (!devup[wifidevs[iw.id]]) - devup[wifidevs[iw.id]] = is_assoc; - var sig = document.getElementById(iw.id + '-iw-signal'); if (sig) sig.innerHTML = String.format( @@ -237,13 +217,13 @@ { if (!iw.disabled) { - toggle.className = 'cbi-button cbi-button-reset'; + toggle.className = 'cbi-button cbi-button-neutral'; toggle.value = '<%:Disable%>'; toggle.title = '<%:Shutdown this network%>'; } else { - toggle.className = 'cbi-button cbi-button-reload'; + toggle.className = 'cbi-button cbi-button-neutral'; toggle.value = '<%:Enable%>'; toggle.title = '<%:Activate this network%>'; } @@ -254,7 +234,7 @@ var info = document.getElementById(iw.id + '-iw-status'); if (info) { - if (is_assoc) + if (iw.is_assoc) info.innerHTML = String.format( '<strong><%:SSID%>:</strong> %h | ' + '<strong><%:Mode%>:</strong> %s<br />' + @@ -274,83 +254,23 @@ : '<em><%:Wireless is disabled or not associated%></em>' ); } - - var dev = document.getElementById(wifidevs[iw.id] + '-iw-devinfo'); - if (dev) - { - if (is_assoc) - dev.innerHTML = String.format( - '<strong><%:Channel%>:</strong> %s (%s <%:GHz%>) | ' + - '<strong><%:Bitrate%>:</strong> %s <%:Mbit/s%>', - iw.channel ? iw.channel : '?', - iw.frequency ? iw.frequency : '?', - iw.bitrate ? iw.bitrate : '?' - ); - else - dev.innerHTML = ''; - } - - if (assoctable) - { - var assoclist = [ ]; - for (var bssid in iw.assoclist) - { - assoclist.push(iw.assoclist[bssid]); - assoclist[assoclist.length-1].bssid = bssid; - } - - assoclist.sort(function(a, b) { a.bssid < b.bssid }); - - for (var j = 0; j < assoclist.length; j++) - { - var icon; - var q = (-1 * (assoclist[j].noise - assoclist[j].signal)) / 5; - if (q < 1) - icon = "<%=resource%>/icons/signal-0.png"; - else if (q < 2) - icon = "<%=resource%>/icons/signal-0-25.png"; - else if (q < 3) - icon = "<%=resource%>/icons/signal-25-50.png"; - else if (q < 4) - icon = "<%=resource%>/icons/signal-50-75.png"; - else - icon = "<%=resource%>/icons/signal-75-100.png"; - - var host = hosts[assoclist[j].bssid], - name = host ? (host.name || 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), [ - E('<div class="td"><span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> %h</span></div>' - .format(iw.device.name, iw.ifname)), - E('<div class="td" style="white-space:nowrap">%h</div>' - .format(iw.ssid || '?')), - E('<div class="td">%h</div>' - .format(assoclist[j].bssid)), - E('<div class="td">', hint ? '<div style="max-width:200px;overflow:hidden;text-overflow:ellipsis">%h (%h)</div>' - .format(name || '?', hint) : (name || '?')), - E('<div class="td"><span class="ifacebadge" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%> / <%:SNR%>: %d"><img src="%s" /> %d / %d <%:dBm%></span></div>' - .format(assoclist[j].signal, assoclist[j].noise, assoclist[j].signal - assoclist[j].noise, icon, assoclist[j].signal, assoclist[j].noise)), - E('<div class="td">', [ - E('<span style="white-space:nowrap">', wifirate(assoclist[j], true)), - E('<br />'), - E('<span style="white-space:nowrap">', wifirate(assoclist[j], false)) - ]) - ])); - - rowstyle = (rowstyle == 1) ? 2 : 1; - } - } } - if (assoctable && assoctable.firstElementChild === assoctable.lastElementChild) - assoctable.appendChild(E('<div class="tr cbi-section-table-row"><div class="td"><em><br /><%:No information available%></em></div></div>')); - - for (var dev in devup) + for (var dev in radiostate) { var img = document.getElementById(dev + '-iw-upstate'); if (img) - img.src = '<%=resource%>/icons/wifi_big' + (devup[dev] ? '' : '_disabled') + '.png'; + img.src = '<%=resource%>/icons/wifi' + (radiostate[dev].up ? '' : '_disabled') + '.png'; + + var stat = document.getElementById(dev + '-iw-devinfo'); + if (stat) + stat.innerHTML = String.format( + '<strong><%:Channel%>:</strong> %s (%s <%:GHz%>) | ' + + '<strong><%:Bitrate%>:</strong> %s <%:Mbit/s%>', + radiostate[dev].channel ? radiostate[dev].channel : '?', + radiostate[dev].frequency ? radiostate[dev].frequency : '?', + radiostate[dev].bitrate ? radiostate[dev].bitrate : '?' + ); } } } @@ -359,37 +279,37 @@ <h2 name="content"><%:Wireless Overview%></h2> -<fieldset class="cbi-section" style="display:none"> +<div class="cbi-section" style="display:none"> <legend><%:Reconnecting interface%></legend> <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> <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() %> <!-- device <%=dev:name()%> --> - <fieldset class="cbi-section"> - <div class="table cbi-section-table" style="margin:10px; empty-cells:hide"> + <div class="cbi-section-node"> + <div class="table"> <!-- physical device --> <div class="tr"> - <div class="td"> - <img src="<%=resource%>/icons/wifi_big_disabled.png" id="<%=dev:name()%>-iw-upstate" /> + <div class="td col-2 center"> + <span class="ifacebadge"><img src="<%=resource%>/icons/wifi_disabled.png" id="<%=dev:name()%>-iw-upstate" /> <%=dev:name()%></span> </div> - <div class="td left"> - <big><strong><%=guess_wifi_hw(dev)%> (<%=dev:name()%>)</strong></big><br /> + <div class="td col-7 left"> + <big><strong><%=guess_wifi_hw(dev)%></strong></big><br /> <span id="<%=dev:name()%>-iw-devinfo"></span> </div> - <div class="td right"> + <div class="td cbi-section-actions"> <form action="<%=url('admin/network/wireless_join')%>" method="post" class="inline"> <input type="hidden" name="device" value="<%=dev:name()%>" /> <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 action="<%=url('admin/network/wireless_add')%>" method="post" class="inline"> <input type="hidden" name="device" value="<%=dev:name()%>" /> <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> </div> </div> @@ -398,22 +318,22 @@ <!-- network list --> <% if #nets > 0 then %> <% for i, net in ipairs(nets) do %> - <div class="tr cbi-section-table-row cbi-rowstyle-<%=1 + ((i-1) % 2)%>"> - <div class="td" id="<%=net:id()%>-iw-signal"> + <div class="tr cbi-rowstyle-<%=1 + ((i-1) % 2)%>"> + <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> </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> </div> - <div class="td right"> - <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 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-remove" style="width:100px" onclick="wifi_delete('<%=net:id()%>')" title="<%:Delete this network%>" value="<%:Remove%>" /> + <div class="td cbi-section-actions"> + <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-action important" onclick="location.href='<%=net:adminlink()%>'" title="<%:Edit this network%>" value="<%:Edit%>" /> + <input type="button" class="cbi-button cbi-button-negative" onclick="wifi_delete('<%=net:id()%>')" title="<%:Delete this network%>" value="<%:Remove%>" /> </div> </div> <% end %> <% else %> - <div class="tr cbi-section-table-row cbi-rowstyle-2"> + <div class="tr cbi-rowstyle-2"> <div class="td left"> <em><%:No network configured on this device%></em> </div> @@ -421,30 +341,14 @@ <% end %> <!-- /network list --> </div> - </fieldset> + </div> <!-- /device <%=dev:name()%> --> <% end %> <h2><%:Associated Stations%></h2> - <fieldset class="cbi-section"> - <div class="table cbi-section-table valign-middle" style="margin:10px" id="iw-assoclist"> - <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell"></div> - <div class="th cbi-section-table-cell"><%:SSID%></div> - <div class="th cbi-section-table-cell"><%:MAC-Address%></div> - <div class="th cbi-section-table-cell"><%:Host%></div> - <div class="th cbi-section-table-cell"><%:Signal%> / <%:Noise%></div> - <div class="th cbi-section-table-cell"><%:RX Rate%> / <%:TX Rate%></div> - </div> - <div class="tr cbi-section-table-row cbi-rowstyle-2"> - <div class="td"> - <em><%:Collecting data...%></em> - </div> - </div> - </div> - </fieldset> + <%+admin_network/wifi_assoclist%> </div> <%+footer%> diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_status/bandwidth.htm b/modules/luci-mod-admin-full/luasrc/view/admin_status/bandwidth.htm index db1d0b8883..b7594bfd45 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_status/bandwidth.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_status/bandwidth.htm @@ -202,18 +202,13 @@ data_rx_peak = Math.max(data_rx_peak, data_rx[i]); data_tx_peak = Math.max(data_tx_peak, data_tx[i]); - if (i > 0) - { - data_rx_avg = (data_rx_avg + data_rx[i]) / 2; - data_tx_avg = (data_tx_avg + data_tx[i]) / 2; - } - else - { - data_rx_avg = data_rx[i]; - data_tx_avg = data_tx[i]; - } + data_rx_avg += data_rx[i]; + data_tx_avg += data_tx[i]; } + data_rx_avg = (data_rx_avg / Math.max(data_rx.length, 1)); + data_tx_avg = (data_tx_avg / Math.max(data_tx.length, 1)); + /* remember current timestamp, calculate horizontal scale */ data_stamp = data[data.length-1][TIME]; data_scale = height / (data_max * 1.1); @@ -258,6 +253,8 @@ label_tx_peak.innerHTML = bandwidth_label(data_tx_peak, true); } ); + + XHR.run(); } }, 1000 ); diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_status/connections.htm b/modules/luci-mod-admin-full/luasrc/view/admin_status/connections.htm index 30d93f78bc..ae8a6bb7ce 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_status/connections.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_status/connections.htm @@ -304,6 +304,8 @@ label_otr_peak.innerHTML = Math.floor(data_otr_peak); } ); + + XHR.run(); } }, 1000 ); diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_status/index.htm b/modules/luci-mod-admin-full/luasrc/view/admin_status/index.htm index c5952064aa..6083a8a2c5 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_status/index.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_status/index.htm @@ -130,7 +130,7 @@ var pc = Math.floor((100 / mn) * vn); 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="position:absolute; left:0; top:0; text-align:center; width:100%%; color:#000000">' + '<small>%s / %s (%d%%)</small>' + @@ -140,24 +140,6 @@ ); } - function wifirate(bss, rx) { - var p = rx ? 'rx_' : 'tx_', - s = '%.1f <%:Mbit/s%>, %d<%:MHz%>' - .format(bss[p+'rate'] / 1000, bss[p+'mhz']), - ht = bss[p+'ht'], vht = bss[p+'vht'], - mhz = bss[p+'mhz'], nss = bss[p+'nss'], - mcs = bss[p+'mcs'], sgi = bss[p+'short_gi']; - - if (ht || vht) { - if (vht) s += ', VHT-MCS %d'.format(mcs); - if (nss) s += ', VHT-NSS %d'.format(nss); - if (ht) s += ', MCS %s'.format(mcs); - if (sgi) s += ', <%:Short GI%>'; - } - - return s; - } - function duid2mac(duid) { // DUID-LLT / Ethernet if (duid.length === 28 && duid.substr(0, 8) === '00010001') @@ -205,7 +187,7 @@ return E('div', { class: 'ifacebox' }, [ E('div', { class: 'ifacebox-head center ' + (active ? 'active' : '') }, E('strong', title)), - E('div', { class: 'ifacebox-body' }, childs) + E('div', { class: 'ifacebox-body left' }, childs) ]); } @@ -334,9 +316,7 @@ var ls = document.getElementById('lease_status_table'); if (ls) { - /* clear all rows */ - while (ls.firstElementChild !== ls.lastElementChild) - ls.removeChild(ls.lastElementChild); + var rows = []; for (var i = 0; i < info.leases.length; i++) { @@ -349,26 +329,23 @@ else 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), [ - E('<div class="td">', info.leases[i].hostname ? info.leases[i].hostname : '?'), - E('<div class="td">', info.leases[i].ipaddr), - E('<div class="td">', info.leases[i].macaddr), - E('<div class="td">', timestr) - ])); + rows.push([ + info.leases[i].hostname ? info.leases[i].hostname : '?', + info.leases[i].ipaddr, + info.leases[i].macaddr, + timestr + ]); } - if (ls.firstElementChild === ls.lastElementChild) - ls.appendChild(E('<div class="tr cbi-section-table-row"><div class="td"><em><br /><%:There are no active leases.%></em></div></div>')); + cbi_update_table(ls, rows, '<em><%:There are no active leases.%></em>'); } var ls6 = document.getElementById('lease6_status_table'); if (ls6 && info.leases6) { - ls6.parentNode.style.display = 'block'; + ls6.parentNode.parentNode.style.display = 'block'; - /* clear all rows */ - while (ls6.firstElementChild !== ls6.lastElementChild) - ls6.removeChild(ls6.lastElementChild); + var rows = []; for (var i = 0; i < info.leases6.length; i++) { @@ -394,22 +371,19 @@ hint = host.name; } - ls6.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-%d">'.format((i % 2) + 1), [ - E('<div class="td nowrap">', hint ? '<div>%h (%h)</div>'.format(name || '?', hint) : (name || '?')), - E('<div class="td nowrap">', info.leases6[i].ip6addr), - E('<div class="td nowrap">', info.leases6[i].duid), - E('<div class="td nowrap">', timestr) - ])); + rows.push([ + hint ? '%h (%h)'.format(name || '?', hint) : (name || '?'), + info.leases6[i].ip6addr, + info.leases6[i].duid, + timestr + ]); } - if (ls6.firstElementChild === ls6.lastElementChild) - ls6.appendChild(E('<div class="tr cbi-section-table-row"><div class="td"><em><br /><%:There are no active leases.%></em></div></div>')); + cbi_update_table(ls6, rows, '<em><%:There are no active leases.%></em>'); } <% end %> <% if has_wifi then %> - var assoclist = [ ]; - var ws = document.getElementById('wifi_status_table'); if (ws) { @@ -426,21 +400,6 @@ { var net = dev.networks[nidx]; var is_assoc = (net.bssid != '00:00:00:00:00:00' && net.channel && !net.disabled); - var num_assoc = 0; - - for (var bssid in net.assoclist) - { - var bss = net.assoclist[bssid]; - - bss.bssid = bssid; - bss.link = net.link; - bss.name = net.name; - bss.ifname = net.ifname; - bss.radio = dev.name; - - assoclist.push(bss); - num_assoc++; - } var icon; if (!is_assoc) @@ -463,7 +422,7 @@ '<%:Mode%>', net.mode, '<%:BSSID%>', is_assoc ? (net.bssid || '-') : null, '<%:Encryption%>', is_assoc ? net.encryption : null, - '<%:Associations%>', is_assoc ? (num_assoc || '-') : null, + '<%:Associations%>', is_assoc ? (net.num_assoc || '-') : null, null, is_assoc ? null : E('em', '<%:Wireless is disabled or not associated%>'))); } @@ -478,62 +437,6 @@ if (!ws.lastElementChild) ws.appendChild(E('<em><%:No information available%></em>')); } - - var ac = document.getElementById('wifi_assoc_table'); - if (ac) - { - /* clear all rows */ - while (ac.firstElementChild !== ac.lastElementChild) - ac.removeChild(ac.lastElementChild); - - assoclist.sort(function(a, b) { - return (a.name == b.name) - ? (a.bssid < b.bssid) - : (a.name > b.name ) - ; - }); - - for (var i = 0; i < assoclist.length; i++) - { - var icon; - var q = (-1 * (assoclist[i].noise - assoclist[i].signal)) / 5; - if (q < 1) - icon = "<%=resource%>/icons/signal-0.png"; - else if (q < 2) - icon = "<%=resource%>/icons/signal-0-25.png"; - else if (q < 3) - icon = "<%=resource%>/icons/signal-25-50.png"; - else if (q < 4) - icon = "<%=resource%>/icons/signal-50-75.png"; - else - icon = "<%=resource%>/icons/signal-75-100.png"; - - var host = hosts[assoclist[i].bssid], - name = host ? (host.name || 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)), [ - E('<div class="td"><span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> %h</span></div>' - .format(assoclist[i].radio, assoclist[i].ifname)), - E('<div class="td"><a href="%s" style="white-space:nowrap">%h</a></div>' - .format(assoclist[i].link, assoclist[i].name)), - E('<div class="td">', - assoclist[i].bssid), - E('<div class="td nowrap">', - hint ? '<div>%h (%h)</div>'.format(name || '?', hint) : (name || '?')), - E('<div class="td"><span class="ifacebadge" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%> / <%:SNR%>: %d"><img src="%s" /> %d / %d <%:dBm%></span></div>' - .format(assoclist[i].signal, assoclist[i].noise, assoclist[i].signal - assoclist[i].noise, icon, assoclist[i].signal, assoclist[i].noise)), - E('<div class="td nowrap">', [ - E('<span style="white-space:nowrap">', wifirate(assoclist[i], true)), - E('<br />'), - E('<span style="white-space:nowrap">', wifirate(assoclist[i], false)) - ]) - ])); - } - - if (ac.firstElementChild === ac.lastElementChild) - ac.appendChild(E('<div class="tr cbi-section-table-row"><div class="td"><em><br /><%:No information available%></em></div></div>')); - } <% end %> var e; @@ -591,8 +494,8 @@ <h2 name="content"><%:Status%></h2> -<fieldset class="cbi-section"> - <legend><%:System%></legend> +<div class="cbi-section"> + <h3><%:System%></h3> <div class="table" width="100%"> <div class="tr"><div class="td left" width="33%"><%:Hostname%></div><div class="td left"><%=luci.sys.hostname() or "?"%></div></div> @@ -607,31 +510,31 @@ <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> -</fieldset> +</div> -<fieldset class="cbi-section"> - <legend><%:Memory%></legend> +<div class="cbi-section"> + <h3><%:Memory%></h3> <div class="table" width="100%"> <div class="tr"><div class="td left" width="33%"><%:Total Available%></div><div class="td left" id="memtotal">-</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> -</fieldset> +</div> <% if swapinfo.total > 0 then %> -<fieldset class="cbi-section"> - <legend><%:Swap%></legend> +<div class="cbi-section"> + <h3><%:Swap%></h3> <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%"><%:Free%></div><div class="td left" id="swapfree">-</div></div> </div> -</fieldset> +</div> <% end %> -<fieldset class="cbi-section"> - <legend><%:Network%></legend> +<div class="cbi-section"> + <h3><%:Network%></h3> <div id="upstream_status_table" class="network-status-table"> <em><%:Collecting data...%></em> @@ -640,87 +543,82 @@ <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> -</fieldset> +</div> <% if has_dhcp then %> -<fieldset class="cbi-section"> - <legend><%:DHCP Leases%></legend> - - <div class="table cbi-section-table" id="lease_status_table"> - <div class="tr cbi-section-table-titles"> - <div class="th"><%:Hostname%></div> - <div class="th"><%:IPv4-Address%></div> - <div class="th"><%:MAC-Address%></div> - <div class="th"><%:Leasetime remaining%></div> - </div> - <div class="tr cbi-section-table-row"> - <div class="td" colspan="4"><em><br /><%:Collecting data...%></em></div> +<div class="cbi-section"> + <h3><%:DHCP Leases%></h3> + + <div class="cbi-section-node"> + <div class="table" id="lease_status_table"> + <div class="tr table-titles"> + <div class="th"><%:Hostname%></div> + <div class="th"><%:IPv4-Address%></div> + <div class="th"><%:MAC-Address%></div> + <div class="th"><%:Leasetime remaining%></div> + </div> + <div class="tr cbi-section-table-row"> + <div class="td" colspan="4"><em><br /><%:Collecting data...%></em></div> + </div> </div> </div> -</fieldset> - -<fieldset class="cbi-section" style="display:none"> - <legend><%:DHCPv6 Leases%></legend> - - <div class="table cbi-section-table" id="lease6_status_table"> - <div class="tr cbi-section-table-titles"> - <div class="th"><%:Host%></div> - <div class="th"><%:IPv6-Address%></div> - <div class="th"><%:DUID%></div> - <div class="th"><%:Leasetime remaining%></div> - </div> - <div class="tr cbi-section-table-row"> - <div class="td" colspan="4"><em><br /><%:Collecting data...%></em></div> +</div> + +<div class="cbi-section" style="display:none"> + <h3><%:DHCPv6 Leases%></h3> + + <div class="cbi-section-node"> + <div class="table" id="lease6_status_table"> + <div class="tr table-titles"> + <div class="th"><%:Host%></div> + <div class="th"><%:IPv6-Address%></div> + <div class="th"><%:DUID%></div> + <div class="th"><%:Leasetime remaining%></div> + </div> + <div class="tr cbi-section-table-row"> + <div class="td" colspan="4"><em><br /><%:Collecting data...%></em></div> + </div> </div> </div> -</fieldset> +</div> <% end %> <% if has_dsl then %> -<fieldset class="cbi-section"> - <legend><%:DSL%></legend> - <div class="table" width="100%"> - <div class="tr"> - <div class="td left" width="33%" style="vertical-align:top"><%:DSL Status%></div> - <div class="td"> - <div class="table"> - <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 class="cbi-section"> + <h3><%:DSL%></h3> + + <div class="cbi-section-node"> + <div class="table" width="100%"> + <div class="tr"> + <div class="td left" width="33%" style="vertical-align:top"><%:DSL Status%></div> + <div class="td"> + <div class="table"> + <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> -</fieldset> +</div> <% end %> <% if has_wifi then %> -<fieldset class="cbi-section"> - <legend><%:Wireless%></legend> +<div class="cbi-section"> + <h3><%:Wireless%></h3> <div id="wifi_status_table" class="network-status-table"> <em><%:Collecting data...%></em> </div> -</fieldset> - -<fieldset class="cbi-section"> - <legend><%:Associated Stations%></legend> - - <div class="table cbi-section-table valign-middle" id="wifi_assoc_table"> - <div class="tr cbi-section-table-titles"> - <div class="th"> </div> - <div class="th"><%:Network%></div> - <div class="th"><%:MAC-Address%></div> - <div class="th"><%:Host%></div> - <div class="th"><%:Signal%> / <%:Noise%></div> - <div class="th"><%:RX Rate%> / <%:TX Rate%></div> - </div> - <div class="tr cbi-section-table-row"> - <div class="td" colspan="6"><em><br /><%:Collecting data...%></em></div> - </div> - </div> -</fieldset> +</div> + +<div class="cbi-section"> + <h3><%:Associated Stations%></h3> + + <%+admin_network/wifi_assoclist%> +</div> <% end %> <%- diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_status/iptables.htm b/modules/luci-mod-admin-full/luasrc/view/admin_status/iptables.htm index ced4d5f774..5d544ca60b 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_status/iptables.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_status/iptables.htm @@ -62,6 +62,7 @@ <%+header%> +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> <style type="text/css"> span:target { color: blue; @@ -70,7 +71,6 @@ </style> <h2 name="content"><%:Firewall Status%></h2> -<br /> <% if has_ip6tables then %> <ul class="cbi-tabmenu"> @@ -88,69 +88,69 @@ <input type="submit" class="cbi-button" name="restart" value="<%:Restart Firewall%>" /> </form> - <fieldset class="cbi-section"> + <div class="cbi-section"> <% for _, tbl in ipairs(tables) do chaincnt = 0 %> <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 %> - <div class="tr cbi-section-table-row cbi-rowstyle-<%=rowstyle()%>"> - <div class="td"><%=rule.packets%></div> - <div class="td" style="white-space: nowrap"><%=wba.byte_format(rule.bytes)%></div> - <div class="td"><%=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" style="width:30%"><small><%=#rule.options > 0 and luci.util.pcdata(table.concat(rule.options, " ")) or "-"%></small></div> + <% for _, chain in ipairs(ipt:chains(tbl)) do + rowcnt = 0 + chaincnt = chaincnt + 1 + chaininfo = ipt:chain(tbl, chain) + %> + <h4 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 -%>) + </h4> + + <div class="cbi-section-node"> + <div class="table" style="font-size:90%"> + <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> - <% end %> - <% if rowcnt == 1 then %> - <div class="tr cbi-section-table-titles cbi-rowstyle-<%=rowstyle()%>"> - <div class="td" colspan="9"><em><%:No rules in this chain%></em></div> - </div> - <% end %> - <% end %> - - <% if chaincnt == 0 then %> - <div class="tr cbi-section-table-titles cbi-rowstyle-<%=rowstyle()%>"> - <div class="td" colspan="9"><em><%:No chains in this table%></em></div> + <% for _, rule in ipairs(ipt:find({table=tbl, chain=chain})) do %> + <div class="tr cbi-rowstyle-<%=rowstyle()%>"> + <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> - <% end %> - </div> + </div> + <% end %> + + <% if chaincnt == 0 then %> + <em><%:No chains in this table%></em> + <% end %> + <br /><br /> <% end %> - </fieldset> + </div> </div> <%+footer%> diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_status/load.htm b/modules/luci-mod-admin-full/luasrc/view/admin_status/load.htm index c8ada71569..dc7d927de8 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_status/load.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_status/load.htm @@ -237,6 +237,8 @@ label_15_peak.innerHTML = (data_15_peak / 100).toFixed(2); } ); + + XHR.run(); } }, 1000 ); diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_status/routes.htm b/modules/luci-mod-admin-full/luasrc/view/admin_status/routes.htm index af80371353..9ed37939fe 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_status/routes.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_status/routes.htm @@ -32,28 +32,30 @@ <%+header%> +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> + <div class="cbi-map" id="cbi-network"> <h2 name="content"><%:Routes%></h2> <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> <div class="cbi-section-node"> - <div class="table cbi-section-table"> - <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell"><%_<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 cbi-section-table-cell"><%:Interface%></div> + <div class="table"> + <div class="tr table-titles"> + <div class="th"><%_<abbr title="Internet Protocol Version 4">IPv4</abbr>-Address%></div> + <div class="th"><%_<abbr title="Media Access Control">MAC</abbr>-Address%></div> + <div class="th"><%:Interface%></div> </div> <% for _, v in ipairs(ip.neighbors({ family = 4 })) do if v.mac then %> - <div class="tr cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>"> - <div class="td cbi-value-field"><%=v.dest%></div> - <div class="td cbi-value-field"><%=v.mac%></div> - <div class="td cbi-value-field"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div> + <div class="tr cbi-rowstyle-<%=(style and 1 or 2)%>"> + <div class="td"><%=v.dest%></div> + <div class="td"><%=v.mac%></div> + <div class="td"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div> </div> <% style = not style @@ -62,61 +64,57 @@ %> </div> </div> - </fieldset> - <br /> + </div> - <fieldset class="cbi-section"> + <div class="cbi-section"> <legend><%_Active <abbr title="Internet Protocol Version 4">IPv4</abbr>-Routes%></legend> - <div class="cbi-section-node"> - <div class="table cbi-section-table"> - <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell"><%:Network%></div> - <div class="th cbi-section-table-cell"><%:Target%></div> - <div class="th cbi-section-table-cell"><%_<abbr title="Internet Protocol Version 4">IPv4</abbr>-Gateway%></div> - <div class="th cbi-section-table-cell"><%:Metric%></div> - <div class="th cbi-section-table-cell"><%:Table%></div> + <div class="table"> + <div class="tr table-titles"> + <div class="th"><%:Network%></div> + <div class="th"><%:Target%></div> + <div class="th"><%_<abbr title="Internet Protocol Version 4">IPv4</abbr>-Gateway%></div> + <div class="th"><%:Metric%></div> + <div class="th"><%:Table%></div> </div> <% 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="td cbi-value-field"><%=luci.tools.webadmin.iface_get_network(v.dev) or v.dev%></div> - <div class="td cbi-value-field"><%=v.dest%></div> - <div class="td cbi-value-field"><%=v.gw%></div> - <div class="td cbi-value-field"><%=v.metric or 0%></div> - <div class="td cbi-value-field"><%=rtn[v.table] or v.table%></div> + <div class="tr cbi-rowstyle-<%=(style and 1 or 2)%>"> + <div class="td"><%=luci.tools.webadmin.iface_get_network(v.dev) or v.dev%></div> + <div class="td"><%=v.dest%></div> + <div class="td"><%=v.gw or "-"%></div> + <div class="td"><%=v.metric or 0%></div> + <div class="td"><%=rtn[v.table] or v.table%></div> </div> <% style = not style end %> </div> </div> - </fieldset> - <br /> + </div> <% if nixio.fs.access("/proc/net/ipv6_route") then style = true %> - <fieldset class="cbi-section"> + <div class="cbi-section"> <legend><%_Active <abbr title="Internet Protocol Version 6">IPv6</abbr>-Routes%></legend> - <div class="cbi-section-node"> - <div class="table cbi-section-table"> - <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell"><%:Network%></div> - <div class="th cbi-section-table-cell"><%:Target%></div> - <div class="th cbi-section-table-cell"><%:Source%></div> - <div class="th cbi-section-table-cell"><%:Metric%></div> - <div class="th cbi-section-table-cell"><%:Table%></div> + <div class="table"> + <div class="tr table-titles"> + <div class="th"><%:Network%></div> + <div class="th"><%:Target%></div> + <div class="th"><%:Source%></div> + <div class="th"><%:Metric%></div> + <div class="th"><%:Table%></div> </div> <% for _, v in ipairs(ip.routes({ family = 6, type = 1 })) do 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="td cbi-value-field"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div> - <div class="td cbi-value-field"><%=v.dest%></div> - <div class="td cbi-value-field"><%=v.from%></div> - <div class="td cbi-value-field"><%=v.metric or 0%></div> - <div class="td cbi-value-field"><%=rtn[v.table] or v.table%></div> + <div class="tr cbi-rowstyle-<%=(style and 1 or 2)%>"> + <div class="td"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div> + <div class="td"><%=v.dest%></div> + <div class="td"><%=v.from%></div> + <div class="td"><%=v.metric or 0%></div> + <div class="td"><%=rtn[v.table] or v.table%></div> </div> <% style = not style @@ -125,27 +123,25 @@ %> </div> </div> - </fieldset> - <br /> + </div> - <fieldset class="cbi-section"> + <div class="cbi-section"> <legend><%:IPv6 Neighbours%></legend> - <div class="cbi-section-node"> - <div class="table cbi-section-table"> - <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell"><%:IPv6-Address%></div> - <div class="th cbi-section-table-cell"><%:MAC-Address%></div> - <div class="th cbi-section-table-cell"><%:Interface%></div> + <div class="table"> + <div class="tr table-titles"> + <div class="th"><%:IPv6-Address%></div> + <div class="th"><%:MAC-Address%></div> + <div class="th"><%:Interface%></div> </div> <% for _, v in ipairs(ip.neighbors({ family = 6 })) do 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="td cbi-value-field"><%=v.dest%></div> - <div class="td cbi-value-field"><%=v.mac%></div> - <div class="td cbi-value-field"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div> + <div class="tr cbi-rowstyle-<%=(style and 1 or 2)%>"> + <div class="td"><%=v.dest%></div> + <div class="td"><%=v.mac%></div> + <div class="td"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div> </div> <% style = not style @@ -154,8 +150,7 @@ %> </div> </div> - </fieldset> - <br /> + </div> <% end %> </div> diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_status/wireless.htm b/modules/luci-mod-admin-full/luasrc/view/admin_status/wireless.htm index 4211b26471..09b7965776 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_status/wireless.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_status/wireless.htm @@ -308,6 +308,8 @@ label_rate_peak.innerHTML = rate_label(data_rate_peak); } ); + + XHR.run(); } }, 1000 ); diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_system/flashops.htm b/modules/luci-mod-admin-full/luasrc/view/admin_system/flashops.htm index b32ef78263..9eec012547 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_system/flashops.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_system/flashops.htm @@ -13,84 +13,78 @@ <li class="cbi-tab-disabled"><a href="<%=REQUEST_URI%>/backupfiles"><%:Configuration%></a></li> </ul> -<fieldset class="cbi-section"> - - <fieldset class="cbi-section"> - <legend><%:Backup / Restore%></legend> - <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> - <div class="cbi-section-node"> - <form class="inline" method="post" action="<%=url('admin/system/flashops/backup')%>"> - <input type="hidden" name="token" value="<%=token%>" /> - <div class="cbi-value<% if not reset_avail then %> cbi-value-last<% end %>"> - <label class="cbi-value-title" for="image"><%:Download backup%>:</label> - <div class="cbi-value-field"> - <input class="cbi-button cbi-button-apply" type="submit" name="backup" value="<%:Generate archive%>" /> - </div> - </div> - </form> - <% if reset_avail then %> - <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 class="cbi-section"> + <legend><%:Backup / Restore%></legend> + <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> + <div class="cbi-section-node"> + <form class="inline" method="post" action="<%=url('admin/system/flashops/backup')%>"> + <input type="hidden" name="token" value="<%=token%>" /> + <div class="cbi-value<% if not reset_avail then %> cbi-value-last<% end %>"> + <label class="cbi-value-title" for="image"><%:Download backup%>:</label> + <div class="cbi-value-field"> + <input class="cbi-button cbi-button-action important" type="submit" name="backup" value="<%:Generate archive%>" /> </div> - </form> - </div> + </div> + </form> <% 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 %> - </fieldset> - + </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-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"> - <legend><%:Flash new firmware image%></legend> - <% if upgrade_avail then %> - <form method="post" action="<%=url('admin/system/flashops/sysupgrade')%>" enctype="multipart/form-data"> - <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-node"> - <div class="cbi-value"> - <label class="cbi-value-title" for="keep"><%:Keep settings%>:</label> - <div class="cbi-value-field"> - <input type="checkbox" name="keep" id="keep" checked="checked" /> - </div> +<div class="cbi-section"> + <legend><%:Flash new firmware image%></legend> + <% if upgrade_avail then %> + <form method="post" action="<%=url('admin/system/flashops/sysupgrade')%>" enctype="multipart/form-data"> + <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-node"> + <div class="cbi-value"> + <label class="cbi-value-title" for="keep"><%:Keep settings%>:</label> + <div class="cbi-value-field"> + <input type="checkbox" name="keep" id="keep" checked="checked" /> </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 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-button-action important" value="<%:Flash image...%>" /> </div> </div> - <% if image_invalid then %> - <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 %> - </fieldset> - -</fieldset> + </div> + <% if image_invalid then %> + <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%> diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_system/packages.htm b/modules/luci-mod-admin-full/luasrc/view/admin_system/packages.htm index 4944a232b2..ef13a91672 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_system/packages.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_system/packages.htm @@ -44,6 +44,8 @@ end <%+header%> +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> + <h2 name="content"><%:Software%></h2> <div class="cbi-map"> @@ -57,8 +59,8 @@ end <input type="hidden" name="exec" value="1" /> <input type="hidden" name="token" value="<%=token%>" /> - <fieldset class="cbi-section"> - <fieldset class="cbi-section-node"> + <div class="cbi-section"> + <div class="cbi-section-node"> <% if (install and next(install)) or (remove and next(remove)) or update or upgrade then %> <div class="cbi-value"> <% 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%>%"> </div> </div> </div> - </fieldset> + </div> <br /> - <fieldset class="cbi-section-node"> + <div class="cbi-section-node"> <input type="hidden" name="display" value="<%=pcdata(display)%>" /> <div class="cbi-value"> <label class="cbi-value-title"><%:Download and install package%>:</label> <div class="cbi-value-field"> <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> @@ -110,11 +112,11 @@ end <label class="cbi-value-title"><%:Filter%>:</label> <div class="cbi-value-field"> <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> - </fieldset> - </fieldset> + </div> + </div> </form> @@ -122,90 +124,90 @@ end <ul class="cbi-tabmenu"> - <li class="cbi-tab<% if display ~= "installed" then %>-disabled<% end %>"><a href="?display=installed&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&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&query=<%=pcdata(query)%>"><%:Installed packages%><% if query then %> (<%=pcdata(query)%>)<% end %></a></li> </ul> <% if display ~= "available" then %> - <fieldset class="cbi-section"> - <div class="table cbi-section-table" style="width:100%"> - <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell" style="text-align:left"> </div> - <div class="th cbi-section-table-cell" style="text-align:left"><%:Package name%></div> - <div class="th cbi-section-table-cell" style="text-align:left"><%:Version%></div> - </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%> "<%=luci.util.pcdata(n)%>" ?') && this.parentNode.submit(); return false" href="#"><%:Remove%></a> - </form> + <div class="cbi-section"> + <div class="cbi-section-node"> + <div class="table"> + <div class="tr cbi-section-table-titles"> + <div class="th left"><%:Package name%></div> + <div class="th left"><%:Version%></div> + <div class="th cbi-section-actions"> </div> </div> - <div class="td" style="text-align:left"><%=luci.util.pcdata(n)%></div> - <div class="td" style="text-align:left"><%=luci.util.pcdata(v)%></div> - </div> - <% end) %> - <% if empty then %> - <div class="tr cbi-section-table-row"> - <div class="td" style="text-align:left"> </div> - <div class="td" style="text-align:left"><em><%:none%></em></div> - <div class="td" style="text-align:left"><em><%:none%></em></div> + <% local empty = true; luci.model.ipkg.list_installed(querypat, function(n, v, s, d) empty = false; filter[n] = true %> + <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%> "<%=luci.util.pcdata(n)%>" ?') && 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"> </div> + <div class="td left"><em><%:none%></em></div> + <div class="td left"><em><%:none%></em></div> + </div> + <% end %> </div> - <% end %> </div> - </fieldset> + </div> <% else %> - <fieldset class="cbi-section"> + <div class="cbi-section"> <% if not querypat then %> - <ul class="cbi-tabmenu"> + <ul class="cbi-tabmenu" style="flex-wrap:wrap"> <% local i; for i = 65, 90 do %> <li class="cbi-tab<% if letter ~= i then %>-disabled<% end %>"><a href="?display=available&letter=<%=string.char(i)%>"><%=string.char(i)%></a></li> <% end %> <li class="cbi-tab<% if letter ~= 35 then %>-disabled<% end %>"><a href="?display=available&letter=%23">#</a></li> </ul> - <div class="cbi-section-node"> <% end %> - <div class="table cbi-section-table" style="width:100%"> - <div class="tr cbi-section-table-titles"> - <div class="th cbi-section-table-cell" style="text-align:left"> </div> - <div class="th cbi-section-table-cell" style="text-align:left"><%:Package name%></div> - <div class="th cbi-section-table-cell" style="text-align:left"><%:Version%></div> - <div class="th cbi-section-table-cell" style="text-align:right"><%:Size (.ipk)%></div> - <div class="th cbi-section-table-cell" style="text-align:left"><%:Description%></div> - </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%> "<%=luci.util.pcdata(n)%>" ?') && this.parentNode.submit(); return false" href="#"><%:Install%></a> - </form> + <div class="cbi-section-node cbi-section-node-tabbed"> + <div class="table"> + <div class="tr cbi-section-table-titles"> + <div class="th col-2 left"><%:Package name%></div> + <div class="th col-2 left"><%:Version%></div> + <div class="th col-1 center"><%:Size (.ipk)%></div> + <div class="th col-10 left"><%:Description%></div> + <div class="th cbi-section-actions"> </div> </div> - <div class="td" style="text-align:left"><%=luci.util.pcdata(n)%></div> - <div class="td" style="text-align:left"><%=luci.util.pcdata(v)%></div> - <div class="td" style="text-align:right"><%=luci.util.pcdata(s)%></div> - <div class="td" style="text-align:left"><%=luci.util.pcdata(d)%></div> - </div> - <% end) %> - <% if empty then %> - <div class="tr cbi-section-table-row"> - <div class="td" style="text-align:left"> </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> + <% 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-rowstyle-<%=rowstyle()%>"> + <div class="td col-2 left"><%=luci.util.pcdata(n)%></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%> "<%=luci.util.pcdata(n)%>" ?') && this.parentNode.submit(); return false" value="<%:Install%>" /> + </form> + </div> + </div> + <% end) %> + <% if empty then %> + <div class="tr"> + <div class="td left"> </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> - <% end %> </div> - <% if not querypat then %> - </div> - <% end %> - </fieldset> + </div> <% end %> </div> diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_system/reboot.htm b/modules/luci-mod-admin-full/luasrc/view/admin_system/reboot.htm index c9551804d2..6ec2b310d2 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_system/reboot.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_system/reboot.htm @@ -7,7 +7,6 @@ <%+header%> <h2 name="content"><%:Reboot%></h2> -<br /> <p><%:Reboots the operating system of your device%></p> @@ -49,7 +48,7 @@ } //]]></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"> <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_uci/changelog.htm b/modules/luci-mod-admin-full/luasrc/view/admin_uci/changelog.htm index 4ed4f0a10f..e05ccdece3 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_uci/changelog.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_uci/changelog.htm @@ -4,7 +4,7 @@ -%> <% export("uci_changelog", function(changes) -%> -<fieldset class="cbi-section"> +<div class="cbi-section"> <strong><%:Legend:%></strong> <div class="uci-change-legend"> <div class="uci-change-legend-label"><ins> </ins> <%:Section added%></div> @@ -32,9 +32,11 @@ ret[#ret+1] = "<br />%s.%s.%s+=<strong>%s</strong>" %{ r, s, o, util.pcdata(v[i]) } end - else + elseif v ~= "" then ret[#ret+1] = "<br />%s.%s.%s=<strong>%s</strong>" %{ r, s, o, util.pcdata(v) } + else + ret[#ret+1] = "<br /><del>%s.%s.<strong>%s</strong></del>" %{ r, s, o } end end end @@ -57,7 +59,7 @@ ret[#ret+1] = "%s.%s.%s+=<strong>%s</strong><br />" %{ r, s, o, util.pcdata(v[i]) } end - + else ret[#ret+1] = "%s.%s.%s=<strong>%s</strong><br />" %{ r, s, o, util.pcdata(v) } @@ -75,5 +77,5 @@ write(table.concat(ret)) %></div> -</fieldset> +</div> <%- end) %> diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_uci/changes.htm b/modules/luci-mod-admin-full/luasrc/view/admin_uci/changes.htm index c69ec1215a..6282244757 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_uci/changes.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_uci/changes.htm @@ -27,21 +27,17 @@ <div class="cbi-page-actions"> <% if redir_url then %> - <div style="float:left"> - <form class="inline" method="get" action="<%=luci.util.pcdata(redir_url)%>"> - <input class="cbi-button cbi-button-link" style="float:left; margin:0" type="submit" value="<%:Back%>" /> - </form> - </div> + <form method="get" action="<%=luci.util.pcdata(redir_url)%>"> + <input class="cbi-button cbi-button-link" type="submit" value="<%:Back%>" /> + </form> <% 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()" /> - <form class="inline" method="post" action="<%=url("admin/uci/revert")%>"> - <input type="hidden" name="token" value="<%=token%>" /> - <input type="hidden" name="redir" value="<%=pcdata(luci.http.formvalue("redir"))%>" /> - <input class="cbi-button cbi-button-reset" type="submit" value="<%:Revert%>" /> - </form> - </div> + <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")%>"> + <input type="hidden" name="token" value="<%=token%>" /> + <input type="hidden" name="redir" value="<%=pcdata(luci.http.formvalue("redir"))%>" /> + <input class="cbi-button cbi-button-reset" type="submit" value="<%:Revert%>" /> + </form> </div> <%+footer%> diff --git a/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css b/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css index 4a40f6d680..622f2b8443 100644 --- a/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css +++ b/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css @@ -215,7 +215,8 @@ a:hover { * ---------------------------------------------------------------------------------------- */ p, .cbi-map-descr, -.cbi-section-descr { +.cbi-section-descr, +.table .tr.cbi-section-table-descr .th { font-size: 13px; font-weight: normal; line-height: 18px; @@ -229,7 +230,7 @@ p small { h1, h2, -h3, +h3, legend, h4, h5, h6 { @@ -265,14 +266,14 @@ h2 small { font-size: 14px; } -h3, +h3, legend, h4, h5, h6 { line-height: 36px; } -h3 { +h3, legend { font-size: 18px; } @@ -645,6 +646,26 @@ textarea[readonly] { 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, .cbi-page-actions { background: #f5f5f5; @@ -706,6 +727,7 @@ textarea[readonly] { padding: 0; font-size: 13px; border-collapse: collapse; + position: relative; } .table .th, .table .td { @@ -732,6 +754,19 @@ textarea[readonly] { 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 * Repeatable UI elements outside the base styles provided from the scaffolding * ---------------------------------------------------------------------------- */ @@ -1244,99 +1279,67 @@ footer { 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-value-error input { color: #FF0000; border-color: #FF0000; } -.cbi-button-up, -.cbi-input-up { - 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-positive, +.cbi-button-fieldadd, +.cbi-button-add, +.cbi-button-save { + border-color: #4a4; + color: #4a4; } +.cbi-button-neutral, +.cbi-button-download, .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-input-add { - background-position: 6px center, left top; - padding-left: 28px; - background-image: url('../resources/cbi/add.gif'), linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); +.cbi-button-link, +.cbi-button-up, +.cbi-button-down { + border-color: #444; + color: #444; } +.btn.primary, +.cbi-button-action, .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-reload, +.cbi-button-edit { + border-color: #0069d6; + color: #0069d6; } +.cbi-button-negative, +.cbi-section-remove .cbi-button, .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-remove { + border-color: #c44; + color: #c44; } -.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); +.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-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-positive.important, +.cbi-page-actions .cbi-button-save { + color: #fff; + background: #4a4; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } -.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-download, -.cbi-input-download { - background-position: 6px center, left top; - padding-left: 28px; - background-image: url('../resources/cbi/download.gif'), linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); +.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 { @@ -1492,6 +1495,58 @@ footer { 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 { box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); } @@ -1522,46 +1577,6 @@ footer { font-size: 11px; } -/* Button icons for specific pages */ -.Startup .cbi-section-table input.cbi-input-apply, -.Startup .cbi-section-table input.cbi-button-apply { - background-image: url("../resources/cbi/apply.gif"); - background-position: 7px 4px; - padding: 3px 9px 3px 27px; -} - -.Processes .cbi-section-table input.cbi-input-reload, -.Startup .cbi-section-table input.cbi-input-reload { - background-image: url("../resources/cbi/reload.gif"); - background-position: 7px 4px; - padding: 3px 9px 3px 27px; -} - -.Processes .cbi-section-table input.cbi-input-remove, -.Processes .cbi-section-table div.cbi-section-remove input, -.Startup .cbi-section-table input.cbi-input-remove, -.Startup .cbi-section-table div.cbi-section-remove input { - background-image: url("../resources/cbi/remove.gif"); - background-position: 7px 4px; - padding: 3px 9px 3px 27px; -} - -.Processes .cbi-section-table input.cbi-input-reset, -.Processes .cbi-section-table input.cbi-button-reset, -.Startup .cbi-section-table input.cbi-input-reset, -.Startup .cbi-section-table input.cbi-button-reset { - background-image: url("../resources/cbi/reset.gif"); - background-position: 7px 4px; - padding: 3px 9px 3px 27px; -} - -.Startup .cbi-section-table input.cbi-input-save, -.Startup .cbi-section-table input.cbi-button-save { - background-image: url("../resources/cbi/save.gif"); - background-position: 7px 4px; - padding: 3px 9px 3px 27px; -} - button.btn::-moz-focus-inner, input[type=submit].btn::-moz-focus-inner { padding: 0; border: 0; @@ -1713,6 +1728,20 @@ header .pull-right { padding-top: 8px; } font-weight: normal; } +.cbi-section-table-titles.named::before, +.cbi-section-table-descr.named::before, +.cbi-section-table-row[data-title]::before { + content: attr(data-title) " "; + display: table-cell; + padding: 10px 10px 9px; + line-height: 18px; + font-weight: bold; +} + +.cbi-section-table-row[data-title]::before { + border-top: 1px solid #ddd; +} + .left { text-align: left !important; } .right { text-align: right !important; } @@ -1751,9 +1780,13 @@ table table td, vertical-align: middle; } -.cbi-value-description { display: inline; } - -.cbi-value-description img { vertical-align: middle; } +.cbi-value-description { + background-image: url(/luci-static/resources/cbi/help.gif); + background-position: .25em .2em; + background-repeat: no-repeat; + margin: .25em 0 0 0; + padding: 0 0 0 1.7em; +} .cbi-section-error { border: 1px solid #FF0000; @@ -1852,6 +1885,7 @@ table table td, flex-wrap: wrap; } +.ifacebadge.large, .network-status-table .ifacebox-body .ifacebadge { flex: 1; margin: .5em .25em 0 .25em; @@ -1866,7 +1900,6 @@ table table td, white-space: nowrap; color: #666666; text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); - cursor: pointer; } .zonebadge > em, diff --git a/themes/luci-theme-material/htdocs/luci-static/material/css/style.css b/themes/luci-theme-material/htdocs/luci-static/material/css/style.css index a9585cf40e..03a82b656a 100755 --- a/themes/luci-theme-material/htdocs/luci-static/material/css/style.css +++ b/themes/luci-theme-material/htdocs/luci-static/material/css/style.css @@ -32,8 +32,8 @@ font-style: normal; } -.table { display: table; } -.tr { display: table-row; } +.table { display: table; position: relative; } +.tr { display: table-row; } .thead { display: table-header-group; } .tbody { display: table-row-group; } .tfoot { display: table-footer-group; } @@ -48,6 +48,19 @@ 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="100%"], .th[width="100%"], .td[width="100%"] { width: 100%; } @@ -442,10 +455,12 @@ h3 { } h4 { - + margin: 2rem 0 0 0; + font-size: 1.2rem; + padding-bottom: 10px; } -fieldset { +.cbi-section { margin: 2rem 0 0 0; padding: 2rem; border: 0; @@ -465,7 +480,7 @@ fieldset { margin-top: 1rem; } -fieldset > legend { +.cbi-section > legend { display: none !important; } @@ -486,10 +501,12 @@ fieldset > fieldset { border-bottom: 1px solid #eee; } -table, -.table { +table { border-spacing: 0; border-collapse: collapse; +} + +table, .table { width: 100%; border: 1px solid #eee; } @@ -501,21 +518,75 @@ table > tbody > tr > td, table > tbody > tr > th, table > tfoot > tr > td, table white-space: nowrap; } +.td.cbi-value-field, .cbi-section-table-cell { 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 { 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); +} + +.cbi-section-table-row:last-child { + 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%; } -fieldset > table > tbody > tr:nth-of-type(2n), -fieldset > .table > .tbody > .tr:nth-of-type(2n) { +div > table > tbody > tr:nth-of-type(2n), +div > .table > .tbody > .tr:nth-of-type(2n) { background-color: #f9f9f9; } -fieldset > table > tbody > tr:nth-of-type(2n), -fieldset > .table > .tbody > .tr:nth-of-type(2n) { +div > table > tbody > tr:nth-of-type(2n), +div > .table > .tbody > .tr:nth-of-type(2n) { background-color: #f9f9f9; } @@ -1029,7 +1100,7 @@ td > .ifacebadge, .ifacebadge > img { display: inline-block; margin: 0 .2rem; - align-self: start; + align-self: flex-start; } .ifacebadge > img + img { @@ -1206,10 +1277,9 @@ td > .ifacebadge, .zonebadge { padding: 0.2rem 0.5rem; display: inline-block; - cursor: pointer; } -.zonebadge > .ifacebadge { +.zonebadge .ifacebadge { padding: .2rem .3rem; margin: 0.1rem 0.2rem; border: 1px solid #6C6C6C; @@ -1255,11 +1325,13 @@ td > .ifacebadge, min-width: 7rem; } -.cbi-section-table-row > .cbi-value-field .cbi-input-select { - width: 7rem; +.cbi-section-create { + margin: .5rem -3px; + display: inline-flex; + align-items: center; } -.cbi-section-create > .cbi-button-add { +.cbi-section-create > * { margin: 0.5rem; } @@ -1291,6 +1363,62 @@ small { 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 { background-color: #f5f5f5; display: block; @@ -1475,11 +1603,6 @@ header > .container > .pull-right > * { 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-system-packages 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 { 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) { @@ -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"] { margin-top: 1rem; } + + .th, .td { + flex-basis: 50%; + } + + .td.cbi-value-field { + flex-basis: 100%; + } } @media screen and (min-width: 992px) { diff --git a/themes/luci-theme-openwrt/htdocs/luci-static/openwrt.org/cascade.css b/themes/luci-theme-openwrt/htdocs/luci-static/openwrt.org/cascade.css index 1d5ac8ab24..926e8cbfb2 100644 --- a/themes/luci-theme-openwrt/htdocs/luci-static/openwrt.org/cascade.css +++ b/themes/luci-theme-openwrt/htdocs/luci-static/openwrt.org/cascade.css @@ -18,8 +18,8 @@ body { background-color: #4a6b7c; background-position: bottom center; background-repeat: repeat-x; - font-family: Verdana, Arial, sans-serif; - font-size: 11pt; + font-family: Arial, Verdana, sans-serif; + font-size: 16px; line-height: 100%; padding-bottom: 1.5em; } @@ -30,7 +30,7 @@ body { box-sizing: border-box; } -.table { display: table; } +.table { display: table; width: 100%; position: relative; } .tr { display: table-row; } .thead { display: table-header-group; } .tbody { display: table-row-group; } @@ -41,6 +41,30 @@ body { .table[width="33%"], .th[width="33%"], .td[width="33%"] { width: 33%; } .table[width="100%"], .th[width="100%"], .td[width="100%"] { width: 100%; } +.col-1 { flex: 1 1 30px !important; -webkit-flex: 1 1 30px !important; } +.col-2 { flex: 2 2 60px !important; -webkit-flex: 2 2 60px !important; } +.col-3 { flex: 3 3 90px !important; -webkit-flex: 3 3 90px !important; } +.col-4 { flex: 4 4 120px !important; -webkit-flex: 4 4 120px !important; } +.col-5 { flex: 5 5 150px !important; -webkit-flex: 5 5 150px !important; } +.col-6 { flex: 6 6 180px !important; -webkit-flex: 6 6 180px !important; } +.col-7 { flex: 7 7 210px !important; -webkit-flex: 7 7 210px !important; } +.col-8 { flex: 8 8 240px !important; -webkit-flex: 8 8 240px !important; } +.col-9 { flex: 9 9 270px !important; -webkit-flex: 9 9 270px !important; } +.col-10 { flex: 10 10 300px !important; -webkit-flex: 10 10 300px !important; } + +.tr.placeholder { + height: 3.5em; +} + +.tr.placeholder > .td { + position: absolute; + left: 0; + right: 0; + bottom: 0; + text-align: center; + line-height: 3em; +} + .nowrap { white-space: nowrap; } @@ -50,81 +74,95 @@ a img { text-decoration: none; } -ul.tabmenu { - margin: 0; - clear: both; - display: block; - vertical-align: bottom; - font-size: 10pt; - padding: 5px 0 0 5px; +#maincontainer { + display: flex; } -div.tabmenu2 { - background-color: #AAAAAA; - background-image: url(tabbg.png); - background-repeat: repeat-x; - margin-top: -1px; - border: 1px solid #444444; - border-bottom: none; +#maincontent { + flex-basis: 100%; } -div.tabmenu3, -div.tabmenu4, -div.tabmenu5 { - background-color: #AAAAAA; - background-image: url(tabbg.png); - background-repeat: repeat-x; - border: none; +#mainmenu { + max-width: 200px; + background: #f5f5f5; + border: 1px solid #444; + border-width: 0 0 1px 1px; + font-size: 85%; + padding-bottom: 1em; } -ul.tabmenu li { - float: left; +#mainmenu ul { display: block; - overflow: hidden; + margin: 0; + padding: 0; } -.lang_he ul.tabmenu li { - float: right; +#mainmenu ul li { + display: block; + white-space: nowrap; } -ul.tabmenu li a { - text-decoration: none; - color: #444444; +#mainmenu ul li > a { display: block; - padding: 3px 8px; - margin: 0 2px; - line-height: 1.3em; - border: 1px solid transparent; - border-bottom: none; + color: #444; + padding: .4em .5em; + text-decoration: none; +} + +#mainmenu ul li.selected > a { + background: #fff; + color: #59d; + border: 1px dotted #444; + border-width: 1px 0; +} + +#mainmenu ul li.selected:first-child > a { + border-top: none; +} + +#mainmenu ul li li > a { font-size: 85%; + padding-left: 1.5em; } -ul.tabmenu li.active a { - font-weight: bold; - color: #000000; - background: #f5f5f5; - border: 1px solid #AAAAAA; - border-bottom: none; +#mainmenu ul li > ul { + flex-basis: 100%; + max-height: 0; + visibility: hidden; + transition: max-height .15s; } -ul.tabmenu li a:hover { - color: #444444; - border-color: #444444; +#mainmenu ul:not(.active) li.selected > ul, +#mainmenu ul li.active > ul { + max-height: 1000px; + visibility: visible; + transition: max-height .25s; } -ul.l1 li a { - background-color: #AAAAAA; - background-image: url(tabbg.png); - background-repeat: repeat-x; - border-color: #444444; +#mainmenu ul li.mainmenu-item-logout { + margin-top: 15%; +} + +#tabmenu { + padding: 0; + margin: -.5em -.5em 1em -.5em; + background: #bbb; +} + +#tabmenu ul { + border-color: #444; + padding-top: .5em; + flex-wrap: wrap; + background: repeating-linear-gradient(#f5f5f5, #bbb 2.4em, #f5f5f5 2.4em, #bbb); + line-height: 1em; } -ul.l1 li.tabmenu-item-logout a { - margin-left: 30px; +#tabmenu ul li { + border-color: #444; } -.lang_he ul.l1 li.tabmenu-item-logout a { - margin-right: 30px; +#tabmenu ul li.cbi-tab { + background: #f5f5f5; } abbr, @@ -151,6 +189,13 @@ code { white-space: pre; } +hr { + margin: .5em 0; + padding: 0; + border: 1px solid #444; + border-width: 0 0 1px 0; +} + #maincontent ul { margin-left: 2em; } @@ -183,7 +228,6 @@ code { } .alert-message { - font-size: 9pt; font-weight: normal; padding: .5em; border-radius: 3px; @@ -206,7 +250,6 @@ code { .alert-message > h4 { font-weight: bold; - font-size: 10pt; } div.hostinfo { @@ -348,56 +391,35 @@ textarea#syslog { direction: rtl; } -#maincontent h2 { +h2, h3, h4, legend { font-size: 150%; font-family: Trebuchet MS, Verdana, sans-serif; font-weight: bold; - margin: 0.25em 0 0.7em 0; + margin: .25em 0 .5em 0; border-bottom: 1px solid; - padding-top: 10px; padding-bottom: 4px; + display: block; + width: 100%; } -#maincontent h3 { - margin: 0.5em 0 1.1em 0; +h3, legend { font-size: 125%; - font-weight: bold; - font-style: italic; - font-family: Trebuchet MS, Verdana, sans-serif; - color: #27408B; } -#maincontent p { - margin-bottom: 1em; +h4 { + font-size: 112%; } -.cbi-section { - margin-bottom: 0.5em; - padding: 0.5em 1em; - border: 1px dotted #555555; - background-color: #ffffff; - color: #000000; -} +fieldset > legend { float: left; } +fieldset > legend + * { clear: both; } -.cbi-section legend { - font-size: 110%; - font-weight: bold; - height: 1em; - padding: 0 0.25em; - background-color: transparent; - color: #555555; -} - -.cbi-section h2 { - margin: 0em 0 0.5em -0.5em !important; +#maincontent p { + margin-bottom: 1em; } -.cbi-section h3 { - text-decoration: none !important; - font-weight: bold !important; - color: #555555 !important; - margin: 0.25em !important; - font-size: 100% !important; +.cbi-section { + padding: .5em; + margin-top: .5em; } .cbi-section-descr { @@ -405,6 +427,10 @@ textarea#syslog { font-size: 95%; } +.cbi-section-descr:empty { + display: none; +} + .cbi-title-ref { color: inherit; text-decoration: none; @@ -450,7 +476,7 @@ input[type=image] { } input:focus, -input:hover, +input:not(.cbi-button):hover, select:focus, select:hover { background-color: #ffffff; @@ -459,21 +485,34 @@ select:hover { input[type=text], input[type=password] { - padding: 1px 3px; + padding: 0 3px; } select, input[type=text], input[type=password] { - font-size: inherit; width: 20em; + font-size: inherit; + line-height: 13pt; + height: 14pt; +} + +input[type=radio], +input[type=checkbox], +[data-dynlist] > input + img, +input.cbi-input-password + img { + vertical-align: middle; } .td select, .td .cbi-dropdown, -.td input[type=text], -.td input[type=password] { - width: 99%; +.td input[type=text] { + width: 100%; +} + +.td [data-dynlist] > input, +.td input.cbi-input-password { + width: calc(100% - 20px); } img.cbi-image-button { @@ -483,18 +522,23 @@ img.cbi-image-button { } .btn, .cbi-button { - padding: 2px; + padding: 0 .5em; border-radius: 3px; border: 1px solid #aaa; - background: #eee 1px center no-repeat; text-decoration: none; color: #000; display: inline-block; + font-size: inherit; + -webkit-appearance: none; + background: #fff; + text-align: center; + font-weight: bold; + line-height: 13pt; + height: 14pt; } .btn:hover, .cbi-button:hover { - border-color: #4a6b7c; - background-color: #fff; + box-shadow: 0 0 3px #59d; } .btn[disabled], @@ -503,153 +547,59 @@ img.cbi-image-button { .cbi-button[disabled]:hover { opacity: .6; cursor: default; - border-color: inherit; - background-color: inherit; -} - -input.cbi-input-user { - background-image: url('../resources/cbi/user.gif'); - background-repeat: no-repeat; - background-position: 1px center; - color: #000000; - text-indent: 17px; -} - -input.cbi-input-password { - background-image: url('../resources/cbi/key.gif'); - background-repeat: no-repeat; - background-position: 1px center; - color: #000000; - text-indent: 17px; -} - -input.cbi-input-find, -input.cbi-button-find { - background-image: url('../resources/cbi/find.gif'); - color: #000000; - padding-left: 17px; -} - -input.cbi-input-reload { - background-image: url('../resources/cbi/reload.gif'); - color: #000000; - padding-left: 17px; -} - -input.cbi-input-add, -input.cbi-button-add { - background-image: url('../resources/cbi/add.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; -} - -input.cbi-input-fieldadd, -input.cbi-button-fieldadd { - background-image: url(../resources/cbi/fieldadd.gif); - color: #000000; - padding-left: 17px; -} - -input.cbi-input-reset, -input.cbi-button-reset { - background-image: url('../resources/cbi/reset.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; -} - -input.cbi-input-save, -input.cbi-button-save { - background-image: url('../resources/cbi/save.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; -} - -/* -input.cbi-input-apply, -input.cbi-button-apply { - background-image: url('../resources/cbi/apply.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; -} -*/ - -input.cbi-input-apply:before, -input.cbi-button-apply:before { - background-image: url('../resources/cbi/apply.gif'); - border: 2px solid red; - width: 100px; - height: 100px; - content: "."; - display: block; - position: absolute; -} - -input.cbi-input-link, -input.cbi-button-link { - background-image: url('../resources/cbi/link.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; -} - -input.cbi-input-download, -input.cbi-button-download { - background-image: url('../resources/cbi/download.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; + pointer-events: none; } -input.cbi-input-remove, -div.cbi-section-remove input { - background-image: url('../resources/cbi/remove.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; +.cbi-button-positive, +.cbi-button-fieldadd, +.cbi-button-add, +.cbi-button-save { + border-color: #7b7; + color: #7b7; } -input.cbi-button-up { - background-image: url('../resources/cbi/up.gif'); - padding-left: 11px; - padding-right: 1px; +.cbi-button-neutral, +.cbi-button-reset, +.cbi-button-download, +.cbi-button-find, +.cbi-button-link, +.cbi-button-up, +.cbi-button-down { + border-color: #444; + color: #444; } -input.cbi-button-down { - background-image: url('../resources/cbi/down.gif'); - padding-left: 11px; - padding-right: 1px; +.cbi-button-action, +.cbi-button-apply, +.cbi-button-reload, +.cbi-button-edit { + border-color: #59d; + color: #59d; } -input.cbi-button-edit { - background-image: url('../resources/cbi/edit.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; +.cbi-button-negative, +.cbi-section-remove .cbi-button, +.cbi-button-remove { + border-color: #b77; + color: #b77; } -input.cbi-button-reload { - background-image: url('../resources/cbi/reload.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; +.cbi-button-action.important, +.cbi-page-actions .cbi-button-apply, +.cbi-section-actions .cbi-button-edit { + color: #fff; + background: #59d; } -input.cbi-button-reset { - background-image: url('../resources/cbi/reset.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; +.cbi-button-positive.important, +.cbi-page-actions .cbi-button-save { + color: #fff; + background: #7b7; } -input.cbi-button-remove { - background-image: url('../resources/cbi/remove.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; +.cbi-page-actions .cbi-button-apply + .cbi-button-save { + background: #fff; + color: #7b7; } .cbi-input-invalid { @@ -660,30 +610,13 @@ input.cbi-button-remove { border-color: #FF0000; } -div.cbi-section-remove input { - border-bottom: none; -} - -textarea { - margin-left: -1px; - margin-bottom: 0.5em; -} - -form > div > input[type=submit], -form > div > input[type=reset] { - float: right; - margin-left: 0.5em; -} - table td, table th { color: #000000; } .table .td, .table .th { color: #000000; - padding: .25em 0; - text-align: center; - vertical-align: middle; + padding: .25em; } .table.smalltext { @@ -716,39 +649,23 @@ table td, table th { border-left: 1px solid #666666; } -.table.cbi-section-table .cbi-rowstyle-1 { +.cbi-rowstyle-1 { background-color: #eeeeff; color: #000000; } -.table.cbi-section-table .cbi-rowstyle-1:hover, -.table.cbi-section-table .cbi-rowstyle-2:hover { - background-color: #b2c8d4; - color: #000000; -} - -.table.cbi-section-table .cbi-section-table-cell { - padding: 3px; - white-space: nowrap; -} - -.cbi-section .cbi-rowstyle-1 h3 { - background-color: #eeeeff; - color: #555555; -} - .cbi-rowstyle-2 { color: #000000; } -div.cbi-value { +.cbi-value { clear: left; vertical-align: middle; padding: 0.25em 0.6em; border-bottom: 1px dotted #bbbbbb; } -div.cbi-value:hover { +.cbi-value:hover { background: #f8f8f8; color: #000000; } @@ -759,35 +676,49 @@ div.cbi-value:hover { line-height: 1.8em; } -div.cbi-value-field { +.cbi-value-field { width: 58%; margin-left: 40%; padding: 0.25em 0; } -div.td.cbi-value-field { +.td.cbi-value-field { width: auto; - vertical-align: middle; + margin-left: 0; + align-self: center; } -div.cbi-value-description { - font-size: 90%; - display: inline; +.cbi-value-description { + background-image: url(/luci-static/resources/cbi/help.gif); + background-position: .25em .25em; + background-repeat: no-repeat; + margin: .25em 0 0 0; + padding: .25em .25em .25em 1.75em; } -div.cbi-section-create { - clear: left; - white-space: nowrap; - vertical-align: top; +.cbi-section-create { + padding: 0 0 .25em 0; + margin: -3px; + display: inline-flex; + align-items: center; +} + +.cbi-section-create > * { + margin: 3px; + flex: 1 1 auto; +} + +.cbi-section-create > * > input { + width: 100%; } -div.cbi-section-create .btn, -div.cbi-section-create .cbi-button { - margin: 0.25em; +.cbi-section-remove > .cbi-button { + margin-bottom: -1px; + border-radius: 3px 3px 0 0; } -input.cbi-section-create-name { - margin-right: -0.25em; +.cbi-section-node + .cbi-section-create { + padding-top: 0; } div.cbi-map-descr { @@ -799,43 +730,39 @@ div.cbi-optionals { border-bottom: 1px dotted #bbbbbb; } -div.cbi-section-remove { - float: right; -} - .cbi-section-node { clear: both; - border: 1px solid #BBBBBB; - border-radius: 3px; padding-bottom: 0; position: relative; + border: 1px dotted #555; + background: #fff; + margin-bottom: 5px; } .cbi-section-node-tabbed { - border-top-left-radius: 0; -} - -.cbi-section-node .cbi-value-last { - border-bottom: none; + border-top: none; } -.cbi-section-node .table div { - padding-bottom: 0; +.cbi-section-node .cbi-value:last-child { border-bottom: none; } -.cbi-section-node div.cbi-section-table-row { - margin: 0.25em; -} - .table.cbi-section-table { width: 100%; font-size: 95%; + border: 1px dotted #444; + background: #fff; + margin: 0 0 .5em 0; } -.table.cbi-section-table .th, -.table.cbi-section-table .td { - text-align: center; +@keyframes flash { + 0% { opacity: 1; } + 50% { opacity: .5; } + 100% { opacity: 1; } +} + +.tr.cbi-section-table-row.flash { + animation: flash .35s; } .tr.cbi-section-table-descr .th { @@ -849,6 +776,93 @@ div.cbi-section-remove { padding-top: 1em; } +.th.cbi-section-actions, +.td.cbi-section-actions { + display: flex; + justify-content: flex-end; + flex-direction: row; + flex: 1 1 150px; + margin: auto -1px auto auto; +} + +.td.cbi-section-actions > form { + display: flex; +} + +.td.cbi-section-actions > *, +.td.cbi-section-actions > form > * { + flex: 1 1 4em; + margin: 1px; +} + +.cbi-page-actions { + display: flex; + justify-content: flex-end; + margin: -3px; + padding: 0 .25em .25em .25em; +} + +.cbi-page-actions > form { + display: flex; +} + +.cbi-page-actions > * { + flex: 0 1 auto; + margin: 3px; +} + +.cbi-page-actions > form > * { + flex: 1; + margin: 0 3px 0 0; +} + +.cbi-page-actions > .cbi-button-link, +.cbi-page-actions > form[method="get"]:first-child { + margin-right: auto; +} + + +.th[data-type="button"], .td[data-type="button"], +.th[data-type="fvalue"], .td[data-type="fvalue"] { + flex: 1 1 2em; + text-align: center; +} + +#cbi-network-switch_vlan .th, +#cbi-network-switch_vlan .td { + flex-basis: 12%; +} + +#cbi-wireless-overview .td:first-child { + align-self: center; +} + +.td[data-title]::before { + content: attr(data-title) ":\20"; + font-weight: bold; + text-align: left; + display: none; + padding: 1px; + white-space: nowrap; +} + +.tr.placeholder .td[data-title]::before { + display: none; +} + +.tr[data-title]::before, +.tr.cbi-section-table-titles.named::before { + content: attr(data-title) "\20"; + font-weight: bold; + text-align: left; + display: inline-block; + align-self: center; + flex: 1 1 5%; + padding: .25em; + white-space: normal; + word-wrap: break-word; +} + .cbi-value-helpicon img { vertical-align: bottom; } @@ -877,55 +891,54 @@ div.cbi-section-remove { } ul.cbi-tabmenu { - padding: 3px 0; - margin-left: 0 !important; list-style-type: none; - position: relative; - z-index: 10; - top: 4px; - line-height: 20px; -} - -ul.cbi-tabmenu li.cbi-tab, -ul.cbi-tabmenu li.cbi-tab-disabled { - display: inline; - margin: 0; + display: flex; + margin: 0 !important; + padding: 0 0 0 5px; + border-bottom: 1px solid #bbb; } -ul.cbi-tabmenu li.cbi-tab a, -ul.cbi-tabmenu li.cbi-tab-disabled a { - text-decoration: none; - padding: 3px 7px; - margin-right: 3px; - border: 1px solid #BBBBBB; +ul.cbi-tabmenu li { + display: inline-flex; + margin: 0 5px -1px 0; + flex: 0 1 auto; + border: 1px solid #bbb; border-bottom: none; border-radius: 3px 3px 0 0; - background-color: #EEEEEE; - color: #BBBBBB; + background: linear-gradient(#ddd 90%, #aaa 100%); + color: #888; + overflow: hidden; + text-overflow: ellipsis; + word-wrap: break-word; } -ul.cbi-tabmenu li.cbi-tab-highlighted a { - color: #000000; - background-color: #FFEEAA; +ul.cbi-tabmenu li a, +ul.cbi-tabmenu li a:hover { + text-decoration: none; + color: inherit; + padding: 5px; + flex: 1; + width: 100%; + height: 100%; } -ul.cbi-tabmenu li a:hover { - color: #000000; +ul.cbi-tabmenu li.cbi-tab-highlighted { + color: #000; + background: #fea; } -ul.cbi-tabmenu li.cbi-tab a { - padding-top: 4px; - color: #000000; - background-color: #FFFFFF; +ul.cbi-tabmenu li.cbi-tab { + color: #000; + background: #fff; } -div.cbi-tab-descr { +.cbi-tab-descr { background-image: url(/luci-static/resources/cbi/help.gif); - background-position: 0.25em 50%; + background-position: .25em 50%; background-repeat: no-repeat; - border-bottom: 1px solid #CCCCCC; - margin: 0.25em 0.25em 2em; - padding: 0.5em 0.5em 0.5em 2em; + border-bottom: 1px solid #ccc; + margin: 0 .25em .25em .25em; + padding: .5em .5em .5em 2em; } @@ -938,6 +951,7 @@ div.cbi-tab-descr { padding: 0; color: #000; min-width: 20em; + max-width: 100%; } .cbi-dropdown:hover { @@ -1091,18 +1105,79 @@ div.cbi-tab-descr { } -.left { +.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: 1px; + background: inherit; + margin: -1.6em 0 0 -5px; +} + + +.zone-forwards { + display: flex; + flex-wrap: wrap; +} + +.zone-forwards > * { + flex: 1 1 45%; + padding: 1px; +} + +.zone-forwards > span { + flex-basis: 10%; + text-align: center; +} + +.zone-forwards .zone-src, +.zone-forwards .zone-dest { + display: flex; + flex-direction: column; +} + + +.left, .left::before { text-align: left !important; } -.right { +.right, .right::before { text-align: right !important; } -.center { +.center, .center::before { text-align: center !important; } +.td.bottom { + align-self: flex-end; +} + +.td.top { + align-self: flex-start; +} + +.td.middle { + align-self: center; +} + .luci { position: absolute; bottom: 0; @@ -1154,10 +1229,13 @@ div.cbi-tab-descr { align-items: center; } +.ifacebadge > * { + align-self: flex-start; +} + .ifacebadge > img, .ifacebadge > em { margin-right: 5px; - align-self: start; display: inline-block; height: 16px; } @@ -1169,15 +1247,21 @@ div.cbi-tab-descr { .ifacebox { flex-direction: column; - margin: 0 10px; + margin: 0; padding: 0; min-width: 100px; + text-align: center; } .ifacebox > * { padding: 2px; } +.td > .ifacebadge, +.td > .zonebadge { + margin: 0; + vertical-align: top; +} .network-status-table { display: flex; @@ -1205,6 +1289,7 @@ div.cbi-tab-descr { flex-wrap: wrap; } +.ifacebadge.large, .network-status-table .ifacebox-body .ifacebadge { flex: 1; margin: .5em .25em .25em .25em; @@ -1218,7 +1303,6 @@ div.cbi-tab-descr { padding: 2px; display: inline-block; white-space: nowrap; - cursor: pointer; border-radius: 3px; } @@ -1234,7 +1318,7 @@ div.cbi-tab-descr { .zonebadge .ifacebadge, .cbi-dropdown .ifacebadge { - margin: 0 .125em; + margin: 1px; } .zonebadge .ifacebadge img, @@ -1322,3 +1406,313 @@ div.cbi-tab-descr { } + +@media screen and (max-width: 992px) { + body { + -webkit-text-size-adjust: 100%; + } + + #maincontainer { + flex-direction: column; + width: 100%; + } + + #maincontent { + width: 96%; + margin: auto; + } + + #mainmenu { + border: none; + border-radius: 0; + max-width: none; + background: #000; + box-shadow: 0 0 2px #444; + padding: 0; + border-top: 1px solid #444; + position: relative; + } + + #mainmenu ul > li.selected > a { + background: #444; + color: #fff; + border-top: none; + } + + #mainmenu ul > li.selected:not(.active) > ul { + max-height: 0; + visibility: hidden; + } + + #mainmenu ul > li > a { + flex: 1; + color: #fff; + border: 1px solid #444; + border-width: 0 0 1px 1px; + } + + #mainmenu ul.l1 { + display: flex; + flex-direction: row; + flex-wrap: wrap; + position: relative; + margin-left: -1px; + width: 100%; + } + + #mainmenu ul.l1 > li { + display: inline-flex; + flex: 1 1 auto; + position: relative; + height: 2em; + } + + #mainmenu ul.l1 ul.l2 { + position: absolute; + top: 2em; + right: 0; + z-index: 1000; + background: #000; + box-shadow: 0 0 2px #444; + min-width: 120px; + display: block; + } + + #mainmenu ul.l1 ul.l2.align-left { + right: auto; + left: 0; + } + + #mainmenu ul.l2 > li { + display: block; + } + + #mainmenu ul.l2 > li > a { + padding: .5em; + } + + #mainmenu ul li.mainmenu-item-logout { + margin-top: 0; + margin-left: auto; + } + + #mainmenu ul li.mainmenu-item-logout::before { + content: "\0a"; + flex: 10; + border: 1px solid #444; + border-width: 0 0 1px 1px; + } + + .table { + display: flex; + flex-direction: column; + width: 100%; + } + + .tr { + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: flex-end; + } + + .th, .td { + flex: 2 2 25%; + align-self: flex-start; + overflow: hidden; + text-overflow: ellipsis; + word-wrap: break-word; + display: inline-block; + } + + .td select { + word-wrap: normal; + } + + .td[data-type="button"], + .td[data-type="fvalue"] { + flex: 1 1 12.5%; + text-align: left; + } + + .td.cbi-value-field { + align-self: flex-start; + } + + .td.cbi-value-field .cbi-button { + width: 100%; + } + + .table.cbi-section-table { + border: none; + background: none; + margin: 0; + } + + .tr.table-titles, + .cbi-section-table-titles, + .cbi-section-table-descr { + display: none; + } + + .cbi-section-table-row { + display: flex; + flex-direction: row; + flex-wrap: wrap; + border: 1px dotted #444; + margin: 0 0 .5em 0; + background: #fff; + } + + .cbi-section-table-row:hover { + border: 1px solid #4a6b7c; + } + + .cbi-section-table + .cbi-section-create { + padding-top: 0; + } + + .tr[data-title]::before { + display: block; + flex: 1 1 100%; + background: #eef; + } + + .td[data-title]::before { + display: block; + } + + .td.cbi-section-actions { + flex-basis: 100%; + margin: auto -1px 0 auto; + } + + .td.cbi-section-actions > *, + .td.cbi-section-actions > form > * { + flex: 0 1 100%; + max-width: 150px; + } + + .hide-sm, + .hide-xs { + display: none; + } +} + +@media screen and (max-width: 480px) { + body { + font-size: 12pt; + } + + input, textarea, select { + font-size: 12pt !important; + line-height: 1.4em; + } + + select, input[type="text"], input[type="password"] { + width: 100%; + height: 1.4em; + } + + [data-dynlist] > input, + input.cbi-input-password { + width: calc(100% - 20px); + } + + .cbi-dropdown { + min-width: 100%; + } + + .btn, .cbi-button { + font-size: 9pt !important; + line-height: 11pt; + } + + #maincontent { + padding: .25em; + } + + #tabmenu { + margin: -.25em -.25em 1em -.25em; + } + + .th, .td { + flex: 2 2 50%; + } + + .td.cbi-value-field { + flex-basis: 100%; + } + + .td.cbi-value-field[data-type="dvalue"] { + flex-basis: 50%; + } + + .td.cbi-value-field[data-type="button"], + .td.cbi-value-field[data-type="fvalue"] { + flex-basis: 25%; + text-align: left; + } + + .cbi-section { + padding: .25em; + } + + .cbi-value-title { + float: none; + font-weight: bold; + } + + .cbi-value-field { + width: 100%; + margin: 0; + } + + .cbi-value-description { + margin-top: 5px; + display: block; + } + + .cbi-section-create { + margin-bottom: 1em; + } + + .cbi-page-actions { + flex-wrap: wrap; + } + + .cbi-page-actions > .cbi-button-link { + flex-basis: 100%; + margin-right: 2px; + } + + .cbi-page-actions > * { + flex: 1 1 auto; + margin: 2px; + } + + ul.cbi-tabmenu { + padding: 0 3px; + } + + ul.cbi-tabmenu li { + font-size: 90%; + margin: 0 1px -1px 0; + } + + .hide-xs { + display: none; + } + + #cbi-network .td[id] > strong { + display: block; + } + + #cbi-network-switch_vlan .td.cbi-section-actions { + flex-basis: 100%; + } + + .network-status-table .ifacebox { + margin: 0 0 .5em 0; + } +} diff --git a/themes/luci-theme-openwrt/luasrc/view/themes/openwrt.org/header.htm b/themes/luci-theme-openwrt/luasrc/view/themes/openwrt.org/header.htm index cbf02a76cd..773cf1f82e 100644 --- a/themes/luci-theme-openwrt/luasrc/view/themes/openwrt.org/header.htm +++ b/themes/luci-theme-openwrt/luasrc/view/themes/openwrt.org/header.htm @@ -56,9 +56,39 @@ local childs = disp.node_childs(node) if #childs > 0 then - write('<div class="tabmenu%d"><ul class="tabmenu l%d">' %{ - level, level - }) + write('<ul class="mainmenu l%d">' % 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_name @@ -71,20 +101,22 @@ selected_name = v end - write('<li class="tabmenu-item-%s %s"><a href="%s">%s</a></li>' %{ - v, (nnode._menu_selected or (node.leaf and v == leaf)) and 'active' or '', - nodeurl(prefix, v, nnode.query), - striptags(translate(nnode.title)) - }) + if level > 2 then + write('<li class="tabmenu-item-%s %s"><a href="%s">%s</a></li>' %{ + v, (nnode._menu_selected or (node.leaf and v == leaf)) and 'cbi-tab' or '', + nodeurl(prefix, v, nnode.query), + striptags(translate(nnode.title)) + }) + end end - write('</ul><br style="clear:both" />') + if level > 2 then + write('</ul>') + end if selected_node then - render_menu(prefix .. "/" .. selected_name, selected_node, level + 1) + render_tabmenu(prefix .. "/" .. selected_name, selected_node, level + 1) end - - write('</div>') 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%>"> <head> <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" /> <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%>" /> @@ -125,6 +158,47 @@ </style> <% end -%> <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> </head> <body class="lang_<%=luci.i18n.context.lang%>"> @@ -161,11 +235,15 @@ </div> <div id="maincontainer"> - <div id="tabmenu"> + <div id="mainmenu"> <% if category then render_menu(category, cattree) end %> </div> <div id="maincontent"> + <div id="tabmenu"> + <% if category then render_tabmenu(category, cattree) end %> + </div> + <noscript> <div class="alert-message warning"> <h4><%:JavaScript required!%></h4> |