Moves table component into a separate one
Adds better support for i18n
This commit is contained in:
parent
9c7807b319
commit
5ae54ca3eb
4 changed files with 163 additions and 127 deletions
|
@ -3,9 +3,8 @@
|
||||||
import { n__, s__ } from '../../locale';
|
import { n__, s__ } from '../../locale';
|
||||||
import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
|
import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
|
||||||
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
|
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
|
||||||
import tablePagination from '../../vue_shared/components/table_pagination.vue';
|
|
||||||
import tooltip from '../../vue_shared/directives/tooltip';
|
import tooltip from '../../vue_shared/directives/tooltip';
|
||||||
import timeagoMixin from '../../vue_shared/mixins/timeago';
|
import tableRegistry from './table_registry.vue';
|
||||||
import { errorMessages, errorMessagesTypes } from '../constants';
|
import { errorMessages, errorMessagesTypes } from '../constants';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -19,11 +18,8 @@
|
||||||
components: {
|
components: {
|
||||||
clipboardButton,
|
clipboardButton,
|
||||||
loadingIcon,
|
loadingIcon,
|
||||||
tablePagination,
|
tableRegistry,
|
||||||
},
|
},
|
||||||
mixins: [
|
|
||||||
timeagoMixin,
|
|
||||||
],
|
|
||||||
directives: {
|
directives: {
|
||||||
tooltip,
|
tooltip,
|
||||||
},
|
},
|
||||||
|
@ -32,24 +28,13 @@
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
shouldRenderPagination() {
|
|
||||||
return this.repo.pagination.total > this.repo.pagination.perPage;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions([
|
...mapActions([
|
||||||
|
'fetchRepos',
|
||||||
'fetchList',
|
'fetchList',
|
||||||
'deleteRepo',
|
'deleteRepo',
|
||||||
'deleteRegistry',
|
|
||||||
'toggleLoading',
|
|
||||||
]),
|
]),
|
||||||
|
|
||||||
layers(item) {
|
|
||||||
const pluralize = n__('layer', 'layers', item.layers);
|
|
||||||
return `${item.layers} ${pluralize}`;
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleRepo() {
|
toggleRepo() {
|
||||||
this.isOpen = !this.isOpen;
|
this.isOpen = !this.isOpen;
|
||||||
if (this.isOpen) {
|
if (this.isOpen) {
|
||||||
|
@ -64,17 +49,6 @@
|
||||||
.catch(() => this.showError(errorMessagesTypes.DELETE_REPO));
|
.catch(() => this.showError(errorMessagesTypes.DELETE_REPO));
|
||||||
},
|
},
|
||||||
|
|
||||||
handleDeleteRegistry(registry) {
|
|
||||||
this.deleteRegistry(registry)
|
|
||||||
.then(() => this.fetchRegistry(this.repo))
|
|
||||||
.catch(() => this.showError(errorMessagesTypes.DELETE_REGISTRY));
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageChange(pageNumber) {
|
|
||||||
this.fetchList({ repo: this.repo, page })
|
|
||||||
.catch(() => this.showError(errorMessagesTypes.FETCH_REGISTRY));
|
|
||||||
},
|
|
||||||
|
|
||||||
clipboardText(text) {
|
clipboardText(text) {
|
||||||
return `docker pull ${text}`;
|
return `docker pull ${text}`;
|
||||||
},
|
},
|
||||||
|
@ -137,89 +111,11 @@
|
||||||
v-else-if="!repo.isLoading && isOpen"
|
v-else-if="!repo.isLoading && isOpen"
|
||||||
class="container-image-tags">
|
class="container-image-tags">
|
||||||
|
|
||||||
<template v-if="repo.list.length">
|
<table-registry
|
||||||
<table class="table tags">
|
v-if="repo.list.length"
|
||||||
<thead>
|
:repo="repo"
|
||||||
<tr>
|
/>
|
||||||
<th>{{s__('ContainerRegistry|Tag')}}</th>
|
|
||||||
<th>{{s__('ContainerRegistry|Tag ID')}}</th>
|
|
||||||
<th>{{s__("ContainerRegistry|Size")}}</th>
|
|
||||||
<th>{{s__("ContainerRegistry|Created")}}</th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr
|
|
||||||
v-for="(item, i) in repo.list"
|
|
||||||
:key="i">
|
|
||||||
<td>
|
|
||||||
|
|
||||||
{{item.tag}}
|
|
||||||
|
|
||||||
<clipboard-button
|
|
||||||
v-if="item.location"
|
|
||||||
:title="item.location"
|
|
||||||
:text="clipboardText(item.location)"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span
|
|
||||||
v-tooltip
|
|
||||||
:title="item.revision"
|
|
||||||
data-placement="bottom">
|
|
||||||
{{item.shortRevision}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<template v-if="item.size">
|
|
||||||
{{item.size}}
|
|
||||||
·
|
|
||||||
{{layers(item)}}
|
|
||||||
</template>
|
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
class="light">
|
|
||||||
\-
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<template v-if="item.createdAt">
|
|
||||||
{{timeFormated(item.createdAt)}}
|
|
||||||
</template>
|
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
class="light">
|
|
||||||
\-
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="content">
|
|
||||||
<button
|
|
||||||
v-if="item.canDelete"
|
|
||||||
type="button"
|
|
||||||
class="js-delete-registry btn btn-danger hidden-xs pull-right"
|
|
||||||
:title="s__('ContainerRegistry|Remove tag')"
|
|
||||||
:aria-label="s__('ContainerRegistry|Remove tag')"
|
|
||||||
data-container="body"
|
|
||||||
v-tooltip
|
|
||||||
@click="handleDeleteRegistry(item)">
|
|
||||||
<i
|
|
||||||
class="fa fa-trash"
|
|
||||||
aria-hidden="true">
|
|
||||||
</i>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<table-pagination
|
|
||||||
v-if="shouldRenderPagination"
|
|
||||||
:change="onPageChange"
|
|
||||||
:page-info="repo.pagination"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
class="nothing-here-block">
|
class="nothing-here-block">
|
||||||
|
|
147
app/assets/javascripts/registry/components/table_registry.vue
Normal file
147
app/assets/javascripts/registry/components/table_registry.vue
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
<script>
|
||||||
|
import { mapActions } from 'vuex';
|
||||||
|
import { n__, s__ } from '../../locale';
|
||||||
|
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 timeagoMixin from '../../vue_shared/mixins/timeago';
|
||||||
|
import { errorMessages, errorMessagesTypes } from '../constants';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
repo: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
clipboardButton,
|
||||||
|
tablePagination,
|
||||||
|
},
|
||||||
|
mixins: [
|
||||||
|
timeagoMixin,
|
||||||
|
],
|
||||||
|
directives: {
|
||||||
|
tooltip,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
shouldRenderPagination() {
|
||||||
|
return this.repo.pagination.total > this.repo.pagination.perPage;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions([
|
||||||
|
'fetchList',
|
||||||
|
'deleteRegistry',
|
||||||
|
]),
|
||||||
|
|
||||||
|
layers(item) {
|
||||||
|
const pluralize = n__('layer', 'layers', item.layers);
|
||||||
|
return `${item.layers} ${pluralize}`;
|
||||||
|
},
|
||||||
|
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 })
|
||||||
|
.catch(() => this.showError(errorMessagesTypes.FETCH_REGISTRY));
|
||||||
|
},
|
||||||
|
|
||||||
|
clipboardText(text) {
|
||||||
|
return `docker pull ${text}`;
|
||||||
|
},
|
||||||
|
|
||||||
|
showError(message) {
|
||||||
|
Flash((errorMessages[message]));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<table class="table tags">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{s__('ContainerRegistry|Tag')}}</th>
|
||||||
|
<th>{{s__('ContainerRegistry|Tag ID')}}</th>
|
||||||
|
<th>{{s__("ContainerRegistry|Size")}}</th>
|
||||||
|
<th>{{s__("ContainerRegistry|Created")}}</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr
|
||||||
|
v-for="(item, i) in repo.list"
|
||||||
|
:key="i">
|
||||||
|
<td>
|
||||||
|
|
||||||
|
{{item.tag}}
|
||||||
|
|
||||||
|
<clipboard-button
|
||||||
|
v-if="item.location"
|
||||||
|
:title="item.location"
|
||||||
|
:text="clipboardText(item.location)"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span
|
||||||
|
v-tooltip
|
||||||
|
:title="item.revision"
|
||||||
|
data-placement="bottom">
|
||||||
|
{{item.shortRevision}}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<template v-if="item.size">
|
||||||
|
{{item.size}}
|
||||||
|
·
|
||||||
|
{{layers(item)}}
|
||||||
|
</template>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="light">
|
||||||
|
\-
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<template v-if="item.createdAt">
|
||||||
|
{{timeFormated(item.createdAt)}}
|
||||||
|
</template>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="light">
|
||||||
|
\-
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="content">
|
||||||
|
<button
|
||||||
|
v-if="item.canDelete"
|
||||||
|
type="button"
|
||||||
|
class="js-delete-registry btn btn-danger hidden-xs pull-right"
|
||||||
|
:title="s__('ContainerRegistry|Remove tag')"
|
||||||
|
:aria-label="s__('ContainerRegistry|Remove tag')"
|
||||||
|
data-container="body"
|
||||||
|
v-tooltip
|
||||||
|
@click="handleDeleteRegistry(item)">
|
||||||
|
<i
|
||||||
|
class="fa fa-trash"
|
||||||
|
aria-hidden="true">
|
||||||
|
</i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table-pagination
|
||||||
|
v-if="shouldRenderPagination"
|
||||||
|
:change="onPageChange"
|
||||||
|
:page-info="repo.pagination"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -9,7 +9,7 @@ export const errorMessagesTypes = {
|
||||||
|
|
||||||
export const errorMessages = {
|
export const errorMessages = {
|
||||||
[errorMessagesTypes.FETCH_REGISTRY]: __('Something went wrong while fetching the registry list.'),
|
[errorMessagesTypes.FETCH_REGISTRY]: __('Something went wrong while fetching the registry list.'),
|
||||||
[errorMessagesTypes.FETCH_REPOS]: __('Something went wrong while fetching the repositories.'),
|
[errorMessagesTypes.FETCH_REPOS]: __('Something went wrong while fetching the projects.'),
|
||||||
[errorMessagesTypes.DELETE_REPO]: __('Something went wrong while deleting the repository.'),
|
[errorMessagesTypes.DELETE_REPO]: __('Something went wrong on our end.'),
|
||||||
[errorMessagesTypes.DELETE_REGISTRY]: __('Something went wrong while deleting registry.'),
|
[errorMessagesTypes.DELETE_REGISTRY]: __('Something went wrong on our end.'),
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,30 +25,23 @@
|
||||||
= s_('ContainerRegistry|How to use the Container Registry')
|
= s_('ContainerRegistry|How to use the Container Registry')
|
||||||
.panel-body
|
.panel-body
|
||||||
%p
|
%p
|
||||||
= _('First log in to GitLab’s Container Registry using your GitLab username and password. If you have').html_safe
|
- link_token = link_to(_('personal access token'), help_page_path('user/profile/account/two_factor_authentication', anchor: 'personal-access-tokens'), target: '_blank')
|
||||||
= link_to _('2FA enabled'), help_page_path('user/profile/account/two_factor_authentication'), target: '_blank'
|
- link_2fa = link_to(_('2FA enabled'), help_page_path('user/profile/account/two_factor_authentication'), target: '_blank')
|
||||||
= _('you need to use a')
|
= s_('ContainerRegistry|First log in to GitLab’s Container Registry using your GitLab username and password. If you have %{link_2fa} you need to use a %{link_token}:').html_safe % { link_2fa: link_2fa, link_token: link_token }
|
||||||
= succeed ':' do
|
|
||||||
= link_to _('personal access token'), help_page_path('user/profile/account/two_factor_authentication', anchor: 'personal-access-tokens'), target: '_blank'
|
|
||||||
%pre
|
%pre
|
||||||
docker login #{Gitlab.config.registry.host_port}
|
docker login #{Gitlab.config.registry.host_port}
|
||||||
%br
|
%br
|
||||||
%p
|
%p
|
||||||
= _('Once you log in, you’re free to create and upload a container image using the common').html_safe
|
= s_('ContainerRegistry|Once you log in, you’re free to create and upload a container image using the common %{build} and %{push} commands').html_safe % { build: "<code>build</code>".html_safe, push: "<code>push</code>".html_safe }
|
||||||
%code
|
|
||||||
= _('build')
|
|
||||||
= _('and')
|
|
||||||
%code push
|
|
||||||
= _('commands:')
|
|
||||||
%pre
|
%pre
|
||||||
:plain
|
:plain
|
||||||
docker build -t #{escape_once(@project.container_registry_url)} .
|
docker build -t #{escape_once(@project.container_registry_url)} .
|
||||||
docker push #{escape_once(@project.container_registry_url)}
|
docker push #{escape_once(@project.container_registry_url)}
|
||||||
%hr
|
%hr
|
||||||
%h5.prepend-top-default
|
%h5.prepend-top-default
|
||||||
= _('Use different image names')
|
= s_('ContainerRegistry|Use different image names')
|
||||||
%p.light
|
%p.light
|
||||||
= _('GitLab supports up to 3 levels of image names. The following examples of images are valid for your project:')
|
= s_('ContainerRegistry|GitLab supports up to 3 levels of image names. The following examples of images are valid for your project:')
|
||||||
%pre
|
%pre
|
||||||
:plain
|
:plain
|
||||||
#{escape_once(@project.container_registry_url)}:tag
|
#{escape_once(@project.container_registry_url)}:tag
|
||||||
|
|
Loading…
Reference in a new issue