diff options
author | Nick Kipling <nkipling@gitlab.com> | 2019-07-26 19:42:49 +0100 |
---|---|---|
committer | Nathan Friend <nathan@gitlab.com> | 2019-07-30 13:49:49 -0300 |
commit | 918e7d43dfe614475ee2dd2b6f4c765726db6ef4 (patch) | |
tree | e76709006133602ecd904827346e21021d8a37da /app/assets/javascripts/registry | |
parent | a37d672ff5c4c102a5b507ad744919748cbdcb34 (diff) | |
download | gitlab-ce-918e7d43dfe614475ee2dd2b6f4c765726db6ef4.tar.gz |
Reworked how deletion works with multi vs single
Single deletion no longer requires a prop
Modal description is now generated on demand
Added dedicated functions for deleting
Updated tests to match new function naming
Updated css class name to be more specific
Diffstat (limited to 'app/assets/javascripts/registry')
-rw-r--r-- | app/assets/javascripts/registry/components/table_registry.vue | 99 | ||||
-rw-r--r-- | app/assets/javascripts/registry/stores/actions.js | 3 |
2 files changed, 54 insertions, 48 deletions
diff --git a/app/assets/javascripts/registry/components/table_registry.vue b/app/assets/javascripts/registry/components/table_registry.vue index 90d6a4ce27f..df665b36c4b 100644 --- a/app/assets/javascripts/registry/components/table_registry.vue +++ b/app/assets/javascripts/registry/components/table_registry.vue @@ -41,6 +41,7 @@ export default { itemsToBeDeleted: [], modalId: `confirm-image-deletion-modal-${this.repo.id}`, selectAllChecked: false, + modalDescription: '', }; }, computed: { @@ -54,67 +55,68 @@ export default { return n__( 'ContainerRegistry|Remove image', 'ContainerRegistry|Remove images', - this.singleItemSelected ? 1 : this.itemsToBeDeleted.length, + this.itemsToBeDeleted.length === 0 ? 1 : this.itemsToBeDeleted.length, ); }, - modalDescription() { - const selectedCount = this.itemsToBeDeleted.length; - - if (this.singleItemSelected) { - // Attempt to pull 'single' property if it's an object in this.itemsToBeDeleted - // Otherwise, simply use the int value of the selected row - const { single: itemIndex = this.itemsToBeDeleted[0] } = this.itemsToBeDeleted[0]; + }, + methods: { + ...mapActions(['fetchList', 'deleteItem', 'multiDeleteItems']), + setModalDescription(itemsToDeleteLength, itemIndex) { + if (itemsToDeleteLength) { + this.modalDescription = sprintf( + s__(`ContainerRegistry|You are about to delete <b>%{count}</b> images. This will + delete the images and all tags pointing to them.`), + { count: itemsToDeleteLength }, + ); + } else { const { tag } = this.repo.list[itemIndex]; - return sprintf( + this.modalDescription = sprintf( s__(`ContainerRegistry|You are about to delete the image <b>%{title}</b>. This will - delete the image and all tags pointing to this image.`), + delete the image and all tags pointing to this image.`), { title: `${this.repo.name}:${tag}` }, ); } - - return sprintf( - s__(`ContainerRegistry|You are about to delete <b>%{count}</b> images. This will - delete the images and all tags pointing to them.`), - { count: selectedCount }, - ); - }, - singleItemSelected() { - return this.findSingleRowToDelete || this.itemsToBeDeleted.length === 1; }, - findSingleRowToDelete() { - return this.itemsToBeDeleted.find(x => x.single !== undefined); - }, - }, - methods: { - ...mapActions(['fetchList', 'deleteItems']), layers(item) { return item.layers ? n__('%d layer', '%d layers', item.layers) : ''; }, formatSize(size) { return numberToHumanSize(size); }, - addSingleItemToBeDeleted(index) { - this.itemsToBeDeleted.push({ single: index }); + removeModalEvents() { + this.$refs.deleteModal.$refs.modal.$off('ok'); + this.$refs.deleteModal.$refs.modal.$off('hide'); }, - removeSingleItemToBeDeleted() { - const singleIndex = this.itemsToBeDeleted.findIndex(x => x.single !== undefined); + deleteSingleItem(index) { + this.setModalDescription(0, index); - if (singleIndex > -1) { - this.itemsToBeDeleted.splice(singleIndex, 1); - } - }, - handleDeleteRegistry() { - let { itemsToBeDeleted } = this; + this.$refs.deleteModal.$refs.modal.$once('ok', () => { + this.removeModalEvents(); + this.handleSingleDelete(this.repo.list[index]); + }); - if (this.findSingleRowToDelete) { - itemsToBeDeleted = [this.findSingleRowToDelete.single]; - } + this.$refs.deleteModal.$refs.modal.$once('hide', this.removeModalEvents); + }, + deleteMultipleItems() { + this.$refs.deleteModal.$refs.modal.$once('ok', () => { + this.removeModalEvents(); + this.handleMultipleDelete(); + }); + this.$refs.deleteModal.$refs.modal.$once('hide', this.removeModalEvents); + }, + handleSingleDelete(itemToDelete) { + this.deleteItem(itemToDelete) + .then(() => this.fetchList({ repo: this.repo })) + .catch(() => this.showError(errorMessagesTypes.DELETE_REGISTRY)); + }, + handleMultipleDelete() { + const { itemsToBeDeleted } = this; this.itemsToBeDeleted = []; if (this.bulkDeletePath) { - this.deleteItems({ + this.multiDeleteItems({ path: this.bulkDeletePath, items: itemsToBeDeleted.map(x => this.repo.list[x].tag), }) @@ -142,6 +144,7 @@ export default { selectAll() { this.itemsToBeDeleted = this.repo.list.map((x, index) => index); this.selectAllChecked = true; + this.setModalDescription(this.itemsToBeDeleted.length); }, deselectAll() { this.itemsToBeDeleted = []; @@ -160,6 +163,12 @@ export default { this.selectAllChecked = true; } } + + if (this.itemsToBeDeleted.length === 1) { + this.setModalDescription(0, this.itemsToBeDeleted[0]); + } else if (this.itemsToBeDeleted.length > 1) { + this.setModalDescription(this.itemsToBeDeleted.length); + } }, }, }; @@ -191,13 +200,14 @@ export default { variant="danger" :title="s__('ContainerRegistry|Remove selected images')" :aria-label="s__('ContainerRegistry|Remove selected images')" + @click="deleteMultipleItems()" ><icon name="remove" /></gl-button> </th> </tr> </thead> <tbody> - <tr v-for="(item, index) in repo.list" :key="item.tag" class="image-row"> + <tr v-for="(item, index) in repo.list" :key="item.tag" class="registry-image-row"> <td class="check"> <gl-form-checkbox v-if="item.canDelete" @@ -242,7 +252,7 @@ export default { :aria-label="s__('ContainerRegistry|Remove image')" variant="danger" class="js-delete-registry-row float-right btn-inverted btn-border-color btn-icon" - @click="addSingleItemToBeDeleted(index)" + @click="deleteSingleItem(index)" > <icon name="remove" /> </gl-button> @@ -257,12 +267,7 @@ export default { :page-info="repo.pagination" /> - <gl-modal - :modal-id="modalId" - ok-variant="danger" - @ok="handleDeleteRegistry" - @cancel="removeSingleItemToBeDeleted" - > + <gl-modal ref="deleteModal" :modal-id="modalId" ok-variant="danger"> <template v-slot:modal-title>{{ modalTitle }}</template> <template v-slot:modal-ok>{{ s__('ContainerRegistry|Remove image(s) and tags') }}</template> <p v-html="modalDescription"></p> diff --git a/app/assets/javascripts/registry/stores/actions.js b/app/assets/javascripts/registry/stores/actions.js index 4c20c003c5a..a2e0130e79e 100644 --- a/app/assets/javascripts/registry/stores/actions.js +++ b/app/assets/javascripts/registry/stores/actions.js @@ -36,7 +36,8 @@ export const fetchList = ({ commit }, { repo, page }) => { }; export const deleteItem = (_, item) => axios.delete(item.destroyPath); -export const deleteItems = (_, { path, items }) => axios.delete(path, { params: { ids: items } }); +export const multiDeleteItems = (_, { path, items }) => + axios.delete(path, { params: { ids: items } }); export const setMainEndpoint = ({ commit }, data) => commit(types.SET_MAIN_ENDPOINT, data); export const toggleLoading = ({ commit }) => commit(types.TOGGLE_MAIN_LOADING); |