mirror of
https://github.com/Joxit/docker-registry-ui.git
synced 2025-04-29 16:39:54 +03:00
feat(riot-v5): upgrade image content-digest, date, size and tag from tag-list
This commit is contained in:
parent
3d4267f5ab
commit
9c303d32c7
8 changed files with 121 additions and 85 deletions
50
src/components/tag-list/image-content-digest.riot
Normal file
50
src/components/tag-list/image-content-digest.riot
Normal file
|
@ -0,0 +1,50 @@
|
|||
<!--
|
||||
Copyright (C) 2016-2021 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/>.
|
||||
-->
|
||||
<image-content-digest>
|
||||
<div title="{ state.title }">{ state.displayId }</div>
|
||||
<script>
|
||||
export default {
|
||||
onMounted(props) {
|
||||
this.chars = -1;
|
||||
props.image.one('content-digest', (digest) => {
|
||||
this.digest = digest;
|
||||
props.image.on('content-digest-chars', this.onResize);
|
||||
props.image.trigger('get-content-digest-chars');
|
||||
});
|
||||
props.image.trigger('get-content-digest');
|
||||
},
|
||||
onResize(chars) {
|
||||
if (chars === this.chars) {
|
||||
return;
|
||||
}
|
||||
let displayId = this.digest;
|
||||
let title = '';
|
||||
this.chars = chars;
|
||||
if (chars >= 70) {
|
||||
displayId = this.digest;
|
||||
} else if (chars <= 0) {
|
||||
displayId = '';
|
||||
title = this.digest;
|
||||
} else {
|
||||
displayId = this.digest.slice(0, chars) + '...';
|
||||
title = this.digest;
|
||||
}
|
||||
this.update({title, displayId});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</image-content-digest>
|
|
@ -15,16 +15,25 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<image-date>
|
||||
<div title="Creation date { this.localDate }">{ registryUI.dateFormat(this.date) } ago</div>
|
||||
<script type="text/javascript">
|
||||
const self = this;
|
||||
|
||||
opts.image.on('creation-date', function(date) {
|
||||
self.date = date;
|
||||
self.localDate = date.toLocaleString()
|
||||
self.update();
|
||||
<div title="Creation date { state.localDate }">{ dateFormat(state.date) } ago</div>
|
||||
<script>
|
||||
import {
|
||||
dateFormat,
|
||||
} from '../../scripts/utils';
|
||||
export default {
|
||||
state: {
|
||||
localDate: 'unknown'
|
||||
},
|
||||
onMounted(props) {
|
||||
props.image.on('creation-date', (date) => {
|
||||
this.update({
|
||||
date: date,
|
||||
localDate: date.toLocaleString()
|
||||
});
|
||||
|
||||
opts.image.trigger('get-date');
|
||||
});
|
||||
props.image.trigger('get-date');
|
||||
},
|
||||
dateFormat
|
||||
}
|
||||
</script>
|
||||
</image-date>
|
|
@ -15,13 +15,21 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<image-size>
|
||||
<div title="Compressed size of your image.">{ registryUI.bytesToSize(this.size) }</div>
|
||||
<script type="text/javascript">
|
||||
const self = this;
|
||||
opts.image.on('size', function(size) {
|
||||
self.size = size;
|
||||
self.update();
|
||||
<div title="Compressed size of your image.">{ bytesToSize(state.size) }</div>
|
||||
<script>
|
||||
import {
|
||||
bytesToSize,
|
||||
} from '../../scripts/utils';
|
||||
export default {
|
||||
onMounted(props) {
|
||||
props.image.on('size', (size) => {
|
||||
this.update({
|
||||
size
|
||||
});
|
||||
opts.image.trigger('get-size');
|
||||
});
|
||||
props.image.trigger('get-size');
|
||||
},
|
||||
bytesToSize
|
||||
}
|
||||
</script>
|
||||
</image-size>
|
|
@ -15,13 +15,17 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<image-tag>
|
||||
<div title="{ this.sha256 }">{ opts.image.tag }</div>
|
||||
<script type="text/javascript">
|
||||
const self = this;
|
||||
opts.image.on('sha256', function(sha256) {
|
||||
self.sha256 = sha256.substring(0, 19);
|
||||
self.update();
|
||||
<div title="{ state.sha256 }">{ props.image.tag }</div>
|
||||
<script>
|
||||
export default {
|
||||
onMounted(props) {
|
||||
props.image.on('sha256', (sha256) => {
|
||||
this.update({
|
||||
sha256: sha256.substring(0, 19)
|
||||
});
|
||||
opts.image.trigger('get-sha256');
|
||||
});
|
||||
props.image.trigger('get-sha256');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</image-tag>
|
|
@ -36,7 +36,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<pagination pages="{ getPageLabels(state.page, getNumPages(state.tags)) }" onPageUpdate="{onPageUpdate}"></pagination>
|
||||
|
||||
<tag-table if="{ state.loadend }" tags="{state.tags}" asc="{state.asc}"
|
||||
<tag-table if="{ state.loadend }" tags="{state.tags}" asc="{state.asc}" page="{ state.page }"
|
||||
show-content-digest="{props.showContentDigest}" is-image-remove-activated="{props.isImageRemoveActivated}"
|
||||
onReverseOrder="{ onReverseOrder }"></tag-table>
|
||||
|
||||
|
@ -72,6 +72,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
},
|
||||
onMounted(props, state) {
|
||||
this.display(props, state)
|
||||
window.addEventListener('resize', this.onResize);
|
||||
// this may be run before the final document size is available, so schedule
|
||||
// a correction once everything is set up.
|
||||
window.requestAnimationFrame(this.onResize);
|
||||
},
|
||||
display(props, state) {
|
||||
state.tags = [];
|
||||
|
@ -82,7 +86,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
if (this.status == 200) {
|
||||
const tags = JSON.parse(this.responseText).tags || [];
|
||||
state.tags = tags.map(function (tag) {
|
||||
return new DockerImage(props.image, tag);
|
||||
return new DockerImage(props.image, tag, null, props.registryUrl);
|
||||
}).sort(compare);
|
||||
window.requestAnimationFrame(self.onResize);
|
||||
self.update({
|
||||
|
@ -130,6 +134,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
chars = 15 + 56 * ((innerWidth - 1024) / 416);
|
||||
}
|
||||
if (max > 20) chars -= (max - 20);
|
||||
chars = Math.floor(chars)
|
||||
this.state.tags.map(function (image) {
|
||||
image.trigger('content-digest-chars', chars);
|
||||
});
|
||||
|
|
|
@ -15,7 +15,7 @@ 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/>.
|
||||
-->
|
||||
<tag-table>
|
||||
<material-card class="taglist" multi-delete="{ this.multiDelete }" tags="{ getPage(props.tags.tags, this.page) }">
|
||||
<material-card class="taglist">
|
||||
<table style="border: none;">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -39,7 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr each="{ image in props.tags }">
|
||||
<tr each="{ image in getPage(props.tags, props.page) }">
|
||||
<td class="creation-date">
|
||||
<image-date image="{ image }" />
|
||||
</td>
|
||||
|
@ -70,10 +70,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
} from '../../scripts/http';
|
||||
import {
|
||||
getPage,
|
||||
} from '../../scripts/utils'
|
||||
} from '../../scripts/utils';
|
||||
import ImageDate from './image-date.riot';
|
||||
import ImageSize from './image-size.riot';
|
||||
import ImageTag from './image-tag.riot';
|
||||
import ImageContentDigest from './image-content-digest.riot';
|
||||
export default {
|
||||
components: {
|
||||
|
||||
ImageDate,
|
||||
ImageSize,
|
||||
ImageTag,
|
||||
ImageContentDigest,
|
||||
},
|
||||
onBeforeMount(props) {
|
||||
this.state = {
|
||||
|
|
|
@ -30,10 +30,11 @@ export function compare(e1, e2) {
|
|||
}
|
||||
|
||||
export class DockerImage {
|
||||
constructor(name, tag, list) {
|
||||
constructor(name, tag, list, registryUrl) {
|
||||
this.name = name;
|
||||
this.tag = tag;
|
||||
this.list = list;
|
||||
this.registryUrl = registryUrl;
|
||||
this.chars = 0;
|
||||
observable(this);
|
||||
this.on('get-size', function () {
|
||||
|
@ -107,7 +108,7 @@ export class DockerImage {
|
|||
// registryUI.snackbar(this.responseText);
|
||||
}
|
||||
});
|
||||
oReq.open('GET', registryUI.url() + '/v2/' + self.name + '/manifests/' + self.tag);
|
||||
oReq.open('GET', this.registryUrl + '/v2/' + self.name + '/manifests/' + self.tag);
|
||||
oReq.setRequestHeader(
|
||||
'Accept',
|
||||
'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json' +
|
||||
|
@ -115,7 +116,7 @@ export class DockerImage {
|
|||
);
|
||||
oReq.send();
|
||||
}
|
||||
getBlobs() {
|
||||
getBlobs(blob) {
|
||||
const oReq = new Http();
|
||||
const self = this;
|
||||
oReq.addEventListener('loadend', function () {
|
||||
|
@ -140,7 +141,7 @@ export class DockerImage {
|
|||
registryUI.snackbar(this.responseText);
|
||||
}
|
||||
});
|
||||
oReq.open('GET', registryUI.url() + '/v2/' + self.name + '/blobs/' + blob);
|
||||
oReq.open('GET', this.registryUrl + '/v2/' + self.name + '/blobs/' + blob);
|
||||
oReq.setRequestHeader(
|
||||
'Accept',
|
||||
'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json'
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
<!--
|
||||
Copyright (C) 2019 Jakob Ackermann
|
||||
|
||||
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/>.
|
||||
-->
|
||||
<image-content-digest>
|
||||
<div title="{ this.title }">{ this.display_id }</div>
|
||||
<script type="text/javascript">
|
||||
const self = this;
|
||||
self.chars = -1;
|
||||
|
||||
self.onResize = function(chars) {
|
||||
if (chars === self.chars) {
|
||||
return;
|
||||
}
|
||||
self.chars = chars;
|
||||
if (chars >= 70) {
|
||||
self.display_id = self.digest;
|
||||
self.title = '';
|
||||
} else if (chars <= 0) {
|
||||
self.display_id = '';
|
||||
self.title = self.digest;
|
||||
} else {
|
||||
self.display_id = self.digest.slice(0, chars) + '...';
|
||||
self.title = self.digest;
|
||||
}
|
||||
self.update();
|
||||
};
|
||||
|
||||
opts.image.one('content-digest', function(digest) {
|
||||
self.digest = digest;
|
||||
opts.image.on('content-digest-chars', self.onResize);
|
||||
opts.image.trigger('get-content-digest-chars');
|
||||
});
|
||||
opts.image.trigger('get-content-digest');
|
||||
</script>
|
||||
</image-content-digest>
|
Loading…
Add table
Add a link
Reference in a new issue