diff --git a/modules/admin-full/luasrc/controller/admin/system.lua b/modules/admin-full/luasrc/controller/admin/system.lua
index f5b6b1493c..d948f28202 100644
--- a/modules/admin-full/luasrc/controller/admin/system.lua
+++ b/modules/admin-full/luasrc/controller/admin/system.lua
@@ -52,6 +52,13 @@ function action_packages()
local stderr = { "" }
local out, err
+ -- Display
+ local display = luci.http.formvalue("display") or "installed"
+
+ -- Letter
+ local letter = string.byte(luci.http.formvalue("letter") or "A", 1)
+ letter = (letter == 35 or (letter >= 65 and letter <= 90)) and letter or 65
+
-- Search query
local query = luci.http.formvalue("query")
query = (query ~= '') and query or nil
@@ -111,6 +118,8 @@ function action_packages()
luci.template.render("admin_system/packages", {
+ display = display,
+ letter = letter,
query = query,
install = install,
remove = remove,
diff --git a/modules/admin-full/luasrc/view/admin_system/packages.htm b/modules/admin-full/luasrc/view/admin_system/packages.htm
index 51a1211712..e78f1c2ca7 100644
--- a/modules/admin-full/luasrc/view/admin_system/packages.htm
+++ b/modules/admin-full/luasrc/view/admin_system/packages.htm
@@ -34,6 +34,19 @@ local free_byte = space_free * fstat.frsize
local filter = { }
+
+local querypat
+if query and #query > 0 then
+ querypat = "*%s*" % query
+end
+
+local letterpat
+if letter == 35 then
+ letterpat = "[^a-zA-Z]*"
+else
+ letterpat = string.char(91, letter, letter + 32, 93, 42) -- '[' 'A' 'a' ']' '*'
+end
+
-%>
<%+header%>
@@ -55,9 +68,10 @@ local filter = { }
-
+
+ <% if querypat then %>
+
+ <%:Displaying only packages containing%>
"<%=pcdata(query)%>"
+
+ <% end %>
+
<% if (install and next(install)) or (remove and next(remove)) or update or upgrade then %>
<% if #stdout > 0 then %>
<%=pcdata(stdout)%> <% end %>
@@ -81,62 +101,75 @@ local filter = { }
-
<%:Installed packages%><% if query then %> (<%=pcdata(query)%>)<% end %>
-
-
-
-
-
- <%:Package name%>
- <%:Version%>
-
- <% local empty = true; luci.model.ipkg.list_installed(query, function(n, v, d) empty = false; filter[n] = true %>
-
- <%:Remove%>
- <%=luci.util.pcdata(n)%>
- <%=luci.util.pcdata(v)%>
-
- <% end) %>
- <% if empty then %>
-
-
- <%:none%>
- <%:none%>
-
- <% end %>
-
-
-
-
-
-
<%:Available packages%><% if query then %> (<%=pcdata(query)%>)<% end %>
-
-
-
-
-
- <%:Package name%>
- <%:Version%>
- <%:Description%>
-
- <% local empty = true; luci.model.ipkg.list_all(query, function(n, v, d) if filter[n] then return end; empty = false %>
-
- <%:Install%>
- <%=luci.util.pcdata(n)%>
- <%=luci.util.pcdata(v)%>
- <%=luci.util.pcdata(d)%>
-
- <% end) %>
- <% if empty then %>
-
-
- <%:none%>
- <%:none%>
- <%:none%>
-
- <% end %>
-
-
+
+
+ <% if display ~= "available" then %>
+
+
+
+
+ <%:Package name%>
+ <%:Version%>
+
+ <% local empty = true; luci.model.ipkg.list_installed(querypat, function(n, v, d) empty = false; filter[n] = true %>
+
+ <%:Remove%>
+ <%=luci.util.pcdata(n)%>
+ <%=luci.util.pcdata(v)%>
+
+ <% end) %>
+ <% if empty then %>
+
+
+ <%:none%>
+ <%:none%>
+
+ <% end %>
+
+
+ <% else %>
+
+ <% if not querypat then %>
+
+
+ <% end %>
+
+
+
+ <%:Package name%>
+ <%:Version%>
+ <%:Description%>
+
+ <% local empty = true; luci.model.ipkg.list_all(querypat or letterpat, function(n, v, d) if filter[n] then return end; empty = false %>
+
+ <%:Install%>
+ <%=luci.util.pcdata(n)%>
+ <%=luci.util.pcdata(v)%>
+ <%=luci.util.pcdata(d)%>
+
+ <% end) %>
+ <% if empty then %>
+
+
+ <%:none%>
+ <%:none%>
+ <%:none%>
+
+ <% end %>
+
+ <% if not querypat then %>
+
+ <% end %>
+
+ <% end %>
<%+footer%>