luci-app-dockerman: view/dockerman: update coding style
authorFlorian Eckert <fe@dev.tdt.de>
Wed, 29 Jul 2020 14:27:03 +0000 (16:27 +0200)
committerFlorian Eckert <fe@dev.tdt.de>
Wed, 29 Jul 2020 14:27:03 +0000 (16:27 +0200)
Signed-off-by: Florian Eckert <fe@dev.tdt.de>
applications/luci-app-dockerman/luasrc/view/dockerman/apply_widget.htm
applications/luci-app-dockerman/luasrc/view/dockerman/container.htm
applications/luci-app-dockerman/luasrc/view/dockerman/container_console.htm
applications/luci-app-dockerman/luasrc/view/dockerman/container_file.htm
applications/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm
applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm
applications/luci-app-dockerman/luasrc/view/dockerman/images_load.htm
applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm
applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm

index 4deb6a88ae3a078137f421b6f12ca6307a36e636..189055c20bd0a5c09c11ed0e50c432ded2053895 100644 (file)
 <style type="text/css">
-  #docker_apply_overlay {
-    position: absolute;
-    top: 0;
-    left: 0;
-    bottom: 0;
-    right: 0;
-    background: rgba(0, 0, 0, 0.7);
-    display: none;
-    z-index: 20000;
-  }
-
-  #docker_apply_overlay .alert-message {
-    position: relative;
-    top: 10%;
-    width: 60%;
-    margin: auto;
-    display: flex;
-    flex-wrap: wrap;
-    min-height: 32px;
-    align-items: center;
-  }
-
-  #docker_apply_overlay .alert-message > h4,
-  #docker_apply_overlay .alert-message > p,
-  #docker_apply_overlay .alert-message > div {
-    flex-basis: 100%;
-  }
-
-  #docker_apply_overlay .alert-message > img {
-    margin-right: 1em;
-    flex-basis: 32px;
-  }
-
-  body.apply-overlay-active {
-    overflow: hidden;
-    height: 100vh;
-  }
-
-  body.apply-overlay-active #docker_apply_overlay {
-    display: block;
-  }
+       #docker_apply_overlay {
+               position: absolute;
+               top: 0;
+               left: 0;
+               bottom: 0;
+               right: 0;
+               background: rgba(0, 0, 0, 0.7);
+               display: none;
+               z-index: 20000;
+       }
+
+       #docker_apply_overlay .alert-message {
+               position: relative;
+               top: 10%;
+               width: 60%;
+               margin: auto;
+               display: flex;
+               flex-wrap: wrap;
+               min-height: 32px;
+               align-items: center;
+       }
+
+       #docker_apply_overlay .alert-message > h4,
+       #docker_apply_overlay .alert-message > p,
+       #docker_apply_overlay .alert-message > div {
+               flex-basis: 100%;
+       }
+
+       #docker_apply_overlay .alert-message > img {
+               margin-right: 1em;
+               flex-basis: 32px;
+       }
+
+       body.apply-overlay-active {
+               overflow: hidden;
+               height: 100vh;
+       }
+
+       body.apply-overlay-active #docker_apply_overlay {
+               display: block;
+       }
 </style>
+
 <script type="text/javascript">//<![CDATA[
-    var xhr = new XHR(),
-      uci_apply_rollback = <%=math.max(luci.config and luci.config.apply and luci.config.apply.rollback or 30, 30)%>,
-      uci_apply_holdoff = <%=math.max(luci.config and luci.config.apply and luci.config.apply.holdoff or 4, 1)%>,
-      uci_apply_timeout = <%=math.max(luci.config and luci.config.apply and luci.config.apply.timeout or 5, 1)%>,
-      uci_apply_display = <%=math.max(luci.config and luci.config.apply and luci.config.apply.display or 1.5, 1)%>,
-      was_xhr_poll_running = false;
-
-function docker_status_message(type, content) {
-  document.getElementById('docker_apply_overlay') || document.body.insertAdjacentHTML("beforeend",'<div id="docker_apply_overlay"><div class="alert-message"></div></div>')
-  var overlay = document.getElementById('docker_apply_overlay')
-      message = overlay.querySelector('.alert-message');
-
-  if (message && type) {
-    if (!message.classList.contains(type)) {
-      message.classList.remove('notice');
-      message.classList.remove('warning');
-      message.classList.add(type);
-    }
-
-    if (content)
-      message.innerHTML = content;
-
-    document.body.classList.add('apply-overlay-active');
-    document.body.scrollTop = document.documentElement.scrollTop = 0;
-    if (!was_xhr_poll_running) {
-      was_xhr_poll_running = XHR.running();
-      XHR.halt();
-    }
-  }
-  else {
-    document.body.classList.remove('apply-overlay-active');
-
-    if (was_xhr_poll_running)
-      XHR.run();
-  }
-}
-var loading_msg="Loading.."
-function uci_confirm_docker() {
-    var tt;
-    docker_status_message('notice');
-    var call = function(r, resjson, duration) {
-      if (r && r.status === 200 ) {
-        var indicator = document.querySelector('.uci_change_indicator');
-        if (indicator) indicator.style.display = 'none';
-        docker_status_message('notice', '<%:Docker actions done.%>');
-        document.body.classList.remove('apply-overlay-active');
-        window.clearTimeout(tt);
-        return;
-      }
-      loading_msg = resjson?resjson.info:loading_msg
-      // var delay = isNaN(duration) ? 0 : Math.max(1000 - duration, 0);
-      var delay =1000
-      window.setTimeout(function() {
-        xhr.get('<%=url("admin/docker/confirm")%>', null, call, uci_apply_timeout * 1000);
-      }, delay);
-    };
-
-    var tick = function() {
-      var now = Date.now();
-
-      docker_status_message('notice',
-        '<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> <span style="white-space:pre-line; word-break:break-all; font-family: \'Courier New\', Courier, monospace;">' +
-        loading_msg + '</span>');
-
-      tt = window.setTimeout(tick, 200);
-      ts = now;
-    };
-    tick();
-    /* wait a few seconds for the settings to become effective */
-    window.setTimeout(call, Math.max(uci_apply_holdoff * 1000 , 1));
-  }
-  // document.getElementsByTagName("form")[0].addEventListener("submit", (e)=>{
-  //   uci_confirm_docker()
-  // })
-
-function fnSubmitForm(el){
-  if (el.id != "cbid.table.1._new") {
-    uci_confirm_docker()
-  }
-}
-
-<% if self.err then -%>
-  docker_status_message('warning', '<span style="white-space:pre-line; word-break:break-all; font-family: \'Courier New\', Courier, monospace;">'+`<%=self.err%>`+'</span>');
-  document.getElementById('docker_apply_overlay').addEventListener("click", (e)=>{
-    docker_status_message()
-  })
-<%- end %>
-
-window.onload= function (){
-var buttons = document.querySelectorAll('input[type="submit"]');
-[].slice.call(buttons).forEach(function (el) {
-  el.onclick = fnSubmitForm.bind(this, el);
-});
-}
+       var xhr = new XHR(),
+       uci_apply_rollback = <%=math.max(luci.config and luci.config.apply and luci.config.apply.rollback or 30, 30)%>,
+       uci_apply_holdoff = <%=math.max(luci.config and luci.config.apply and luci.config.apply.holdoff or 4, 1)%>,
+       uci_apply_timeout = <%=math.max(luci.config and luci.config.apply and luci.config.apply.timeout or 5, 1)%>,
+       uci_apply_display = <%=math.max(luci.config and luci.config.apply and luci.config.apply.display or 1.5, 1)%>,
+       was_xhr_poll_running = false;
+
+       function docker_status_message(type, content) {
+               document.getElementById('docker_apply_overlay') || document.body.insertAdjacentHTML("beforeend",'<div id="docker_apply_overlay"><div class="alert-message"></div></div>')
+               var overlay = document.getElementById('docker_apply_overlay')
+               message = overlay.querySelector('.alert-message');
+
+               if (message && type) {
+                       if (!message.classList.contains(type)) {
+                               message.classList.remove('notice');
+                               message.classList.remove('warning');
+                               message.classList.add(type);
+                       }
+
+                       if (content)
+                               message.innerHTML = content;
+
+                       document.body.classList.add('apply-overlay-active');
+                       document.body.scrollTop = document.documentElement.scrollTop = 0;
+                       if (!was_xhr_poll_running) {
+                               was_xhr_poll_running = XHR.running();
+                               XHR.halt();
+                       }
+               }
+               else {
+                       document.body.classList.remove('apply-overlay-active');
+                       if (was_xhr_poll_running)
+                               XHR.run();
+               }
+       }
+
+       var loading_msg="Loading.."
+       function uci_confirm_docker() {
+               var tt;
+               docker_status_message('notice');
+               var call = function(r, resjson, duration) {
+                       if (r && r.status === 200 ) {
+                               var indicator = document.querySelector('.uci_change_indicator');
+                               if (indicator)
+                                       indicator.style.display = 'none';
+                               docker_status_message('notice', '<%:Docker actions done.%>');
+                               document.body.classList.remove('apply-overlay-active');
+                               window.clearTimeout(tt);
+                               return;
+                       }
+                       loading_msg = resjson?resjson.info:loading_msg
+                       // var delay = isNaN(duration) ? 0 : Math.max(1000 - duration, 0);
+                       var delay =1000
+                       window.setTimeout(function() {
+                               xhr.get('<%=url("admin/docker/confirm")%>', null, call, uci_apply_timeout * 1000);
+                       },delay);
+               };
+
+               var tick = function() {
+                       var now = Date.now();
+
+                       docker_status_message(
+                               'notice',
+                               '<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> <span style="white-space:pre-line; word-break:break-all; font-family: \'Courier New\', Courier, monospace;">' + loading_msg + '</span>'
+                       );
+
+                       tt = window.setTimeout(tick, 200);
+                       ts = now;
+               };
+
+               tick();
+               /* wait a few seconds for the settings to become effective */
+               window.setTimeout(call, Math.max(uci_apply_holdoff * 1000 , 1));
+       }
+       // document.getElementsByTagName("form")[0].addEventListener("submit", (e)=>{
+       // uci_confirm_docker()
+       // })
+
+       function fnSubmitForm(el){
+               if (el.id != "cbid.table.1._new") {
+                       uci_confirm_docker()
+               }
+       }
+
+       <% if self.err then -%>
+               docker_status_message('warning', '<span style="white-space:pre-line; word-break:break-all; font-family: \'Courier New\', Courier, monospace;">'+`<%=self.err%>`+'</span>');
+               document.getElementById('docker_apply_overlay').addEventListener(
+                       "click",
+                       (e)=>{
+                               docker_status_message()
+                       }
+               )
+       <%- end %>
+
+       window.onload= function (){
+               var buttons = document.querySelectorAll('input[type="submit"]');
+               [].slice.call(buttons).forEach(function (el) {
+                       el.onclick = fnSubmitForm.bind(this, el);
+               });
+       }
 
 //]]></script>
index dab1dee562be2ac50732e6a8d074b2dbc6b75465..9f05d9d58944172710bc1e02a2092c570f3e8c69 100644 (file)
@@ -1,12 +1,12 @@
 <br>
 <ul class="cbi-tabmenu">
-       <li  id="cbi-tab-container_info"><a id="a-cbi-tab-container_info" href=""><%:Info%></a></li>
+       <li id="cbi-tab-container_info"><a id="a-cbi-tab-container_info" href=""><%:Info%></a></li>
        <li id="cbi-tab-container_resources"><a id="a-cbi-tab-container_resources" href=""><%:Resources%></a></li>
-       <li  id="cbi-tab-container_stats"><a id="a-cbi-tab-container_stats" href=""><%:Stats%></a></li>
-       <li  id="cbi-tab-container_file"><a id="a-cbi-tab-container_file" href=""><%:File%></a></li>
-       <li  id="cbi-tab-container_console"><a id="a-cbi-tab-container_console" href=""><%:Console%></a></li>
-       <li  id="cbi-tab-container_inspect"><a id="a-cbi-tab-container_inspect" href=""><%:Inspect%></a></li>
-       <li  id="cbi-tab-container_logs"><a id="a-cbi-tab-container_logs" href=""><%:Logs%></a></li>
+       <li id="cbi-tab-container_stats"><a id="a-cbi-tab-container_stats" href=""><%:Stats%></a></li>
+       <li id="cbi-tab-container_file"><a id="a-cbi-tab-container_file" href=""><%:File%></a></li>
+       <li id="cbi-tab-container_console"><a id="a-cbi-tab-container_console" href=""><%:Console%></a></li>
+       <li id="cbi-tab-container_inspect"><a id="a-cbi-tab-container_inspect" href=""><%:Inspect%></a></li>
+       <li id="cbi-tab-container_logs"><a id="a-cbi-tab-container_logs" href=""><%:Logs%></a></li>
 </ul>
 
 <script type="text/javascript">
@@ -20,7 +20,8 @@
                document.getElementById("a-cbi-tab-container_" + item).href= path[0]+"/admin/docker/container/"+container_id+'/'+item
                if (action === item) {
                        document.getElementById("cbi-tab-container_" + item).className="cbi-tab"
-               }       else {
+               }
+               else {
                        document.getElementById("cbi-tab-container_" + item).className="cbi-tab-disabled"
                }
        })
index 636aec96058375924ef9a0c7d24f461bda2a3653..7f626b3dc837c43c1d6554331238b402bc09d8b4 100644 (file)
@@ -1,6 +1,6 @@
 <div class="cbi-map">
-  <iframe id="terminal" style="width: 100%; min-height: 500px; border: none; border-radius: 3px;"></iframe>
+       <iframe id="terminal" style="width: 100%; min-height: 500px; border: none; border-radius: 3px;"></iframe>
 </div>
 <script type="text/javascript">
-  document.getElementById("terminal").src = "http://" + window.location.hostname + ":7682";
+       document.getElementById("terminal").src = "http://" + window.location.hostname + ":7682";
 </script>
index 8be43fbddbbae1f30b08d1f45695717caf5e6d36..ab5ecdd488ca10b97ca5b8ca17e8389fa89ef467 100644 (file)
@@ -1,63 +1,73 @@
-
 <div id="upload-container" class="cbi-value cbi-value-last">
-  <label class="cbi-value-title" for="archive"><%:Upload%></label>
-  <div class="cbi-value-field">
-    <input type="file" name="upload_archive" accept="application/x-tar" id="upload_archive" />
-  </div>
-  <br>
-  <label class="cbi-value-title" for="path"><%:Path%></label>
-  <div class="cbi-value-field">
-    <input type="text" class="cbi-input-text" name="path" value="/tmp/" id="path" />
-  </div>
-  <br>
-  <div class="cbi-value-field">
-    <input type="button"" class="btn cbi-button cbi-button-action important" id="upload" name="upload" value="<%:Upload%>" />
-    <input type="button"" class="btn cbi-button cbi-button-action important" id="download" name="download" value="<%:Download%>" />
-  </div>
+       <label class="cbi-value-title" for="archive"><%:Upload%></label>
+       <div class="cbi-value-field">
+               <input type="file" name="upload_archive" accept="application/x-tar" id="upload_archive" />
+       </div>
+       <br>
+       <label class="cbi-value-title" for="path"><%:Path%></label>
+       <div class="cbi-value-field">
+               <input type="text" class="cbi-input-text" name="path" value="/tmp/" id="path" />
+       </div>
+       <br>
+       <div class="cbi-value-field">
+               <input type="button"" class="btn cbi-button cbi-button-action important" id="upload" name="upload" value="<%:Upload%>" />
+               <input type="button"" class="btn cbi-button cbi-button-action important" id="download" name="download" value="<%:Download%>" />
+       </div>
 </div>
+
 <script type="text/javascript">
-  let btnUpload = document.getElementById('upload')
-  btnUpload.onclick = function (e) {
-    let uploadArchive = document.getElementById('upload_archive')
-    let uploadPath = document.getElementById('path').value
-    if (!uploadArchive.value || !uploadPath) {
-      docker_status_message('warning', "<%:Please input the PATH and select the file !%>")
-      document.getElementById('docker_apply_overlay').addEventListener("click", (e)=>{
-          docker_status_message()
-        })
-      return
-    }
-    let fileName = uploadArchive.files[0].name
-    let formData = new FormData()
-    formData.append('upload-filename', fileName)
-    formData.append('upload-path', uploadPath)
-    formData.append('upload-archive', uploadArchive.files[0])
-    let xhr = new XMLHttpRequest()
-    xhr.open("POST", '<%=luci.dispatcher.build_url("admin/docker/container_put_archive")%>/<%=self.container%>', true)
-    xhr.onload = function() {
-      if (xhr.status == 200) {
-        uploadArchive.value = ''
-        docker_status_message('notice', "<%:Upload Success%>")
-      }
-      else {
-        docker_status_message('warning', "<%:Upload Error%>:" + xhr.statusText)
-      }
-      document.getElementById('docker_apply_overlay').addEventListener("click", (e)=>{
-          docker_status_message()
-        })
-    }
-    xhr.send(formData)
-  }
-  let btnDownload = document.getElementById('download')
-  btnDownload.onclick = function (e) {
-    let downloadPath = document.getElementById('path').value
-    if (!downloadPath) {
-      docker_status_message('warning', "<%:Please input the PATH !%>")
-      document.getElementById('docker_apply_overlay').addEventListener("click", (e)=>{
-          docker_status_message()
-        })
-      return
-    }
-    window.open('<%=luci.dispatcher.build_url("admin/docker/container_get_archive")%>?id=<%=self.container%>&path=' + encodeURIComponent(downloadPath))
-  }
+       let btnUpload = document.getElementById('upload')
+       btnUpload.onclick = function (e) {
+               let uploadArchive = document.getElementById('upload_archive')
+               let uploadPath = document.getElementById('path').value
+               if (!uploadArchive.value || !uploadPath) {
+                       docker_status_message('warning', "<%:Please input the PATH and select the file !%>")
+                       document.getElementById('docker_apply_overlay').addEventListener(
+                               "click",
+                               (e)=>{
+                                       docker_status_message()
+                               }
+                       )
+                       return
+               }
+               let fileName = uploadArchive.files[0].name
+               let formData = new FormData()
+               formData.append('upload-filename', fileName)
+               formData.append('upload-path', uploadPath)
+               formData.append('upload-archive', uploadArchive.files[0])
+               let xhr = new XMLHttpRequest()
+               xhr.open("POST", '<%=luci.dispatcher.build_url("admin/docker/container_put_archive")%>/<%=self.container%>', true)
+               xhr.onload = function() {
+                       if (xhr.status == 200) {
+                               uploadArchive.value = ''
+                               docker_status_message('notice', "<%:Upload Success%>")
+                       }
+                       else {
+                               docker_status_message('warning', "<%:Upload Error%>:" + xhr.statusText)
+                       }
+                       document.getElementById('docker_apply_overlay').addEventListener(
+                               "click",
+                               (e)=>{
+                                       docker_status_message()
+                               }
+                       )
+               }
+               xhr.send(formData)
+       }
+
+       let btnDownload = document.getElementById('download')
+       btnDownload.onclick = function (e) {
+               let downloadPath = document.getElementById('path').value
+               if (!downloadPath) {
+                       docker_status_message('warning', "<%:Please input the PATH !%>")
+                       document.getElementById('docker_apply_overlay').addEventListener(
+                               "click",
+                               (e)=>{
+                                       docker_status_message()
+                               }
+                       )
+                       return
+               }
+               window.open('<%=luci.dispatcher.build_url("admin/docker/container_get_archive")%>?id=<%=self.container%>&path=' + encodeURIComponent(downloadPath))
+       }
 </script>
index b5600e49797852ca96271f7280417bba7be60c97..bbcd633e7d18445d5a46166f982fd69ac897b6cb 100644 (file)
@@ -2,6 +2,7 @@
        let last_bw_tx
        let last_bw_rx
        let interval = 3
+
        function progressbar(v, m, pc, np, f) {
                m = m || 100
 
index 6587087b6df197ac56696f82239f4d05d9f1f475..b87759d00ff223ec258f9f95496233e4acb46ff8 100644 (file)
 <input type="text" class="cbi-input-text" name="isrc" placeholder="http://host/image.tar" id="isrc" />
 <input type="text" class="cbi-input-text" name="itag" placeholder="repository:tag" id="itag" />
 <div style="display: inline-block;">
-  <input type="button"" class="btn cbi-button cbi-button-add" id="btnimport" name="import" value="<%:Import%>" />
-  <input type="file" id="file_import" style="visibility:hidden; position: absolute;top: 0px; left: 0px;" />
+       <input type="button"" class="btn cbi-button cbi-button-add" id="btnimport" name="import" value="<%:Import%>" />
+       <input type="file" id="file_import" style="visibility:hidden; position: absolute;top: 0px; left: 0px;" />
 </div>
 
 <script type="text/javascript">
-  let btnImport = document.getElementById('btnimport')
-  let valISrc = document.getElementById('isrc')
-  let valITag = document.getElementById('itag')
-  btnImport.onclick = function (e) {
-    if (valISrc.value == "") {
-      document.getElementById("file_import").click()
-      return
-    } else {
-      let formData = new FormData()
-      formData.append('src', valISrc.value)
-      formData.append('tag', valITag.value)
-      let xhr = new XMLHttpRequest()
-      uci_confirm_docker()
-      xhr.open("POST", "<%=luci.dispatcher.build_url('admin/docker/images_import')%>", true)
-      xhr.onload = function () {
-        location.reload()
-      }
-      xhr.send(formData)
-    }
-  }
-  let fileimport = document.getElementById('file_import')
-  fileimport.onchange = function (e) {
-    let fileimport = document.getElementById('file_import')
-    if (!fileimport.value) {
-      return
-    }
-    let valITag = document.getElementById('itag')
-    let fileName = fileimport.files[0].name
-    let formData = new FormData()
-    formData.append('upload-filename', fileName)
-    formData.append('tag', valITag.value)
-    formData.append('upload-archive', fileimport.files[0])
-    let xhr = new XMLHttpRequest()
-    uci_confirm_docker()
-    xhr.open("POST", "<%=luci.dispatcher.build_url('admin/docker/images_import')%>", true)
-    xhr.onload = function () {
-      fileimport.value = ''
-      location.reload()
-    }
-    xhr.send(formData)
-  }
+       let btnImport = document.getElementById('btnimport')
+       let valISrc = document.getElementById('isrc')
+       let valITag = document.getElementById('itag')
+       btnImport.onclick = function (e) {
+               if (valISrc.value == "") {
+                       document.getElementById("file_import").click()
+                       return
+               }
+               else {
+                       let formData = new FormData()
+                       formData.append('src', valISrc.value)
+                       formData.append('tag', valITag.value)
+                       let xhr = new XMLHttpRequest()
+                       uci_confirm_docker()
+                       xhr.open("POST", "<%=luci.dispatcher.build_url('admin/docker/images_import')%>", true)
+                       xhr.onload = function () {
+                               location.reload()
+                       }
+                       xhr.send(formData)
+               }
+       }
 
-  let new_tag = function (image_id) {
-    let new_tag = prompt("<%:New tag%>\n<%:Image%>" + "ID: " + image_id + "\n<%:Please input new tag%>:", "")
-    if (new_tag) {
-      (new XHR()).post("<%=luci.dispatcher.build_url('admin/docker/images_tag')%>",
-        { id: image_id, tag: new_tag },
-        function (r) {
-          if (r.status == 201) {
-            location.reload()
-          }
-          else {
-            docker_status_message('warning', 'Image: untagging ' + tag + '...fail code:' + r.status + r.statusText);
-            document.getElementById('docker_apply_overlay').addEventListener("click", (e)=>{
-              docker_status_message()
-            })
-          }
-        })
-    }
-  }
+       let fileimport = document.getElementById('file_import')
+       fileimport.onchange = function (e) {
+               let fileimport = document.getElementById('file_import')
+               if (!fileimport.value) {
+                       return
+               }
+               let valITag = document.getElementById('itag')
+               let fileName = fileimport.files[0].name
+               let formData = new FormData()
+               formData.append('upload-filename', fileName)
+               formData.append('tag', valITag.value)
+               formData.append('upload-archive', fileimport.files[0])
+               let xhr = new XMLHttpRequest()
+               uci_confirm_docker()
+               xhr.open("POST", "<%=luci.dispatcher.build_url('admin/docker/images_import')%>", true)
+               xhr.onload = function () {
+                       fileimport.value = ''
+                       location.reload()
+               }
+               xhr.send(formData)
+       }
 
-  let un_tag = function (tag) {
-    if (tag.match("<none>")) return
-    if (confirm("<%:Remove tag%>: " + tag + " ?")) {
-      (new XHR()).post("<%=luci.dispatcher.build_url('admin/docker/images_untag')%>",
-        { tag: tag },
-        function (r) {
-          if (r.status == 200) {
-            location.reload()
-          }
-          else {
-            docker_status_message('warning', 'Image: untagging ' + tag + '...fail code:' + r.status + r.statusText);
-            document.getElementById('docker_apply_overlay').addEventListener("click", (e)=>{
-              docker_status_message()
-            })
-          }
-        })
-    }
-  }
+       let new_tag = function (image_id) {
+               let new_tag = prompt("<%:New tag%>\n<%:Image%>" + "ID: " + image_id + "\n<%:Please input new tag%>:", "")
+               if (new_tag) {
+                       (new XHR()).post("<%=luci.dispatcher.build_url('admin/docker/images_tag')%>",
+                               {
+                                       id: image_id,
+                                       tag: new_tag
+                               },
+                               function (r) {
+                                       if (r.status == 201) {
+                                               location.reload()
+                                       }
+                                       else {
+                                               docker_status_message('warning', 'Image: untagging ' + tag + '...fail code:' + r.status + r.statusText);
+                                               document.getElementById('docker_apply_overlay').addEventListener(
+                                                       "click",
+                                                       (e)=>{
+                                                               docker_status_message()
+                                                       }
+                                               )
+                                       }
+                               }
+                       )
+               }
+       }
+
+       let un_tag = function (tag) {
+               if (tag.match("<none>"))
+                       return
+               if (confirm("<%:Remove tag%>: " + tag + " ?")) {
+                       (new XHR()).post("<%=luci.dispatcher.build_url('admin/docker/images_untag')%>",
+                               {
+                                       tag: tag
+                               },
+                               function (r) {
+                                       if (r.status == 200) {
+                                               location.reload()
+                                       }
+                                       else {
+                                               docker_status_message('warning', 'Image: untagging ' + tag + '...fail code:' + r.status + r.statusText);
+                                               document.getElementById('docker_apply_overlay').addEventListener(
+                                                       "click",
+                                                       (e)=>{
+                                                               docker_status_message()
+                                                       }
+                                               )
+                                       }
+                               }
+                       )
+               }
+       }
 </script>
index 3ea4bd06638e72a9a9c87422c17a50a2cfd4fa87..9a90a90f033c2026bba1a2a262cdd1cc67fd80d9 100644 (file)
@@ -1,29 +1,30 @@
 <div style="display: inline-block;">
-  <input type="button"" class="btn cbi-button cbi-button-add" id="btnload" name="load" value="<%:Load%>" />
-  <input type="file" id="file_load" style="visibility:hidden; position: absolute;top: 0px; left: 0px;" accept="application/x-tar" />
+       <input type="button"" class="btn cbi-button cbi-button-add" id="btnload" name="load" value="<%:Load%>" />
+       <input type="file" id="file_load" style="visibility:hidden; position: absolute;top: 0px; left: 0px;" accept="application/x-tar" />
 </div>
 <script type="text/javascript">
-  let btnLoad = document.getElementById('btnload')
-  btnLoad.onclick = function (e) {
-    document.getElementById("file_load").click()
-    e.preventDefault()
-  }
-  let fileLoad = document.getElementById('file_load')
-  fileLoad.onchange = function(e){
-    let fileLoad = document.getElementById('file_load')
-      if (!fileLoad.value) {
-      return
-    }
-    let fileName = fileLoad.files[0].name
-    let formData = new FormData()
-    formData.append('upload-filename', fileName)
-    formData.append('upload-archive', fileLoad.files[0])
-    let xhr = new XMLHttpRequest()
-    uci_confirm_docker()
-    xhr.open("POST", '<%=luci.dispatcher.build_url("admin/docker/images_load")%>', true)
-    xhr.onload = function() {
-      location.reload()
-    }
-    xhr.send(formData)
-  }
+       let btnLoad = document.getElementById('btnload')
+       btnLoad.onclick = function (e) {
+               document.getElementById("file_load").click()
+               e.preventDefault()
+       }
+
+       let fileLoad = document.getElementById('file_load')
+       fileLoad.onchange = function(e){
+               let fileLoad = document.getElementById('file_load')
+               if (!fileLoad.value) {
+                       return
+               }
+               let fileName = fileLoad.files[0].name
+               let formData = new FormData()
+               formData.append('upload-filename', fileName)
+               formData.append('upload-archive', fileLoad.files[0])
+               let xhr = new XMLHttpRequest()
+               uci_confirm_docker()
+               xhr.open("POST", '<%=luci.dispatcher.build_url("admin/docker/images_load")%>', true)
+               xhr.onload = function() {
+                       location.reload()
+               }
+       xhr.send(formData)
+       }
 </script>
index 1b130b4ec6630a7e7c1ad2ebc35f7e883d13acb8..dd6cafa062b14948288fa80fcb4ce7c593ab7442 100644 (file)
 <style type="text/css">
-  #dialog_reslov {
-    position: absolute;
-    top: 0;
-    left: 0;
-    bottom: 0;
-    right: 0;
-    background: rgba(0, 0, 0, 0.7);
-    display: none;
-    z-index: 20000;
-  }
-
-  #dialog_reslov .dialog_box {
-    position: relative;
-    background: rgba(255, 255, 255);
-    top: 10%;
-    width: 50%;
-    margin: auto;
-    display: flex;
-    flex-wrap: wrap;
-    height:auto;
-    align-items: center;
-  }
-
-  #dialog_reslov .dialog_line {
-    margin-top: .5em;
-    margin-bottom: .5em;
-    margin-left: 2em;
-    margin-right: 2em;
-  }
-
-  #dialog_reslov .dialog_box>h4,
-  #dialog_reslov .dialog_box>p,
-  #dialog_reslov .dialog_box>div {
-    flex-basis: 100%;
-  }
-
-  #dialog_reslov .dialog_box>img {
-    margin-right: 1em;
-    flex-basis: 32px;
-  }
-
-  body.dialog-reslov-active {
-    overflow: hidden;
-    height: 100vh;
-  }
-
-  body.dialog-reslov-active #dialog_reslov {
-    display: block;
-  }
+       #dialog_reslov {
+               position: absolute;
+               top: 0;
+               left: 0;
+               bottom: 0;
+               right: 0;
+               background: rgba(0, 0, 0, 0.7);
+               display: none;
+               z-index: 20000;
+       }
+
+       #dialog_reslov .dialog_box {
+               position: relative;
+               background: rgba(255, 255, 255);
+               top: 10%;
+               width: 50%;
+               margin: auto;
+               display: flex;
+               flex-wrap: wrap;
+               height:auto;
+               align-items: center;
+       }
+
+       #dialog_reslov .dialog_line {
+               margin-top: .5em;
+               margin-bottom: .5em;
+               margin-left: 2em;
+               margin-right: 2em;
+       }
+
+       #dialog_reslov .dialog_box>h4,
+       #dialog_reslov .dialog_box>p,
+       #dialog_reslov .dialog_box>div {
+               flex-basis: 100%;
+       }
+
+       #dialog_reslov .dialog_box>img {
+               margin-right: 1em;
+               flex-basis: 32px;
+       }
+
+       body.dialog-reslov-active {
+               overflow: hidden;
+               height: 100vh;
+       }
+
+       body.dialog-reslov-active #dialog_reslov {
+               display: block;
+       }
 </style>
+
 <script type="text/javascript">
-  function close_reslov_dialog() {
-    document.body.classList.remove('dialog-reslov-active')
-    document.documentElement.style.overflowY = 'scroll'
-  }
-
-  function reslov_container() {
-    let s = document.getElementById('cmd-line-status')
-    if (!s) return
-    let cmd_line = document.getElementById("dialog_reslov_text").value;
-    if (cmd_line == null || cmd_line == "") {
-      return
-    }
-    cmd_line = cmd_line.replace(/(^\s*)/g,"")
-    if (!cmd_line.match(/^docker\s+(run|create)/)) {
-      s.innerHTML = "<font color='red'><%:Command line Error%></font>"
-      return
-    }
-    let reg_space = /\s+/g
-    let reg_muti_line= /\\\s*\n/g
-    //   reg_rem =/(?<!\\)`#.+(?<!\\)`/g  // the command has `# `
-    let reg_rem =/`#.+`/g// the command has `# `
-    cmd_line = cmd_line.replace(/^docker\s+(run|create)/,"DOCKERCLI").replace(reg_rem, " ").replace(reg_muti_line, " ").replace(reg_space, " ")
-    console.log(cmd_line)
-    window.location.href = '<%=luci.dispatcher.build_url("admin/docker/newcontainer")%>/' + encodeURI(cmd_line)
-  }
-
-  function clear_text(){
-    let s = document.getElementById('cmd-line-status')
-    s.innerHTML = ""
-  }
-
-  function show_reslov_dialog() {
-    document.getElementById('dialog_reslov') || document.body.insertAdjacentHTML("beforeend", '<div id="dialog_reslov"><div class="dialog_box"><div class="dialog_line"></div><div class="dialog_line"><span><%:Plese input <docker create/run> command line:%></span><br><span id="cmd-line-status"></span></div><div class="dialog_line"><textarea class="cbi-input-textarea" id="dialog_reslov_text" style="width: 100%; height:100%;" rows="15" onkeyup="clear_text()"></textarea></div><div class="dialog_line" style="text-align: right;"><input type="button" class="btn cbi-button cbi-button-apply" type="submit" value="<%:Submit%>" onclick="reslov_container()" /> <input type="button" class="btn cbi-button cbi-button-reset" type="reset" value="<%:Cancel%>" onclick="close_reslov_dialog()" /></div><div class="dialog_line"></div></div></div>')
-    document.body.classList.add('dialog-reslov-active')
-    let s = document.getElementById('cmd-line-status')
-    s.innerHTML = ""
-    document.documentElement.style.overflowY = 'hidden'
-  }
+       function close_reslov_dialog() {
+               document.body.classList.remove('dialog-reslov-active')
+               document.documentElement.style.overflowY = 'scroll'
+       }
+
+       function reslov_container() {
+               let s = document.getElementById('cmd-line-status')
+
+               if (!s)
+                       return
+
+               let cmd_line = document.getElementById("dialog_reslov_text").value;
+               if (cmd_line == null || cmd_line == "") {
+                       return
+               }
+
+               cmd_line = cmd_line.replace(/(^\s*)/g,"")
+               if (!cmd_line.match(/^docker\s+(run|create)/)) {
+                       s.innerHTML = "<font color='red'><%:Command line Error%></font>"
+                       return
+               }
+
+               let reg_space = /\s+/g
+               let reg_muti_line= /\\\s*\n/g
+               //   reg_rem =/(?<!\\)`#.+(?<!\\)`/g  // the command has `# `
+               let reg_rem =/`#.+`/g// the command has `# `
+               cmd_line = cmd_line.replace(/^docker\s+(run|create)/,"DOCKERCLI").replace(reg_rem, " ").replace(reg_muti_line, " ").replace(reg_space, " ")
+               console.log(cmd_line)
+               window.location.href = '<%=luci.dispatcher.build_url("admin/docker/newcontainer")%>/' + encodeURI(cmd_line)
+       }
+
+       function clear_text(){
+               let s = document.getElementById('cmd-line-status')
+               s.innerHTML = ""
+       }
+
+       function show_reslov_dialog() {
+               document.getElementById('dialog_reslov') || document.body.insertAdjacentHTML("beforeend", '<div id="dialog_reslov"><div class="dialog_box"><div class="dialog_line"></div><div class="dialog_line"><span><%:Plese input <docker create/run> command line:%></span><br><span id="cmd-line-status"></span></div><div class="dialog_line"><textarea class="cbi-input-textarea" id="dialog_reslov_text" style="width: 100%; height:100%;" rows="15" onkeyup="clear_text()"></textarea></div><div class="dialog_line" style="text-align: right;"><input type="button" class="btn cbi-button cbi-button-apply" type="submit" value="<%:Submit%>" onclick="reslov_container()" /> <input type="button" class="btn cbi-button cbi-button-reset" type="reset" value="<%:Cancel%>" onclick="close_reslov_dialog()" /></div><div class="dialog_line"></div></div></div>')
+               document.body.classList.add('dialog-reslov-active')
+               let s = document.getElementById('cmd-line-status')
+               s.innerHTML = ""
+               document.documentElement.style.overflowY = 'hidden'
+       }
 </script>
 <%+cbi/valueheader%>
+
 <input type="button" class="btn cbi-button cbi-button-apply" value="<%:Command line%>" onclick="show_reslov_dialog()" />
 
 <%+cbi/valuefooter%>
index 474009dfdc912285a8494b9533e4a037ec0daf32..d11105bdcd7c1d58a2fd3c1d4c5d14742f3e07f3 100644 (file)
 <style>
-  /*!
-Pure v1.0.1
-Copyright 2013 Yahoo!
-Licensed under the BSD License.
-https://github.com/pure-css/pure/blob/master/LICENSE.md
-*/
-  .pure-g {
-    letter-spacing: -.31em;
-    text-rendering: optimizespeed;
-    font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif;
-    display: -webkit-box;
-    display: -webkit-flex;
-    display: -ms-flexbox;
-    display: flex;
-    -webkit-box-orient: horizontal;
-    -webkit-box-direction: normal;
-    -webkit-flex-flow: row wrap;
-    -ms-flex-flow: row wrap;
-    flex-flow: row wrap;
-    -webkit-align-content: flex-start;
-    -ms-flex-line-pack: start;
-    align-content: flex-start
-  }
+       /*!
+       Pure v1.0.1
+       Copyright 2013 Yahoo!
+       Licensed under the BSD License.
+       https://github.com/pure-css/pure/blob/master/LICENSE.md
+       */
+       .pure-g {
+               letter-spacing: -.31em;
+               text-rendering: optimizespeed;
+               font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif;
+               display: -webkit-box;
+               display: -webkit-flex;
+               display: -ms-flexbox;
+               display: flex;
+               -webkit-box-orient: horizontal;
+               -webkit-box-direction: normal;
+               -webkit-flex-flow: row wrap;
+               -ms-flex-flow: row wrap;
+               flex-flow: row wrap;
+               -webkit-align-content: flex-start;
+               -ms-flex-line-pack: start;
+               align-content: flex-start
+       }
 
-  .pure-u {
-    display: inline-block;
-    zoom: 1;
-    letter-spacing: normal;
-    word-spacing: normal;
-    vertical-align: top;
-    text-rendering: auto
-  }
+       .pure-u {
+               display: inline-block;
+               zoom: 1;
+               letter-spacing: normal;
+               word-spacing: normal;
+               vertical-align: top;
+               text-rendering: auto
+       }
 
-  .pure-g [class*=pure-u] {
-    font-family: sans-serif
-  }
+       .pure-g [class*=pure-u] {
+               font-family: sans-serif
+       }
 
-  .pure-u-1-4,
-  .pure-u-2-5,
-  .pure-u-3-5 {
-    display: inline-block;
-    zoom: 1;
-    letter-spacing: normal;
-    word-spacing: normal;
-    vertical-align: top;
-    text-rendering: auto
-  }
+       .pure-u-1-4,
+       .pure-u-2-5,
+       .pure-u-3-5 {
+               display: inline-block;
+               zoom: 1;
+               letter-spacing: normal;
+               word-spacing: normal;
+               vertical-align: top;
+               text-rendering: auto
+       }
 
-  .pure-u-1-4 {
-    width: 25%
-  }
+       .pure-u-1-4 {
+               width: 25%
+       }
 
-  .pure-u-2-5 {
-    width: 40%
-  }
+       .pure-u-2-5 {
+               width: 40%
+       }
 
-  .pure-u-3-5 {
-    width: 60%
-  }
+       .pure-u-3-5 {
+               width: 60%
+       }
 
-  .status {
-    margin: 1rem -0.5rem 1rem -0.5rem;
-  }
+       .status {
+               margin: 1rem -0.5rem 1rem -0.5rem;
+       }
 
-  .block {
-    margin: 0.5rem 0.5rem;
-    padding: 0;
-    font-weight: normal;
-    font-style: normal;
-    line-height: 1;
-    font-family: inherit;
-    min-width: inherit;
-    overflow-x: auto;
-    overflow-y: hidden;
-    border: 1px solid rgba(0, 0, 0, .05);
-    border-radius: .375rem;
-    box-shadow: 0 0 2rem 0 rgba(136, 152, 170, .15);
-  }
+       .block {
+               margin: 0.5rem 0.5rem;
+               padding: 0;
+               font-weight: normal;
+               font-style: normal;
+               line-height: 1;
+               font-family: inherit;
+               min-width: inherit;
+               overflow-x: auto;
+               overflow-y: hidden;
+               border: 1px solid rgba(0, 0, 0, .05);
+               border-radius: .375rem;
+               box-shadow: 0 0 2rem 0 rgba(136, 152, 170, .15);
+       }
 
-  .img-con {
-    margin: 1rem;
-    min-width: 4rem;
-    max-width: 4rem;
-    min-height: 4rem;
-    max-height: 4rem;
-  }
+       .img-con {
+               margin: 1rem;
+               min-width: 4rem;
+               max-width: 4rem;
+               min-height: 4rem;
+               max-height: 4rem;
+       }
 
-  .block h4 {
-    font-size: .8125rem;
-    font-weight: 600;
-    margin: 1rem;
-    color: #8898aa !important;
-    line-height: 1.8em;
-  }
+       .block h4 {
+               font-size: .8125rem;
+               font-weight: 600;
+               margin: 1rem;
+               color: #8898aa !important;
+               line-height: 1.8em;
+       }
 
-  .cbi-section-table-cell {
-    position: relative;
-  }
+       .cbi-section-table-cell {
+               position: relative;
+       }
 
-  @media screen and (max-width: 700px) {
-    .pure-u-1-4 {
-      width: 50%;
-    }
+       @media screen and (max-width: 700px) {
+               .pure-u-1-4 {
+                       width: 50%;
+               }
 
-    .cbi-button-add {
-      position: fixed;
-      padding: 0.3rem 0.5rem;
-      z-index: 1000;
-      width: 50px !important;
-      height: 50px;
-      bottom: 90px;
-      right: 5px;
-      font-size: 16px;
-      border-radius: 50%;
-      display: block;
-      background-color: #fb6340 !important;
-      border-color: #fb6340 !important;
-      box-shadow: 0 0 1rem 0 rgba(136, 152, 170, .75);
-    }
-  }
+               .cbi-button-add {
+                       position: fixed;
+                       padding: 0.3rem 0.5rem;
+                       z-index: 1000;
+                       width: 50px !important;
+                       height: 50px;
+                       bottom: 90px;
+                       right: 5px;
+                       font-size: 16px;
+                       border-radius: 50%;
+                       display: block;
+                       background-color: #fb6340 !important;
+                       border-color: #fb6340 !important;
+                       box-shadow: 0 0 1rem 0 rgba(136, 152, 170, .75);
+               }
+       }
 </style>
 
 <div class="pure-g status">
-  <div class="pure-u-1-4">
-    <div class="block pure-g">
-      <div class="pure-u-2-5">
-        <div class="img-con">
-          <svg role="img" viewBox="0 0 24 24">
-            <title>Docker icon</title>
-            <path
-              d="M4.82 17.275c-.684 0-1.304-.56-1.304-1.24s.56-1.243 1.305-1.243c.748 0 1.31.56 1.31 1.242s-.622 1.24-1.305 1.24zm16.012-6.763c-.135-.992-.75-1.8-1.56-2.42l-.315-.25-.254.31c-.494.56-.69 1.553-.63 2.295.06.562.24 1.12.554 1.554-.254.13-.568.25-.81.377-.57.187-1.124.25-1.68.25H.097l-.06.37c-.12 1.182.06 2.42.562 3.54l.244.435v.06c1.5 2.483 4.17 3.6 7.078 3.6 5.594 0 10.182-2.42 12.357-7.633 1.425.062 2.864-.31 3.54-1.676l.18-.31-.3-.187c-.81-.494-1.92-.56-2.85-.31l-.018.002zm-8.008-.992h-2.428v2.42h2.43V9.518l-.002.003zm0-3.043h-2.428v2.42h2.43V6.48l-.002-.003zm0-3.104h-2.428v2.42h2.43v-2.42h-.002zm2.97 6.147H13.38v2.42h2.42V9.518l-.007.003zm-8.998 0H4.383v2.42h2.422V9.518l-.01.003zm3.03 0h-2.4v2.42H9.84V9.518l-.015.003zm-6.03 0H1.4v2.42h2.428V9.518l-.03.003zm6.03-3.043h-2.4v2.42H9.84V6.48l-.015-.003zm-3.045 0H4.387v2.42H6.8V6.48l-.016-.003z" />
-          </svg>
-        </div>
-      </div>
-      <div class="pure-u-3-5">
-        <h4 style="text-align: right; font-size: 1rem"><%:Containers%></h4>
-        <h4 style="text-align: right;">
-            <%- if self.containers_total ~= "-" then -%><a href='<%=luci.dispatcher.build_url("admin/docker/containers")%>'><%- end -%>
-            <span style="font-size: 2rem; color: #2dce89;"><%=self.containers_running%></span>
-            <span style="font-size: 1rem; color: #8898aa !important;">/<%=self.containers_total%></span>
-          <%- if self.containers_total ~= "-" then -%></a><%- end -%>
-        </h4>
-      </div>
-    </div>
-  </div>
-  <div class="pure-u-1-4">
-    <div class="block pure-g">
-      <div class="pure-u-2-5">
-        <div class="img-con">
-          <svg id="icon-hub" viewBox="0 -4 42 50" stroke-width="2" fill-rule="nonzero" width="100%" height="100%">
-            <path
-              d="M37.176371,36.2324812 C37.1920117,36.8041095 36.7372743,37.270685 36.1684891,37.270685 L3.74335204,37.2703476 C3.17827583,37.2703476 2.72400056,36.8091818 2.72400056,36.2397767 L2.72400056,19.6131383 C1.4312007,18.4881431 0.662551336,16.8884326 0.662551336,15.1618249 L0.664207893,14.69503 C0.63774183,14.4532127 0.650524255,14.2942438 0.711604827,14.1238231 L5.10793246,1.20935468 C5.24853286,0.797020623 5.63848594,0.511627907 6.06681069,0.511627907 L34.0728364,0.511627907 C34.5091607,0.511627907 34.889927,0.793578201 35.0316653,1.20921034 L39.4428567,14.1234095 C39.4871296,14.273204 39.5020782,14.4249444 39.4884726,14.5493649 L39.4884726,15.1505835 C39.4884726,16.9959517 38.6190601,18.6883031 37.1764746,19.7563084 L37.176371,36.2324812 Z M35.1376208,35.209311 L35.1376208,20.7057152 C34.7023924,20.8097593 34.271333,20.8633641 33.8336069,20.8633641 C32.0046019,20.8633641 30.3013756,19.9547008 29.2437221,18.4771538 C28.1860473,19.954695 26.4828515,20.8633641 24.6538444,20.8633641 C22.824803,20.8633641 21.1216155,19.9547157 20.0639591,18.4771544 C19.0062842,19.9546953 17.3030887,20.8633641 15.4740818,20.8633641 C13.6450404,20.8633641 11.9418529,19.9547157 10.8841965,18.4771544 C9.82652161,19.9546953 8.12332608,20.8633641 6.29431919,20.8633641 C5.76735555,20.8633641 5.24095778,20.7883418 4.73973398,20.644674 L4.73973398,35.209311 L35.1376208,35.209311 Z M30.2720226,15.6557626 C30.5154632,17.4501192 32.0503909,18.8018554 33.845083,18.8018554 C35.7286794,18.8018554 37.285413,17.3395134 37.4474599,15.4751932 L30.2280765,15.4751932 C30.2470638,15.532987 30.2617919,15.5932958 30.2720226,15.6557626 Z M21.0484306,15.4751932 C21.0674179,15.532987 21.0821459,15.5932958 21.0923767,15.6557626 C21.3358173,17.4501192 22.8707449,18.8018554 24.665437,18.8018554 C26.4601001,18.8018554 27.9950169,17.4501481 28.2378191,15.6611556 C28.2451225,15.5981318 28.2590045,15.5358056 28.2787375,15.4751932 L21.0484306,15.4751932 Z M11.9238102,15.6557626 C12.1672508,17.4501192 13.7021785,18.8018554 15.4968705,18.8018554 C17.2915336,18.8018554 18.8264505,17.4501481 19.0692526,15.6611556 C19.0765561,15.5981318 19.0904381,15.5358056 19.110171,15.4751932 L11.8798641,15.4751932 C11.8988514,15.532987 11.9135795,15.5932958 11.9238102,15.6557626 Z M6.31682805,18.8018317 C8.11149114,18.8018317 9.64640798,17.4501244 9.88921012,15.6611319 C9.89651357,15.5981081 9.91039559,15.5357819 9.93012856,15.4751696 L2.70318796,15.4751696 C2.86612006,17.3346852 4.42809696,18.8018317 6.31682805,18.8018317 Z M3.09670082,13.4139924 L37.04257,13.4139924 L33.3489482,2.57204736 L6.80119239,2.57204736 L3.09670082,13.4139924 Z"
-              id="Fill-1"></path>
-            <rect id="Rectangle-3" x="14" y="26" width="6" height="10"></rect>
-            <path d="M20,26 L20,36 L26,36 L26,26 L20,26 Z" id="Rectangle-3"></path>
-          </svg>
-        </div>
-      </div>
-      <div class="pure-u-3-5">
-        <h4 style="text-align: right; font-size: 1rem"><%:Images%></h4>
-        <h4 style="text-align: right;">
-          <%- if self.images_total ~= "-" then -%><a href='<%=luci.dispatcher.build_url("admin/docker/images")%>'><%- end -%>
-            <span style="font-size: 2rem; color: #2dce89;"><%=self.images_used%></span>
-            <span style="font-size: 1rem; color: #8898aa !important;">/<%=self.images_total%></span>
-          <%- if self.images_total ~= "-" then -%></a><%- end -%>
-        </h4>
-      </div>
-    </div>
-  </div>
-  <div class="pure-u-1-4">
-    <div class="block pure-g">
-      <div class="pure-u-2-5">
-        <div class="img-con">
-          <svg version="1.1" x="0px" y="0px" width="100%" height="100%" viewBox="0 0 48.723 48.723" xml:space="preserve">
-                  <path d="M7.452,24.152h3.435v5.701h0.633c0.001,0,0.001,0,0.002,0h0.636v-5.701h3.51v-1.059h17.124v1.104h3.178v5.656h0.619
-                            c0,0,0,0,0.002,0h0.619v-5.656h3.736v-0.856c0-0.012,0.006-0.021,0.006-0.032c0-0.072,0-0.143,0-0.215h5.721v-1.316h-5.721
-                            c0-0.054,0-0.108,0-0.164c0-0.011-0.006-0.021-0.006-0.032v-0.832h-8.154v1.028h-7.911v-2.652h-0.689c-0.001,0-0.001,0-0.002,0
-                            h-0.678v2.652h-7.846v-1.104H7.452v1.104H1.114v1.316h6.338V24.152z" />
-                  <path
-                    d="M21.484,16.849h5.204v-2.611h7.133V1.555H14.588v12.683h6.896V16.849z M16.537,12.288V3.505h15.335v8.783H16.537z" />
-                  <rect x="18.682" y="16.898" width="10.809" height="0.537" />
-                  <path
-                    d="M0,43.971h6.896v2.611H12.1v-2.611h7.134V31.287H0V43.971z M1.95,33.236h15.334v8.785H1.95V33.236z" />
-                  <rect x="4.095" y="46.631" width="10.808" height="0.537" />
-                  <path
-                    d="M29.491,30.994v12.684h6.895v2.611h5.205v-2.611h7.133V30.994H29.491z M46.774,41.729H31.44v-8.783h15.334V41.729z" />
-                  <rect x="33.584" y="46.338" width="10.809" height="0.537" />
-          </svg>
-        </div>
-      </div>
-      <div class="pure-u-3-5">
-        <h4 style="text-align: right; font-size: 1rem"><%:Networks%></h4>
-        <h4 style="text-align: right;">
-          <%- if self.networks_total ~= "-" then -%><a href='<%=luci.dispatcher.build_url("admin/docker/networks")%>'><%- end -%>
-          <span style="font-size: 2rem; color: #2dce89;"><%=self.networks_total%></span>
-          <!-- <span style="font-size: 1rem; color: #8898aa !important;">/20</span> -->
-          <%- if self.networks_total ~= "-" then -%></a><%- end -%>
-        </h4>
-      </div>
-    </div>
-  </div>
-  <div class="pure-u-1-4">
-    <div class="block pure-g">
-      <div class="pure-u-2-5">
-        <div class="img-con">
-          <svg x="0px" y="0px" viewBox="0 0 55 55" style="enable-background:new 0 0 55 55;" xml:space="preserve">
-            <path
-              d="M52.354,8.51C51.196,4.22,42.577,0,27.5,0C12.423,0,3.803,4.22,2.646,8.51C2.562,8.657,2.5,8.818,2.5,9v0.5V21v0.5V22v11
-           v0.5V34v12c0,0.162,0.043,0.315,0.117,0.451C3.798,51.346,14.364,55,27.5,55c13.106,0,23.655-3.639,24.875-8.516
-           C52.455,46.341,52.5,46.176,52.5,46V34v-0.5V33V22v-0.5V21V9.5V9C52.5,8.818,52.438,8.657,52.354,8.51z M50.421,33.985
-           c-0.028,0.121-0.067,0.241-0.116,0.363c-0.04,0.099-0.089,0.198-0.143,0.297c-0.067,0.123-0.142,0.246-0.231,0.369
-           c-0.066,0.093-0.141,0.185-0.219,0.277c-0.111,0.131-0.229,0.262-0.363,0.392c-0.081,0.079-0.17,0.157-0.26,0.236
-           c-0.164,0.143-0.335,0.285-0.526,0.426c-0.082,0.061-0.17,0.12-0.257,0.18c-0.226,0.156-0.462,0.311-0.721,0.463
-           c-0.068,0.041-0.141,0.08-0.212,0.12c-0.298,0.168-0.609,0.335-0.945,0.497c-0.043,0.021-0.088,0.041-0.132,0.061
-           c-0.375,0.177-0.767,0.351-1.186,0.519c-0.012,0.005-0.024,0.009-0.036,0.014c-2.271,0.907-5.176,1.67-8.561,2.17
-           c-0.017,0.002-0.034,0.004-0.051,0.007c-0.658,0.097-1.333,0.183-2.026,0.259c-0.113,0.012-0.232,0.02-0.346,0.032
-           c-0.605,0.063-1.217,0.121-1.847,0.167c-0.288,0.021-0.59,0.031-0.883,0.049c-0.474,0.028-0.943,0.059-1.429,0.076
-           C29.137,40.984,28.327,41,27.5,41s-1.637-0.016-2.432-0.044c-0.486-0.017-0.955-0.049-1.429-0.076
-           c-0.293-0.017-0.595-0.028-0.883-0.049c-0.63-0.046-1.242-0.104-1.847-0.167c-0.114-0.012-0.233-0.02-0.346-0.032
-           c-0.693-0.076-1.368-0.163-2.026-0.259c-0.017-0.002-0.034-0.004-0.051-0.007c-3.385-0.5-6.29-1.263-8.561-2.17
-           c-0.012-0.004-0.024-0.009-0.036-0.014c-0.419-0.168-0.812-0.342-1.186-0.519c-0.043-0.021-0.089-0.041-0.132-0.061
-           c-0.336-0.162-0.647-0.328-0.945-0.497c-0.07-0.04-0.144-0.079-0.212-0.12c-0.259-0.152-0.495-0.307-0.721-0.463
-           c-0.086-0.06-0.175-0.119-0.257-0.18c-0.191-0.141-0.362-0.283-0.526-0.426c-0.089-0.078-0.179-0.156-0.26-0.236
-           c-0.134-0.13-0.252-0.26-0.363-0.392c-0.078-0.092-0.153-0.184-0.219-0.277c-0.088-0.123-0.163-0.246-0.231-0.369
-           c-0.054-0.099-0.102-0.198-0.143-0.297c-0.049-0.121-0.088-0.242-0.116-0.363C4.541,33.823,4.5,33.661,4.5,33.5
-           c0-0.113,0.013-0.226,0.031-0.338c0.025-0.151,0.011-0.302-0.031-0.445v-7.424c0.028,0.026,0.063,0.051,0.092,0.077
-           c0.218,0.192,0.44,0.383,0.69,0.567C9.049,28.786,16.582,31,27.5,31c10.872,0,18.386-2.196,22.169-5.028
-           c0.302-0.22,0.574-0.447,0.83-0.678l0.001-0.001v7.424c-0.042,0.143-0.056,0.294-0.031,0.445c0.019,0.112,0.031,0.225,0.031,0.338
-           C50.5,33.661,50.459,33.823,50.421,33.985z M50.5,13.293v7.424c-0.042,0.143-0.056,0.294-0.031,0.445
-           c0.019,0.112,0.031,0.225,0.031,0.338c0,0.161-0.041,0.323-0.079,0.485c-0.028,0.121-0.067,0.241-0.116,0.363
-           c-0.04,0.099-0.089,0.198-0.143,0.297c-0.067,0.123-0.142,0.246-0.231,0.369c-0.066,0.093-0.141,0.185-0.219,0.277
-           c-0.111,0.131-0.229,0.262-0.363,0.392c-0.081,0.079-0.17,0.157-0.26,0.236c-0.164,0.143-0.335,0.285-0.526,0.426
-           c-0.082,0.061-0.17,0.12-0.257,0.18c-0.226,0.156-0.462,0.311-0.721,0.463c-0.068,0.041-0.141,0.08-0.212,0.12
-           c-0.298,0.168-0.609,0.335-0.945,0.497c-0.043,0.021-0.088,0.041-0.132,0.061c-0.375,0.177-0.767,0.351-1.186,0.519
-           c-0.012,0.005-0.024,0.009-0.036,0.014c-2.271,0.907-5.176,1.67-8.561,2.17c-0.017,0.002-0.034,0.004-0.051,0.007
-           c-0.658,0.097-1.333,0.183-2.026,0.259c-0.113,0.012-0.232,0.02-0.346,0.032c-0.605,0.063-1.217,0.121-1.847,0.167
-           c-0.288,0.021-0.59,0.031-0.883,0.049c-0.474,0.028-0.943,0.059-1.429,0.076C29.137,28.984,28.327,29,27.5,29
-           s-1.637-0.016-2.432-0.044c-0.486-0.017-0.955-0.049-1.429-0.076c-0.293-0.017-0.595-0.028-0.883-0.049
-           c-0.63-0.046-1.242-0.104-1.847-0.167c-0.114-0.012-0.233-0.02-0.346-0.032c-0.693-0.076-1.368-0.163-2.026-0.259
-           c-0.017-0.002-0.034-0.004-0.051-0.007c-3.385-0.5-6.29-1.263-8.561-2.17c-0.012-0.004-0.024-0.009-0.036-0.014
-           c-0.419-0.168-0.812-0.342-1.186-0.519c-0.043-0.021-0.089-0.041-0.132-0.061c-0.336-0.162-0.647-0.328-0.945-0.497
-           c-0.07-0.04-0.144-0.079-0.212-0.12c-0.259-0.152-0.495-0.307-0.721-0.463c-0.086-0.06-0.175-0.119-0.257-0.18
-           c-0.191-0.141-0.362-0.283-0.526-0.426c-0.089-0.078-0.179-0.156-0.26-0.236c-0.134-0.13-0.252-0.26-0.363-0.392
-           c-0.078-0.092-0.153-0.184-0.219-0.277c-0.088-0.123-0.163-0.246-0.231-0.369c-0.054-0.099-0.102-0.198-0.143-0.297
-           c-0.049-0.121-0.088-0.242-0.116-0.363C4.541,21.823,4.5,21.661,4.5,21.5c0-0.113,0.013-0.226,0.031-0.338
-           c0.025-0.151,0.011-0.302-0.031-0.445v-7.424c0.12,0.109,0.257,0.216,0.387,0.324c0.072,0.06,0.139,0.12,0.215,0.18
-           c0.3,0.236,0.624,0.469,0.975,0.696c0.073,0.047,0.155,0.093,0.231,0.14c0.294,0.183,0.605,0.362,0.932,0.538
-           c0.121,0.065,0.242,0.129,0.367,0.193c0.365,0.186,0.748,0.367,1.151,0.542c0.066,0.029,0.126,0.059,0.193,0.087
-           c0.469,0.199,0.967,0.389,1.485,0.573c0.143,0.051,0.293,0.099,0.44,0.149c0.412,0.139,0.838,0.272,1.279,0.401
-           c0.159,0.046,0.315,0.094,0.478,0.138c0.585,0.162,1.189,0.316,1.823,0.458c0.087,0.02,0.181,0.036,0.269,0.055
-           c0.559,0.122,1.139,0.235,1.735,0.341c0.202,0.036,0.407,0.07,0.613,0.104c0.567,0.093,1.151,0.178,1.75,0.256
-           c0.154,0.02,0.301,0.043,0.457,0.062c0.744,0.09,1.514,0.167,2.305,0.233c0.195,0.016,0.398,0.028,0.596,0.042
-           c0.633,0.046,1.28,0.084,1.942,0.114c0.241,0.011,0.481,0.022,0.727,0.031C25.712,18.979,26.59,19,27.5,19s1.788-0.021,2.65-0.05
-           c0.245-0.009,0.485-0.02,0.727-0.031c0.662-0.03,1.309-0.068,1.942-0.114c0.198-0.015,0.4-0.026,0.596-0.042
-           c0.791-0.065,1.561-0.143,2.305-0.233c0.156-0.019,0.303-0.042,0.457-0.062c0.599-0.078,1.182-0.163,1.75-0.256
-           c0.206-0.034,0.411-0.068,0.613-0.104c0.596-0.106,1.176-0.219,1.735-0.341c0.088-0.019,0.182-0.036,0.269-0.055
-           c0.634-0.142,1.238-0.297,1.823-0.458c0.163-0.045,0.319-0.092,0.478-0.138c0.441-0.129,0.867-0.262,1.279-0.401
-           c0.147-0.05,0.297-0.098,0.44-0.149c0.518-0.184,1.017-0.374,1.485-0.573c0.067-0.028,0.127-0.058,0.193-0.087
-           c0.403-0.176,0.786-0.356,1.151-0.542c0.125-0.064,0.247-0.128,0.367-0.193c0.327-0.175,0.638-0.354,0.932-0.538
-           c0.076-0.047,0.158-0.093,0.231-0.14c0.351-0.227,0.675-0.459,0.975-0.696c0.075-0.06,0.142-0.12,0.215-0.18
-           C50.243,13.509,50.38,13.402,50.5,13.293z M27.5,2c13.555,0,23,3.952,23,7.5s-9.445,7.5-23,7.5s-23-3.952-23-7.5S13.945,2,27.5,2z
-            M50.5,45.703c-0.014,0.044-0.024,0.089-0.032,0.135C49.901,49.297,40.536,53,27.5,53S5.099,49.297,4.532,45.838
-           c-0.008-0.045-0.019-0.089-0.032-0.131v-8.414c0.028,0.026,0.063,0.051,0.092,0.077c0.218,0.192,0.44,0.383,0.69,0.567
-           C9.049,40.786,16.582,43,27.5,43c10.872,0,18.386-2.196,22.169-5.028c0.302-0.22,0.574-0.447,0.83-0.678l0.001-0.001V45.703z" />
-          </svg>
-        </div>
-      </div>
-      <div class="pure-u-3-5">
-        <h4 style="text-align: right; font-size: 1rem"><%:Volumes%></h4>
-        <h4 style="text-align: right;">
-          <%- if self.volumes_total ~= "-" then -%><a href='<%=luci.dispatcher.build_url("admin/docker/volumes")%>'><%- end -%>
-            <span style="font-size: 2rem; color: #2dce89;"><%=self.volumes_total%></span>
-            <!-- <span style="font-size: 1rem; color: #8898aa !important;">/20</span> -->
-            <%- if self.volumes_total ~= "-" then -%></a><%- end -%>
-        </h4>
-      </div>
-    </div>
-  </div>
+       <div class="pure-u-1-4">
+               <div class="block pure-g">
+                       <div class="pure-u-2-5">
+                               <div class="img-con">
+                                       <svg role="img" viewBox="0 0 24 24">
+                                       <title>Docker icon</title>
+                                       <path d="M4.82 17.275c-.684 0-1.304-.56-1.304-1.24s.56-1.243 1.305-1.243c.748 0 1.31.56 1.31 1.242s-.622 1.24-1.305 1.24zm16.012-6.763c-.135-.992-.75-1.8-1.56-2.42l-.315-.25-.254.31c-.494.56-.69 1.553-.63 2.295.06.562.24 1.12.554 1.554-.254.13-.568.25-.81.377-.57.187-1.124.25-1.68.25H.097l-.06.37c-.12 1.182.06 2.42.562 3.54l.244.435v.06c1.5 2.483 4.17 3.6 7.078 3.6 5.594 0 10.182-2.42 12.357-7.633 1.425.062 2.864-.31 3.54-1.676l.18-.31-.3-.187c-.81-.494-1.92-.56-2.85-.31l-.018.002zm-8.008-.992h-2.428v2.42h2.43V9.518l-.002.003zm0-3.043h-2.428v2.42h2.43V6.48l-.002-.003zm0-3.104h-2.428v2.42h2.43v-2.42h-.002zm2.97 6.147H13.38v2.42h2.42V9.518l-.007.003zm-8.998 0H4.383v2.42h2.422V9.518l-.01.003zm3.03 0h-2.4v2.42H9.84V9.518l-.015.003zm-6.03 0H1.4v2.42h2.428V9.518l-.03.003zm6.03-3.043h-2.4v2.42H9.84V6.48l-.015-.003zm-3.045 0H4.387v2.42H6.8V6.48l-.016-.003z" />
+                                       </svg>
+                               </div>
+                       </div>
+                       <div class="pure-u-3-5">
+                               <h4 style="text-align: right; font-size: 1rem"><%:Containers%></h4>
+                               <h4 style="text-align: right;">
+                                       <%- if self.containers_total ~= "-" then -%><a href='<%=luci.dispatcher.build_url("admin/docker/containers")%>'><%- end -%>
+                                       <span style="font-size: 2rem; color: #2dce89;"><%=self.containers_running%></span>
+                                       <span style="font-size: 1rem; color: #8898aa !important;">/<%=self.containers_total%></span>
+                               <%- if self.containers_total ~= "-" then -%></a><%- end -%>
+                               </h4>
+                       </div>
+               </div>
+       </div>
+       <div class="pure-u-1-4">
+               <div class="block pure-g">
+                       <div class="pure-u-2-5">
+                               <div class="img-con">
+                                       <svg id="icon-hub" viewBox="0 -4 42 50" stroke-width="2" fill-rule="nonzero" width="100%" height="100%">
+                                       <path d="M37.176371,36.2324812 C37.1920117,36.8041095 36.7372743,37.270685 36.1684891,37.270685 L3.74335204,37.2703476 C3.17827583,37.2703476 2.72400056,36.8091818 2.72400056,36.2397767 L2.72400056,19.6131383 C1.4312007,18.4881431 0.662551336,16.8884326 0.662551336,15.1618249 L0.664207893,14.69503 C0.63774183,14.4532127 0.650524255,14.2942438 0.711604827,14.1238231 L5.10793246,1.20935468 C5.24853286,0.797020623 5.63848594,0.511627907 6.06681069,0.511627907 L34.0728364,0.511627907 C34.5091607,0.511627907 34.889927,0.793578201 35.0316653,1.20921034 L39.4428567,14.1234095 C39.4871296,14.273204 39.5020782,14.4249444 39.4884726,14.5493649 L39.4884726,15.1505835 C39.4884726,16.9959517 38.6190601,18.6883031 37.1764746,19.7563084 L37.176371,36.2324812 Z M35.1376208,35.209311 L35.1376208,20.7057152 C34.7023924,20.8097593 34.271333,20.8633641 33.8336069,20.8633641 C32.0046019,20.8633641 30.3013756,19.9547008 29.2437221,18.4771538 C28.1860473,19.954695 26.4828515,20.8633641 24.6538444,20.8633641 C22.824803,20.8633641 21.1216155,19.9547157 20.0639591,18.4771544 C19.0062842,19.9546953 17.3030887,20.8633641 15.4740818,20.8633641 C13.6450404,20.8633641 11.9418529,19.9547157 10.8841965,18.4771544 C9.82652161,19.9546953 8.12332608,20.8633641 6.29431919,20.8633641 C5.76735555,20.8633641 5.24095778,20.7883418 4.73973398,20.644674 L4.73973398,35.209311 L35.1376208,35.209311 Z M30.2720226,15.6557626 C30.5154632,17.4501192 32.0503909,18.8018554 33.845083,18.8018554 C35.7286794,18.8018554 37.285413,17.3395134 37.4474599,15.4751932 L30.2280765,15.4751932 C30.2470638,15.532987 30.2617919,15.5932958 30.2720226,15.6557626 Z M21.0484306,15.4751932 C21.0674179,15.532987 21.0821459,15.5932958 21.0923767,15.6557626 C21.3358173,17.4501192 22.8707449,18.8018554 24.665437,18.8018554 C26.4601001,18.8018554 27.9950169,17.4501481 28.2378191,15.6611556 C28.2451225,15.5981318 28.2590045,15.5358056 28.2787375,15.4751932 L21.0484306,15.4751932 Z M11.9238102,15.6557626 C12.1672508,17.4501192 13.7021785,18.8018554 15.4968705,18.8018554 C17.2915336,18.8018554 18.8264505,17.4501481 19.0692526,15.6611556 C19.0765561,15.5981318 19.0904381,15.5358056 19.110171,15.4751932 L11.8798641,15.4751932 C11.8988514,15.532987 11.9135795,15.5932958 11.9238102,15.6557626 Z M6.31682805,18.8018317 C8.11149114,18.8018317 9.64640798,17.4501244 9.88921012,15.6611319 C9.89651357,15.5981081 9.91039559,15.5357819 9.93012856,15.4751696 L2.70318796,15.4751696 C2.86612006,17.3346852 4.42809696,18.8018317 6.31682805,18.8018317 Z M3.09670082,13.4139924 L37.04257,13.4139924 L33.3489482,2.57204736 L6.80119239,2.57204736 L3.09670082,13.4139924 Z"
+                                       id="Fill-1"></path>
+                                       <rect id="Rectangle-3" x="14" y="26" width="6" height="10"></rect>
+                                       <path d="M20,26 L20,36 L26,36 L26,26 L20,26 Z" id="Rectangle-3"></path>
+                                       </svg>
+                               </div>
+                       </div>
+                       <div class="pure-u-3-5">
+                               <h4 style="text-align: right; font-size: 1rem"><%:Images%></h4>
+                               <h4 style="text-align: right;">
+                                       <%- if self.images_total ~= "-" then -%><a href='<%=luci.dispatcher.build_url("admin/docker/images")%>'><%- end -%>
+                                       <span style="font-size: 2rem; color: #2dce89;"><%=self.images_used%></span>
+                                       <span style="font-size: 1rem; color: #8898aa !important;">/<%=self.images_total%></span>
+                                       <%- if self.images_total ~= "-" then -%></a><%- end -%>
+                               </h4>
+                       </div>
+               </div>
+       </div>
+       <div class="pure-u-1-4">
+               <div class="block pure-g">
+                       <div class="pure-u-2-5">
+                               <div class="img-con">
+                                       <svg version="1.1" x="0px" y="0px" width="100%" height="100%" viewBox="0 0 48.723 48.723" xml:space="preserve">
+                                       <path d="M7.452,24.152h3.435v5.701h0.633c0.001,0,0.001,0,0.002,0h0.636v-5.701h3.51v-1.059h17.124v1.104h3.178v5.656h0.619 c0,0,0,0,0.002,0h0.619v-5.656h3.736v-0.856c0-0.012,0.006-0.021,0.006-0.032c0-0.072,0-0.143,0-0.215h5.721v-1.316h-5.721 c0-0.054,0-0.108,0-0.164c0-0.011-0.006-0.021-0.006-0.032v-0.832h-8.154v1.028h-7.911v-2.652h-0.689c-0.001,0-0.001,0-0.002,0 h-0.678v2.652h-7.846v-1.104H7.452v1.104H1.114v1.316h6.338V24.152z" />
+                                       <path d="M21.484,16.849h5.204v-2.611h7.133V1.555H14.588v12.683h6.896V16.849z M16.537,12.288V3.505h15.335v8.783H16.537z" />
+                                       <rect x="18.682" y="16.898" width="10.809" height="0.537" />
+                                       <path d="M0,43.971h6.896v2.611H12.1v-2.611h7.134V31.287H0V43.971z M1.95,33.236h15.334v8.785H1.95V33.236z" />
+                                       <rect x="4.095" y="46.631" width="10.808" height="0.537" />
+                                       <path d="M29.491,30.994v12.684h6.895v2.611h5.205v-2.611h7.133V30.994H29.491z M46.774,41.729H31.44v-8.783h15.334V41.729z" />
+                                       <rect x="33.584" y="46.338" width="10.809" height="0.537" />
+                                       </svg>
+                               </div>
+                       </div>
+                       <div class="pure-u-3-5">
+                               <h4 style="text-align: right; font-size: 1rem"><%:Networks%></h4>
+                               <h4 style="text-align: right;">
+                                       <%- if self.networks_total ~= "-" then -%><a href='<%=luci.dispatcher.build_url("admin/docker/networks")%>'><%- end -%>
+                                       <span style="font-size: 2rem; color: #2dce89;"><%=self.networks_total%></span>
+                                       <!-- <span style="font-size: 1rem; color: #8898aa !important;">/20</span> -->
+                                       <%- if self.networks_total ~= "-" then -%></a><%- end -%>
+                               </h4>
+                       </div>
+               </div>
+       </div>
+       <div class="pure-u-1-4">
+               <div class="block pure-g">
+                       <div class="pure-u-2-5">
+                               <div class="img-con">
+                                       <svg x="0px" y="0px" viewBox="0 0 55 55" style="enable-background:new 0 0 55 55;" xml:space="preserve">
+                                       <path d="M52.354,8.51C51.196,4.22,42.577,0,27.5,0C12.423,0,3.803,4.22,2.646,8.51C2.562,8.657,2.5,8.818,2.5,9v0.5V21v0.5V22v11 v0.5V34v12c0,0.162,0.043,0.315,0.117,0.451C3.798,51.346,14.364,55,27.5,55c13.106,0,23.655-3.639,24.875-8.516 C52.455,46.341,52.5,46.176,52.5,46V34v-0.5V33V22v-0.5V21V9.5V9C52.5,8.818,52.438,8.657,52.354,8.51z M50.421,33.985 c-0.028,0.121-0.067,0.241-0.116,0.363c-0.04,0.099-0.089,0.198-0.143,0.297c-0.067,0.123-0.142,0.246-0.231,0.369 c-0.066,0.093-0.141,0.185-0.219,0.277c-0.111,0.131-0.229,0.262-0.363,0.392c-0.081,0.079-0.17,0.157-0.26,0.236 c-0.164,0.143-0.335,0.285-0.526,0.426c-0.082,0.061-0.17,0.12-0.257,0.18c-0.226,0.156-0.462,0.311-0.721,0.463 c-0.068,0.041-0.141,0.08-0.212,0.12c-0.298,0.168-0.609,0.335-0.945,0.497c-0.043,0.021-0.088,0.041-0.132,0.061 c-0.375,0.177-0.767,0.351-1.186,0.519c-0.012,0.005-0.024,0.009-0.036,0.014c-2.271,0.907-5.176,1.67-8.561,2.17 c-0.017,0.002-0.034,0.004-0.051,0.007c-0.658,0.097-1.333,0.183-2.026,0.259c-0.113,0.012-0.232,0.02-0.346,0.032 c-0.605,0.063-1.217,0.121-1.847,0.167c-0.288,0.021-0.59,0.031-0.883,0.049c-0.474,0.028-0.943,0.059-1.429,0.076 C29.137,40.984,28.327,41,27.5,41s-1.637-0.016-2.432-0.044c-0.486-0.017-0.955-0.049-1.429-0.076 c-0.293-0.017-0.595-0.028-0.883-0.049c-0.63-0.046-1.242-0.104-1.847-0.167c-0.114-0.012-0.233-0.02-0.346-0.032 c-0.693-0.076-1.368-0.163-2.026-0.259c-0.017-0.002-0.034-0.004-0.051-0.007c-3.385-0.5-6.29-1.263-8.561-2.17 c-0.012-0.004-0.024-0.009-0.036-0.014c-0.419-0.168-0.812-0.342-1.186-0.519c-0.043-0.021-0.089-0.041-0.132-0.061 c-0.336-0.162-0.647-0.328-0.945-0.497c-0.07-0.04-0.144-0.079-0.212-0.12c-0.259-0.152-0.495-0.307-0.721-0.463 c-0.086-0.06-0.175-0.119-0.257-0.18c-0.191-0.141-0.362-0.283-0.526-0.426c-0.089-0.078-0.179-0.156-0.26-0.236 c-0.134-0.13-0.252-0.26-0.363-0.392c-0.078-0.092-0.153-0.184-0.219-0.277c-0.088-0.123-0.163-0.246-0.231-0.369 c-0.054-0.099-0.102-0.198-0.143-0.297c-0.049-0.121-0.088-0.242-0.116-0.363C4.541,33.823,4.5,33.661,4.5,33.5 c0-0.113,0.013-0.226,0.031-0.338c0.025-0.151,0.011-0.302-0.031-0.445v-7.424c0.028,0.026,0.063,0.051,0.092,0.077 c0.218,0.192,0.44,0.383,0.69,0.567C9.049,28.786,16.582,31,27.5,31c10.872,0,18.386-2.196,22.169-5.028 c0.302-0.22,0.574-0.447,0.83-0.678l0.001-0.001v7.424c-0.042,0.143-0.056,0.294-0.031,0.445c0.019,0.112,0.031,0.225,0.031,0.338 C50.5,33.661,50.459,33.823,50.421,33.985z M50.5,13.293v7.424c-0.042,0.143-0.056,0.294-0.031,0.445 c0.019,0.112,0.031,0.225,0.031,0.338c0,0.161-0.041,0.323-0.079,0.485c-0.028,0.121-0.067,0.241-0.116,0.363 c-0.04,0.099-0.089,0.198-0.143,0.297c-0.067,0.123-0.142,0.246-0.231,0.369c-0.066,0.093-0.141,0.185-0.219,0.277 c-0.111,0.131-0.229,0.262-0.363,0.392c-0.081,0.079-0.17,0.157-0.26,0.236c-0.164,0.143-0.335,0.285-0.526,0.426 c-0.082,0.061-0.17,0.12-0.257,0.18c-0.226,0.156-0.462,0.311-0.721,0.463c-0.068,0.041-0.141,0.08-0.212,0.12 c-0.298,0.168-0.609,0.335-0.945,0.497c-0.043,0.021-0.088,0.041-0.132,0.061c-0.375,0.177-0.767,0.351-1.186,0.519 c-0.012,0.005-0.024,0.009-0.036,0.014c-2.271,0.907-5.176,1.67-8.561,2.17c-0.017,0.002-0.034,0.004-0.051,0.007 c-0.658,0.097-1.333,0.183-2.026,0.259c-0.113,0.012-0.232,0.02-0.346,0.032c-0.605,0.063-1.217,0.121-1.847,0.167 c-0.288,0.021-0.59,0.031-0.883,0.049c-0.474,0.028-0.943,0.059-1.429,0.076C29.137,28.984,28.327,29,27.5,29 s-1.637-0.016-2.432-0.044c-0.486-0.017-0.955-0.049-1.429-0.076c-0.293-0.017-0.595-0.028-0.883-0.049 c-0.63-0.046-1.242-0.104-1.847-0.167c-0.114-0.012-0.233-0.02-0.346-0.032c-0.693-0.076-1.368-0.163-2.026-0.259 c-0.017-0.002-0.034-0.004-0.051-0.007c-3.385-0.5-6.29-1.263-8.561-2.17c-0.012-0.004-0.024-0.009-0.036-0.014 c-0.419-0.168-0.812-0.342-1.186-0.519c-0.043-0.021-0.089-0.041-0.132-0.061c-0.336-0.162-0.647-0.328-0.945-0.497 c-0.07-0.04-0.144-0.079-0.212-0.12c-0.259-0.152-0.495-0.307-0.721-0.463c-0.086-0.06-0.175-0.119-0.257-0.18 c-0.191-0.141-0.362-0.283-0.526-0.426c-0.089-0.078-0.179-0.156-0.26-0.236c-0.134-0.13-0.252-0.26-0.363-0.392 c-0.078-0.092-0.153-0.184-0.219-0.277c-0.088-0.123-0.163-0.246-0.231-0.369c-0.054-0.099-0.102-0.198-0.143-0.297 c-0.049-0.121-0.088-0.242-0.116-0.363C4.541,21.823,4.5,21.661,4.5,21.5c0-0.113,0.013-0.226,0.031-0.338 c0.025-0.151,0.011-0.302-0.031-0.445v-7.424c0.12,0.109,0.257,0.216,0.387,0.324c0.072,0.06,0.139,0.12,0.215,0.18 c0.3,0.236,0.624,0.469,0.975,0.696c0.073,0.047,0.155,0.093,0.231,0.14c0.294,0.183,0.605,0.362,0.932,0.538 c0.121,0.065,0.242,0.129,0.367,0.193c0.365,0.186,0.748,0.367,1.151,0.542c0.066,0.029,0.126,0.059,0.193,0.087 c0.469,0.199,0.967,0.389,1.485,0.573c0.143,0.051,0.293,0.099,0.44,0.149c0.412,0.139,0.838,0.272,1.279,0.401 c0.159,0.046,0.315,0.094,0.478,0.138c0.585,0.162,1.189,0.316,1.823,0.458c0.087,0.02,0.181,0.036,0.269,0.055 c0.559,0.122,1.139,0.235,1.735,0.341c0.202,0.036,0.407,0.07,0.613,0.104c0.567,0.093,1.151,0.178,1.75,0.256 c0.154,0.02,0.301,0.043,0.457,0.062c0.744,0.09,1.514,0.167,2.305,0.233c0.195,0.016,0.398,0.028,0.596,0.042 c0.633,0.046,1.28,0.084,1.942,0.114c0.241,0.011,0.481,0.022,0.727,0.031C25.712,18.979,26.59,19,27.5,19s1.788-0.021,2.65-0.05 c0.245-0.009,0.485-0.02,0.727-0.031c0.662-0.03,1.309-0.068,1.942-0.114c0.198-0.015,0.4-0.026,0.596-0.042 c0.791-0.065,1.561-0.143,2.305-0.233c0.156-0.019,0.303-0.042,0.457-0.062c0.599-0.078,1.182-0.163,1.75-0.256 c0.206-0.034,0.411-0.068,0.613-0.104c0.596-0.106,1.176-0.219,1.735-0.341c0.088-0.019,0.182-0.036,0.269-0.055 c0.634-0.142,1.238-0.297,1.823-0.458c0.163-0.045,0.319-0.092,0.478-0.138c0.441-0.129,0.867-0.262,1.279-0.401 c0.147-0.05,0.297-0.098,0.44-0.149c0.518-0.184,1.017-0.374,1.485-0.573c0.067-0.028,0.127-0.058,0.193-0.087 c0.403-0.176,0.786-0.356,1.151-0.542c0.125-0.064,0.247-0.128,0.367-0.193c0.327-0.175,0.638-0.354,0.932-0.538 c0.076-0.047,0.158-0.093,0.231-0.14c0.351-0.227,0.675-0.459,0.975-0.696c0.075-0.06,0.142-0.12,0.215-0.18 C50.243,13.509,50.38,13.402,50.5,13.293z M27.5,2c13.555,0,23,3.952,23,7.5s-9.445,7.5-23,7.5s-23-3.952-23-7.5S13.945,2,27.5,2z M50.5,45.703c-0.014,0.044-0.024,0.089-0.032,0.135C49.901,49.297,40.536,53,27.5,53S5.099,49.297,4.532,45.838 c-0.008-0.045-0.019-0.089-0.032-0.131v-8.414c0.028,0.026,0.063,0.051,0.092,0.077c0.218,0.192,0.44,0.383,0.69,0.567 C9.049,40.786,16.582,43,27.5,43c10.872,0,18.386-2.196,22.169-5.028c0.302-0.22,0.574-0.447,0.83-0.678l0.001-0.001V45.703z" />
+                                       </svg>
+                               </div>
+                       </div>
+                       <div class="pure-u-3-5">
+                               <h4 style="text-align: right; font-size: 1rem"><%:Volumes%></h4>
+                               <h4 style="text-align: right;">
+                                       <%- if self.volumes_total ~= "-" then -%><a href='<%=luci.dispatcher.build_url("admin/docker/volumes")%>'><%- end -%>
+                                       <span style="font-size: 2rem; color: #2dce89;"><%=self.volumes_total%></span>
+                                       <!-- <span style="font-size: 1rem; color: #8898aa !important;">/20</span> -->
+                                       <%- if self.volumes_total ~= "-" then -%></a><%- end -%>
+                               </h4>
+                       </div>
+               </div>
+       </div>
 </div>