Commit f8bfc2cf authored by Filipa Lacerda's avatar Filipa Lacerda

Reduces technical debt

Updates icons to use gitlab-svg
Updates buttons to use gitlab-ui

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