mirror of
https://github.com/Joxit/docker-registry-ui.git
synced 2026-05-23 04:42:47 +00:00
feat(branching): add configuration for catalog arborescence
This commit is contained in:
@@ -52,6 +52,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
show-catalog-nb-tags="{ props.showCatalogNbTags }"
|
||||
class="animated {!state.expanded && !props.filterResults ? 'hide' : ''} {state.expanding ? 'expanding' : ''}"
|
||||
each="{item in state.images}"
|
||||
z-index="{ props.zIndex - 1 }"
|
||||
item="{ item }"
|
||||
></catalog-element>
|
||||
</div>
|
||||
@@ -76,6 +77,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
this.getNbTags(props, state);
|
||||
}
|
||||
},
|
||||
onMounted(props, state) {
|
||||
const materialCard = this.$('material-card');
|
||||
if (materialCard) {
|
||||
materialCard.style['z-index'] = props.zIndex;
|
||||
}
|
||||
},
|
||||
onBeforeUpdate(props, state) {
|
||||
if (props.filterResults && state.images) {
|
||||
state.nImages = state.images.filter((image) => matchSearch(props.filterResults, image)).length;
|
||||
|
||||
@@ -35,10 +35,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
on-authentication="{ props.onAuthentication }"
|
||||
show-catalog-nb-tags="{ props.showCatalogNbTags }"
|
||||
catalog-default-expanded="{ props.catalogDefaultExpanded || state.nRepositories === 1 }"
|
||||
z-index="{ props.catalogMaxBranches - props.catalogMinBranches + 2 }"
|
||||
></catalog-element>
|
||||
<script>
|
||||
import CatalogElement from './catalog-element.riot';
|
||||
import { Http } from '../../scripts/http';
|
||||
import { getBranching } from '../../scripts/repositories';
|
||||
import { getRegistryServers } from '../../scripts/utils';
|
||||
|
||||
export default {
|
||||
@@ -56,6 +58,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
onBeforeMount(props) {
|
||||
this.state.registryName = props.registryName;
|
||||
this.state.catalogElementsLimit = props.catalogElementsLimit;
|
||||
try {
|
||||
this.state.branching = getBranching(props.catalogMinBranches, props.catalogMaxBranches);
|
||||
} catch (e) {
|
||||
props.onNotify(e);
|
||||
}
|
||||
},
|
||||
onMounted(props, state) {
|
||||
this.display(props, state);
|
||||
@@ -69,6 +76,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
}
|
||||
state.registryUrl = props.registryUrl;
|
||||
let repositories = [];
|
||||
let nImages = 0;
|
||||
const self = this;
|
||||
const catalogUrl = `${props.registryUrl}/v2/_catalog?n=${state.catalogElementsLimit}`;
|
||||
const oReq = new Http({
|
||||
@@ -78,22 +86,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
if (this.status === 200) {
|
||||
repositories = JSON.parse(this.responseText).repositories || [];
|
||||
repositories.sort();
|
||||
repositories = 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;
|
||||
}, []);
|
||||
nImages = repositories.length;
|
||||
if (typeof state.branching === 'function') {
|
||||
repositories = state.branching(repositories);
|
||||
}
|
||||
} else if (this.status === 404) {
|
||||
self.props.onNotify({ code: 'CATALOG_NOT_FOUND', url: catalogUrl }, true);
|
||||
} else if (this.status === 400) {
|
||||
@@ -116,7 +112,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
self.update({
|
||||
repositories,
|
||||
nRepositories: repositories.length,
|
||||
nImages: repositories.reduce((acc, e) => acc + ((e.images && e.images.length) || 1), 0),
|
||||
nImages,
|
||||
loadend: true,
|
||||
});
|
||||
});
|
||||
@@ -125,4 +121,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
catalog {
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
catalog > material-card {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
</catalog>
|
||||
|
||||
@@ -31,6 +31,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
</material-navbar>
|
||||
</header>
|
||||
<main>
|
||||
<error-page
|
||||
if="{ state.pageError && !Array.isArray(state.pageError.errors) }"
|
||||
code="{ state.pageError.code }"
|
||||
status="{ state.pageError.status }"
|
||||
message="{ state.pageError.message }"
|
||||
url="{ state.pageError.url }"
|
||||
></error-page>
|
||||
<error-page
|
||||
if="{ state.pageError && Array.isArray(state.pageError.errors) }"
|
||||
each="{ error in (state.pageError && state.pageError.errors) }"
|
||||
code="{ error.code }"
|
||||
detail="{ error.detail }"
|
||||
message="{ error.message }"
|
||||
url="{ state.pageError.url }"
|
||||
></error-page>
|
||||
<router base="#!">
|
||||
<route path="{baseRoute}">
|
||||
<catalog
|
||||
@@ -42,6 +57,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
on-authentication="{ onAuthentication }"
|
||||
show-catalog-nb-tags="{ truthy(props.showCatalogNbTags) }"
|
||||
catalog-default-expanded="{ truthy(props.catalogDefaultExpanded) }"
|
||||
catalog-min-branches="{ props.catalogMinBranches }"
|
||||
catalog-max-branches="{ props.catalogMaxBranches }"
|
||||
></catalog>
|
||||
</route>
|
||||
<route path="{baseRoute}taglist/(.*)">
|
||||
@@ -82,21 +99,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
on-authenticated="{ state.onAuthenticated }"
|
||||
opened="{ state.authenticationDialogOpened }"
|
||||
></registry-authentication>
|
||||
<error-page
|
||||
if="{ state.pageError && !Array.isArray(state.pageError.errors) }"
|
||||
code="{ state.pageError.code }"
|
||||
status="{ state.pageError.status }"
|
||||
message="{ state.pageError.message }"
|
||||
url="{ state.pageError.url }"
|
||||
></error-page>
|
||||
<error-page
|
||||
if="{ state.pageError && Array.isArray(state.pageError.errors) }"
|
||||
each="{ error in (state.pageError && state.pageError.errors) }"
|
||||
code="{ error.code }"
|
||||
detail="{ error.detail }"
|
||||
message="{ error.message }"
|
||||
url="{ state.pageError.url }"
|
||||
></error-page>
|
||||
<material-snackbar message="{ state.snackbarMessage }" is-error="{ state.snackbarIsError }"></material-snackbar>
|
||||
</main>
|
||||
<footer>
|
||||
|
||||
@@ -61,6 +61,10 @@
|
||||
<a href="https://github.com/Joxit/docker-registry-ui/issues/306">Joxit/docker-registry-ui#306</a>.
|
||||
</p>
|
||||
</template>
|
||||
<template if="{ props.code === 'CATALOG_BRANCHING_CONFIGURATION' }">
|
||||
<p>Wrong configuration for the branching feature: { props.message }</p>
|
||||
<p>Configuration environment variables are : CATALOG_MIN_BRANCH and CATALOG_MAX_BRANCH</p>
|
||||
</template>
|
||||
</div>
|
||||
<script>
|
||||
export default {
|
||||
|
||||
@@ -159,7 +159,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
return router.taglist(this.props.image);
|
||||
},
|
||||
showDockerfile() {
|
||||
console.log(this);
|
||||
this.update({ showDockerfile: true });
|
||||
},
|
||||
onDockerfileClose() {
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
use-control-cache-header="${USE_CONTROL_CACHE_HEADER}"
|
||||
taglist-order="${TAGLIST_ORDER}"
|
||||
catalog-default-expanded="${CATALOG_DEFAULT_EXPANDED}"
|
||||
catalog-min-branches="${CATALOG_MIN_BRANCHES}"
|
||||
catalog-max-branches="${CATALOG_MAX_BRANCHES}"
|
||||
theme="${THEME}"
|
||||
theme-primary-text="${THEME_PRIMARY_TEXT}"
|
||||
theme-neutral-text="${THEME_NEUTRAL_TEXT}"
|
||||
@@ -77,6 +79,8 @@
|
||||
use-control-cache-header="false"
|
||||
taglist-order=""
|
||||
catalog-default-expanded=""
|
||||
catalog-min-branches="1"
|
||||
catalog-max-branches="1"
|
||||
theme="auto"
|
||||
theme-primary-text=""
|
||||
theme-neutral-text=""
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export class DockerRegistryUIError extends Error {
|
||||
constructor(msg) {
|
||||
constructor(msg, code) {
|
||||
super(msg);
|
||||
this.isError = true;
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { DockerRegistryUIError } from './error.js';
|
||||
const ERROR_CODE = 'CATALOG_BRANCHING_CONFIGURATION';
|
||||
|
||||
const getRepositoryName = (split, max) => {
|
||||
let repositoryName = '';
|
||||
@@ -29,14 +30,24 @@ const getLatestRepository = (repo, repoName) => {
|
||||
}
|
||||
};
|
||||
|
||||
const cleanInt = (n) => (n === '' ? 1 : parseInt(n));
|
||||
|
||||
export const getBranching = (min = 1, max = 1) => {
|
||||
if (min > max) {
|
||||
throw new DockerRegistryUIError(`min must be inferior to max (min: ${min} <= max: ${max})`);
|
||||
min = cleanInt(min);
|
||||
max = cleanInt(max);
|
||||
if (isNaN(min) || isNaN(max)) {
|
||||
throw new DockerRegistryUIError(`min and max must be integers: (min: ${min} and max: ${max}))`, ERROR_CODE);
|
||||
} else if (min > max) {
|
||||
throw new DockerRegistryUIError(`min must be inferior to max (min: ${min} <= max: ${max})`, ERROR_CODE);
|
||||
} else if (max < 0 || min < 0) {
|
||||
throw new DockerRegistryUIError(
|
||||
`min and max must be greater than equals to 0 (min: ${min} >= 0 and max: ${max} >= 0)`
|
||||
`min and max must be greater than equals to 0 (min: ${min} >= 0 and max: ${max} >= 0)`,
|
||||
ERROR_CODE
|
||||
);
|
||||
}
|
||||
if (max == 1) {
|
||||
min = 1;
|
||||
}
|
||||
return (repositories) =>
|
||||
repositories.sort().reduce(function (acc, image) {
|
||||
const split = image.split('/');
|
||||
|
||||
@@ -69,17 +69,18 @@ material-card {
|
||||
material-card,
|
||||
material-tabs,
|
||||
pagination .container {
|
||||
max-width: 95%;
|
||||
margin: auto;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* 1515px * 0.95 = 1440px */
|
||||
@media screen and (min-width: 1515px) {
|
||||
material-card,
|
||||
material-tabs,
|
||||
pagination .container {
|
||||
material-card,
|
||||
material-tabs,
|
||||
pagination .container,
|
||||
catalog {
|
||||
max-width: 95%;
|
||||
/* 1515px * 0.95 = 1440px */
|
||||
@media screen and (min-width: 1515px) {
|
||||
max-width: 1440px;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user