Reduces technical debt
Updates icons to use gitlab-svg Updates buttons to use gitlab-ui Updates broken tests
This commit is contained in:
parent
7019b646c5
commit
f8bfc2cf7c
|
@ -26,7 +26,7 @@ export default {
|
||||||
this.setMainEndpoint(this.endpoint);
|
this.setMainEndpoint(this.endpoint);
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.fetchRepos().catch(() => createFlash(errorMessages[errorMessagesTypes.FETCH_REPOS]));
|
this.fetchRepos();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['setMainEndpoint', 'fetchRepos']),
|
...mapActions(['setMainEndpoint', 'fetchRepos']),
|
||||||
|
@ -38,9 +38,9 @@ export default {
|
||||||
<gl-loading-icon v-if="isLoading" :size="3" />
|
<gl-loading-icon v-if="isLoading" :size="3" />
|
||||||
|
|
||||||
<collapsible-container
|
<collapsible-container
|
||||||
v-for="(item, index) in repos"
|
v-for="item in repos"
|
||||||
v-else-if="!isLoading && repos.length"
|
v-else-if="!isLoading && repos.length"
|
||||||
:key="index"
|
:key="item.id"
|
||||||
:repo="item"
|
:repo="item"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapActions } from 'vuex';
|
import { mapActions } from 'vuex';
|
||||||
import { GlLoadingIcon } from '@gitlab/ui';
|
import { GlLoadingIcon, GlButton, GlTooltipDirective } from '@gitlab/ui';
|
||||||
import createFlash from '../../flash';
|
import createFlash from '../../flash';
|
||||||
import ClipboardButton from '../../vue_shared/components/clipboard_button.vue';
|
import ClipboardButton from '../../vue_shared/components/clipboard_button.vue';
|
||||||
import tooltip from '../../vue_shared/directives/tooltip';
|
import Icon from '../../vue_shared/components/icon.vue';
|
||||||
import TableRegistry from './table_registry.vue';
|
import TableRegistry from './table_registry.vue';
|
||||||
import { errorMessages, errorMessagesTypes } from '../constants';
|
import { errorMessages, errorMessagesTypes } from '../constants';
|
||||||
import { __ } from '../../locale';
|
import { __ } from '../../locale';
|
||||||
|
@ -14,9 +14,11 @@ export default {
|
||||||
ClipboardButton,
|
ClipboardButton,
|
||||||
TableRegistry,
|
TableRegistry,
|
||||||
GlLoadingIcon,
|
GlLoadingIcon,
|
||||||
|
GlButton,
|
||||||
|
Icon,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
tooltip,
|
GlTooltip: GlTooltipDirective,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
repo: {
|
repo: {
|
||||||
|
@ -29,15 +31,18 @@ export default {
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
iconName() {
|
||||||
|
return this.isOpen ? 'angle-up' : 'angle-right';
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['fetchRepos', 'fetchList', 'deleteRepo']),
|
...mapActions(['fetchRepos', 'fetchList', 'deleteRepo']),
|
||||||
toggleRepo() {
|
toggleRepo() {
|
||||||
this.isOpen = !this.isOpen;
|
this.isOpen = !this.isOpen;
|
||||||
|
|
||||||
if (this.isOpen) {
|
if (this.isOpen) {
|
||||||
this.fetchList({ repo: this.repo }).catch(() =>
|
this.fetchList({ repo: this.repo });
|
||||||
this.showError(errorMessagesTypes.FETCH_REGISTRY),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleDeleteRepository() {
|
handleDeleteRepository() {
|
||||||
|
@ -58,18 +63,9 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<div class="container-image">
|
<div class="container-image">
|
||||||
<div class="container-image-head">
|
<div class="container-image-head">
|
||||||
<button type="button" class="js-toggle-repo btn-link" @click="toggleRepo">
|
<gl-button class="js-toggle-repo btn-link align-baseline" @click="toggleRepo">
|
||||||
<i
|
<icon :name="iconName" /> {{ repo.name }}
|
||||||
:class="{
|
</gl-button>
|
||||||
'fa-chevron-right': !isOpen,
|
|
||||||
'fa-chevron-up': isOpen,
|
|
||||||
}"
|
|
||||||
class="fa"
|
|
||||||
aria-hidden="true"
|
|
||||||
>
|
|
||||||
</i>
|
|
||||||
{{ repo.name }}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<clipboard-button
|
<clipboard-button
|
||||||
v-if="repo.location"
|
v-if="repo.location"
|
||||||
|
@ -79,17 +75,17 @@ export default {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="controls d-none d-sm-block float-right">
|
<div class="controls d-none d-sm-block float-right">
|
||||||
<button
|
<gl-button
|
||||||
v-if="repo.canDelete"
|
v-if="repo.canDelete"
|
||||||
v-tooltip
|
v-gl-tooltip
|
||||||
:title="s__('ContainerRegistry|Remove repository')"
|
:title="s__('ContainerRegistry|Remove repository')"
|
||||||
:aria-label="s__('ContainerRegistry|Remove repository')"
|
:aria-label="s__('ContainerRegistry|Remove repository')"
|
||||||
type="button"
|
class="js-remove-repo"
|
||||||
class="js-remove-repo btn btn-danger"
|
variant="danger"
|
||||||
@click="handleDeleteRepository"
|
@click="handleDeleteRepository"
|
||||||
>
|
>
|
||||||
<i class="fa fa-trash" aria-hidden="true"> </i>
|
<icon name="remove" />
|
||||||
</button>
|
</gl-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,24 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapActions } from 'vuex';
|
import { mapActions } from 'vuex';
|
||||||
|
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
|
||||||
import { n__ } from '../../locale';
|
import { n__ } from '../../locale';
|
||||||
import Flash from '../../flash';
|
import createFlash from '../../flash';
|
||||||
import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
|
import ClipboardButton from '../../vue_shared/components/clipboard_button.vue';
|
||||||
import tablePagination from '../../vue_shared/components/table_pagination.vue';
|
import TablePagination from '../../vue_shared/components/table_pagination.vue';
|
||||||
import tooltip from '../../vue_shared/directives/tooltip';
|
import Icon from '../../vue_shared/components/icon.vue';
|
||||||
import timeagoMixin from '../../vue_shared/mixins/timeago';
|
import timeagoMixin from '../../vue_shared/mixins/timeago';
|
||||||
import { errorMessages, errorMessagesTypes } from '../constants';
|
import { errorMessages, errorMessagesTypes } from '../constants';
|
||||||
import { numberToHumanSize } from '../../lib/utils/number_utils';
|
import { numberToHumanSize } from '../../lib/utils/number_utils';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
clipboardButton,
|
ClipboardButton,
|
||||||
tablePagination,
|
TablePagination,
|
||||||
|
GlButton,
|
||||||
|
Icon,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
tooltip,
|
GlTooltip: GlTooltipDirective,
|
||||||
},
|
},
|
||||||
mixins: [timeagoMixin],
|
mixins: [timeagoMixin],
|
||||||
props: {
|
props: {
|
||||||
|
@ -31,29 +34,24 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['fetchList', 'deleteRegistry']),
|
...mapActions(['fetchList', 'deleteRegistry']),
|
||||||
|
|
||||||
layers(item) {
|
layers(item) {
|
||||||
return item.layers ? n__('%d layer', '%d layers', item.layers) : '';
|
return item.layers ? n__('%d layer', '%d layers', item.layers) : '';
|
||||||
},
|
},
|
||||||
|
|
||||||
formatSize(size) {
|
formatSize(size) {
|
||||||
return numberToHumanSize(size);
|
return numberToHumanSize(size);
|
||||||
},
|
},
|
||||||
|
|
||||||
handleDeleteRegistry(registry) {
|
handleDeleteRegistry(registry) {
|
||||||
this.deleteRegistry(registry)
|
this.deleteRegistry(registry)
|
||||||
.then(() => this.fetchList({ repo: this.repo }))
|
.then(() => this.fetchList({ repo: this.repo }))
|
||||||
.catch(() => this.showError(errorMessagesTypes.DELETE_REGISTRY));
|
.catch(() => this.showError(errorMessagesTypes.DELETE_REGISTRY));
|
||||||
},
|
},
|
||||||
|
|
||||||
onPageChange(pageNumber) {
|
onPageChange(pageNumber) {
|
||||||
this.fetchList({ repo: this.repo, page: pageNumber }).catch(() =>
|
this.fetchList({ repo: this.repo, page: pageNumber }).catch(() =>
|
||||||
this.showError(errorMessagesTypes.FETCH_REGISTRY),
|
this.showError(errorMessagesTypes.FETCH_REGISTRY),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
showError(message) {
|
showError(message) {
|
||||||
Flash(errorMessages[message]);
|
createFlash(errorMessages[message]);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -71,10 +69,9 @@ export default {
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(item, i) in repo.list" :key="i">
|
<tr v-for="item in repo.list" :key="item.tag">
|
||||||
<td>
|
<td>
|
||||||
{{ item.tag }}
|
{{ item.tag }}
|
||||||
|
|
||||||
<clipboard-button
|
<clipboard-button
|
||||||
v-if="item.location"
|
v-if="item.location"
|
||||||
:title="item.location"
|
:title="item.location"
|
||||||
|
@ -83,37 +80,34 @@ export default {
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span v-tooltip :title="item.revision" data-placement="bottom">
|
<span v-gl-tooltip.bottom :title="item.revision">{{ item.shortRevision }}</span>
|
||||||
{{ item.shortRevision }}
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ formatSize(item.size) }}
|
{{ formatSize(item.size) }}
|
||||||
<template v-if="item.size && item.layers">
|
<template v-if="item.size && item.layers"
|
||||||
·
|
>·</template
|
||||||
</template>
|
>
|
||||||
{{ layers(item) }}
|
{{ layers(item) }}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<span v-tooltip :title="tooltipTitle(item.createdAt)" data-placement="bottom">
|
<span v-gl-tooltip.bottom :title="tooltipTitle(item.createdAt)">{{
|
||||||
{{ timeFormated(item.createdAt) }}
|
timeFormated(item.createdAt)
|
||||||
</span>
|
}}</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="content">
|
<td class="content">
|
||||||
<button
|
<gl-button
|
||||||
v-if="item.canDelete"
|
v-if="item.canDelete"
|
||||||
v-tooltip
|
v-gl-tooltip
|
||||||
:title="s__('ContainerRegistry|Remove tag')"
|
:title="s__('ContainerRegistry|Remove tag')"
|
||||||
:aria-label="s__('ContainerRegistry|Remove tag')"
|
:aria-label="s__('ContainerRegistry|Remove tag')"
|
||||||
type="button"
|
variant="danger"
|
||||||
class="js-delete-registry btn btn-danger d-none d-sm-block float-right"
|
class="js-delete-registry d-none d-sm-block float-right"
|
||||||
data-container="body"
|
|
||||||
@click="handleDeleteRegistry(item);"
|
@click="handleDeleteRegistry(item);"
|
||||||
>
|
>
|
||||||
<i class="fa fa-trash" aria-hidden="true"> </i>
|
<icon name="remove" />
|
||||||
</button>
|
</gl-button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
|
import createFlash from '~/flash';
|
||||||
import * as types from './mutation_types';
|
import * as types from './mutation_types';
|
||||||
|
import { errorMessages, errorMessagesTypes } from '../constants';
|
||||||
|
|
||||||
export const fetchRepos = ({ commit, state }) => {
|
export const fetchRepos = ({ commit, state }) => {
|
||||||
commit(types.TOGGLE_MAIN_LOADING);
|
commit(types.TOGGLE_MAIN_LOADING);
|
||||||
|
@ -10,18 +11,28 @@ export const fetchRepos = ({ commit, state }) => {
|
||||||
.then(({ data }) => {
|
.then(({ data }) => {
|
||||||
commit(types.TOGGLE_MAIN_LOADING);
|
commit(types.TOGGLE_MAIN_LOADING);
|
||||||
commit(types.SET_REPOS_LIST, data);
|
commit(types.SET_REPOS_LIST, data);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
commit(types.TOGGLE_MAIN_LOADING);
|
||||||
|
createFlash(errorMessages[errorMessagesTypes.FETCH_REPOS]);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchList = ({ commit }, { repo, page }) => {
|
export const fetchList = ({ commit }, { repo, page }) => {
|
||||||
commit(types.TOGGLE_REGISTRY_LIST_LOADING, repo);
|
commit(types.TOGGLE_REGISTRY_LIST_LOADING, repo);
|
||||||
|
|
||||||
return axios.get(repo.tagsPath, { params: { page } }).then(response => {
|
return axios
|
||||||
const { headers, data } = response;
|
.get(repo.tagsPath, { params: { page } })
|
||||||
|
.then(response => {
|
||||||
|
const { headers, data } = response;
|
||||||
|
|
||||||
commit(types.TOGGLE_REGISTRY_LIST_LOADING, repo);
|
commit(types.TOGGLE_REGISTRY_LIST_LOADING, repo);
|
||||||
commit(types.SET_REGISTRY_LIST, { repo, resp: data, headers });
|
commit(types.SET_REGISTRY_LIST, { repo, resp: data, headers });
|
||||||
});
|
})
|
||||||
|
.catch(() => {
|
||||||
|
commit(types.TOGGLE_REGISTRY_LIST_LOADING, repo);
|
||||||
|
createFlash(errorMessages[errorMessagesTypes.FETCH_REGISTRY]);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
|
|
@ -48,6 +48,7 @@ export default {
|
||||||
|
|
||||||
[types.TOGGLE_REGISTRY_LIST_LOADING](state, list) {
|
[types.TOGGLE_REGISTRY_LIST_LOADING](state, list) {
|
||||||
const listToUpdate = state.repos.find(el => el.id === list.id);
|
const listToUpdate = state.repos.find(el => el.id === list.id);
|
||||||
|
|
||||||
listToUpdate.isLoading = !listToUpdate.isLoading;
|
listToUpdate.isLoading = !listToUpdate.isLoading;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -57,9 +57,9 @@ describe('Registry List', () => {
|
||||||
Vue.nextTick(() => {
|
Vue.nextTick(() => {
|
||||||
vm.$el.querySelector('.js-toggle-repo').click();
|
vm.$el.querySelector('.js-toggle-repo').click();
|
||||||
Vue.nextTick(() => {
|
Vue.nextTick(() => {
|
||||||
expect(vm.$el.querySelector('.js-toggle-repo i').className).toEqual(
|
expect(
|
||||||
'fa fa-chevron-up',
|
vm.$el.querySelector('.js-toggle-repo use').getAttribute('xlink:href'),
|
||||||
);
|
).toContain('angle-up');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,9 @@ import axios from '~/lib/utils/axios_utils';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import collapsibleComponent from '~/registry/components/collapsible_container.vue';
|
import collapsibleComponent from '~/registry/components/collapsible_container.vue';
|
||||||
import store from '~/registry/stores';
|
import store from '~/registry/stores';
|
||||||
import { repoPropsData, registryServerResponse } from '../mock_data';
|
import * as types from '~/registry/stores/mutation_types';
|
||||||
|
|
||||||
|
import { repoPropsData, registryServerResponse, reposServerResponse } from '../mock_data';
|
||||||
|
|
||||||
describe('collapsible registry container', () => {
|
describe('collapsible registry container', () => {
|
||||||
let vm;
|
let vm;
|
||||||
|
@ -13,9 +15,9 @@ describe('collapsible registry container', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mock = new MockAdapter(axios);
|
mock = new MockAdapter(axios);
|
||||||
|
|
||||||
mock
|
mock.onGet(repoPropsData.tagsPath).replyOnce(200, registryServerResponse, {});
|
||||||
.onGet(repoPropsData.tagsPath)
|
|
||||||
.replyOnce(200, registryServerResponse, {});
|
store.commit(types.SET_REPOS_LIST, reposServerResponse);
|
||||||
|
|
||||||
vm = new Component({
|
vm = new Component({
|
||||||
store,
|
store,
|
||||||
|
@ -33,25 +35,16 @@ describe('collapsible registry container', () => {
|
||||||
describe('toggle', () => {
|
describe('toggle', () => {
|
||||||
it('should be closed by default', () => {
|
it('should be closed by default', () => {
|
||||||
expect(vm.$el.querySelector('.container-image-tags')).toBe(null);
|
expect(vm.$el.querySelector('.container-image-tags')).toBe(null);
|
||||||
expect(vm.$el.querySelector('.container-image-head i').className).toEqual(
|
expect(vm.iconName).toEqual('angle-right');
|
||||||
'fa fa-chevron-right',
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
fit('should be open when user clicks on closed repo', done => {
|
it('should be open when user clicks on closed repo', done => {
|
||||||
|
|
||||||
console.log(vm.repo, vm.$el)
|
|
||||||
|
|
||||||
vm.$el.querySelector('.js-toggle-repo').click();
|
vm.$el.querySelector('.js-toggle-repo').click();
|
||||||
|
|
||||||
Vue.nextTick(() => {
|
Vue.nextTick(() => {
|
||||||
|
|
||||||
console.log('nextTick', vm.repo, vm.$el)
|
|
||||||
|
|
||||||
expect(vm.$el.querySelector('.container-image-tags')).not.toBeNull();
|
expect(vm.$el.querySelector('.container-image-tags')).not.toBeNull();
|
||||||
expect(vm.$el.querySelector('.container-image-head i').className).toEqual(
|
expect(vm.iconName).toEqual('angle-up');
|
||||||
'fa fa-chevron-up',
|
|
||||||
);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -61,12 +54,12 @@ describe('collapsible registry container', () => {
|
||||||
|
|
||||||
Vue.nextTick(() => {
|
Vue.nextTick(() => {
|
||||||
vm.$el.querySelector('.js-toggle-repo').click();
|
vm.$el.querySelector('.js-toggle-repo').click();
|
||||||
Vue.nextTick(() => {
|
setTimeout(() => {
|
||||||
expect(vm.$el.querySelector('.container-image-tags')).toBe(null);
|
Vue.nextTick(() => {
|
||||||
expect(vm.$el.querySelector('.container-image-head i').className).toEqual(
|
expect(vm.$el.querySelector('.container-image-tags')).toBe(null);
|
||||||
'fa fa-chevron-right',
|
expect(vm.iconName).toEqual('angle-right');
|
||||||
);
|
done();
|
||||||
done();
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -28,9 +28,7 @@ describe('Actions Registry Store', () => {
|
||||||
describe('server requests', () => {
|
describe('server requests', () => {
|
||||||
describe('fetchRepos', () => {
|
describe('fetchRepos', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mock
|
mock.onGet(`${TEST_HOST}/endpoint.json`).replyOnce(200, reposServerResponse, {});
|
||||||
.onGet(`${TEST_HOST}/endpoint.json`)
|
|
||||||
.replyOnce(200, reposServerResponse, {})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set receveived repos', done => {
|
it('should set receveived repos', done => {
|
||||||
|
@ -53,11 +51,9 @@ describe('Actions Registry Store', () => {
|
||||||
let repo;
|
let repo;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockedState.repos = parsedReposServerResponse;
|
mockedState.repos = parsedReposServerResponse;
|
||||||
[, repo ] = mockedState.repos;
|
[, repo] = mockedState.repos;
|
||||||
|
|
||||||
mock
|
mock.onGet(repo.tagsPath).replyOnce(200, registryServerResponse, {});
|
||||||
.onGet(repo.tagsPath)
|
|
||||||
.replyOnce(200, registryServerResponse, {})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set received list', done => {
|
it('should set received list', done => {
|
||||||
|
|
Loading…
Reference in New Issue