mirror of
https://github.com/Joxit/docker-registry-ui.git
synced 2025-04-29 16:39:54 +03:00
Merge pull request #23 from Joxit/riot-mui
Move from material-design lite to riot-mui
This commit is contained in:
commit
b9effee691
15 changed files with 480 additions and 258 deletions
|
@ -7,7 +7,7 @@ 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.
|
||||
|
||||
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 use [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/)
|
||||
|
||||
|
@ -20,6 +20,7 @@ This web user interface use [Riot](https://github.com/Riot/riot) the react-like
|
|||
- Sort the tag list
|
||||
- One interface for many registry
|
||||
- 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
|
||||
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
||||
|
|
|
@ -9,13 +9,11 @@
|
|||
"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": "^3.0.0",
|
||||
"dialog-polyfill": "^0.4",
|
||||
"gulp": "^3.9",
|
||||
"gulp-clean-css": "^3.7.0",
|
||||
"gulp-concat": "^2.6.0",
|
||||
|
@ -26,9 +24,9 @@
|
|||
"gulp-riot": "^1.1.1",
|
||||
"gulp-uglify": "^2.1.2",
|
||||
"gulp-useref": "^3.0.0",
|
||||
"material-design-lite": "^1.1",
|
||||
"pump": "^1.0.2",
|
||||
"riot": "^3.7.0",
|
||||
"riot-mui": "^0.1.1",
|
||||
"riotgear-router": "^1.3.1",
|
||||
"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"><a href="https://joxit.github.io/docker-registry-ui/">Docker Registry UI</a></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>
|
||||
|
|
|
@ -18,7 +18,7 @@ var registryUI = {}
|
|||
registryUI.URL_QUERY_PARAM_REGEX = /[&?]url=/;
|
||||
registryUI.URL_PARAM_REGEX = /^url=/;
|
||||
|
||||
registryUI.url = function() {
|
||||
registryUI.url = function(byPassQueryParam) {
|
||||
if (!registryUI._url) {
|
||||
var url = registryUI.getUrlQueryParam();
|
||||
if (url) {
|
||||
|
@ -78,10 +78,14 @@ 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=' + registryUI.encodeURI(url) + window.location.hash);
|
||||
history.pushState(null, '', (url ? '?url=' + registryUI.encodeURI(url) : '?') + window.location.hash);
|
||||
registryUI._url = url;
|
||||
}
|
||||
|
||||
|
|
283
src/style.css
283
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;
|
||||
|
@ -50,8 +41,270 @@ html > body {
|
|||
word-break: break-all;
|
||||
}
|
||||
|
||||
.mdl-logo a {
|
||||
.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 ref="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" ref="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 () {
|
||||
registryUI.addTag.dialog = this.refs['add-server-dialog'];
|
||||
registryUI.addTag.addServer = this.refs['add-server-input'];
|
||||
componentHandler.upgradeElements(registryUI.addTag.dialog);
|
||||
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.refs['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 && 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>
|
|
@ -16,57 +16,42 @@
|
|||
-->
|
||||
<catalog>
|
||||
<!-- Begin of tag -->
|
||||
<div ref="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 ref="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 ref="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 = registryUI.catalog.instance.refs['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.refs['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 ref="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">
|
||||
<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.refs['change-server-dialog']);
|
||||
registryUI.changeTag.dialog = registryUI.changeTag.dialog || this.refs['change-server-dialog'];
|
||||
registryUI.changeTag.serverList = registryUI.changeTag.serverList || this.refs['server-list'];
|
||||
if (!registryUI.changeTag.dialog.showModal) {
|
||||
dialogPolyfill.registerDialog(registryUI.changeTag.dialog);
|
||||
}
|
||||
this.refs['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();
|
||||
};
|
||||
|
|
|
@ -15,23 +15,31 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<menu>
|
||||
<div ref="card-menu" id="card-menu" class="mdl-card__menu">
|
||||
<button ref="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.refs['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 ref="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.refs['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 ref="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 ref="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 ref="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 = registryUI.taglist.instance['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.refs['taglist-tag']);
|
||||
});
|
||||
|
||||
registryUI.taglist.reverse = function () {
|
||||
if (registryUI.taglist.asc) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue