From 13c86bb4ad7a858799440002fa3451e3513167a9 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Fri, 15 Sep 2017 14:10:08 +0100 Subject: Init store for registry --- app/assets/javascripts/registry/components/app.vue | 0 .../registry/components/collapsible_container.vue | 42 ++++++++++++++++++++++ .../registry/components/registry_table.vue | 0 app/assets/javascripts/registry/index.js | 0 app/assets/javascripts/registry/stores/actions.js | 39 ++++++++++++++++++++ app/assets/javascripts/registry/stores/index.js | 37 +++++++++++++++++++ .../javascripts/registry/stores/mutation_types.js | 9 +++++ .../javascripts/registry/stores/mutations.js | 38 ++++++++++++++++++++ .../vue_shared/components/clipboard_button.vue | 40 +++++++++++++++++++++ 9 files changed, 205 insertions(+) create mode 100644 app/assets/javascripts/registry/components/app.vue create mode 100644 app/assets/javascripts/registry/components/collapsible_container.vue create mode 100644 app/assets/javascripts/registry/components/registry_table.vue create mode 100644 app/assets/javascripts/registry/index.js create mode 100644 app/assets/javascripts/registry/stores/actions.js create mode 100644 app/assets/javascripts/registry/stores/index.js create mode 100644 app/assets/javascripts/registry/stores/mutation_types.js create mode 100644 app/assets/javascripts/registry/stores/mutations.js create mode 100644 app/assets/javascripts/vue_shared/components/clipboard_button.vue diff --git a/app/assets/javascripts/registry/components/app.vue b/app/assets/javascripts/registry/components/app.vue new file mode 100644 index 00000000000..e69de29bb2d diff --git a/app/assets/javascripts/registry/components/collapsible_container.vue b/app/assets/javascripts/registry/components/collapsible_container.vue new file mode 100644 index 00000000000..7014562be08 --- /dev/null +++ b/app/assets/javascripts/registry/components/collapsible_container.vue @@ -0,0 +1,42 @@ + + + diff --git a/app/assets/javascripts/registry/components/registry_table.vue b/app/assets/javascripts/registry/components/registry_table.vue new file mode 100644 index 00000000000..e69de29bb2d diff --git a/app/assets/javascripts/registry/index.js b/app/assets/javascripts/registry/index.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/app/assets/javascripts/registry/stores/actions.js b/app/assets/javascripts/registry/stores/actions.js new file mode 100644 index 00000000000..6c0286e2be6 --- /dev/null +++ b/app/assets/javascripts/registry/stores/actions.js @@ -0,0 +1,39 @@ +import Vue from 'vue'; +import VueResource from 'vue-resource'; +import * as types from './mutation_types'; + +Vue.use(VueResource); + +export const fetchRepos = ({ commit, state }) => { + commit(types.TOGGLE_MAIN_LOADING); + + return Vue.http.get(state.endpoint) + .then(res => res.json()) + .then((response) => { + commit(types.TOGGLE_MAIN_LOADING); + commit(types.SET_REPOS_LIST, response); + }); +}; + +export const fetchList = ({ commit }, list) => { + commit(types.TOGGLE_IMAGE_LOADING, list); + + return Vue.http.get(list.path) + .then(res => res.json()) + .then((response) => { + commit(types.TOGGLE_IMAGE_LOADING, list); + commit(types.SET_IMAGES_LIST, list, response); + }); +}; + +export const deleteRepo = ({ commit }, repo) => Vue.http.delete(repo.path) + .then(res => res.json()) + .then(() => { + commit(types.DELETE_REPO, repo); + }); + +export const deleteImage = ({ commit }, image) => Vue.http.delete(image.path) + .then(res => res.json()) + .then(() => { + commit(types.DELETE_IMAGE, image); + }); diff --git a/app/assets/javascripts/registry/stores/index.js b/app/assets/javascripts/registry/stores/index.js new file mode 100644 index 00000000000..6cf9df57f08 --- /dev/null +++ b/app/assets/javascripts/registry/stores/index.js @@ -0,0 +1,37 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; +import actions from './actions'; +import mutations from './mutations'; + +Vue.use(Vuex); + +export default new Vuex.Store({ + state: { + isLoading: false, + endpoint: '', // initial endpoint to fetch the repos list + /** + * Each object in `repos` has the following strucure: + * { + * name: String, + * isLoading: Boolean, + * tagsPath: String // endpoint to request the list + * destroyPath: String // endpoit to delete the repo + * list: Array // List of the registry images + * } + * + * Each registry image inside `list` has the following structure: + * { + * tag: String, + * revision: String + * shortRevision: String + * size: Number + * layers: Number + * createdAt: String + * destroyPath: String // endpoit to delete each image + * } + */ + repos: [], + actions, + mutations, + }, +}); diff --git a/app/assets/javascripts/registry/stores/mutation_types.js b/app/assets/javascripts/registry/stores/mutation_types.js new file mode 100644 index 00000000000..fb4e24e10e3 --- /dev/null +++ b/app/assets/javascripts/registry/stores/mutation_types.js @@ -0,0 +1,9 @@ +export const FETCH_REPOS_LIST = 'FETCH_REPOS_LIST'; +export const DELETE_REPO = 'DELETE_REPO'; +export const SET_REPOS_LIST = 'SET_REPOS_LIST'; +export const TOGGLE_MAIN_LOADING = 'TOGGLE_MAIN_LOADING'; + +export const FETCH_IMAGES_LIST = 'FETCH_IMAGES_LIST'; +export const SET_IMAGES_LIST = 'SET_IMAGES_LIST'; +export const DELETE_IMAGE = 'DELETE_IMAGE'; +export const TOGGLE_IMAGE_LOADING = 'TOGGLE_MAIN_LOADING'; diff --git a/app/assets/javascripts/registry/stores/mutations.js b/app/assets/javascripts/registry/stores/mutations.js new file mode 100644 index 00000000000..5fa41fb5255 --- /dev/null +++ b/app/assets/javascripts/registry/stores/mutations.js @@ -0,0 +1,38 @@ +import * as types from './mutation_types'; + +export default { + [types.SET_REPOS_LIST](state, list) { + Object.assign(state, { + repos: list.map(el => ({ + name: el.name, + isLoading: false, + canDelete: !!el.destroy_path, + destroyPath: el.destroy_path, + list: [], + })), + }); + }, + + [types.TOGGLE_MAIN_LOADING](state) { + Object.assign(state, { isLoading: !state.isLoading }); + }, + + [types.SET_IMAGES_LIST](state, image, list) { + const listToUpdate = state.repos.find(el => el.name === image.name); + listToUpdate.list = list.map(element => ({ + tag: element.name, + revision: element.revision, + shortRevision: element.short_revision, + size: element.size, + layers: element.layers, + createdAt: element.created_at, + destroyPath: element.destroy_path, + canDelete: !!element.destroy_path, + })); + }, + + [types.TOGGLE_IMAGE_LOADING](state, image) { + const listToUpdate = state.repos.find(el => el.name === image.name); + listToUpdate.isLoading = !listToUpdate.isLoading; + }, +}; diff --git a/app/assets/javascripts/vue_shared/components/clipboard_button.vue b/app/assets/javascripts/vue_shared/components/clipboard_button.vue new file mode 100644 index 00000000000..ebb3dbd0112 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/clipboard_button.vue @@ -0,0 +1,40 @@ + +import Clipboard from 'vendor/clipboard'; + + + + -- cgit v1.2.1 From 23024a70dbc50dbd0114ed715c906cac1a9b1d59 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Fri, 15 Sep 2017 17:05:46 +0100 Subject: Adds clipboard button component --- .../registry/components/collapsible_container.vue | 117 ++++++++++++++++++--- .../registry/components/registry_table.vue | 0 .../vue_shared/components/clipboard_button.vue | 5 +- 3 files changed, 105 insertions(+), 17 deletions(-) delete mode 100644 app/assets/javascripts/registry/components/registry_table.vue diff --git a/app/assets/javascripts/registry/components/collapsible_container.vue b/app/assets/javascripts/registry/components/collapsible_container.vue index 7014562be08..20ebedd2b45 100644 --- a/app/assets/javascripts/registry/components/collapsible_container.vue +++ b/app/assets/javascripts/registry/components/collapsible_container.vue @@ -1,18 +1,24 @@ diff --git a/app/assets/javascripts/registry/components/registry_table.vue b/app/assets/javascripts/registry/components/registry_table.vue deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/app/assets/javascripts/vue_shared/components/clipboard_button.vue b/app/assets/javascripts/vue_shared/components/clipboard_button.vue index ebb3dbd0112..cb9ad4c7dee 100644 --- a/app/assets/javascripts/vue_shared/components/clipboard_button.vue +++ b/app/assets/javascripts/vue_shared/components/clipboard_button.vue @@ -1,7 +1,6 @@ - -import Clipboard from 'vendor/clipboard'; - + diff --git a/app/assets/javascripts/registry/components/collapsible_container.vue b/app/assets/javascripts/registry/components/collapsible_container.vue index 20ebedd2b45..6be2aa60ebd 100644 --- a/app/assets/javascripts/registry/components/collapsible_container.vue +++ b/app/assets/javascripts/registry/components/collapsible_container.vue @@ -1,24 +1,22 @@ diff --git a/app/assets/javascripts/registry/constants.js b/app/assets/javascripts/registry/constants.js new file mode 100644 index 00000000000..d3de6441dae --- /dev/null +++ b/app/assets/javascripts/registry/constants.js @@ -0,0 +1,13 @@ +export const errorMessagesTypes = { + FETCH_REGISTRY: 'FETCH_REGISTRY', + FETCH_REPOS: 'FETCH_REPOS', + DELETE_REPO: 'DELETE_REPO', + DELETE_REGISTRY: 'DELETE_REGISTRY', +}; + +export const errorMessages = { + [errorMessagesTypes.FETCH_REGISTRY]: 'Something went wrong while fetching the registry list.', + [errorMessagesTypes.FETCH_REPOS]: 'Something went wrong while fetching the repositories.', + [errorMessagesTypes.DELETE_REPO]: 'Something went wrong while deleting the repository.', + [errorMessagesTypes.DELETE_REGISTRY]: 'Something went wrong while deleting registry.', +}; diff --git a/app/assets/javascripts/registry/index.js b/app/assets/javascripts/registry/index.js index e69de29bb2d..4f7895897b2 100644 --- a/app/assets/javascripts/registry/index.js +++ b/app/assets/javascripts/registry/index.js @@ -0,0 +1,25 @@ +import Vue from 'vue'; +import Translate from '../vue_shared/translate'; +import registryApp from './components/app.vue'; + +// Vue.use(Translate); + +document.addEventListener('DOMContentLoaded', () => new Vue({ + el: '#js-vue-registry-images', + components: { + registryApp, + }, + data() { + const dataset = document.querySelector(this.$options.el).dataset; + return { + endpoint: dataset.endpoint, + }; + }, + render(createElement) { + return createElement('registry-app', { + props: { + endpoint: this.endpoint, + }, + }); + }, +})); diff --git a/app/assets/javascripts/registry/stores/actions.js b/app/assets/javascripts/registry/stores/actions.js index 6c0286e2be6..5dda16b8d9a 100644 --- a/app/assets/javascripts/registry/stores/actions.js +++ b/app/assets/javascripts/registry/stores/actions.js @@ -16,13 +16,13 @@ export const fetchRepos = ({ commit, state }) => { }; export const fetchList = ({ commit }, list) => { - commit(types.TOGGLE_IMAGE_LOADING, list); + commit(types.TOGGLE_REGISTRY_LIST_LOADING, list); return Vue.http.get(list.path) .then(res => res.json()) .then((response) => { - commit(types.TOGGLE_IMAGE_LOADING, list); - commit(types.SET_IMAGES_LIST, list, response); + commit(types.TOGGLE_REGISTRY_LIST_LOADING, list); + commit(types.SET_REGISTRY_LIST, list, response); }); }; @@ -32,8 +32,11 @@ export const deleteRepo = ({ commit }, repo) => Vue.http.delete(repo.path) commit(types.DELETE_REPO, repo); }); -export const deleteImage = ({ commit }, image) => Vue.http.delete(image.path) +export const deleteRegistry = ({ commit }, image) => Vue.http.delete(image.path) .then(res => res.json()) .then(() => { commit(types.DELETE_IMAGE, image); }); + +export const setMainEndpoint = ({ commit }, data) => commit(types.SET_MAIN_ENDPOINT, data); +export const toggleIsLoading = ({ commit }) => commit(types.TOGGLE_MAIN_LOADING); diff --git a/app/assets/javascripts/registry/stores/getters.js b/app/assets/javascripts/registry/stores/getters.js new file mode 100644 index 00000000000..6c6ed0cd738 --- /dev/null +++ b/app/assets/javascripts/registry/stores/getters.js @@ -0,0 +1,2 @@ +export const isLoading = state => state.isLoading; +export const repos = state => state.repos; \ No newline at end of file diff --git a/app/assets/javascripts/registry/stores/index.js b/app/assets/javascripts/registry/stores/index.js index 6cf9df57f08..78b67881210 100644 --- a/app/assets/javascripts/registry/stores/index.js +++ b/app/assets/javascripts/registry/stores/index.js @@ -1,6 +1,7 @@ import Vue from 'vue'; import Vuex from 'vuex'; -import actions from './actions'; +import * as actions from './actions'; +import * as getters from './getters'; import mutations from './mutations'; Vue.use(Vuex); @@ -31,7 +32,8 @@ export default new Vuex.Store({ * } */ repos: [], - actions, - mutations, }, + actions, + getters, + mutations, }); diff --git a/app/assets/javascripts/registry/stores/mutation_types.js b/app/assets/javascripts/registry/stores/mutation_types.js index fb4e24e10e3..aece401a24a 100644 --- a/app/assets/javascripts/registry/stores/mutation_types.js +++ b/app/assets/javascripts/registry/stores/mutation_types.js @@ -1,9 +1,10 @@ +export const SET_MAIN_ENDPOINT = 'SET_MAIN_ENDPOINT'; export const FETCH_REPOS_LIST = 'FETCH_REPOS_LIST'; export const DELETE_REPO = 'DELETE_REPO'; export const SET_REPOS_LIST = 'SET_REPOS_LIST'; export const TOGGLE_MAIN_LOADING = 'TOGGLE_MAIN_LOADING'; export const FETCH_IMAGES_LIST = 'FETCH_IMAGES_LIST'; -export const SET_IMAGES_LIST = 'SET_IMAGES_LIST'; +export const SET_REGISTRY_LIST = 'SET_REGISTRY_LIST'; export const DELETE_IMAGE = 'DELETE_IMAGE'; -export const TOGGLE_IMAGE_LOADING = 'TOGGLE_MAIN_LOADING'; +export const TOGGLE_REGISTRY_LIST_LOADING = 'TOGGLE_REGISTRY_LIST_LOADING'; diff --git a/app/assets/javascripts/registry/stores/mutations.js b/app/assets/javascripts/registry/stores/mutations.js index 5fa41fb5255..796548bffec 100644 --- a/app/assets/javascripts/registry/stores/mutations.js +++ b/app/assets/javascripts/registry/stores/mutations.js @@ -1,14 +1,22 @@ import * as types from './mutation_types'; export default { + + [types.SET_MAIN_ENDPOINT](state, endpoint) { + Object.assign(state, { endpoint }); + }, + [types.SET_REPOS_LIST](state, list) { Object.assign(state, { repos: list.map(el => ({ - name: el.name, - isLoading: false, canDelete: !!el.destroy_path, destroyPath: el.destroy_path, + isLoading: false, list: [], + location: el.location, + name: el.name, + tagsPath: el.tags_path, + id: el.id, })), }); }, @@ -17,8 +25,29 @@ export default { Object.assign(state, { isLoading: !state.isLoading }); }, - [types.SET_IMAGES_LIST](state, image, list) { - const listToUpdate = state.repos.find(el => el.name === image.name); + [types.SET_REGISTRY_LIST](state, repo, list) { + // mock + list = [ + { + name: 'centos6', + short_revision: '0b6091a66', + revision: '0b6091a665af68bbbbb36a3e088ec3cd6f35389deebf6d4617042d56722d76fb', + size: 706, + layers: 19, + created_at: 1505828744434, + }, + { + name: 'centos7', + short_revision: 'b118ab5b0', + revision: 'b118ab5b0e90b7cb5127db31d5321ac14961d097516a8e0e72084b6cdc783b43', + size: 679, + layers: 19, + created_at: 1505828744434, + }, + ]; + + const listToUpdate = state.repos.find(el => el.id === repo.id); + listToUpdate.list = list.map(element => ({ tag: element.name, revision: element.revision, @@ -31,8 +60,8 @@ export default { })); }, - [types.TOGGLE_IMAGE_LOADING](state, image) { - const listToUpdate = state.repos.find(el => el.name === image.name); + [types.TOGGLE_REGISTRY_LIST_LOADING](state, list) { + const listToUpdate = state.repos.find(el => el.id === list.id); listToUpdate.isLoading = !listToUpdate.isLoading; }, }; diff --git a/app/assets/javascripts/vue_shared/components/clipboard_button.vue b/app/assets/javascripts/vue_shared/components/clipboard_button.vue index cb9ad4c7dee..fbf7233b13d 100644 --- a/app/assets/javascripts/vue_shared/components/clipboard_button.vue +++ b/app/assets/javascripts/vue_shared/components/clipboard_button.vue @@ -14,11 +14,11 @@ }, }, mounted() { - return new Clipboard(this.$refs.btn, { - text: () => { - return this.text; - }, - }); + // return new Clipboard(this.$refs.btn, { + // text: () => { + // return this.text; + // }, + // }); } }; diff --git a/app/assets/stylesheets/pages/container_registry.scss b/app/assets/stylesheets/pages/container_registry.scss index 3266714396e..089a693efe4 100644 --- a/app/assets/stylesheets/pages/container_registry.scss +++ b/app/assets/stylesheets/pages/container_registry.scss @@ -9,6 +9,10 @@ .container-image-head { padding: 0 16px; line-height: 4em; + + &:hover { + text-decoration: underline; + } } .table.tags { diff --git a/app/controllers/projects/registry/repositories_controller.rb b/app/controllers/projects/registry/repositories_controller.rb index 71e7dc70a4d..89093e4172a 100644 --- a/app/controllers/projects/registry/repositories_controller.rb +++ b/app/controllers/projects/registry/repositories_controller.rb @@ -6,6 +6,37 @@ module Projects def index @images = project.container_repositories + + respond_to do |format| + format.html + format.json do + # render json: @images + render json: [ + { + name: 'gitlab-org/omnibus-gitlab/foo', + tags_path: 'foo', + destroy_path: 'bar', + location: 'foo', + id: '134', + destroy_path: 'bar' + }, + { + name: 'gitlab-org/omnibus-gitlab', + tags_path: 'foo', + destroy_path: 'bar', + location: 'foo', + id: '123', + }, + { + name: 'gitlab-org/omnibus-gitlab/bar', + tags_path: 'foo', + destroy_path: 'bar', + location: 'foo', + id: '973', + } + ] + end + end end def destroy diff --git a/app/views/projects/registry/repositories/index.html.haml b/app/views/projects/registry/repositories/index.html.haml index 5661af01302..ab263091c1f 100644 --- a/app/views/projects/registry/repositories/index.html.haml +++ b/app/views/projects/registry/repositories/index.html.haml @@ -52,9 +52,15 @@ #{escape_once(@project.container_registry_url)}/optional-image-name:tag #{escape_once(@project.container_registry_url)}/optional-name/optional-image-name:tag - - if @images.blank? - %p.settings-message.text-center.append-bottom-default - No container images stored for this project. Add one by following the - instructions above. - - else - = render partial: 'image', collection: @images + #js-vue-registry-images{ data: { endpoint: project_container_registry_index_path(@project, format: :json)}} + + = page_specific_javascript_bundle_tag('common_vue') + = page_specific_javascript_bundle_tag('registry_list') + + + -# - if @images.blank? + -# %p.settings-message.text-center.append-bottom-default + -# No container images stored for this project. Add one by following the + -# instructions above. + -# - else + -# = render partial: 'image', collection: @images diff --git a/config/webpack.config.js b/config/webpack.config.js index 6b0cd023291..4a6c876906b 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -67,6 +67,7 @@ var config = { prometheus_metrics: './prometheus_metrics', protected_branches: './protected_branches', protected_tags: './protected_tags', + registry_list: './registry/index.js', repo: './repo/index.js', sidebar: './sidebar/sidebar_bundle.js', schedule_form: './pipeline_schedules/pipeline_schedule_form_bundle.js', @@ -199,6 +200,7 @@ var config = { 'pdf_viewer', 'pipelines', 'pipelines_details', + 'registry_list', 'repo', 'schedule_form', 'schedules_index', -- cgit v1.2.1 From 6c63520ef5735e56749c77b495f8137a20942504 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Tue, 19 Sep 2017 17:53:57 +0100 Subject: Removes 2 column layout. Adds i18n support --- .../projects/registry/repositories/index.html.haml | 102 ++++++++++----------- 1 file changed, 47 insertions(+), 55 deletions(-) diff --git a/app/views/projects/registry/repositories/index.html.haml b/app/views/projects/registry/repositories/index.html.haml index ab263091c1f..4a76431494c 100644 --- a/app/views/projects/registry/repositories/index.html.haml +++ b/app/views/projects/registry/repositories/index.html.haml @@ -1,66 +1,58 @@ - page_title "Container Registry" -.row.prepend-top-default.append-bottom-default - .col-lg-3 - %h4.prepend-top-0 +%section + .settings-header + %h4 = page_title %p - With the Docker Container Registry integrated into GitLab, every project - can have its own space to store its Docker images. + = _('With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images.') %p.append-bottom-0 = succeed '.' do Learn more about - = link_to 'Container Registry', help_page_path('user/project/container_registry'), target: '_blank' + = link_to _('Container Registry'), help_page_path('user/project/container_registry'), target: '_blank' + .row + .col-lg-12 + .panel.panel-default + .panel-heading + %h4.panel-title + = _('How to use the Container Registry') + .panel-body + %p + = _('First log in to GitLab’s Container Registry using your GitLab username and password. If you have') + = link_to _('2FA enabled'), help_page_path('user/profile/account/two_factor_authentication'), target: '_blank' + you need to use a + = succeed ':' do + = link_to _('personal access token'), help_page_path('user/profile/account/two_factor_authentication', anchor: 'personal-access-tokens'), target: '_blank' + %pre + docker login #{Gitlab.config.registry.host_port} + %br + %p + = _("Once you log in, you’re free to create and upload a container image using the common") + %code + = _('build') + = _('and') + %code push + = _('commands:') + %pre + :plain + docker build -t #{escape_once(@project.container_registry_url)} . + docker push #{escape_once(@project.container_registry_url)} - .col-lg-9 - .panel.panel-default - .panel-heading - %h4.panel-title - How to use the Container Registry - .panel-body - %p - First log in to GitLab’s Container Registry using your GitLab username - and password. If you have - = link_to '2FA enabled', help_page_path('user/profile/account/two_factor_authentication'), target: '_blank' - you need to use a - = succeed ':' do - = link_to 'personal access token', help_page_path('user/profile/account/two_factor_authentication', anchor: 'personal-access-tokens'), target: '_blank' - %pre - docker login #{Gitlab.config.registry.host_port} - %br - %p - Once you log in, you’re free to create and upload a container image - using the common - %code build - and - %code push - commands: - %pre - :plain - docker build -t #{escape_once(@project.container_registry_url)} . - docker push #{escape_once(@project.container_registry_url)} + %hr + %h5.prepend-top-default + = _('Use different image names') + %p.light + = _('GitLab supports up to 3 levels of image names. The following examples of images are valid for your project:') + %pre + :plain + #{escape_once(@project.container_registry_url)}:tag + #{escape_once(@project.container_registry_url)}/optional-image-name:tag + #{escape_once(@project.container_registry_url)}/optional-name/optional-image-name:tag - %hr - %h5.prepend-top-default - Use different image names - %p.light - GitLab supports up to 3 levels of image names. The following - examples of images are valid for your project: - %pre - :plain - #{escape_once(@project.container_registry_url)}:tag - #{escape_once(@project.container_registry_url)}/optional-image-name:tag - #{escape_once(@project.container_registry_url)}/optional-name/optional-image-name:tag - #js-vue-registry-images{ data: { endpoint: project_container_registry_index_path(@project, format: :json)}} + .row + .col-lg-12 + #js-vue-registry-images{ data: { endpoint: project_container_registry_index_path(@project, format: :json)}} - = page_specific_javascript_bundle_tag('common_vue') - = page_specific_javascript_bundle_tag('registry_list') - - - -# - if @images.blank? - -# %p.settings-message.text-center.append-bottom-default - -# No container images stored for this project. Add one by following the - -# instructions above. - -# - else - -# = render partial: 'image', collection: @images + = page_specific_javascript_bundle_tag('common_vue') + = page_specific_javascript_bundle_tag('registry_list') -- cgit v1.2.1 From ee3cf5d6f3d5a3631fa7e94a242f2dfe9b38a935 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Wed, 20 Sep 2017 19:03:53 +0100 Subject: [ci skip] Adds tests to vuex and collapsibe component Formats dates Fixes clipboard button Simplifies HTML --- app/assets/javascripts/registry/components/app.vue | 4 +- .../registry/components/collapsible_container.vue | 69 ++++++++----- app/assets/javascripts/registry/index.js | 3 - app/assets/javascripts/registry/stores/actions.js | 12 +-- app/assets/javascripts/registry/stores/getters.js | 2 +- .../javascripts/registry/stores/mutation_types.js | 5 +- .../javascripts/registry/stores/mutations.js | 23 +---- .../vue_shared/components/clipboard_button.vue | 15 +-- .../stylesheets/pages/container_registry.scss | 4 - .../projects/registry/repositories_controller.rb | 28 ++++-- .../projects/registry/repositories/index.html.haml | 9 +- spec/javascripts/helpers/vuex_action_helper.js | 37 +++++++ spec/javascripts/notes/stores/actions_spec.js | 2 +- spec/javascripts/notes/stores/helpers.js | 37 ------- spec/javascripts/registry/components/app_spec.js | 0 .../components/collapsible_container_spec.js | 112 +++++++++++++++++++++ spec/javascripts/registry/stores/actions_spec.js | 85 ++++++++++++++++ spec/javascripts/registry/stores/getters_spec.js | 43 ++++++++ spec/javascripts/registry/stores/mock_data.js | 91 +++++++++++++++++ spec/javascripts/registry/stores/mutations_spec.js | 57 +++++++++++ 20 files changed, 506 insertions(+), 132 deletions(-) create mode 100644 spec/javascripts/helpers/vuex_action_helper.js delete mode 100644 spec/javascripts/notes/stores/helpers.js create mode 100644 spec/javascripts/registry/components/app_spec.js create mode 100644 spec/javascripts/registry/components/collapsible_container_spec.js create mode 100644 spec/javascripts/registry/stores/actions_spec.js create mode 100644 spec/javascripts/registry/stores/getters_spec.js create mode 100644 spec/javascripts/registry/stores/mock_data.js create mode 100644 spec/javascripts/registry/stores/mutations_spec.js diff --git a/app/assets/javascripts/registry/components/app.vue b/app/assets/javascripts/registry/components/app.vue index 17a57ae248d..c4d66382850 100644 --- a/app/assets/javascripts/registry/components/app.vue +++ b/app/assets/javascripts/registry/components/app.vue @@ -33,7 +33,7 @@ 'fetchList', 'deleteRepo', 'deleteRegistry', - 'toggleIsLoading', + 'toggleLoading', ]), fetchRegistryList(repo) { @@ -49,7 +49,7 @@ deleteRepository(repo) { this.deleteRepo(repo) - .then(() => this.fetchRepo()) + .then(() => this.fetchRepos()) .catch(() => this.showError(errorMessagesTypes.DELETE_REPO)); }, diff --git a/app/assets/javascripts/registry/components/collapsible_container.vue b/app/assets/javascripts/registry/components/collapsible_container.vue index 6be2aa60ebd..739e48b93f2 100644 --- a/app/assets/javascripts/registry/components/collapsible_container.vue +++ b/app/assets/javascripts/registry/components/collapsible_container.vue @@ -2,6 +2,7 @@ import clipboardButton from '../../vue_shared/components/clipboard_button.vue'; import loadingIcon from '../../vue_shared/components/loading_icon.vue'; import tooltip from '../../vue_shared/directives/tooltip'; + import timeagoMixin from '../../vue_shared/mixins/timeago'; export default { name: 'collapsibeContainerRegisty', @@ -15,6 +16,9 @@ clipboardButton, loadingIcon, }, + mixins: [ + timeagoMixin, + ], directives: { tooltip, }, @@ -28,16 +32,18 @@ const pluralize = gl.text.pluralize('layer', item.layers); return `${item.layers} ${pluralize}`; }, + toggleRepo() { if (this.isOpen === false) { - // consider not fetching data the second time it is toggled? :fry: this.$emit('fetchRegistryList', this.repo); } this.isOpen = !this.isOpen; }, + handleDeleteRepository() { this.$emit('deleteRepository', this.repo) }, + handleDeleteRegistry(registry) { this.$emit('deleteRegistry', this.repo, registry); }, @@ -51,7 +57,8 @@ class="container-image-head"> + @click="toggleRepo" + class="js-toggle-repo"> +