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'; + + + +