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/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<image-date>
|
<image-date>
|
||||||
<div title="Creation date { this.localDate }">{ registryUI.dateFormat(this.date) } ago</div>
|
<div title="Creation date { state.localDate }">{ dateFormat(state.date) } ago</div>
|
||||||
<script type="text/javascript">
|
<script>
|
||||||
const self = this;
|
import {
|
||||||
|
dateFormat,
|
||||||
opts.image.on('creation-date', function(date) {
|
} from '../../scripts/utils';
|
||||||
self.date = date;
|
export default {
|
||||||
self.localDate = date.toLocaleString()
|
state: {
|
||||||
self.update();
|
localDate: 'unknown'
|
||||||
});
|
},
|
||||||
|
onMounted(props) {
|
||||||
opts.image.trigger('get-date');
|
props.image.on('creation-date', (date) => {
|
||||||
|
this.update({
|
||||||
|
date: date,
|
||||||
|
localDate: date.toLocaleString()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
props.image.trigger('get-date');
|
||||||
|
},
|
||||||
|
dateFormat
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</image-date>
|
</image-date>
|
|
@ -15,13 +15,21 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<image-size>
|
<image-size>
|
||||||
<div title="Compressed size of your image.">{ registryUI.bytesToSize(this.size) }</div>
|
<div title="Compressed size of your image.">{ bytesToSize(state.size) }</div>
|
||||||
<script type="text/javascript">
|
<script>
|
||||||
const self = this;
|
import {
|
||||||
opts.image.on('size', function(size) {
|
bytesToSize,
|
||||||
self.size = size;
|
} from '../../scripts/utils';
|
||||||
self.update();
|
export default {
|
||||||
});
|
onMounted(props) {
|
||||||
opts.image.trigger('get-size');
|
props.image.on('size', (size) => {
|
||||||
|
this.update({
|
||||||
|
size
|
||||||
|
});
|
||||||
|
});
|
||||||
|
props.image.trigger('get-size');
|
||||||
|
},
|
||||||
|
bytesToSize
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</image-size>
|
</image-size>
|
|
@ -15,13 +15,17 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<image-tag>
|
<image-tag>
|
||||||
<div title="{ this.sha256 }">{ opts.image.tag }</div>
|
<div title="{ state.sha256 }">{ props.image.tag }</div>
|
||||||
<script type="text/javascript">
|
<script>
|
||||||
const self = this;
|
export default {
|
||||||
opts.image.on('sha256', function(sha256) {
|
onMounted(props) {
|
||||||
self.sha256 = sha256.substring(0, 19);
|
props.image.on('sha256', (sha256) => {
|
||||||
self.update();
|
this.update({
|
||||||
});
|
sha256: sha256.substring(0, 19)
|
||||||
opts.image.trigger('get-sha256');
|
});
|
||||||
|
});
|
||||||
|
props.image.trigger('get-sha256');
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</image-tag>
|
</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>
|
<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}"
|
show-content-digest="{props.showContentDigest}" is-image-remove-activated="{props.isImageRemoveActivated}"
|
||||||
onReverseOrder="{ onReverseOrder }"></tag-table>
|
onReverseOrder="{ onReverseOrder }"></tag-table>
|
||||||
|
|
||||||
|
@ -72,6 +72,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
},
|
},
|
||||||
onMounted(props, state) {
|
onMounted(props, state) {
|
||||||
this.display(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) {
|
display(props, state) {
|
||||||
state.tags = [];
|
state.tags = [];
|
||||||
|
@ -82,7 +86,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
if (this.status == 200) {
|
if (this.status == 200) {
|
||||||
const tags = JSON.parse(this.responseText).tags || [];
|
const tags = JSON.parse(this.responseText).tags || [];
|
||||||
state.tags = tags.map(function (tag) {
|
state.tags = tags.map(function (tag) {
|
||||||
return new DockerImage(props.image, tag);
|
return new DockerImage(props.image, tag, null, props.registryUrl);
|
||||||
}).sort(compare);
|
}).sort(compare);
|
||||||
window.requestAnimationFrame(self.onResize);
|
window.requestAnimationFrame(self.onResize);
|
||||||
self.update({
|
self.update({
|
||||||
|
@ -130,6 +134,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
chars = 15 + 56 * ((innerWidth - 1024) / 416);
|
chars = 15 + 56 * ((innerWidth - 1024) / 416);
|
||||||
}
|
}
|
||||||
if (max > 20) chars -= (max - 20);
|
if (max > 20) chars -= (max - 20);
|
||||||
|
chars = Math.floor(chars)
|
||||||
this.state.tags.map(function (image) {
|
this.state.tags.map(function (image) {
|
||||||
image.trigger('content-digest-chars', chars);
|
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/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<tag-table>
|
<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;">
|
<table style="border: none;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -39,7 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr each="{ image in props.tags }">
|
<tr each="{ image in getPage(props.tags, props.page) }">
|
||||||
<td class="creation-date">
|
<td class="creation-date">
|
||||||
<image-date image="{ image }" />
|
<image-date image="{ image }" />
|
||||||
</td>
|
</td>
|
||||||
|
@ -70,10 +70,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
} from '../../scripts/http';
|
} from '../../scripts/http';
|
||||||
import {
|
import {
|
||||||
getPage,
|
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 {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
ImageDate,
|
||||||
|
ImageSize,
|
||||||
|
ImageTag,
|
||||||
|
ImageContentDigest,
|
||||||
},
|
},
|
||||||
onBeforeMount(props) {
|
onBeforeMount(props) {
|
||||||
this.state = {
|
this.state = {
|
||||||
|
|
|
@ -30,10 +30,11 @@ export function compare(e1, e2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DockerImage {
|
export class DockerImage {
|
||||||
constructor(name, tag, list) {
|
constructor(name, tag, list, registryUrl) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.tag = tag;
|
this.tag = tag;
|
||||||
this.list = list;
|
this.list = list;
|
||||||
|
this.registryUrl = registryUrl;
|
||||||
this.chars = 0;
|
this.chars = 0;
|
||||||
observable(this);
|
observable(this);
|
||||||
this.on('get-size', function () {
|
this.on('get-size', function () {
|
||||||
|
@ -107,7 +108,7 @@ export class DockerImage {
|
||||||
// registryUI.snackbar(this.responseText);
|
// 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(
|
oReq.setRequestHeader(
|
||||||
'Accept',
|
'Accept',
|
||||||
'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json' +
|
'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json' +
|
||||||
|
@ -115,7 +116,7 @@ export class DockerImage {
|
||||||
);
|
);
|
||||||
oReq.send();
|
oReq.send();
|
||||||
}
|
}
|
||||||
getBlobs() {
|
getBlobs(blob) {
|
||||||
const oReq = new Http();
|
const oReq = new Http();
|
||||||
const self = this;
|
const self = this;
|
||||||
oReq.addEventListener('loadend', function () {
|
oReq.addEventListener('loadend', function () {
|
||||||
|
@ -140,7 +141,7 @@ export class DockerImage {
|
||||||
registryUI.snackbar(this.responseText);
|
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(
|
oReq.setRequestHeader(
|
||||||
'Accept',
|
'Accept',
|
||||||
'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json'
|
'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