docker-registry-ui/src/components/catalog/catalog-element.riot

121 lines
4.3 KiB
Plaintext

<!--
Copyright (C) 2016-2023 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 -->
<div
class="content"
if="{!props.filterResults || state.nImages > 0 || matchSearch(props.filterResults, state.image)}"
>
<material-card class="list highlight" expanded="{state.expanded}" onclick="{ onClick }">
<a if="{ state.image }" href="{ router.taglist(state.image) }">
<material-waves center="true" color="#ddd"></material-waves>
</a>
<material-waves if="{ state.images }" center="true" color="#ddd"></material-waves>
<span>
<i class="material-icons">send</i>
{ state.image || state.repo }
<div if="{state.images}" class="item-count right">
{ state.nImages } images
<i class="material-icons animated {state.expanded ? 'expanded' : ''}">expand_more</i>
</div>
<div if="{props.showCatalogNbTags && state.image}" class="item-count right">
{ state.nbTags } tags
<i class="material-icons animated"></i>
</div>
</span>
</material-card>
<catalog-element
if="{ state.images }"
filter-results="{ props.filterResults }"
registry-url="{ props.registryUrl }"
on-notify="{ props.onnNotify }"
on-authentication="{ props.onAuthentication }"
show-catalog-nb-tags="{ props.showCatalogNbTags }"
class="animated {!state.expanded && !props.filterResults ? 'hide' : ''} {state.expanding ? 'expanding' : ''}"
each="{item in state.images}"
item="{ item }"
></catalog-element>
</div>
<script>
import router from '../../scripts/router';
import { Http } from '../../scripts/http';
import { matchSearch } from '../search-bar.riot';
export default {
onBeforeMount(props, state) {
if (props.item.images && props.item.images.length === 1) {
state.image = props.item.images[0];
} else if (typeof props.item === 'string') {
state.image = props.item;
} else if (props.item.images && props.item.repo) {
state.images = props.item.images;
state.repo = props.item.repo;
state.nImages = props.item.images.length;
}
if (props.showCatalogNbTags && state.image) {
this.getNbTags(props, state);
}
},
onBeforeUpdate(props, state) {
if (props.filterResults && state.images) {
state.nImages = state.images.filter((image) => matchSearch(props.filterResults, image)).length;
} else {
state.nImages = state.images && state.images.length;
}
},
onClick() {
const state = this.state;
if (state.repo) {
this.update({
expanded: !this.state.expanded,
expanding: true,
});
setTimeout(() => {
this.update({
expanding: false,
});
}, 50);
}
},
getNbTags(props, state) {
const self = this;
const oReq = new Http({
onAuthentication: props.onAuthentication,
});
oReq.addEventListener('load', function () {
if (this.status === 200) {
const nbTags = (JSON.parse(this.responseText).tags || []).length;
self.update({ nbTags });
} else if (this.status === 404) {
props.onNotify('Server not found', true);
} else {
props.onNotify(this.responseText, true);
}
});
oReq.addEventListener('error', function () {
props.onNotify(this.getErrorMessage(), true);
});
oReq.open('GET', props.registryUrl + '/v2/' + state.image + '/tags/list');
oReq.send();
},
matchSearch,
router,
};
</script>
<!-- End of tag -->
</catalog-element>