Merge pull request #66 from Joxit/feat/56-image-aggregation

Image aggregation
This commit is contained in:
Jones Magloire 2019-01-08 00:25:30 +01:00 committed by GitHub
commit e6d9f11b83
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 124 additions and 11 deletions

View file

@ -39,6 +39,7 @@
<!-- endbuild -->
<!-- build:js scripts/docker-registry-ui.js -->
<script src="tags/catalog.tag" type="riot/tag"></script>
<script src="tags/catalog-element.tag" type="riot/tag"></script>
<script src="tags/tag-history-button.tag" type="riot/tag"></script>
<script src="tags/tag-history.tag" type="riot/tag"></script>
<script src="tags/tag-history-element.tag" type="riot/tag"></script>

View file

@ -99,11 +99,12 @@ h2 {
list-style: none;
}
.list.highlight > li:hover {
.list.highlight:hover {
background-color: #eee;
cursor: pointer;
}
.list > span,
.list > li {
box-sizing: border-box;
line-height: 1;
@ -112,6 +113,7 @@ h2 {
overflow: hidden;
}
.list > span i.material-icons,
.list > li i.material-icons {
margin-right: 32px;
height: 24px;
@ -121,6 +123,28 @@ h2 {
color: #757575;
}
.list > span .right i.material-icons.animated {
transition: all 350ms cubic-bezier(.4,0,.2,1);
margin-right: 10px;
}
.list > span .right {
position: absolute;
align-self: end;
display: flex;
align-items: center;
right: 0;
}
.list > span i.material-icons.animated.expanded {
transform: rotate(180deg);
}
.list > span .item-count {
font-size: 0.75em;
}
.list > span,
.list > li > span {
height: 100%;
text-decoration: none;
@ -133,6 +157,11 @@ h2 {
align-items: center;
}
material-card.list {
margin-top: 10px;
margin-bottom: 10px;
}
.material-card-title-action {
-webkit-align-items: center;
-ms-flex-align: center;
@ -306,6 +335,7 @@ material-popup .popup {
footer {
width: 100%;
position: fixed;
z-index: 75;
bottom: 0;
}
@ -345,6 +375,7 @@ select {
text-align: center;
}
catalog material-card,
tag-history material-card {
min-height: auto;
}
@ -398,3 +429,20 @@ material-button:hover material-waves {
material-card material-button {
background-color: inherit;
}
catalog-element material-card {
z-index: 2;
position: relative;
}
catalog-element catalog-element material-card {
transition: all 350ms cubic-bezier(.4,0,.2,1);
z-index: 1;
position: relative;
}
catalog-element catalog-element.showing material-card,
catalog-element catalog-element.hide material-card {
margin-top: -50px;
opacity: 0;
}

View file

@ -0,0 +1,59 @@
<!--
Copyright (C) 2016-2018 Jones Magloire @Joxit
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
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/>.
-->
<catalog-element>
<!-- Begin of tag -->
<material-card class="list highlight" item="{item}" expanded="{expanded}">
<material-waves onmousedown="{launch}" center="true" color="#ddd" />
<span>
<i class="material-icons">send</i>
{ typeof opts.item === "string" ? opts.item : opts.item.repo }
<div hide="{typeof opts.item === "string"}" class="item-count right">
{ opts.item.images && opts.item.images.length } images
<i class="material-icons animated {expanded: opts.expanded}">expand_more</i>
</div>
</span>
</material-card>
<catalog-element hide="{typeof opts.item === "string"}" class="animated {hide: !expanded, expanding: expanding}" each="{item in item.images}" />
<script>
this.on('mount', function() {
const self = this;
const card = this.tags['material-card'];
if (!card) {
return;
}
// Launch waves
card.launch = function(e) {
card.tags['material-waves'].trigger('launch',e);
}
if (this.item.images && this.item.images.length === 1) {
this.item = this.item.images[0];
}
card.root.onclick = function(e) {
if (!self.item.repo) {
registryUI.taglist.go(self.item);
} else {
self.expanded = !self.expanded;
self.update({expanded: self.expanded, expanding: true});
setTimeout(function() {
self.update({expanded: self.expanded, expanding: false});
}, 50)
}
}
})
</script>
<!-- End of tag -->
</catalog-element>

View file

@ -20,22 +20,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<div class="material-card-title-action">
<h2>
Repositories of { registryUI.name() }
<div class="item-count">{ registryUI.catalog.repositories.length } images</div>
<div class="item-count">{ registryUI.catalog.length } images</div>
</h2>
</div>
<div hide="{ registryUI.catalog.loadend }" class="spinner-wrapper">
<material-spinner></material-spinner>
</div>
<ul class="list highlight" show="{ registryUI.catalog.loadend }">
<li each="{ item in registryUI.catalog.repositories }" onclick="registryUI.taglist.go('{item}');">
<span>
<i class="material-icons">send</i>
{ item }
</span>
</li>
</ul>
</material-card>
<catalog-element each="{ item in registryUI.catalog.repositories }" />
<script>
registryUI.catalog.instance = this;
registryUI.catalog.display = function() {
@ -46,6 +38,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
if (this.status == 200) {
registryUI.catalog.repositories = JSON.parse(this.responseText).repositories || [];
registryUI.catalog.repositories.sort();
registryUI.catalog.length = registryUI.catalog.repositories.length; registryUI.catalog.repositories = registryUI.catalog.repositories.reduce(function(acc, e) {
const slash = e.indexOf('/');
if (slash > 0) {
const repoName = e.substring(0, slash) + '/';
if (acc.length == 0 || acc[acc.length - 1].repo != repoName) {
acc.push({repo: repoName, images: []});
}
acc[acc.length - 1].images.push(e);
return acc;
}
acc.push(e);
return acc;
}, []);
} else if (this.status == 404) {
registryUI.snackbar('Server not found', true);
} else {