summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/registry
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-18 09:09:24 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-18 09:09:24 +0000
commit4720b569f0fcbb47e9f1a60e95172ae63b6f065a (patch)
tree5c6bcecbca227e608753a57a9aad19ccfe0567b6 /app/assets/javascripts/registry
parentcefe554b7ce2d0b52f9de855be832a47c2bc24ab (diff)
downloadgitlab-ce-4720b569f0fcbb47e9f1a60e95172ae63b6f065a.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/registry')
-rw-r--r--app/assets/javascripts/registry/explorer/components/registry_breadcrumb.vue59
-rw-r--r--app/assets/javascripts/registry/explorer/index.js47
-rw-r--r--app/assets/javascripts/registry/explorer/pages/details.vue7
-rw-r--r--app/assets/javascripts/registry/explorer/pages/list.vue2
-rw-r--r--app/assets/javascripts/registry/explorer/router.js10
-rw-r--r--app/assets/javascripts/registry/explorer/stores/actions.js16
-rw-r--r--app/assets/javascripts/registry/explorer/utils.js2
7 files changed, 117 insertions, 26 deletions
diff --git a/app/assets/javascripts/registry/explorer/components/registry_breadcrumb.vue b/app/assets/javascripts/registry/explorer/components/registry_breadcrumb.vue
new file mode 100644
index 00000000000..f51948da8cc
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/components/registry_breadcrumb.vue
@@ -0,0 +1,59 @@
+<script>
+import { initial, first, last } from 'lodash';
+
+export default {
+ props: {
+ crumbs: {
+ type: Array,
+ required: true,
+ },
+ },
+ computed: {
+ rootRoute() {
+ return this.$router.options.routes.find(r => r.meta.root);
+ },
+ isRootRoute() {
+ return this.$route.name === this.rootRoute.name;
+ },
+ rootCrumbs() {
+ return initial(this.crumbs);
+ },
+ divider() {
+ const { classList, tagName, innerHTML } = first(this.crumbs).querySelector('svg');
+ return { classList: [...classList], tagName, innerHTML };
+ },
+ lastCrumb() {
+ const { children } = last(this.crumbs);
+ const { tagName, classList } = first(children);
+ return {
+ tagName,
+ classList: [...classList],
+ text: this.$route.meta.nameGenerator(this.$route),
+ path: { to: this.$route.name },
+ };
+ },
+ },
+};
+</script>
+
+<template>
+ <ul>
+ <li
+ v-for="(crumb, index) in rootCrumbs"
+ :key="index"
+ :class="crumb.classList"
+ v-html="crumb.innerHTML"
+ ></li>
+ <li v-if="!isRootRoute">
+ <router-link ref="rootRouteLink" :to="rootRoute.path">
+ {{ rootRoute.meta.nameGenerator(rootRoute) }}
+ </router-link>
+ <component :is="divider.tagName" :class="divider.classList" v-html="divider.innerHTML" />
+ </li>
+ <li>
+ <component :is="lastCrumb.tagName" ref="lastCrumb" :class="lastCrumb.classList">
+ <router-link ref="childRouteLink" :to="lastCrumb.path">{{ lastCrumb.text }}</router-link>
+ </component>
+ </li>
+ </ul>
+</template>
diff --git a/app/assets/javascripts/registry/explorer/index.js b/app/assets/javascripts/registry/explorer/index.js
index daa2e4fb109..a36978303c6 100644
--- a/app/assets/javascripts/registry/explorer/index.js
+++ b/app/assets/javascripts/registry/explorer/index.js
@@ -1,6 +1,7 @@
import Vue from 'vue';
import Translate from '~/vue_shared/translate';
import RegistryExplorer from './pages/index.vue';
+import RegistryBreadcrumb from './components/registry_breadcrumb.vue';
import { createStore } from './stores';
import createRouter from './router';
@@ -19,15 +20,39 @@ export default () => {
const router = createRouter(endpoint, store);
store.dispatch('setInitialState', el.dataset);
- return new Vue({
- el,
- store,
- router,
- components: {
- RegistryExplorer,
- },
- render(createElement) {
- return createElement('registry-explorer');
- },
- });
+ const attachMainComponent = () =>
+ new Vue({
+ el,
+ store,
+ router,
+ components: {
+ RegistryExplorer,
+ },
+ render(createElement) {
+ return createElement('registry-explorer');
+ },
+ });
+
+ const attachBreadcrumb = () => {
+ const breadCrumbEl = document.querySelector('nav .js-breadcrumbs-list');
+ const crumbs = [...document.querySelectorAll('.js-breadcrumbs-list li')];
+ return new Vue({
+ el: breadCrumbEl,
+ store,
+ router,
+ components: {
+ RegistryBreadcrumb,
+ },
+ render(createElement) {
+ return createElement('registry-breadcrumb', {
+ class: breadCrumbEl.className,
+ props: {
+ crumbs,
+ },
+ });
+ },
+ });
+ };
+
+ return { attachBreadcrumb, attachMainComponent };
};
diff --git a/app/assets/javascripts/registry/explorer/pages/details.vue b/app/assets/javascripts/registry/explorer/pages/details.vue
index bff67bb8376..bc613db8672 100644
--- a/app/assets/javascripts/registry/explorer/pages/details.vue
+++ b/app/assets/javascripts/registry/explorer/pages/details.vue
@@ -19,6 +19,7 @@ import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import Tracking from '~/tracking';
+import { decodeAndParse } from '../utils';
import {
LIST_KEY_TAG,
LIST_KEY_IMAGE_ID,
@@ -62,7 +63,7 @@ export default {
computed: {
...mapState(['tags', 'tagsPagination', 'isLoading', 'config']),
imageName() {
- const { name } = JSON.parse(window.atob(this.$route.params.id));
+ const { name } = decodeAndParse(this.$route.params.id);
return name;
},
fields() {
@@ -169,7 +170,7 @@ export default {
},
handleSingleDelete(itemToDelete) {
this.itemsToBeDeleted = [];
- this.requestDeleteTag({ tag: itemToDelete, imageId: this.$route.params.id });
+ this.requestDeleteTag({ tag: itemToDelete, params: this.$route.params.id });
},
handleMultipleDelete() {
const { itemsToBeDeleted } = this;
@@ -178,7 +179,7 @@ export default {
this.requestDeleteTags({
ids: itemsToBeDeleted.map(x => this.tags[x].name),
- imageId: this.$route.params.id,
+ params: this.$route.params.id,
});
},
onDeletionConfirmed() {
diff --git a/app/assets/javascripts/registry/explorer/pages/list.vue b/app/assets/javascripts/registry/explorer/pages/list.vue
index dc730ac2828..1dbc7cc2242 100644
--- a/app/assets/javascripts/registry/explorer/pages/list.vue
+++ b/app/assets/javascripts/registry/explorer/pages/list.vue
@@ -70,7 +70,7 @@ export default {
this.itemToDelete = {};
},
encodeListItem(item) {
- const params = JSON.stringify({ name: item.path, tags_path: item.tags_path });
+ const params = JSON.stringify({ name: item.path, tags_path: item.tags_path, id: item.id });
return window.btoa(params);
},
},
diff --git a/app/assets/javascripts/registry/explorer/router.js b/app/assets/javascripts/registry/explorer/router.js
index 8cf35b8f245..7e4c3d28623 100644
--- a/app/assets/javascripts/registry/explorer/router.js
+++ b/app/assets/javascripts/registry/explorer/router.js
@@ -1,8 +1,9 @@
import Vue from 'vue';
import VueRouter from 'vue-router';
-import { __ } from '~/locale';
+import { s__ } from '~/locale';
import List from './pages/list.vue';
import Details from './pages/details.vue';
+import { decodeAndParse } from './utils';
Vue.use(VueRouter);
@@ -16,7 +17,8 @@ export default function createRouter(base, store) {
path: '/',
component: List,
meta: {
- name: __('Container Registry'),
+ nameGenerator: () => s__('ContainerRegistry|Container Registry'),
+ root: true,
},
beforeEnter: (to, from, next) => {
store.dispatch('requestImagesList');
@@ -28,10 +30,10 @@ export default function createRouter(base, store) {
path: '/:id',
component: Details,
meta: {
- name: __('Tags'),
+ nameGenerator: route => decodeAndParse(route.params.id).name,
},
beforeEnter: (to, from, next) => {
- store.dispatch('requestTagsList', { id: to.params.id });
+ store.dispatch('requestTagsList', { params: to.params.id });
next();
},
},
diff --git a/app/assets/javascripts/registry/explorer/stores/actions.js b/app/assets/javascripts/registry/explorer/stores/actions.js
index 25ff105ac53..86d00d4fca9 100644
--- a/app/assets/javascripts/registry/explorer/stores/actions.js
+++ b/app/assets/javascripts/registry/explorer/stores/actions.js
@@ -13,6 +13,7 @@ import {
DELETE_IMAGE_ERROR_MESSAGE,
DELETE_IMAGE_SUCCESS_MESSAGE,
} from '../constants';
+import { decodeAndParse } from '../utils';
export const setInitialState = ({ commit }, data) => commit(types.SET_INITIAL_STATE, data);
@@ -43,9 +44,9 @@ export const requestImagesList = ({ commit, dispatch, state }, pagination = {})
});
};
-export const requestTagsList = ({ commit, dispatch }, { pagination = {}, id }) => {
+export const requestTagsList = ({ commit, dispatch }, { pagination = {}, params }) => {
commit(types.SET_MAIN_LOADING, true);
- const { tags_path } = JSON.parse(window.atob(id));
+ const { tags_path } = decodeAndParse(params);
const { page = DEFAULT_PAGE, perPage = DEFAULT_PAGE_SIZE } = pagination;
return axios
@@ -61,13 +62,13 @@ export const requestTagsList = ({ commit, dispatch }, { pagination = {}, id }) =
});
};
-export const requestDeleteTag = ({ commit, dispatch, state }, { tag, imageId }) => {
+export const requestDeleteTag = ({ commit, dispatch, state }, { tag, params }) => {
commit(types.SET_MAIN_LOADING, true);
return axios
.delete(tag.destroy_path)
.then(() => {
createFlash(DELETE_TAG_SUCCESS_MESSAGE, 'success');
- dispatch('requestTagsList', { pagination: state.tagsPagination, id: imageId });
+ dispatch('requestTagsList', { pagination: state.tagsPagination, params });
})
.catch(() => {
createFlash(DELETE_TAG_ERROR_MESSAGE);
@@ -77,15 +78,16 @@ export const requestDeleteTag = ({ commit, dispatch, state }, { tag, imageId })
});
};
-export const requestDeleteTags = ({ commit, dispatch, state }, { ids, imageId }) => {
+export const requestDeleteTags = ({ commit, dispatch, state }, { ids, params }) => {
commit(types.SET_MAIN_LOADING, true);
- const url = `/${state.config.projectPath}/registry/repository/${imageId}/tags/bulk_destroy`;
+ const { id } = decodeAndParse(params);
+ const url = `/${state.config.projectPath}/registry/repository/${id}/tags/bulk_destroy`;
return axios
.delete(url, { params: { ids } })
.then(() => {
createFlash(DELETE_TAGS_SUCCESS_MESSAGE, 'success');
- dispatch('requestTagsList', { pagination: state.tagsPagination, id: imageId });
+ dispatch('requestTagsList', { pagination: state.tagsPagination, params });
})
.catch(() => {
createFlash(DELETE_TAGS_ERROR_MESSAGE);
diff --git a/app/assets/javascripts/registry/explorer/utils.js b/app/assets/javascripts/registry/explorer/utils.js
new file mode 100644
index 00000000000..b1df87c6993
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/utils.js
@@ -0,0 +1,2 @@
+// eslint-disable-next-line import/prefer-default-export
+export const decodeAndParse = param => JSON.parse(window.atob(param));