mirror of
https://github.com/Joxit/docker-registry-ui.git
synced 2026-02-17 21:19:51 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89c532edbd | ||
|
|
b9effee691 | ||
|
|
05090d121d | ||
|
|
c8d98f68d1 | ||
|
|
a8bede51db | ||
|
|
cce858cbd9 | ||
|
|
215733c6e4 | ||
|
|
93a8d4a188 | ||
|
|
ab0571eaa1 | ||
|
|
dc929951cf | ||
|
|
91497a06c3 | ||
|
|
4d1db1f884 | ||
|
|
a59e759c9c | ||
|
|
46b80e73f2 | ||
|
|
bdc0d34a87 | ||
|
|
d4b99b2cb2 | ||
|
|
c1f9d02afb | ||
|
|
d404ead587 | ||
|
|
5569f1f0bf | ||
|
|
9d48643957 | ||
|
|
961342d34c | ||
|
|
02c95fee44 | ||
|
|
ca5fb09fc6 | ||
|
|
83e2befd5d | ||
|
|
06e4d62543 | ||
|
|
5cf136541f |
23
README.md
23
README.md
@@ -5,9 +5,9 @@
|
||||
This project aims to provide a user interface for your private docker registry v2.
|
||||
There is no default registry on this UI, you should add your own with the UI.
|
||||
You can manage more than one registry server.
|
||||
All registry will be stored in the [local storage](https://en.wikipedia.org/wiki/Web_storage#Local_and_session_storage) of your browser.
|
||||
All registries will be stored in the [local storage](https://en.wikipedia.org/wiki/Web_storage#Local_and_session_storage) of your browser.
|
||||
|
||||
This web user interface use [Riot](https://github.com/Riot/riot) the react-like user interface micro-library and [Material Design Lite](https://github.com/google/material-design-lite) components.
|
||||
This web user interface uses [Riot](https://github.com/Riot/riot) the react-like user interface micro-library and [riot-mui](https://github.com/kysonic/riot-mui) components.
|
||||
|
||||
## [GitHub Page](https://joxit.github.io/docker-registry-ui) and [Live Demo](https://joxit.github.io/docker-registry-ui/demo/)
|
||||
|
||||
@@ -18,8 +18,9 @@ This web user interface use [Riot](https://github.com/Riot/riot) the react-like
|
||||
- List all your repositories/images.
|
||||
- List all tags for a repository/image
|
||||
- Sort the tag list
|
||||
- One interface for many registry
|
||||
- One interface for many registries
|
||||
- Use a secured docker registry
|
||||
- Share your docker registry with query parameter `url` (e.g. `https://joxit.github.io/docker-registry-ui/demo?url=https://registry.example.com`)
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -48,7 +49,7 @@ The docker contains the source code and a node webserver in order to serve the d
|
||||
|
||||
You can get the image in three ways
|
||||
|
||||
From sources with this command :
|
||||
From sources with this command:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/Joxit/docker-registry-ui.git
|
||||
@@ -56,14 +57,14 @@ docker build -t joxit/docker-registry-ui docker-registry-ui
|
||||
docker build -t joxit/docker-registry-ui -f docker-registry-ui/Dockerfile.static docker-registry-ui
|
||||
```
|
||||
|
||||
Or build with the url :
|
||||
Or build with the url:
|
||||
|
||||
```sh
|
||||
docker build -t joxit/docker-registry-ui github.com/Joxit/docker-registry-ui
|
||||
docker build -t joxit/docker-registry-ui -f Dockerfile.static github.com/Joxit/docker-registry-ui
|
||||
```
|
||||
|
||||
Or pull the image from [docker hub](https://hub.docker.com/r/joxit/docker-registry-ui/) :
|
||||
Or pull the image from [docker hub](https://hub.docker.com/r/joxit/docker-registry-ui/):
|
||||
|
||||
```sh
|
||||
docker pull joxit/docker-registry-ui
|
||||
@@ -72,7 +73,7 @@ docker pull joxit/docker-registry-ui:static
|
||||
|
||||
#### Run the docker
|
||||
|
||||
To run the docker and see the website on your 80 port, try this :
|
||||
To run the docker and see the website on your 80 port, try this:
|
||||
|
||||
```sh
|
||||
docker run -d -p 80:80 joxit/docker-registry-ui
|
||||
@@ -93,11 +94,11 @@ docker run -d -p 80:80 -e URL=http://127.0.0.1:5000 -e DELETE_IMAGES=true joxit/
|
||||
|
||||
Your server should be configured to accept CORS.
|
||||
|
||||
If your docker registry does not need credentials, you will need to send this HEADER :
|
||||
If your docker registry does not need credentials, you will need to send this HEADER:
|
||||
|
||||
Access-Control-Allow-Origin: '*'
|
||||
|
||||
If your docker registry need credentials, you will need to send these HEADERS :
|
||||
If your docker registry need credentials, you will need to send these HEADERS:
|
||||
|
||||
```yml
|
||||
http:
|
||||
@@ -109,7 +110,7 @@ http:
|
||||
|
||||
## Using delete
|
||||
|
||||
For deleting images, you need to activate the delete feature in your registry :
|
||||
For deleting images, you need to activate the delete feature in your registry:
|
||||
|
||||
```yml
|
||||
storage:
|
||||
@@ -117,7 +118,7 @@ storage:
|
||||
enabled: true
|
||||
```
|
||||
|
||||
And you need to add these HEADERS :
|
||||
And you need to add these HEADERS:
|
||||
|
||||
```yml
|
||||
http:
|
||||
|
||||
@@ -26,32 +26,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Always shows a header, even in smaller screens. -->
|
||||
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
|
||||
<header class="mdl-layout__header">
|
||||
<div class="mdl-layout__header-row">
|
||||
<!-- Title --><span class="mdl-layout-title">Docker Registry UI</span>
|
||||
<menu></menu>
|
||||
</div>
|
||||
</header>
|
||||
<main class="mdl-layout__content">
|
||||
<div class="page-content">
|
||||
<app></app>
|
||||
</div>
|
||||
</main>
|
||||
<change></change>
|
||||
<add></add>
|
||||
<remove></remove>
|
||||
<footer class="mdl-mini-footer">
|
||||
<div class="mdl-mini-footer__left-section">
|
||||
<div class="mdl-logo">Docker Registry UI</div>
|
||||
<ul class="mdl-mini-footer__link-list">
|
||||
<li><a href="https://github.com/Joxit/docker-registry-ui">Contribute on GitHub</a></li>
|
||||
<li><a href="https://github.com/Joxit/docker-registry-ui/blob/master/LICENSE">Privacy & Terms</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<app></app>
|
||||
<script src="../dist/scripts/vendor.js"></script>
|
||||
<script src="../dist/scripts/tags.js"></script>
|
||||
<script src="../dist/scripts/script.js"></script>
|
||||
|
||||
2
dist/index.html
vendored
2
dist/index.html
vendored
@@ -13,4 +13,4 @@
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--><!DOCTYPE html><html><head><meta charset="UTF-8"><link rel="stylesheet" href="vendor.css"><link rel="stylesheet" href="style.css"><link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&lang=en" rel="stylesheet" type="text/css"><title>Docker Registry UI</title></head><body><!-- Always shows a header, even in smaller screens. --><div class="mdl-layout mdl-js-layout mdl-layout--fixed-header"><header class="mdl-layout__header"><div class="mdl-layout__header-row"><!-- Title --> <span class="mdl-layout-title">Docker Registry UI</span><menu></menu></div></header><main class="mdl-layout__content"><div class="page-content"><app></app></div></main><change></change><add></add><remove></remove><footer class="mdl-mini-footer"><div class="mdl-mini-footer__left-section"><div class="mdl-logo">Docker Registry UI</div><ul class="mdl-mini-footer__link-list"><li><a href="https://github.com/Joxit/docker-registry-ui">Contribute on GitHub</a></li><li><a href="https://github.com/Joxit/docker-registry-ui/blob/master/LICENSE">Privacy & Terms</a></li></ul></div></footer></div><script src="scripts/vendor.js"></script><script src="scripts/tags.js"></script><script src="scripts/script.js"></script></body></html>
|
||||
--><!DOCTYPE html><html><head><meta charset="UTF-8"><link rel="stylesheet" href="vendor.css"><link rel="stylesheet" href="style.css"><link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&lang=en" rel="stylesheet" type="text/css"><title>Docker Registry UI</title></head><body><app></app><script src="scripts/vendor.js"></script><script src="scripts/tags.js"></script><script src="scripts/script.js"></script></body></html>
|
||||
2
dist/scripts/script-static.js
vendored
2
dist/scripts/script-static.js
vendored
@@ -15,4 +15,4 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
function Http(){this.oReq=new XMLHttpRequest,this.oReq.hasHeader=Http.hasHeader,this._events={},this._headers={}}Http.prototype.addEventListener=function(e,t){this._events[e]=t;var s=this;switch(e){case"loadend":s.oReq.addEventListener("loadend",function(){if(401==this.status){var e=new XMLHttpRequest;e.open(s._method,s._url);for(key in s._events)e.addEventListener(key,s._events[key]);for(key in s._headers)e.setRequestHeader(key,s._headers[key]);e.withCredentials=!0,e.hasHeader=Http.hasHeader,e.send()}else t.bind(this)()});break;case"load":s.oReq.addEventListener("load",function(){401!==this.status&&t.bind(this)()});break;default:s.oReq.addEventListener(e,function(){t.bind(this)()})}},Http.prototype.setRequestHeader=function(e,t){this.oReq.setRequestHeader(e,t),this._headers[e]=t},Http.prototype.open=function(e,t){this._method=e,this._url=t,this.oReq.open(e,t)},Http.prototype.send=function(){this.oReq.send()},Http.hasHeader=function(e){return this.getAllResponseHeaders().split("\n").some(function(t){return t.match(new RegExp("^"+e+":"),"i")})};var registryUI={};registryUI.url=function(){return"${URL}"},registryUI.isImageRemoveActivated=!0,registryUI.catalog={},registryUI.taglist={},riot.mount("catalog"),riot.mount("taglist"),riot.mount("app");
|
||||
function Http(){this.oReq=new XMLHttpRequest,this.oReq.hasHeader=Http.hasHeader,this._events={},this._headers={}}Http.prototype.addEventListener=function(e,t){this._events[e]=t;var s=this;switch(e){case"loadend":s.oReq.addEventListener("loadend",function(){if(401==this.status){var e=new XMLHttpRequest;e.open(s._method,s._url);for(key in s._events)e.addEventListener(key,s._events[key]);for(key in s._headers)e.setRequestHeader(key,s._headers[key]);e.withCredentials=!0,e.hasHeader=Http.hasHeader,e.send()}else t.bind(this)()});break;case"load":s.oReq.addEventListener("load",function(){401!==this.status&&t.bind(this)()});break;default:s.oReq.addEventListener(e,function(){t.bind(this)()})}},Http.prototype.setRequestHeader=function(e,t){this.oReq.setRequestHeader(e,t),this._headers[e]=t},Http.prototype.open=function(e,t){this._method=e,this._url=t,this.oReq.open(e,t)},Http.prototype.send=function(){this.oReq.send()},Http.hasHeader=function(e){return this.getAllResponseHeaders().split("\n").some(function(t){return new RegExp("^"+e+":","i").test(t)})};var registryUI={};registryUI.url=function(){return"${URL}"},registryUI.isImageRemoveActivated=!0,registryUI.catalog={},registryUI.taglist={},riot.mount("catalog"),riot.mount("taglist"),riot.mount("app");
|
||||
2
dist/scripts/script.js
vendored
2
dist/scripts/script.js
vendored
@@ -15,4 +15,4 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
function Http(){this.oReq=new XMLHttpRequest,this.oReq.hasHeader=Http.hasHeader,this._events={},this._headers={}}Http.prototype.addEventListener=function(e,t){this._events[e]=t;var r=this;switch(e){case"loadend":r.oReq.addEventListener("loadend",function(){if(401==this.status){var e=new XMLHttpRequest;e.open(r._method,r._url);for(key in r._events)e.addEventListener(key,r._events[key]);for(key in r._headers)e.setRequestHeader(key,r._headers[key]);e.withCredentials=!0,e.hasHeader=Http.hasHeader,e.send()}else t.bind(this)()});break;case"load":r.oReq.addEventListener("load",function(){401!==this.status&&t.bind(this)()});break;default:r.oReq.addEventListener(e,function(){t.bind(this)()})}},Http.prototype.setRequestHeader=function(e,t){this.oReq.setRequestHeader(e,t),this._headers[e]=t},Http.prototype.open=function(e,t){this._method=e,this._url=t,this.oReq.open(e,t)},Http.prototype.send=function(){this.oReq.send()},Http.hasHeader=function(e){return this.getAllResponseHeaders().split("\n").some(function(t){return t.match(new RegExp("^"+e+":"),"i")})};var registryUI={};registryUI.url=function(){return registryUI.getRegistryServer(0)},registryUI.getRegistryServer=function(e){try{var t=JSON.parse(localStorage.getItem("registryServer"));if(t instanceof Array)return isNaN(e)?t.map(function(e){return e.trim().replace(/\/*$/,"")}):t[e]}catch(e){}return isNaN(e)?[]:""},registryUI.addServer=function(e){var t=registryUI.getRegistryServer();e=e.trim().replace(/\/*$/,"");var r=t.indexOf(e);r==-1&&(t.push(e),localStorage.setItem("registryServer",JSON.stringify(t)))},registryUI.changeServer=function(e){var t=registryUI.getRegistryServer();e=e.trim().replace(/\/*$/,"");var r=t.indexOf(e);r!=-1&&(t.splice(r,1),t=[e].concat(t),localStorage.setItem("registryServer",JSON.stringify(t)))},registryUI.removeServer=function(e){var t=registryUI.getRegistryServer();e=e.trim().replace(/\/*$/,"");var r=t.indexOf(e);r!=-1&&(t.splice(r,1),localStorage.setItem("registryServer",JSON.stringify(t)))},registryUI.isImageRemoveActivated=!0,registryUI.catalog={},registryUI.taglist={},riot.mount("add"),riot.mount("change"),riot.mount("remove"),riot.mount("menu"),riot.mount("app");
|
||||
function Http(){this.oReq=new XMLHttpRequest,this.oReq.hasHeader=Http.hasHeader,this._events={},this._headers={}}Http.prototype.addEventListener=function(e,r){this._events[e]=r;var t=this;switch(e){case"loadend":t.oReq.addEventListener("loadend",function(){if(401==this.status){var e=new XMLHttpRequest;e.open(t._method,t._url);for(key in t._events)e.addEventListener(key,t._events[key]);for(key in t._headers)e.setRequestHeader(key,t._headers[key]);e.withCredentials=!0,e.hasHeader=Http.hasHeader,e.send()}else r.bind(this)()});break;case"load":t.oReq.addEventListener("load",function(){401!==this.status&&r.bind(this)()});break;default:t.oReq.addEventListener(e,function(){r.bind(this)()})}},Http.prototype.setRequestHeader=function(e,r){this.oReq.setRequestHeader(e,r),this._headers[e]=r},Http.prototype.open=function(e,r){this._method=e,this._url=r,this.oReq.open(e,r)},Http.prototype.send=function(){this.oReq.send()},Http.hasHeader=function(e){return this.getAllResponseHeaders().split("\n").some(function(r){return new RegExp("^"+e+":","i").test(r)})};var registryUI={};registryUI.URL_QUERY_PARAM_REGEX=/[&?]url=/,registryUI.URL_PARAM_REGEX=/^url=/,registryUI.url=function(e){if(!registryUI._url){var r=registryUI.getUrlQueryParam();if(r)try{return registryUI._url=registryUI.decodeURI(r),registryUI._url}catch(e){console.log(e)}registryUI._url=registryUI.getRegistryServer(0)}return registryUI._url},registryUI.getRegistryServer=function(e){try{var r=JSON.parse(localStorage.getItem("registryServer"));if(r instanceof Array)return isNaN(e)?r.map(function(e){return e.trim().replace(/\/*$/,"")}):r[e]}catch(e){}return isNaN(e)?[]:""},registryUI.addServer=function(e){var r=registryUI.getRegistryServer();e=e.trim().replace(/\/*$/,"");var t=r.indexOf(e);t==-1&&(r.push(e),registryUI._url||registryUI.updateHistory(e),localStorage.setItem("registryServer",JSON.stringify(r)))},registryUI.changeServer=function(e){var r=registryUI.getRegistryServer();e=e.trim().replace(/\/*$/,"");var t=r.indexOf(e);t!=-1&&(r.splice(t,1),r=[e].concat(r),registryUI.updateHistory(e),localStorage.setItem("registryServer",JSON.stringify(r)))},registryUI.removeServer=function(e){var r=registryUI.getRegistryServer();e=e.trim().replace(/\/*$/,"");var t=r.indexOf(e);t!=-1&&(r.splice(t,1),localStorage.setItem("registryServer",JSON.stringify(r)),e==registryUI.url()&&(registryUI.updateHistory(registryUI.getRegistryServer(0)),rg.router.go("home")))},registryUI.updateHistory=function(e){history.pushState(null,"",(e?"?url="+registryUI.encodeURI(e):"?")+window.location.hash),registryUI._url=e},registryUI.getUrlQueryParam=function(){var e=window.location.search;if(registryUI.URL_QUERY_PARAM_REGEX.test(e)){var r=e.split(/^\?|&/).find(function(e){return e&®istryUI.URL_PARAM_REGEX.test(e)});return r?r.replace(registryUI.URL_PARAM_REGEX,""):r}},registryUI.encodeURI=function(e){return e.indexOf("&")<0?window.encodeURIComponent(e):btoa(e)},registryUI.decodeURI=function(e){return e.startsWith("http")?window.decodeURIComponent(e):atob(e)},registryUI.isImageRemoveActivated=!0,registryUI.catalog={},registryUI.taglist={},riot.mount("*");
|
||||
2
dist/scripts/tags-static.js
vendored
2
dist/scripts/tags-static.js
vendored
File diff suppressed because one or more lines are too long
2
dist/scripts/tags.js
vendored
2
dist/scripts/tags.js
vendored
File diff suppressed because one or more lines are too long
750
dist/scripts/vendor.js
vendored
750
dist/scripts/vendor.js
vendored
File diff suppressed because one or more lines are too long
2
dist/style.css
vendored
2
dist/style.css
vendored
@@ -15,4 +15,4 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(MaterialIcons-Regular.eot);src:local('fonts/Material Icons'),local('fonts/MaterialIcons-Regular'),url(fonts/MaterialIcons-Regular.woff2) format('woff2'),url(fonts/MaterialIcons-Regular.woff) format('woff'),url(fonts/MaterialIcons-Regular.ttf) format('truetype')}.material-icons{font-family:'Material Icons';font-weight:400;font-style:normal;font-size:24px;display:inline-block;width:1em;height:1em;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:'liga'}html>body{font-family:Roboto,Helvetica,Arial,sans-serif!important}.mdl-mini-footer{padding-top:8px;padding-bottom:8px}.catalog,.taglist{padding:16px}.section-centerd{margin:auto}.mdl-data-table th{font-size:18px}.mdl-data-table td{font-size:16px}.full-table{width:100%;border:none}.url{font-size:14px;word-break:break-all}
|
||||
@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(MaterialIcons-Regular.eot);src:local('fonts/Material Icons'),local('fonts/MaterialIcons-Regular'),url(fonts/MaterialIcons-Regular.woff2) format('woff2'),url(fonts/MaterialIcons-Regular.woff) format('woff'),url(fonts/MaterialIcons-Regular.ttf) format('truetype')}.material-icons{font-family:'Material Icons';font-weight:400;font-style:normal;font-size:24px;display:inline-block;width:1em;height:1em;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:'liga'}html>body{font-family:Roboto,Helvetica,Arial,sans-serif!important}body,html{margin:0;height:100%}main{margin-bottom:100px}.section-centerd{margin:auto}.full-table{width:100%;border:none}.url{font-size:14px;word-break:break-all}.material-card-title-action a{color:inherit;text-decoration:none;font-weight:inherit}material-card{min-height:200px;max-width:75%;margin:auto;margin-top:20px;margin-bottom:20px}material-spinner{align-self:center}.spinner-wrapper{margin-top:50px;display:flex;flex-direction:column}material-navbar{height:64px}.logo{padding:0 16px 0 72px;text-decoration:none;font-size:20px;line-height:1;letter-spacing:.02em;font-weight:400}h2{padding:16px;margin:auto;font-size:24px;font-weight:300;line-height:normal;overflow:hidden}.list{display:block;padding:8px 0;list-style:none}.list.highlight>li:hover{background-color:#eee;cursor:pointer}.list>li{box-sizing:border-box;line-height:1;height:48px;padding:0 16px;overflow:hidden}.list>li i.material-icons{margin-right:32px;height:24px;width:24px;font-size:24px;box-sizing:border-box;color:#757575}.list>li>span{height:100%;text-decoration:none;box-sizing:border-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.material-card-title-action{-webkit-align-items:center;-ms-flex-align:center;align-items:center;display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;padding:16px}.material-card-title-action h2{margin:0}material-card table{width:100%;border:none;position:relative;border:1px solid rgba(0,0,0,.12);border-collapse:collapse;white-space:nowrap;font-size:13px;background-color:#fff;border:none}material-card table th{font-size:18px;vertical-align:bottom;line-height:24px;height:48px;color:rgba(0,0,0,.54);box-sizing:border-box;padding:0 18px 12px 18px;text-align:right}.material-card-th-left{text-align:left}material-card table tbody tr:hover{background-color:#eee}material-card table tbody tr{position:relative;height:48px;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:background-color}material-card table td{font-size:16px;position:relative;height:48px;border-top:1px solid rgba(0,0,0,.12);border-bottom:1px solid rgba(0,0,0,.12);padding:12px 18px;box-sizing:border-box;vertical-align:middle;text-align:right}material-card table th.material-card-th-sorted-ascending:hover,material-card table th.material-card-th-sorted-descending:hover{cursor:pointer}material-card table th.material-card-th-sorted-ascending:hover:before,material-card table th.material-card-th-sorted-descending:hover:before{color:rgba(0,0,0,.26)}material-card table th.material-card-th-sorted-ascending:before,material-card table th.material-card-th-sorted-descending:before{font-family:'Material Icons';font-weight:400;font-style:normal;line-height:1;font-size:16px;content:"\e5d8";margin-right:5px;vertical-align:sub}material-card table th.material-card-th-sorted-descending:before{content:"\e5db"}.material-icons{color:#777}material-snackbar .toast{height:auto}menu{position:absolute;top:0;right:16px;color:#000}menu .overlay{position:fixed;height:100%;width:100%;top:0;right:0;z-index:1}#menu-control-button{background:rgba(255,255,255,0);float:right}#menu-control-button i{color:#fff;font-size:24px}#menu-control-dropdown{display:inline-block;position:relative}.dropdown{min-width:124px;padding:8px 0;margin:0}#menu-control-dropdown p,dropdown-item{padding:0 16px;margin:auto;line-height:48px;height:48px;cursor:pointer}#menu-control-dropdown p:hover{background-color:#eee}#menu-control-dropdown p:active,.material-button-active:active{background-color:#e0e0e0}material-popup material-button{background-color:#fff;color:#000}material-popup material-button:hover material-waves{background-color:hsla(0,0%,75%,.2)}material-popup .popup{max-width:450px}footer{width:100%;position:fixed;bottom:0}.select-padding{padding:20px 0}select{position:relative;outline:0;box-shadow:none;padding:0;width:100%;background:0 0;border:none;font-weight:400;line-height:24px;height:24px;border-bottom:1px solid #2f6975;appearance:none;-moz-appearance:none;-webkit-appearance:none}
|
||||
47
dist/vendor.css
vendored
47
dist/vendor.css
vendored
File diff suppressed because one or more lines are too long
14
gulpfile.js
14
gulpfile.js
@@ -14,7 +14,7 @@ var uglify = require('uglify-js-harmony');
|
||||
var useref = require('gulp-useref');
|
||||
|
||||
gulp.task('html', function() {
|
||||
var htmlFilter = filter('**/*.html');
|
||||
var htmlFilter = filter('**/*.html', {restore: true});
|
||||
return gulp.src(['src/index.html'])
|
||||
.pipe(useref())
|
||||
.pipe(gIf(['*.js', '!*.min.js'], minifier({}, uglify))) // FIXME
|
||||
@@ -26,12 +26,12 @@ gulp.task('html', function() {
|
||||
removeEmptyAttributes: true,
|
||||
minifyJS: uglify
|
||||
}))
|
||||
.pipe(htmlFilter.restore())
|
||||
.pipe(htmlFilter.restore)
|
||||
.pipe(gulp.dest('dist'));
|
||||
});
|
||||
|
||||
gulp.task('clean', function(done) {
|
||||
del(['dist'], done);
|
||||
return del(['dist']);
|
||||
});
|
||||
|
||||
gulp.task('riot-tag', ['html'], function() {
|
||||
@@ -88,6 +88,12 @@ gulp.task('scripts', ['html'], function() {
|
||||
.pipe(gulp.dest('dist/scripts'));
|
||||
});
|
||||
|
||||
gulp.task('vendor', ['html'], function() {
|
||||
return gulp.src(['node_modules/riot/riot.min.js', 'node_modules/riotgear-router/dist/rg-router.min.js', 'node_modules/riot-mui/build/js/riot-mui-min.js'])
|
||||
.pipe(concat('vendor.js'))
|
||||
.pipe(gulp.dest('dist/scripts'));
|
||||
});
|
||||
|
||||
gulp.task('styles', ['html'], function() {
|
||||
return gulp.src(['src/*.css'])
|
||||
.pipe(concat('style.css'))
|
||||
@@ -109,7 +115,7 @@ gulp.task('fonts', function() {
|
||||
.pipe(gulp.dest('dist/fonts'));
|
||||
});
|
||||
|
||||
gulp.task('sources', ['riot-tag', 'riot-static-tag', 'scripts', 'scripts-static', 'styles'], function() {
|
||||
gulp.task('sources', ['riot-tag', 'riot-static-tag', 'scripts', 'vendor', 'scripts-static', 'styles'], function() {
|
||||
gulp.start();
|
||||
});
|
||||
|
||||
|
||||
28
package.json
28
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docker-registry-ui",
|
||||
"version": "0.2.2",
|
||||
"version": "0.3.0",
|
||||
"scripts": {
|
||||
"build": "./node_modules/gulp/bin/gulp.js build"
|
||||
},
|
||||
@@ -9,26 +9,26 @@
|
||||
"url": "https://github.com/Joxit/docker-registry-ui.git"
|
||||
},
|
||||
"author": "Jones Magloire (Joxit)",
|
||||
"license": "AGPLv3",
|
||||
"license": "AGPL-3.0",
|
||||
"description": "A web UI for private docker registry",
|
||||
"dependencies": {
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"del": "^0.1.3",
|
||||
"dialog-polyfill": "^0.4",
|
||||
"del": "^3.0.0",
|
||||
"gulp": "^3.9",
|
||||
"gulp-clean-css": "^3.7.0",
|
||||
"gulp-concat": "^2.6.0",
|
||||
"gulp-filter": "^1.0.0",
|
||||
"gulp-htmlmin": "^2.0.0",
|
||||
"gulp-filter": "^5.0.1",
|
||||
"gulp-htmlmin": "^3.0.0",
|
||||
"gulp-if": "^2.0.0",
|
||||
"gulp-license": "^1.1.0",
|
||||
"gulp-clean-css": "^2.0.11",
|
||||
"gulp-riot": "^0.5.2",
|
||||
"gulp-uglify": "^1.0.0",
|
||||
"gulp-riot": "^1.1.1",
|
||||
"gulp-uglify": "^2.1.2",
|
||||
"gulp-useref": "^3.0.0",
|
||||
"material-design-lite": "^1.1",
|
||||
"riot": "^2.3",
|
||||
"pump": "^1.0.2",
|
||||
"riot": "^3.7.0",
|
||||
"riot-mui": "^0.1.1",
|
||||
"riotgear-router": "^1.3.1",
|
||||
"uglify-js-harmony": "^2.6.2"
|
||||
"uglify-js": "^3.0.28",
|
||||
"uglify-js-harmony": "^2.7.7"
|
||||
}
|
||||
}
|
||||
|
||||
BIN
screenshot.png
BIN
screenshot.png
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 38 KiB |
@@ -20,8 +20,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!-- build:css vendor.css -->
|
||||
<LINK href="../node_modules/dialog-polyfill/dialog-polyfill.css" rel="stylesheet" type="text/css">
|
||||
<LINK href="../node_modules/material-design-lite/dist/material.min.css" rel="stylesheet" type="text/css">
|
||||
<LINK href="../node_modules/riot-mui/build/styles/riot-mui.min.css" rel="stylesheet" type="text/css">
|
||||
<!-- endbuild -->
|
||||
<!-- build:css style.css -->
|
||||
<LINK href="style.css" rel="stylesheet" type="text/css">
|
||||
@@ -32,38 +31,11 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Always shows a header, even in smaller screens. -->
|
||||
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
|
||||
<header class="mdl-layout__header">
|
||||
<div class="mdl-layout__header-row">
|
||||
<!-- Title -->
|
||||
<span class="mdl-layout-title">Docker Registry UI</span>
|
||||
<menu></menu>
|
||||
</div>
|
||||
</header>
|
||||
<main class="mdl-layout__content">
|
||||
<div class="page-content">
|
||||
<app></app>
|
||||
</div>
|
||||
</main>
|
||||
<change></change>
|
||||
<add></add>
|
||||
<remove></remove>
|
||||
<footer class="mdl-mini-footer">
|
||||
<div class="mdl-mini-footer__left-section">
|
||||
<div class="mdl-logo">Docker Registry UI</div>
|
||||
<ul class="mdl-mini-footer__link-list">
|
||||
<li><a href="https://github.com/Joxit/docker-registry-ui">Contribute on GitHub</a></li>
|
||||
<li><a href="https://github.com/Joxit/docker-registry-ui/blob/master/LICENSE">Privacy & Terms</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<app></app>
|
||||
<!-- build:js scripts/vendor.js -->
|
||||
<script src="../node_modules/riot/riot+compiler.min.js"></script>
|
||||
<script src="../node_modules/riotgear-router/dist/rg-router.min.js"></script>
|
||||
<script src="../node_modules/dialog-polyfill/dialog-polyfill.js"></script>
|
||||
<script src="../node_modules/material-design-lite/dist/material.min.js"></script>
|
||||
<script src="../node_modules/riot-mui/build/js/riot-mui.js"></script>
|
||||
<!-- endbuild -->
|
||||
<!-- build:js scripts/tags.js -->
|
||||
<script src="tags/catalog.tag" type="riot/tag"></script>
|
||||
|
||||
@@ -82,6 +82,6 @@ Http.prototype.send = function() {
|
||||
|
||||
Http.hasHeader = function(header) {
|
||||
return this.getAllResponseHeaders().split('\n').some(function(h) {
|
||||
return h.match(new RegExp('^' + header + ':'), 'i');
|
||||
return new RegExp('^' + header + ':', 'i').test(h);
|
||||
});
|
||||
};
|
||||
@@ -15,8 +15,23 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
var registryUI = {}
|
||||
registryUI.url = function() {
|
||||
return registryUI.getRegistryServer(0);
|
||||
registryUI.URL_QUERY_PARAM_REGEX = /[&?]url=/;
|
||||
registryUI.URL_PARAM_REGEX = /^url=/;
|
||||
|
||||
registryUI.url = function(byPassQueryParam) {
|
||||
if (!registryUI._url) {
|
||||
var url = registryUI.getUrlQueryParam();
|
||||
if (url) {
|
||||
try {
|
||||
registryUI._url = registryUI.decodeURI(url);
|
||||
return registryUI._url;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
registryUI._url = registryUI.getRegistryServer(0);
|
||||
}
|
||||
return registryUI._url;
|
||||
}
|
||||
registryUI.getRegistryServer = function(i) {
|
||||
try {
|
||||
@@ -37,6 +52,9 @@ registryUI.addServer = function(url) {
|
||||
return;
|
||||
}
|
||||
registryServer.push(url);
|
||||
if (!registryUI._url) {
|
||||
registryUI.updateHistory(url);
|
||||
}
|
||||
localStorage.setItem('registryServer', JSON.stringify(registryServer));
|
||||
}
|
||||
registryUI.changeServer = function(url) {
|
||||
@@ -48,6 +66,7 @@ registryUI.changeServer = function(url) {
|
||||
}
|
||||
registryServer.splice(index, 1);
|
||||
registryServer = [url].concat(registryServer);
|
||||
registryUI.updateHistory(url);
|
||||
localStorage.setItem('registryServer', JSON.stringify(registryServer));
|
||||
}
|
||||
registryUI.removeServer = function(url) {
|
||||
@@ -59,13 +78,37 @@ registryUI.removeServer = function(url) {
|
||||
}
|
||||
registryServer.splice(index, 1);
|
||||
localStorage.setItem('registryServer', JSON.stringify(registryServer));
|
||||
if (url == registryUI.url()) {
|
||||
registryUI.updateHistory(registryUI.getRegistryServer(0));
|
||||
rg.router.go('home');
|
||||
}
|
||||
}
|
||||
|
||||
registryUI.updateHistory = function(url) {
|
||||
history.pushState(null, '', (url ? '?url=' + registryUI.encodeURI(url) : '?') + window.location.hash);
|
||||
registryUI._url = url;
|
||||
}
|
||||
|
||||
registryUI.getUrlQueryParam = function () {
|
||||
var search = window.location.search;
|
||||
if (registryUI.URL_QUERY_PARAM_REGEX.test(search)) {
|
||||
var param = search.split(/^\?|&/).find(function(param) {
|
||||
return param && registryUI.URL_PARAM_REGEX.test(param);
|
||||
});
|
||||
return param ? param.replace(registryUI.URL_PARAM_REGEX, '') : param;
|
||||
}
|
||||
};
|
||||
|
||||
registryUI.encodeURI = function(url) {
|
||||
return url.indexOf('&') < 0 ? window.encodeURIComponent(url) : btoa(url);
|
||||
};
|
||||
|
||||
registryUI.decodeURI = function(url) {
|
||||
return url.startsWith('http') ? window.decodeURIComponent(url) : atob(url);
|
||||
};
|
||||
|
||||
registryUI.isImageRemoveActivated = true;
|
||||
registryUI.catalog = {};
|
||||
registryUI.taglist = {};
|
||||
|
||||
riot.mount('add');
|
||||
riot.mount('change');
|
||||
riot.mount('remove');
|
||||
riot.mount('menu');
|
||||
riot.mount('app');
|
||||
riot.mount('*');
|
||||
|
||||
287
src/style.css
287
src/style.css
@@ -18,28 +18,19 @@
|
||||
html > body {
|
||||
font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif !important;
|
||||
}
|
||||
|
||||
.mdl-mini-footer {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
html, body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.catalog, .taglist {
|
||||
padding: 16px;
|
||||
main {
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
|
||||
.section-centerd {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.mdl-data-table th {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.mdl-data-table td {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.full-table {
|
||||
width: 100%;
|
||||
border: none;
|
||||
@@ -48,4 +39,272 @@ html > body {
|
||||
.url {
|
||||
font-size: 14px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.material-card-title-action a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
material-card {
|
||||
min-height: 200px;
|
||||
max-width: 75%;
|
||||
margin: auto;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
material-spinner {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.spinner-wrapper {
|
||||
margin-top: 50px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
material-navbar {
|
||||
height: 64px;
|
||||
}
|
||||
.logo {
|
||||
padding: 0 16px 0 72px;
|
||||
text-decoration: none;
|
||||
font-size: 20px;
|
||||
line-height: 1;
|
||||
letter-spacing: .02em;
|
||||
font-weight: 400;
|
||||
}
|
||||
h2 {
|
||||
padding: 16px;
|
||||
margin: auto;
|
||||
font-size: 24px;
|
||||
font-weight: 300;
|
||||
line-height: normal;
|
||||
overflow: hidden;
|
||||
}
|
||||
.list {
|
||||
display: block;
|
||||
padding: 8px 0;
|
||||
list-style: none;
|
||||
}
|
||||
.list.highlight>li:hover {
|
||||
background-color: #eee;
|
||||
cursor: pointer;
|
||||
}
|
||||
.list>li {
|
||||
box-sizing: border-box;
|
||||
line-height: 1;
|
||||
height: 48px;
|
||||
padding: 0 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.list>li i.material-icons {
|
||||
margin-right: 32px;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
font-size: 24px;
|
||||
box-sizing: border-box;
|
||||
color: #757575;
|
||||
}
|
||||
.list>li>span {
|
||||
height: 100%;
|
||||
text-decoration: none;
|
||||
box-sizing: border-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.material-card-title-action {
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
display: block;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.material-card-title-action h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
material-card table {
|
||||
width: 100%;
|
||||
border: none;
|
||||
position: relative;
|
||||
border: 1px solid rgba(0,0,0,.12);
|
||||
border-collapse: collapse;
|
||||
white-space: nowrap;
|
||||
font-size: 13px;
|
||||
background-color: #fff;
|
||||
border: none;
|
||||
}
|
||||
|
||||
material-card table th {
|
||||
font-size: 18px;
|
||||
vertical-align: bottom;
|
||||
line-height: 24px;
|
||||
height: 48px;
|
||||
color: rgba(0,0,0,.54);
|
||||
box-sizing: border-box;
|
||||
padding: 0 18px 12px 18px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.material-card-th-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
material-card table tbody tr:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
material-card table tbody tr {
|
||||
position: relative;
|
||||
height: 48px;
|
||||
transition-duration: .28s;
|
||||
transition-timing-function: cubic-bezier(.4,0,.2,1);
|
||||
transition-property: background-color;
|
||||
}
|
||||
|
||||
material-card table td {
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
height: 48px;
|
||||
border-top: 1px solid rgba(0,0,0,.12);
|
||||
border-bottom: 1px solid rgba(0,0,0,.12);
|
||||
padding: 12px 18px;
|
||||
box-sizing: border-box;
|
||||
vertical-align: middle;
|
||||
text-align: right;
|
||||
}
|
||||
material-card table th.material-card-th-sorted-ascending:hover,
|
||||
material-card table th.material-card-th-sorted-descending:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
material-card table th.material-card-th-sorted-ascending:hover:before,
|
||||
material-card table th.material-card-th-sorted-descending:hover:before {
|
||||
color: rgba(0,0,0,.26);
|
||||
}
|
||||
|
||||
material-card table th.material-card-th-sorted-ascending:before,
|
||||
material-card table th.material-card-th-sorted-descending:before {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
line-height: 1;
|
||||
font-size: 16px;
|
||||
content: "\e5d8";
|
||||
margin-right: 5px;
|
||||
vertical-align: sub;
|
||||
}
|
||||
material-card table th.material-card-th-sorted-descending:before {
|
||||
content: "\e5db";
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
material-snackbar .toast {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
menu {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 16px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
menu .overlay {
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#menu-control-button {
|
||||
background: rgba(255,255,255,0);
|
||||
float: right;
|
||||
}
|
||||
|
||||
#menu-control-button i {
|
||||
color: #fff;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
#menu-control-dropdown {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
min-width: 124px;
|
||||
padding: 8px 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
dropdown-item, #menu-control-dropdown p {
|
||||
padding: 0 16px;
|
||||
margin: auto;
|
||||
line-height: 48px;
|
||||
height: 48px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#menu-control-dropdown p:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
#menu-control-dropdown p:active, .material-button-active:active {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
material-popup material-button {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
material-popup material-button:hover material-waves {
|
||||
background-color: hsla(0,0%,75%,.2);
|
||||
}
|
||||
|
||||
material-popup .popup {
|
||||
max-width: 450px;
|
||||
}
|
||||
|
||||
footer {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.select-padding {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
select {
|
||||
position: relative;
|
||||
outline: 0;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
background: 0 0;
|
||||
border: none;
|
||||
font-weight: 400;
|
||||
line-height: 24px;
|
||||
height: 24px;
|
||||
border-bottom: 1px solid #2f6975;
|
||||
appearance: none;
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
@@ -15,51 +15,45 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<add>
|
||||
<dialog id="add-server-dialog" class="mdl-dialog">
|
||||
<h4 class="mdl-dialog__title">Add your Server ?</h4>
|
||||
<div class="mdl-dialog__content">
|
||||
<div class="mdl-textfield mdl-js-textfield">
|
||||
<input class="mdl-textfield__input" type="text" id="add-server-input">
|
||||
<label class="mdl-textfield__label" for="add-server-input">Server url</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mdl-dialog__actions">
|
||||
<button type="button" class="mdl-button change" onClick="registryUI.addTag.add();">Add</button>
|
||||
<button type="button" class="mdl-button close" onClick="registryUI.addTag.close();">Cancel</button>
|
||||
</div>
|
||||
</dialog>
|
||||
<material-popup>
|
||||
<div class="material-popup-title">Add your Server ?</div>
|
||||
<div class="material-popup-content">
|
||||
<material-input onkeyup="{ registryUI.addTag.onkeyup }" placeholder="Server URL"></material-input>
|
||||
<span>Write your URL without /v2</span>
|
||||
</div>
|
||||
<div class="material-popup-action">
|
||||
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="registryUI.addTag.add();">Add</material-button>
|
||||
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="registryUI.addTag.close();">Cancel</material-button>
|
||||
</div>
|
||||
</material-popup>
|
||||
|
||||
<script type="text/javascript">
|
||||
registryUI.addTag = registryUI.addTag || {};
|
||||
registryUI.addTag.update = this.update;
|
||||
this.on('updated', function () {
|
||||
componentHandler.upgradeElements(this['add-server-dialog']);
|
||||
registryUI.addTag.dialog = registryUI.addTag.dialog || document.querySelector('#add-server-dialog');
|
||||
registryUI.addTag.addServer = registryUI.addTag.tileServerList || registryUI.addTag.dialog.querySelector('#add-server-input');
|
||||
if (!registryUI.addTag.dialog.showModal) {
|
||||
dialogPolyfill.registerDialog(registryUI.addTag.dialog);
|
||||
this.one('mount', function () {
|
||||
registryUI.addTag.dialog = this.tags['material-popup'];
|
||||
registryUI.addTag.dialog.getAddServer = function() {
|
||||
return this.tags['material-input'] ? this.tags['material-input'].value : '';
|
||||
}
|
||||
this['add-server-input'].onkeyup = function (e) {
|
||||
// if keyCode is Enter
|
||||
if (e.keyCode == 13) {
|
||||
registryUI.addTag.add();
|
||||
}
|
||||
};
|
||||
});
|
||||
registryUI.addTag.onkeyup = function (e) {
|
||||
// if keyCode is Enter
|
||||
if (e.keyCode == 13) {
|
||||
registryUI.addTag.add();
|
||||
}
|
||||
};
|
||||
registryUI.addTag.show = function () {
|
||||
registryUI.addTag.dialog.showModal();
|
||||
registryUI.addTag.dialog.open();
|
||||
};
|
||||
registryUI.addTag.add = function () {
|
||||
if (registryUI.addTag.addServer.value && registryUI.addTag.addServer.value.length > 0) {
|
||||
registryUI.addServer(registryUI.addTag.addServer.value);
|
||||
if (registryUI.addTag.dialog.getAddServer().length > 0) {
|
||||
registryUI.addServer(registryUI.addTag.dialog.getAddServer());
|
||||
}
|
||||
registryUI.addTag.addServer.value = '';
|
||||
rg.router.go('home');
|
||||
registryUI.addTag.dialog.close();
|
||||
registryUI.addTag.close();
|
||||
};
|
||||
registryUI.addTag.close = function () {
|
||||
registryUI.addTag.addServer.value = '';
|
||||
registryUI.addTag.dialog.tags['material-input'].value = '';
|
||||
registryUI.addTag.dialog.close();
|
||||
};
|
||||
registryUI.addTag.update();
|
||||
</script>
|
||||
</add>
|
||||
|
||||
@@ -15,8 +15,34 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<app>
|
||||
<catalog if="{!rg.router.current || rg.router.current.name == 'home'}"></catalog>
|
||||
<taglist if="{rg.router.current.name == 'taglist'}"></taglist>
|
||||
<header>
|
||||
<material-navbar>
|
||||
<div class="logo">Docker Registry UI</div>
|
||||
<menu></menu>
|
||||
</material-navbar>
|
||||
</header>
|
||||
<main>
|
||||
<catalog if="{!rg.router.current || rg.router.current.name == 'home'}"></catalog>
|
||||
<taglist if="{rg.router.current && rg.router.current.name == 'taglist'}"></taglist>
|
||||
<change></change>
|
||||
<add></add>
|
||||
<remove></remove>
|
||||
<material-snackbar></material-snackbar>
|
||||
</main>
|
||||
<footer>
|
||||
<material-footer>
|
||||
<a class="material-footer-logo" href="https://joxit.github.io/docker-registry-ui/">Docker Registry UI</a>
|
||||
<ul class="material-footer-link-list">
|
||||
<li>
|
||||
<a href="https://github.com/Joxit/docker-registry-ui">Contribute on GitHub</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://github.com/Joxit/docker-registry-ui/blob/master/LICENSE">Privacy & Terms</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</material-footer>
|
||||
</footer>
|
||||
<script>
|
||||
|
||||
this.mixin('rg.router');
|
||||
@@ -37,7 +63,14 @@
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
});
|
||||
registryUI.appTag = this;
|
||||
registryUI.snackbar = function (message, isError) {
|
||||
registryUI.appTag.tags['material-snackbar'].addToast({'message': message, 'isError': isError});
|
||||
};
|
||||
registryUI.errorSnackbar = function (message) {
|
||||
return registryUI.snackbar(message, true);
|
||||
}
|
||||
this.router.start();
|
||||
</script>
|
||||
</app>
|
||||
</app>
|
||||
@@ -16,57 +16,42 @@
|
||||
-->
|
||||
<catalog>
|
||||
<!-- Begin of tag -->
|
||||
<div id="catalog-tag" class="catalog">
|
||||
<div class="section-centerd mdl-card mdl-shadow--2dp mdl-cell--6-col">
|
||||
<div class="mdl-card__title">
|
||||
<h2 class="mdl-card__title-text">Repositories of { registryUI.url() }</h2>
|
||||
</div>
|
||||
<div id="catalog-spinner" hide="{ registryUI.catalog.loadend }" class="mdl-spinner mdl-js-spinner is-active section-centerd"></div>
|
||||
<ul class="mdl-list" show="{ registryUI.catalog.loadend }">
|
||||
<li class="mdl-list__item mdl-menu__item" style="opacity: 1;" each="{ item in registryUI.catalog.repositories }" onclick="registryUI.catalog.go('{item}');">
|
||||
<span class="mdl-list__item-primary-content">
|
||||
<i class="material-icons mdl-list__item-icon">send</i>
|
||||
{ item }
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<material-card ref="catalog-tag" class="catalog">
|
||||
<div class="material-card-title-action">
|
||||
<h2>Repositories of { registryUI.url() }</h2>
|
||||
</div>
|
||||
<div id="error-snackbar" aria-live="assertive" aria-atomic="true" aria-relevant="text" class="mdl-js-snackbar mdl-snackbar">
|
||||
<div class="mdl-snackbar__text"></div>
|
||||
<button class="mdl-snackbar__action" type="button"></button>
|
||||
<div hide="{ registryUI.catalog.loadend }" class="spinner-wrapper">
|
||||
<material-spinner></material-spinner>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="list highlight" show="{ registryUI.catalog.loadend }">
|
||||
<li each="{ item in registryUI.catalog.repositories }" onclick="registryUI.catalog.go('{item}');">
|
||||
<span>
|
||||
<i class="material-icons">send</i>
|
||||
{ item }
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</material-card>
|
||||
|
||||
<script>
|
||||
registryUI.catalog.instance = this;
|
||||
this.mixin('rg.router');
|
||||
registryUI.catalog.display = function () {
|
||||
var oReq = new Http();
|
||||
registryUI.catalog.createSnackbar = function (msg) {
|
||||
var snackbar = document.querySelector('#error-snackbar');
|
||||
registryUI.catalog.error = msg;
|
||||
var data = {
|
||||
message: registryUI.catalog.error,
|
||||
timeout: 100000,
|
||||
actionHandler: function () {
|
||||
snackbar.classList.remove('mdl-snackbar--active');
|
||||
},
|
||||
actionText: 'Undo'
|
||||
};
|
||||
snackbar.MaterialSnackbar.showSnackbar(data);
|
||||
};
|
||||
oReq.addEventListener('load', function () {
|
||||
registryUI.catalog.repositories = [];
|
||||
if (this.status == 200) {
|
||||
registryUI.catalog.repositories = JSON.parse(this.responseText).repositories || [];
|
||||
registryUI.catalog.repositories.sort();
|
||||
} else if (this.status == 404) {
|
||||
registryUI.catalog.createSnackbar('Server not found');
|
||||
registryUI.snackbar('Server not found', true);
|
||||
} else {
|
||||
registryUI.catalog.createSnackbar(this.responseText);
|
||||
registryUI.snackbar(this.responseText);
|
||||
}
|
||||
});
|
||||
oReq.addEventListener('error', function () {
|
||||
registryUI.catalog.createSnackbar('An error occured');
|
||||
registryUI.snackbar('An error occured', true);
|
||||
registryUI.catalog.repositories = [];
|
||||
});
|
||||
oReq.addEventListener('loadend', function () {
|
||||
registryUI.catalog.loadend = true;
|
||||
@@ -75,9 +60,6 @@
|
||||
oReq.open('GET', registryUI.url() + '/v2/_catalog');
|
||||
oReq.send();
|
||||
};
|
||||
this.on('updated', function () {
|
||||
componentHandler.upgradeElements(this['catalog-tag']);
|
||||
});
|
||||
registryUI.catalog.go = function (image) {
|
||||
rg.router.go('taglist', {
|
||||
repository: image.split('/')[0],
|
||||
|
||||
@@ -15,47 +15,42 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<change>
|
||||
<dialog id="change-server-dialog" class="mdl-dialog">
|
||||
<h4 class="mdl-dialog__title">Change your Server ?</h4>
|
||||
<div class="mdl-dialog__content">
|
||||
<div class="mdl-textfield mdl-js-textfield">
|
||||
<select class="mdl-textfield__input mdl-textfield__select" name="server-list" id="server-list">
|
||||
<material-popup>
|
||||
<div class="material-popup-title">Change your Server ?</div>
|
||||
<div class="material-popup-content">
|
||||
<div class="select-padding">
|
||||
<select class="mdl-textfield__input mdl-textfield__select" name="server-list" ref="server-list">
|
||||
<option each="{ url in registryUI.getRegistryServer() }" value={url}>{url}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mdl-dialog__actions">
|
||||
<button type="button" class="mdl-button change" onClick="registryUI.changeTag.change();">Change</button>
|
||||
<button type="button" class="mdl-button close" onClick="registryUI.changeTag.close();">Cancel</button>
|
||||
<div class="material-popup-action">
|
||||
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="registryUI.changeTag.change();">Change</material-button>
|
||||
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="registryUI.changeTag.close();">Cancel</material-button>
|
||||
</div>
|
||||
</dialog>
|
||||
</material-popup>
|
||||
<script type="text/javascript">
|
||||
registryUI.changeTag = registryUI.changeTag || {};
|
||||
registryUI.changeTag.update = this.update;
|
||||
this.on('updated', function () {
|
||||
componentHandler.upgradeElements(this['change-server-dialog']);
|
||||
registryUI.changeTag.dialog = registryUI.changeTag.dialog || document.querySelector('#change-server-dialog');
|
||||
registryUI.changeTag.serverList = registryUI.changeTag.serverList || registryUI.changeTag.dialog.querySelector('#server-list');
|
||||
if (!registryUI.changeTag.dialog.showModal) {
|
||||
dialogPolyfill.registerDialog(registryUI.changeTag.dialog);
|
||||
}
|
||||
this['server-list'].onkeyup = function (e) {
|
||||
// if keyCode is Enter
|
||||
if (e.keyCode == 13) {
|
||||
registryUI.changeTag.change();
|
||||
}
|
||||
this.one('mount', function () {
|
||||
registryUI.changeTag.dialog = this.tags['material-popup'];
|
||||
registryUI.changeTag.dialog.getServerUrl = function () {
|
||||
return this.refs['server-list']
|
||||
? this.refs['server-list'].value
|
||||
: '';
|
||||
};
|
||||
registryUI.changeTag.dialog.on('updated', function () {
|
||||
if (this.refs['server-list']) {
|
||||
this.refs['server-list'].value = registryUI.url();
|
||||
}
|
||||
});
|
||||
});
|
||||
registryUI.changeTag.show = function () {
|
||||
registryUI.changeTag.update();
|
||||
registryUI.changeTag.serverList.value = registryUI.url();;
|
||||
registryUI.changeTag.dialog.showModal();
|
||||
registryUI.changeTag.dialog.open();
|
||||
};
|
||||
registryUI.changeTag.change = function () {
|
||||
if (registryUI.changeTag.serverList.value && registryUI.changeTag.serverList.value.length > 0) {
|
||||
registryUI.changeServer(registryUI.changeTag.serverList.value);
|
||||
if (registryUI.changeTag.dialog.getServerUrl().length > 0) {
|
||||
registryUI.changeServer(registryUI.changeTag.dialog.getServerUrl());
|
||||
}
|
||||
registryUI.changeTag.serverList.value = '';
|
||||
rg.router.go('home');
|
||||
registryUI.changeTag.dialog.close();
|
||||
};
|
||||
@@ -63,4 +58,4 @@
|
||||
registryUI.changeTag.dialog.close();
|
||||
};
|
||||
</script>
|
||||
</change>
|
||||
</change>
|
||||
@@ -15,23 +15,31 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<menu>
|
||||
<div id="card-menu" class="mdl-card__menu">
|
||||
<button id="registry-menu" name="registry-menu" class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
<ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="registry-menu">
|
||||
<li class="mdl-menu__item" onclick="registryUI.addTag.show();">Add URL</li>
|
||||
<li class="mdl-menu__item" onclick="registryUI.changeTag.show();">Change URL</li>
|
||||
<li class="mdl-menu__item" onclick="registryUI.removeTag.show();">Remove URL</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<material-button id="menu-control-button" onclick="registryUI.menuTag.toggle();" waves-center="true" rounded="true" waves-opacity="0.6" waves-duration="600">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</material-button>
|
||||
<material-dropdown id="menu-control-dropdown">
|
||||
<p onclick="registryUI.addTag.show(); registryUI.menuTag.close();">Add URL</p>
|
||||
<p onclick="registryUI.changeTag.show(); registryUI.menuTag.close();">Change URL</p>
|
||||
<p onclick="registryUI.removeTag.show(); registryUI.menuTag.close();">Remove URL</p>
|
||||
</material-dropdown>
|
||||
<div class="overlay" onclick="registryUI.menuTag.close();" show="{ registryUI.menuTag.isOpen && registryUI.menuTag.isOpen() }"></div>
|
||||
<script type="text/javascript">
|
||||
registryUI.menuTag = registryUI.menuTag || {};
|
||||
registryUI.menuTag.update = this.update;
|
||||
this.on('updated', function () {
|
||||
componentHandler.upgradeElements(this['card-menu']);
|
||||
this.one('mount', function(args) {
|
||||
var self = this;
|
||||
registryUI.menuTag.close = function() {
|
||||
self.tags['material-dropdown'].close();
|
||||
self.update();
|
||||
}
|
||||
registryUI.menuTag.isOpen = function() {
|
||||
return self.tags['material-dropdown'].opened;
|
||||
}
|
||||
registryUI.menuTag.toggle = function() {
|
||||
self.tags['material-dropdown'].opened ? self.tags['material-dropdown'].close() : self.tags['material-dropdown'].open();
|
||||
self.update();
|
||||
};
|
||||
});
|
||||
registryUI.menuTag.update();
|
||||
</script>
|
||||
</menu>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
-->
|
||||
<remove-image>
|
||||
<a href="#" onclick="registryUI.removeImage.remove('{ opts.name }', '{ opts.tag }')">
|
||||
<i class="material-icons mdl-list__item-icon">delete</i>
|
||||
<i class="material-icons">delete</i>
|
||||
</a>
|
||||
<script type="text/javascript">
|
||||
registryUI.removeImage = registryUI.removeImage || {}
|
||||
@@ -28,7 +28,7 @@
|
||||
registryUI.taglist.refresh();
|
||||
if (this.status == 200) {
|
||||
if (!this.hasHeader('Docker-Content-Digest')) {
|
||||
registryUI.taglist.createSnackbar('You need to add Access-Control-Expose-Headers: [\'Docker-Content-Digest\'] in your server configuration.');
|
||||
registryUI.errorSnackbar('You need to add Access-Control-Expose-Headers: [\'Docker-Content-Digest\'] in your server configuration.');
|
||||
return;
|
||||
}
|
||||
var digest = this.getResponseHeader('Docker-Content-Digest');
|
||||
@@ -36,23 +36,23 @@
|
||||
oReq.addEventListener('loadend', function () {
|
||||
if (this.status == 200 || this.status == 202) {
|
||||
registryUI.taglist.refresh();
|
||||
registryUI.taglist.createSnackbar('Deleting ' + name + ':' + tag + ' image. Run `registry garbage-collect config.yml` on your registry');
|
||||
registryUI.snackbar('Deleting ' + name + ':' + tag + ' image. Run `registry garbage-collect config.yml` on your registry');
|
||||
} else if (this.status == 404) {
|
||||
registryUI.taglist.createSnackbar('Digest not found');
|
||||
registryUI.errorSnackbar('Digest not found');
|
||||
} else {
|
||||
registryUI.taglist.createSnackbar(this.responseText);
|
||||
registryUI.snackbar(this.responseText);
|
||||
}
|
||||
});
|
||||
oReq.open('DELETE', registryUI.url() + '/v2/' + name + '/manifests/' + digest);
|
||||
oReq.setRequestHeader('Accept', 'application/vnd.docker.distribution.manifest.v2+json');
|
||||
oReq.addEventListener('error', function () {
|
||||
registryUI.taglist.createSnackbar('An error occurred when deleting image. Check if your server accept DELETE methods Access-Control-Allow-Methods: [\'DELETE\'].');
|
||||
registryUI.errorSnackbar('An error occurred when deleting image. Check if your server accept DELETE methods Access-Control-Allow-Methods: [\'DELETE\'].');
|
||||
});
|
||||
oReq.send();
|
||||
} else if (this.status == 404) {
|
||||
registryUI.taglist.createSnackbar('Manifest for' + name + ':' + tag + 'not found');
|
||||
registryUI.errorSnackbar('Manifest for ' + name + ':' + tag + ' not found');
|
||||
} else {
|
||||
registryUI.taglist.createSnackbar(this.responseText);
|
||||
registryUI.snackbar(this.responseText);
|
||||
}
|
||||
});
|
||||
oReq.open('HEAD', registryUI.url() + '/v2/' + name + '/manifests/' + tag);
|
||||
|
||||
@@ -15,33 +15,32 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<remove>
|
||||
<dialog id="remove-server-dialog" class="mdl-dialog">
|
||||
<h4 class="mdl-dialog__title">Remove your Registry Server ?</h4>
|
||||
<div class="mdl-dialog__content">
|
||||
<div class="mdl-textfield mdl-js-textfield">
|
||||
<ul class="mdl-list">
|
||||
<li class="mdl-list__item" each="{ url in registryUI.getRegistryServer() }">
|
||||
<span class="mdl-list__item-primary-content">
|
||||
<a href="#" onClick="registryUI.removeTag.removeUrl('{url}');">
|
||||
<i class="material-icons mdl-list__item-icon">delete</i>
|
||||
</a>
|
||||
<span class="url">{url}</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mdl-dialog__actions">
|
||||
<button type="button" class="mdl-button close" onClick="registryUI.removeTag.close();">Close</button>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<material-popup>
|
||||
<div class="material-popup-title">Remove your Registry Server ?</div>
|
||||
<div class="material-popup-content">
|
||||
<ul class="list">
|
||||
<li each="{ url in registryUI.getRegistryServer() }">
|
||||
<span>
|
||||
<a href="#" onClick="registryUI.removeTag.removeUrl('{url}');">
|
||||
<i class="material-icons">delete</i>
|
||||
</a>
|
||||
<span class="url">{ url }</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="material-popup-action">
|
||||
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="registryUI.removeTag.close();">Close</material-button>
|
||||
</div>
|
||||
</material-popup>
|
||||
<script type="text/javascript">
|
||||
registryUI.removeTag = registryUI.removeTag || {}
|
||||
registryUI.removeTag.update = this.update;
|
||||
|
||||
registryUI.removeTag.removeUrl = function (url) {
|
||||
registryUI.removeServer(url);
|
||||
registryUI.removeTag.update();
|
||||
registryUI.removeTag.close();
|
||||
};
|
||||
|
||||
registryUI.removeTag.close = function () {
|
||||
@@ -50,15 +49,11 @@
|
||||
};
|
||||
|
||||
registryUI.removeTag.show = function () {
|
||||
registryUI.removeTag.update();
|
||||
registryUI.removeTag.dialog.showModal();
|
||||
registryUI.removeTag.dialog.open();
|
||||
};
|
||||
|
||||
this.on('updated', function () {
|
||||
registryUI.removeTag.dialog = this['remove-server-dialog'];
|
||||
if (!registryUI.removeTag.dialog.showModal) {
|
||||
dialogPolyfill.registerDialog(registryUI.removeTag.dialog);
|
||||
}
|
||||
this.one('mount', function () {
|
||||
registryUI.removeTag.dialog = this.tags['material-popup'];
|
||||
});
|
||||
</script>
|
||||
</remove>
|
||||
|
||||
@@ -16,40 +16,35 @@
|
||||
-->
|
||||
<taglist>
|
||||
<!-- Begin of tag -->
|
||||
<div id="taglist-tag" class="taglist">
|
||||
<div class="section-centerd mdl-card mdl-shadow--2dp mdl-cell--6-col">
|
||||
<div class="mdl-card__title">
|
||||
<a href="#" onclick="registryUI.taglist.back();">
|
||||
<i class="material-icons mdl-list__item-icon">arrow_back</i>
|
||||
</a>
|
||||
<h2 class="mdl-card__title-text">Tags of { registryUI.url() + '/' + registryUI.taglist.name }</h2>
|
||||
</div>
|
||||
<div id="taglist-spinner" hide="{ registryUI.taglist.loadend }" class="mdl-spinner mdl-js-spinner section-centerd is-active"></div>
|
||||
<table class="mdl-data-table mdl-js-data-table full-table" show="{ registryUI.taglist.loadend }" style="border: none;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="mdl-data-table__cell--non-numeric">Repository</th>
|
||||
<th class="{ registryUI.taglist.asc ? 'mdl-data-table__header--sorted-ascending' : 'mdl-data-table__header--sorted-descending' }" onclick="registryUI.taglist.reverse();">Tag</th>
|
||||
<th show="{ registryUI.isImageRemoveActivated }" ></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr each="{ item in registryUI.taglist.tags }">
|
||||
<td class="mdl-data-table__cell--non-numeric">{ registryUI.taglist.name }</td>
|
||||
<td>{ item }</td>
|
||||
<td show="{ registryUI.isImageRemoveActivated }" >
|
||||
<remove-image name={ registryUI.taglist.name } tag={ item } />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<material-card ref="taglist-tag" class="taglist">
|
||||
<div class="material-card-title-action">
|
||||
<a href="#" onclick="registryUI.taglist.back();">
|
||||
<i class="material-icons">arrow_back</i>
|
||||
</a>
|
||||
<h2>Tags of { registryUI.url() + '/' + registryUI.taglist.name }</h2>
|
||||
</div>
|
||||
<div id="error-snackbar" aria-live="assertive" aria-atomic="true" aria-relevant="text" class="mdl-js-snackbar mdl-snackbar">
|
||||
<div class="mdl-snackbar__text"></div>
|
||||
<button class="mdl-snackbar__action" type="button"></button>
|
||||
<div hide="{ registryUI.taglist.loadend }" class="spinner-wrapper">
|
||||
<material-spinner></material-spinner>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table show="{ registryUI.taglist.loadend }" style="border: none;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="material-card-th-left">Repository</th>
|
||||
<th class="{ registryUI.taglist.asc ? 'material-card-th-sorted-ascending' : 'material-card-th-sorted-descending' }" onclick="registryUI.taglist.reverse();">Tag</th>
|
||||
<th show="{ registryUI.isImageRemoveActivated }"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr each="{ item in registryUI.taglist.tags }">
|
||||
<td class="material-card-th-left">{ registryUI.taglist.name }</td>
|
||||
<td>{ item }</td>
|
||||
<td show="{ registryUI.isImageRemoveActivated }">
|
||||
<remove-image name={ registryUI.taglist.name } tag={ item }/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</material-card>
|
||||
<script>
|
||||
registryUI.taglist.instance = this;
|
||||
registryUI.taglist.display = function () {
|
||||
@@ -60,31 +55,20 @@
|
||||
var oReq = new Http();
|
||||
registryUI.taglist.name = name;
|
||||
registryUI.taglist.instance.update();
|
||||
registryUI.taglist.createSnackbar = function (msg) {
|
||||
var snackbar = document.querySelector('#error-snackbar');
|
||||
registryUI.taglist.error = msg;
|
||||
var data = {
|
||||
message: registryUI.taglist.error,
|
||||
timeout: 100000,
|
||||
actionHandler: function () {
|
||||
snackbar.classList.remove('mdl-snackbar--active');
|
||||
},
|
||||
actionText: 'Undo'
|
||||
};
|
||||
snackbar.MaterialSnackbar.showSnackbar(data);
|
||||
};
|
||||
oReq.addEventListener('load', function () {
|
||||
registryUI.taglist.tags = [];
|
||||
if (this.status == 200) {
|
||||
registryUI.taglist.tags = JSON.parse(this.responseText).tags || [];
|
||||
registryUI.taglist.tags.sort();
|
||||
} else if (this.status == 404) {
|
||||
registryUI.taglist.createSnackbar('Server not found');
|
||||
registryUI.snackbar('Server not found', true);
|
||||
} else {
|
||||
registryUI.taglist.createSnackbar(this.responseText);
|
||||
registryUI.snackbar(this.responseText, true);
|
||||
}
|
||||
});
|
||||
oReq.addEventListener('error', function () {
|
||||
registryUI.taglist.createSnackbar('An error occured');
|
||||
registryUI.snackbar('An error occured', true);
|
||||
registryUI.taglist.tags = [];
|
||||
});
|
||||
oReq.addEventListener('loadend', function () {
|
||||
registryUI.taglist.loadend = true;
|
||||
@@ -97,9 +81,6 @@
|
||||
};
|
||||
registryUI.taglist.display();
|
||||
registryUI.taglist.instance.update();
|
||||
this.on('updated', function () {
|
||||
componentHandler.upgradeElements(this['taglist-tag']);
|
||||
});
|
||||
|
||||
registryUI.taglist.reverse = function () {
|
||||
if (registryUI.taglist.asc) {
|
||||
|
||||
Reference in New Issue
Block a user