treewide: rework uci change display
authorJo-Philipp Wich <jo@mein.io>
Sat, 4 Aug 2018 20:09:49 +0000 (22:09 +0200)
committerJo-Philipp Wich <jo@mein.io>
Sun, 20 Jan 2019 11:28:39 +0000 (12:28 +0100)
 - Use native rpcd uci changes format instead of incompletely converting
   back and forth between the old and the new format
 - Rework uci changelog template to print the equivalent uci commands
   for the various changes
 - Rework theme headers to properly count the uncomitted changes
 - Rework theme CSS to properly style new changelog

Fixes: #2170

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
(cherry picked from commit 849d153851db2fc193c1c82648dbe719463d3a38)

modules/luci-base/luasrc/model/uci.lua
modules/luci-mod-admin-full/luasrc/view/admin_uci/changelog.htm
themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css
themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/header.htm
themes/luci-theme-material/luasrc/view/themes/material/header.htm
themes/luci-theme-openwrt/htdocs/luci-static/openwrt.org/cascade.css
themes/luci-theme-openwrt/luasrc/view/themes/openwrt.org/header.htm

index b2c1e463bf97db59b0515195a22e56406884e99f..2119a210bb9884cf4e312a1ec181732c17dac5c0 100644 (file)
@@ -95,41 +95,15 @@ end
 
 
 function changes(self, config)
-       local rv = call("changes", { config = config })
-       local res = {}
+       local rv, err = call("changes", { config = config })
 
        if type(rv) == "table" and type(rv.changes) == "table" then
-               local package, changes
-               for package, changes in pairs(rv.changes) do
-                       res[package] = {}
-
-                       local _, change
-                       for _, change in ipairs(changes) do
-                               local operation, section, option, value = unpack(change)
-                               if option and operation ~= "add" then
-                                       res[package][section] = res[package][section] or { }
-
-                                       if operation == "list-add" then
-                                               local v = res[package][section][option]
-                                               if type(v) == "table" then
-                                                       v[#v+1] = value or ""
-                                               elseif v ~= nil then
-                                                       res[package][section][option] = { v, value }
-                                               else
-                                                       res[package][section][option] = { value }
-                                               end
-                                       else
-                                               res[package][section][option] = value or ""
-                                       end
-                               else
-                                       res[package][section] = res[package][section] or {}
-                                       res[package][section][".type"] = option or ""
-                               end
-                       end
-               end
+               return rv.changes
+       elseif err then
+               return nil, ERRSTR[err]
+       else
+               return { }
        end
-
-       return res
 end
 
 
index e05ccdece332385ccf677b1efa8ea167ae3e8ef7..8a162c88b6f9dc1c2d2d5afb3e5b6720ec402331 100644 (file)
@@ -1,5 +1,5 @@
 <%#
- Copyright 2010 Jo-Philipp Wich <jow@openwrt.org>
+ Copyright 2010 Jo-Philipp Wich <jo@mein.io>
  Licensed to the public under the Apache License 2.0.
 -%>
 
 
        <div class="uci-change-list"><%
                local util = luci.util
-               local ret  = { }
+               local tpl = {
+                       ["add-3"] = "<ins>uci add %0 <strong>%3</strong> # =%2</ins>",
+                       ["set-3"] = "<ins>uci set %0.<strong>%2</strong></ins>=%3",
+                       ["set-4"] = "<var><ins>uci set %0.%2.%3=<strong>%4</strong></ins></var>",
+                       ["remove-2"] = "<del>uci del %0.<strong>%2</strong></del>",
+                       ["remove-3"] = "<var><del>uci del %0.%2.<strong>%3</strong></del></var>",
+                       ["order-3"] = "<var>uci reorder %0.%2=<strong>%3</strong></var>",
+                       ["list-add-4"] = "<var><ins>uci add_list %0.%2.%3=<strong>%4</strong></ins></var>",
+                       ["list-del-4"] = "<var><del>uci del_list %0.%2.%3=<strong>%4</strong></del></var>",
+                       ["rename-3"] = "<var>uci rename %0.%2=<strong>%3</strong></var>",
+                       ["rename-4"] = "<var>uci rename %0.%2.%3=<strong>%4</strong></var>"
+               }
 
-               for r, tbl in pairs(changes) do
-                       for s, os in pairs(tbl) do
-                               -- section add
-                               if os['.type'] and os['.type'] ~= "" then
-                                       ret[#ret+1] = "<ins>%s.%s=<strong>%s</strong>" %{ r, s, os['.type'] }
-                                       for o, v in util.kspairs(os) do
-                                               if o:sub(1,1) ~= "." then
-                                                       if type(v) == "table" then
-                                                               local i
-                                                               for i = 1, #v do
-                                                                       ret[#ret+1] = "<br />%s.%s.%s+=<strong>%s</strong>"
-                                                                               %{ r, s, o, util.pcdata(v[i]) }
-                                                               end
-                                                       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
-                                       ret[#ret+1] = "</ins><br />"
-
-                               -- section delete
-                               elseif os['.type'] and os['.type'] == "" then
-                                       ret[#ret+1] = "<del>%s.<strong>%s</strong></del><br />" %{ r, s }
+               local conf, deltas
+               for conf, deltas in util.kspairs(changes) do
+                       write("<h3># /etc/config/%s</h3>" % conf)
 
-                               -- modifications
-                               else
-                                       ret[#ret+1] = "<var>%s.%s<br />" %{ r, s }
-                                       for o, v in util.kspairs(os) do
-                                               if o:sub(1,1) ~= "." then
-                                                       if v and #v > 0 then
-                                                               ret[#ret+1] = "<ins>"
-                                                               if type(v) == "table" then
-                                                                       local i
-                                                                       for i = 1, #v do
-                                                                               ret[#ret+1] = "%s.%s.%s+=<strong>%s</strong><br />"
-                                                                                       %{ r, s, o, util.pcdata(v[i]) }
-                                                                       end
+                       local _, delta, added
+                       for _, delta in pairs(deltas) do
+                               local t = tpl["%s-%d" %{ delta[1], #delta }]
 
-                                                               else
-                                                                       ret[#ret+1] = "%s.%s.%s=<strong>%s</strong><br />"
-                                                                               %{ r, s, o, util.pcdata(v) }
-                                                               end
-                                                               ret[#ret+1] = "</ins>"
-                                                       else
-                                                               ret[#ret+1] = "<del>%s.%s.<strong>%s</strong><br /></del>" %{ r, s, o }
-                                                       end
+                               write(t:gsub("%%(%d)", function(n)
+                                       if n == "0" then
+                                               return conf
+                                       elseif n == "2" then
+                                               if added and delta[2] == added[1] then
+                                                       return "@%s[-1]" % added[2]
+                                               else
+                                                       return delta[2]
                                                end
+                                       elseif n == "4" then
+                                               return util.shellquote(delta[4])
+                                       else
+                                               return delta[tonumber(n)]
                                        end
-                                       ret[#ret+1] = "</var><br />"
+                               end))
+
+                               if delta[1] == "add" then
+                                       added = { delta[2], delta[3] }
                                end
                        end
-               end
 
-               write(table.concat(ret))
+                       write("<br />")
+               end
        %></div>
 </div>
 <%- end) %>
index 644a47fee1b8209d29fcd862ec62a0bcd2ac25db..260f5e31cc297c7aaa5630bee5a39b36efcd49fd 100644 (file)
@@ -23,7 +23,7 @@ body {
        padding: 5px;
 }
 
-h1, h2, h3, h4, h5, h6, p, pre, a, abbr, acronym, code, del, em, img, q, s,
+h1, h2, h3, h4, h5, h6, p, pre, a, abbr, acronym, code, del, em, img, ins, q, s,
 small, strike, strong, sub, sup, tt, var, dd, dl, dt, li, ol, ul, fieldset,
 form, label, legend, button, table, caption, tbody, tfoot, thead, tr, th, td,
 .table, .tbody, .tfoot, .thead, .tr, .th, .td {
@@ -1956,47 +1956,51 @@ div.cbi-value var,
 }
 
 .uci-change-list {
-       font-family: monospace;
+       line-height: 170%;
+       white-space: pre;
 }
 
+.uci-change-list del,
 .uci-change-list ins,
-.uci-change-legend-label ins {
+.uci-change-list var,
+.uci-change-legend-label del,
+.uci-change-legend-label ins,
+.uci-change-legend-label var {
        text-decoration: none;
-       border: 1px solid #0f0;
-       background-color: #cfc;
-       display: block;
+       font-family: monospace;
+       font-style: normal;
+       border: 1px solid #ccc;
+       background: #eee;
        padding: 2px;
+       display: block;
+       line-height: 15px;
+       margin-bottom: 1px;
+}
+
+.uci-change-list ins,
+.uci-change-legend-label ins {
+       border-color: #0f0;
+       background: #cfc;
 }
 
 .uci-change-list del,
 .uci-change-legend-label del {
-       text-decoration: none;
-       border: 1px solid #f00;
-       background-color: #fcc;
-       display: block;
-       font-style: normal;
-       padding: 2px;
+       border-color: #f00;
+       background: #fcc;
 }
 
 .uci-change-list var,
 .uci-change-legend-label var {
-       text-decoration: none;
-       border: 1px solid #ccc;
-       background-color: #eee;
-       display: block;
-       font-style: normal;
-       padding: 2px;
-       line-height: 19px;
-       white-space: pre;
+       border-color: #ccc;
+       background: #eee;
 }
 
 .uci-change-list var ins,
 .uci-change-list var del {
-       display: inline;
-       /*border: none;*/
-       white-space: pre;
-       font-style: normal;
-       padding: 0px;
+       display: inline-block;
+       border: none;
+       width: 100%;
+       padding: 0;
 }
 
 .uci-change-legend {
@@ -2016,12 +2020,17 @@ div.cbi-value var,
        width: 10px;
        height: 10px;
        display: block;
+       position: relative;
 }
 
 .uci-change-legend-label var ins,
 .uci-change-legend-label var del {
-       line-height: 6px;
        border: none;
+       position: absolute;
+       top: 2px;
+       left: 2px;
+       right: 2px;
+       bottom: 2px;
 }
 
 html body.apply-overlay-active {
index 6ad32efb47e2b1b0bb118e003fd1d263d5b2e68d..4347f133a463c3d5c64c3ccf47f150c2afbce6dc 100644 (file)
                if tree.nodes[category] and tree.nodes[category].ucidata then
                        local ucichanges = 0
 
+                       local i, j
                        for i, j in pairs(require("luci.model.uci").cursor():changes()) do
-                               for k, l in pairs(j) do
-                                       for m, n in pairs(l) do
-                                               ucichanges = ucichanges + 1;
-                                       end
-                               end
+                               ucichanges = ucichanges + #j
                        end
 
                        if ucichanges > 0 then
index e6047614f6a30ac5eea1a76cb60522cf65b8a0aa..c070b1a617cb53690aa5e90f1fbb7a7ce13465c7 100644 (file)
                -- calculate the number of unsaved changes
                if tree.nodes[category] and tree.nodes[category].ucidata then
                        local ucichanges = 0
-
+                       local i, j
                        for i, j in pairs(require("luci.model.uci").cursor():changes()) do
-                               for k, l in pairs(j) do
-                                       for m, n in pairs(l) do
-                                               ucichanges = ucichanges + 1;
-                                       end
-                               end
+                               ucichanges = ucichanges + #j
                        end
 
                        if ucichanges > 0 then
index e7952338efbb5cd693ebee26947849faf3d38e0c..5becfc5ba59ad1d44bc6af3c969d08060f9d9b7a 100644 (file)
@@ -1397,44 +1397,49 @@ select + .cbi-button {
 
 .uci-change-list {
        font-family: monospace;
+       white-space: pre;
 }
 
+.uci-change-list del,
 .uci-change-list ins,
-.uci-change-legend-label ins {
+.uci-change-list var,
+.uci-change-legend-label del,
+.uci-change-legend-label ins,
+.uci-change-legend-label var {
        text-decoration: none;
-       border: 1px solid #00FF00;
-       background-color: #CCFFCC;
-       display: block;
+       font-style: normal;
+       border: 1px solid #ccc;
+       background: #eee;
        padding: 2px;
+       display: block;
+       line-height: 15px;
+       margin-bottom: 1px;
+}
+
+.uci-change-list ins,
+.uci-change-legend-label ins {
+       border-color: #0f0;
+       background: #cfc;
 }
 
 .uci-change-list del,
 .uci-change-legend-label del {
-       text-decoration: none;
-       border: 1px solid #FF0000;
-       background-color: #FFCCCC;
-       display: block;
-       font-style: normal;
-       padding: 2px;
+       border-color: #f00;
+       background: #fcc;
 }
 
 .uci-change-list var,
 .uci-change-legend-label var {
-       text-decoration: none;
-       border: 1px solid #CCCCCC;
-       background-color: #EEEEEE;
-       display: block;
-       font-style: normal;
-       padding: 2px;
+       border-color: #ccc;
+       background: #eee;
 }
 
 .uci-change-list var ins,
 .uci-change-list var del {
-       /*display: inline;*/
+       display: inline-block;
        border: none;
-       white-space: pre;
-       font-style: normal;
-       padding: 0px;
+       width: 100%;
+       padding: 0;
 }
 
 .uci-change-legend {
@@ -1452,15 +1457,20 @@ select + .cbi-button {
 .uci-change-legend-label>var {
        float: left;
        margin-right: 4px;
-       width: 10px;
-       height: 10px;
+       width: 12px;
+       height: 12px;
        display: block;
+       position: relative;
 }
 
 .uci-change-legend-label var ins,
 .uci-change-legend-label var del {
-       line-height: 6px;
        border: none;
+       position: absolute;
+       top: 1px;
+       left: 1px;
+       right: 1px;
+       bottom: 1px;
 }
 
 
index e77f9a4bfee1bb382a7b075cd4fa0f6f8c173e5a..6fc657ddce9acf0facd579c736559c65c52b6b4c 100644 (file)
        local function render_changes()
                if tree.nodes[category] and tree.nodes[category].ucidata then
                        local ucic = 0
+                       local i, j
                        for i, j in pairs(require("luci.model.uci").cursor():changes()) do
-                               for k, l in pairs(j) do
-                                       for m, n in pairs(l) do
-                                               ucic = ucic + 1;
-                                       end
-                               end
+                               ucic = ucic + #j
                        end
 
                        if ucic > 0 then