mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-07-27 08:31:44 +08:00
364 lines
10 KiB
HTML
364 lines
10 KiB
HTML
<%-
|
|
local rowcnt = 0
|
|
|
|
function rowstyle()
|
|
rowcnt = rowcnt + 1
|
|
if rowcnt % 2 == 0 then
|
|
return " cbi-rowstyle-1"
|
|
else
|
|
return " cbi-rowstyle-2"
|
|
end
|
|
end
|
|
|
|
function width(o)
|
|
if o.width then
|
|
if type(o.width) == "number" then
|
|
return ' style="width:%dpx"' % o.width
|
|
end
|
|
return ' style="width:%s"' % o.width
|
|
end
|
|
return ""
|
|
end
|
|
|
|
local has_titles = false
|
|
local has_descriptions = false
|
|
|
|
local anonclass = (not self.anonymous or self.sectiontitle) and "named" or "anonymous"
|
|
local titlename = ifattr(not self.anonymous or self.sectiontitle, "data-title", translate("Name"))
|
|
|
|
local i, k
|
|
for i, k in pairs(self.children) do
|
|
if not k.typename then
|
|
k.typename = k.template and k.template:gsub("^.+/", "") or ""
|
|
end
|
|
|
|
if not has_titles and k.title and #k.title > 0 then
|
|
has_titles = true
|
|
end
|
|
|
|
if not has_descriptions and k.description and #k.description > 0 then
|
|
has_descriptions = true
|
|
end
|
|
end
|
|
|
|
local total = tonumber(self.server_total) or 0
|
|
local page = tonumber(self.server_page) or 1
|
|
local page_size = tonumber(self.server_page_size) or 0
|
|
local page_count = tonumber(self.server_page_count) or 1
|
|
local first_index = tonumber(self.server_first_index) or 0
|
|
local last_index = tonumber(self.server_last_index) or 0
|
|
local page_sizes = self.server_page_sizes or {}
|
|
local base_url = self.server_base_url or ""
|
|
|
|
local function page_url(target_page, target_size)
|
|
return string.format(
|
|
"%s?server_page=%d&server_page_size=%d",
|
|
base_url,
|
|
target_page,
|
|
target_size
|
|
)
|
|
end
|
|
|
|
function render_titles()
|
|
if not has_titles then
|
|
return
|
|
end
|
|
|
|
%><tr class="tr cbi-section-table-titles <%=anonclass%>"<%=titlename%>><%
|
|
|
|
local i, k
|
|
for i, k in ipairs(self.children) do
|
|
if not k.optional then
|
|
%><th class="th cbi-section-table-cell"<%=
|
|
width(k) .. attr("data-widget", k.typename) %>><%
|
|
|
|
if k.titleref then
|
|
%><a title="<%=self.titledesc or translate("Go to relevant configuration page")%>" class="cbi-title-ref" href="<%=k.titleref%>"><%
|
|
end
|
|
|
|
write(k.title)
|
|
|
|
if k.titleref then
|
|
%></a><%
|
|
end
|
|
|
|
%></th><%
|
|
end
|
|
end
|
|
|
|
if self.sortable or self.extedit or self.addremove then
|
|
%><th class="th cbi-section-table-cell cbi-section-actions"></th><%
|
|
end
|
|
|
|
%></tr><%
|
|
|
|
rowcnt = rowcnt + 1
|
|
end
|
|
|
|
function render_descriptions()
|
|
if not has_descriptions then
|
|
return
|
|
end
|
|
|
|
%><tr class="tr cbi-section-table-descr <%=anonclass%>"><%
|
|
|
|
local i, k
|
|
for i, k in ipairs(self.children) do
|
|
if not k.optional then
|
|
%><th class="th cbi-section-table-cell"<%=
|
|
width(k) .. attr("data-widget", k.typename) %>><%
|
|
|
|
write(k.description)
|
|
|
|
%></th><%
|
|
end
|
|
end
|
|
|
|
if self.sortable or self.extedit or self.addremove then
|
|
%><th class="th cbi-section-table-cell cbi-section-actions"></th><%
|
|
end
|
|
|
|
%></tr><%
|
|
|
|
rowcnt = rowcnt + 1
|
|
end
|
|
|
|
function render_pager()
|
|
if total == 0 then
|
|
return
|
|
end
|
|
|
|
%>
|
|
<div class="ssr-server-pager">
|
|
<span class="ssr-server-pager-summary">
|
|
<%=string.format(translate("Showing %d-%d of %d nodes"), first_index, last_index, total)%>
|
|
</span>
|
|
<span class="ssr-server-pager-pages">
|
|
<% if page_count > 1 then %>
|
|
<% if page > 1 then %>
|
|
<a class="cbi-button cbi-button-link" href="<%=page_url(page - 1, page_size)%>"><%:Prev%></a>
|
|
<% end %>
|
|
<% for current = 1, page_count do %>
|
|
<% if current == page then %>
|
|
<strong><%=current%></strong>
|
|
<% else %>
|
|
<a class="cbi-button cbi-button-link" href="<%=page_url(current, page_size)%>"><%=current%></a>
|
|
<% end %>
|
|
<% end %>
|
|
<% if page < page_count then %>
|
|
<a class="cbi-button cbi-button-link" href="<%=page_url(page + 1, page_size)%>"><%:Next%></a>
|
|
<% end %>
|
|
<% end %>
|
|
</span>
|
|
<span class="ssr-server-pager-sizes">
|
|
<%:Per page%>:
|
|
<% for _, size in ipairs(page_sizes) do %>
|
|
<%
|
|
local label = size == 0 and translate("All") or tostring(size)
|
|
local selected = size == page_size
|
|
%>
|
|
<% if selected then %>
|
|
<strong><%=label%></strong>
|
|
<% else %>
|
|
<a class="cbi-button cbi-button-link" href="<%=page_url(1, size)%>"><%=label%></a>
|
|
<% end %>
|
|
<% end %>
|
|
</span>
|
|
</div>
|
|
<input type="hidden" id="cbi-server-page" value="<%=page%>" />
|
|
<input type="hidden" id="cbi-server-page-size" value="<%=page_size%>" />
|
|
<%
|
|
end
|
|
-%>
|
|
|
|
<style type="text/css">
|
|
.ssr-server-pager {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 0.5rem 0.75rem;
|
|
align-items: center;
|
|
margin: 0.5rem 0 0.75rem;
|
|
}
|
|
|
|
.ssr-server-pager-pages,
|
|
.ssr-server-pager-sizes {
|
|
display: inline-flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
gap: 0.35rem;
|
|
}
|
|
|
|
.ssr-server-pager .cbi-button-link {
|
|
padding: 0 0.45rem;
|
|
min-width: 1.75rem;
|
|
text-align: center;
|
|
}
|
|
</style>
|
|
|
|
<!-- tblsection -->
|
|
<div class="cbi-section cbi-tblsection" id="cbi-<%=self.config%>-<%=self.sectiontype%>">
|
|
<script type="text/javascript">
|
|
if (!window.ssrXHR) {
|
|
window.ssrXHR = (function() {
|
|
function encode(data) {
|
|
var pairs = [];
|
|
var key;
|
|
for (key in (data || {})) {
|
|
if (Object.prototype.hasOwnProperty.call(data, key)) {
|
|
pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key] == null ? '' : data[key]));
|
|
}
|
|
}
|
|
return pairs.join('&');
|
|
}
|
|
|
|
function request(method, url, data, callback) {
|
|
var lower = method.toLowerCase();
|
|
if (window.XHR && typeof window.XHR[lower] === "function") {
|
|
return window.XHR[lower](url, data, callback);
|
|
}
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
var payload = encode(data);
|
|
var finalUrl = url;
|
|
|
|
if (lower === "get" && payload) {
|
|
finalUrl += (url.indexOf('?') === -1 ? '?' : '&') + payload;
|
|
}
|
|
|
|
xhr.open(method, finalUrl, true);
|
|
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
|
if (lower !== "get") {
|
|
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
|
|
}
|
|
xhr.onreadystatechange = function() {
|
|
if (xhr.readyState !== 4) return;
|
|
|
|
var rv = null;
|
|
try {
|
|
rv = JSON.parse(xhr.responseText || 'null');
|
|
} catch (e) {}
|
|
|
|
if (callback) callback(xhr, rv);
|
|
};
|
|
xhr.send(lower === "get" ? null : payload);
|
|
}
|
|
|
|
return {
|
|
get: function(url, data, callback) {
|
|
return request('GET', url, data, callback);
|
|
},
|
|
post: function(url, data, callback) {
|
|
return request('POST', url, data, callback);
|
|
}
|
|
};
|
|
})();
|
|
}
|
|
|
|
if (typeof window.ssrDeleteNode !== "function") {
|
|
window.ssrDeleteNode = function(sid) {
|
|
window.ssrXHR.post('<%=luci.dispatcher.build_url("admin", "services", "shadowsocksr", "delete_node")%>', {
|
|
sid: sid
|
|
}, function(x, result) {
|
|
result = result || {};
|
|
if (result.ret == 1) {
|
|
window.location.reload();
|
|
}
|
|
});
|
|
return false;
|
|
};
|
|
}
|
|
</script>
|
|
<% if self.title and #self.title > 0 then -%>
|
|
<h3><%=self.title%></h3>
|
|
<%- end %>
|
|
<%- if self.sortable then -%>
|
|
<input type="hidden" id="cbi.sts.<%=self.config%>.<%=self.sectiontype%>" name="cbi.sts.<%=self.config%>.<%=self.sectiontype%>" value="" />
|
|
<%- end -%>
|
|
<div class="cbi-section-descr"><%=self.description%></div>
|
|
<% render_pager() %>
|
|
<table class="table cbi-section-table">
|
|
<%-
|
|
render_titles()
|
|
render_descriptions()
|
|
|
|
local isempty, section, i, k = true, nil, nil
|
|
for i, k in ipairs(self:cfgsections()) do
|
|
isempty = false
|
|
section = k
|
|
|
|
local 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, true)
|
|
local colorclass = (self.extedit or self.rowcolors) and rowstyle() or ""
|
|
local scope = {
|
|
valueheader = "cbi/cell_valueheader",
|
|
valuefooter = "cbi/cell_valuefooter"
|
|
}
|
|
-%>
|
|
<tr 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
|
|
end
|
|
-%>
|
|
|
|
<%- if self.sortable or self.extedit or self.addremove then -%>
|
|
<td class="td cbi-section-table-cell nowrap cbi-section-actions">
|
|
<div>
|
|
<% if self.extedit then -%>
|
|
<input class="btn 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="btn cbi-button cbi-button-remove" type="button" value="<%:Delete%>"
|
|
onclick="return window.ssrDeleteNode('<%=k%>')"
|
|
/>
|
|
<%- end -%>
|
|
</div>
|
|
</td>
|
|
<%- end -%>
|
|
</tr>
|
|
<%- end -%>
|
|
|
|
<%- if isempty then -%>
|
|
<tr class="tr cbi-section-table-row placeholder">
|
|
<td class="td"><em><%:This section contains no values yet%></em></td>
|
|
</tr>
|
|
<%- end -%>
|
|
</table>
|
|
<% render_pager() %>
|
|
|
|
<% 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="btn 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%>.<%=section%>" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" data-type="uciname" data-optional="true" onkeyup="cbi_validate_named_section_add(this)" />
|
|
</div>
|
|
<input class="btn cbi-button cbi-button-add" type="submit" onclick="this.form.cbi_state='add-section'; return true" value="<%:Add%>" title="<%:Add%>" disabled="" />
|
|
<% end %>
|
|
</div>
|
|
<%- end %>
|
|
<%- end -%>
|
|
</div>
|
|
<!-- /tblsection -->
|