diff options
Diffstat (limited to 'app/assets/javascripts/packages_and_registries/package_registry/components')
4 files changed, 180 insertions, 76 deletions
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/delete_modal.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/delete_modal.vue new file mode 100644 index 00000000000..2a1de2ae4a7 --- /dev/null +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/delete_modal.vue @@ -0,0 +1,61 @@ +<script> +import { GlModal } from '@gitlab/ui'; +import { __, n__ } from '~/locale'; +import { + DELETE_PACKAGES_MODAL_TITLE, + DELETE_PACKAGE_MODAL_PRIMARY_ACTION, +} from '~/packages_and_registries/package_registry/constants'; + +export default { + name: 'DeleteModal', + i18n: { + DELETE_PACKAGES_MODAL_TITLE, + }, + components: { + GlModal, + }, + props: { + itemsToBeDeleted: { + type: Array, + required: true, + }, + }, + computed: { + description() { + return n__( + 'PackageRegistry|You are about to delete 1 package. This operation is irreversible.', + `PackageRegistry|You are about to delete %d packages. This operation is irreversible.`, + this.itemsToBeDeleted.length, + ); + }, + }, + modal: { + packagesDeletePrimaryAction: { + text: DELETE_PACKAGE_MODAL_PRIMARY_ACTION, + attributes: [{ variant: 'danger' }, { category: 'primary' }], + }, + cancelAction: { + text: __('Cancel'), + }, + }, + methods: { + show() { + this.$refs.deleteModal.show(); + }, + }, +}; +</script> + +<template> + <gl-modal + ref="deleteModal" + size="sm" + modal-id="delete-packages-modal" + :action-primary="$options.modal.packagesDeletePrimaryAction" + :action-cancel="$options.modal.cancelAction" + :title="$options.i18n.DELETE_PACKAGES_MODAL_TITLE" + @primary="$emit('confirm')" + > + <span>{{ description }}</span> + </gl-modal> +</template> diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_versions_list.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_versions_list.vue new file mode 100644 index 00000000000..efc60c9c037 --- /dev/null +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_versions_list.vue @@ -0,0 +1,57 @@ +<script> +import { GlKeysetPagination } from '@gitlab/ui'; +import VersionRow from '~/packages_and_registries/package_registry/components/details/version_row.vue'; +import PackagesListLoader from '~/packages_and_registries/shared/components/packages_list_loader.vue'; + +export default { + components: { + VersionRow, + GlKeysetPagination, + PackagesListLoader, + }, + props: { + versions: { + type: Array, + required: true, + default: () => [], + }, + pageInfo: { + type: Object, + required: true, + }, + isLoading: { + type: Boolean, + required: false, + default: false, + }, + }, + computed: { + showPagination() { + return this.pageInfo.hasPreviousPage || this.pageInfo.hasNextPage; + }, + isListEmpty() { + return this.versions.length === 0; + }, + }, +}; +</script> +<template> + <div> + <div v-if="isLoading"> + <packages-list-loader /> + </div> + <slot v-else-if="isListEmpty" name="empty-state"></slot> + <div v-else> + <version-row v-for="version in versions" :key="version.id" :package-entity="version" /> + <div class="gl-display-flex gl-justify-content-center"> + <gl-keyset-pagination + v-if="showPagination" + v-bind="pageInfo" + class="gl-mt-3" + @prev="$emit('prev-page')" + @next="$emit('next-page')" + /> + </div> + </div> + </div> +</template> diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_list_row.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_list_row.vue index 7a000aca0f2..4553dd3421b 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_list_row.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_list_row.vue @@ -2,6 +2,7 @@ import { GlDropdown, GlDropdownItem, + GlFormCheckbox, GlIcon, GlSprintf, GlTooltipDirective, @@ -26,6 +27,7 @@ export default { components: { GlDropdown, GlDropdownItem, + GlFormCheckbox, GlIcon, GlSprintf, GlTruncate, @@ -45,6 +47,11 @@ export default { type: Object, required: true, }, + selected: { + type: Boolean, + default: false, + required: false, + }, }, computed: { packageType() { @@ -90,7 +97,15 @@ export default { </script> <template> - <list-item data-testid="package-row"> + <list-item data-testid="package-row" v-bind="$attrs"> + <template #left-action> + <gl-form-checkbox + v-if="packageEntity.canDestroy" + class="gl-m-0" + :checked="selected" + @change="$emit('select')" + /> + </template> <template #left-primary> <div class="gl-display-flex gl-align-items-center gl-mr-3 gl-min-w-0"> <router-link @@ -168,12 +183,9 @@ export default { category="tertiary" no-caret > - <gl-dropdown-item - data-testid="action-delete" - variant="danger" - @click="$emit('packageToDelete', packageEntity)" - >{{ $options.i18n.deletePackage }}</gl-dropdown-item - > + <gl-dropdown-item data-testid="action-delete" variant="danger" @click="$emit('delete')">{{ + $options.i18n.deletePackage + }}</gl-dropdown-item> </gl-dropdown> </template> </list-item> diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/list/packages_list.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/list/packages_list.vue index c6583b8f09f..ddcddf80c15 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/list/packages_list.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/list/packages_list.vue @@ -1,8 +1,10 @@ <script> -import { GlAlert, GlModal, GlSprintf, GlKeysetPagination } from '@gitlab/ui'; -import { __, s__, sprintf } from '~/locale'; +import { GlAlert } from '@gitlab/ui'; +import { s__, sprintf, n__ } from '~/locale'; +import DeletePackageModal from '~/packages_and_registries/shared/components/delete_package_modal.vue'; import PackagesListRow from '~/packages_and_registries/package_registry/components/list/package_list_row.vue'; import PackagesListLoader from '~/packages_and_registries/shared/components/packages_list_loader.vue'; +import RegistryList from '~/packages_and_registries/shared/components/registry_list.vue'; import { DELETE_PACKAGE_TRACKING_ACTION, REQUEST_DELETE_PACKAGE_TRACKING_ACTION, @@ -13,13 +15,13 @@ import { packageTypeToTrackCategory } from '~/packages_and_registries/package_re import Tracking from '~/tracking'; export default { + name: 'PackagesList', components: { GlAlert, - GlKeysetPagination, - GlModal, - GlSprintf, + DeletePackageModal, PackagesListLoader, PackagesListRow, + RegistryList, }, mixins: [Tracking.mixin()], props: { @@ -46,12 +48,12 @@ export default { }; }, computed: { + listTitle() { + return n__('%d package', '%d packages', this.list.length); + }, isListEmpty() { return !this.list || this.list.length === 0; }, - deletePackageName() { - return this.itemToBeDeleted?.name ?? ''; - }, tracking() { const category = this.itemToBeDeleted ? packageTypeToTrackCategory(this.itemToBeDeleted.packageType) @@ -60,32 +62,6 @@ export default { category, }; }, - showPagination() { - return this.pageInfo.hasPreviousPage || this.pageInfo.hasNextPage; - }, - showDeleteModal: { - get() { - return Boolean(this.itemToBeDeleted); - }, - set(value) { - if (!value) { - this.itemToBeDeleted = null; - } - }, - }, - deleteModalActionPrimaryProps() { - return { - text: this.$options.i18n.modalAction, - attributes: { - variant: 'danger', - }, - }; - }, - deleteModalActionCancelProps() { - return { - text: __('Cancel'), - }; - }, errorTitleAlert() { return sprintf( s__('PackageRegistry|There was an error publishing a %{packageName} package'), @@ -110,21 +86,28 @@ export default { this.itemToBeDeleted = { ...item }; this.track(REQUEST_DELETE_PACKAGE_TRACKING_ACTION); }, + setItemsToBeDeleted(items) { + if (items.length === 1) { + const [item] = items; + this.setItemToBeDeleted(item); + return; + } + this.$emit('delete', items); + }, deleteItemConfirmation() { this.$emit('package:delete', this.itemToBeDeleted); this.track(DELETE_PACKAGE_TRACKING_ACTION); + this.itemToBeDeleted = null; }, deleteItemCanceled() { this.track(CANCEL_DELETE_PACKAGE_TRACKING_ACTION); + this.itemToBeDeleted = null; }, showConfirmationModal() { this.setItemToBeDeleted(this.errorPackages[0]); }, }, i18n: { - deleteModalContent: s__('PackageRegistry|You are about to delete %{name}, are you sure?'), - modalTitle: s__('PackageRegistry|Delete package'), - modalAction: s__('PackageRegistry|Permanently delete'), errorMessageBodyAlert: s__( 'PackageRegistry|There was a timeout and the package was not published. Delete this package and try again.', ), @@ -150,41 +133,32 @@ export default { @primaryAction="showConfirmationModal" >{{ $options.i18n.errorMessageBodyAlert }}</gl-alert > - <div data-testid="packages-table"> - <packages-list-row - v-for="packageEntity in list" - :key="packageEntity.id" - :package-entity="packageEntity" - @packageToDelete="setItemToBeDeleted" - /> - </div> - - <div class="gl-display-flex gl-justify-content-center"> - <gl-keyset-pagination - v-if="showPagination" - v-bind="pageInfo" - class="gl-mt-3" - @prev="$emit('prev-page')" - @next="$emit('next-page')" - /> - </div> + <registry-list + data-testid="packages-table" + :is-loading="isLoading" + :items="list" + :pagination="pageInfo" + :title="listTitle" + @delete="setItemsToBeDeleted" + @prev-page="$emit('prev-page')" + @next-page="$emit('next-page')" + > + <template #default="{ selectItem, isSelected, item, first }"> + <packages-list-row + :first="first" + :package-entity="item" + :selected="isSelected(item)" + @delete="setItemToBeDeleted(item)" + @select="selectItem(item)" + /> + </template> + </registry-list> - <gl-modal - v-model="showDeleteModal" - modal-id="confirm-delete-package" - size="sm" - :action-primary="deleteModalActionPrimaryProps" - :action-cancel="deleteModalActionCancelProps" + <delete-package-modal + :item-to-be-deleted="itemToBeDeleted" @ok="deleteItemConfirmation" @cancel="deleteItemCanceled" - > - <template #modal-title>{{ $options.i18n.modalTitle }}</template> - <gl-sprintf :message="$options.i18n.deleteModalContent"> - <template #name> - <strong>{{ deletePackageName }}</strong> - </template> - </gl-sprintf> - </gl-modal> + /> </template> </div> </template> |