diff options
Diffstat (limited to 'app/assets/javascripts/packages_and_registries/package_registry')
11 files changed, 341 insertions, 144 deletions
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue index 3d3fa62fd43..bcbeec72961 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue @@ -23,6 +23,7 @@ import PackageFiles from '~/packages_and_registries/package_registry/components/ import PackageHistory from '~/packages_and_registries/package_registry/components/details/package_history.vue'; import PackageTitle from '~/packages_and_registries/package_registry/components/details/package_title.vue'; import VersionRow from '~/packages_and_registries/package_registry/components/details/version_row.vue'; +import DeletePackage from '~/packages_and_registries/package_registry/components/functional/delete_package.vue'; import { PACKAGE_TYPE_NUGET, PACKAGE_TYPE_COMPOSER, @@ -35,12 +36,10 @@ import { CANCEL_DELETE_PACKAGE_FILE_TRACKING_ACTION, SHOW_DELETE_SUCCESS_ALERT, FETCH_PACKAGE_DETAILS_ERROR_MESSAGE, - DELETE_PACKAGE_ERROR_MESSAGE, DELETE_PACKAGE_FILE_ERROR_MESSAGE, DELETE_PACKAGE_FILE_SUCCESS_MESSAGE, } from '~/packages_and_registries/package_registry/constants'; -import destroyPackageMutation from '~/packages_and_registries/package_registry/graphql/mutations/destroy_package.mutation.graphql'; import destroyPackageFileMutation from '~/packages_and_registries/package_registry/graphql/mutations/destroy_package_file.mutation.graphql'; import getPackageDetails from '~/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql'; import Tracking from '~/tracking'; @@ -62,6 +61,7 @@ export default { AdditionalMetadata, InstallationCommands, PackageFiles, + DeletePackage, }, directives: { GlTooltip: GlTooltipDirective, @@ -148,40 +148,15 @@ export default { formatSize(size) { return numberToHumanSize(size); }, - async deletePackage() { - const { data } = await this.$apollo.mutate({ - mutation: destroyPackageMutation, - variables: { - id: this.packageEntity.id, - }, - }); + navigateToListWithSuccessModal() { + const returnTo = + !this.groupListUrl || document.referrer.includes(this.projectName) + ? this.projectListUrl + : this.groupListUrl; // to avoid security issue url are supplied from backend - if (data?.destroyPackage?.errors[0]) { - throw data.destroyPackage.errors[0]; - } - }, - async confirmPackageDeletion() { - this.track(DELETE_PACKAGE_TRACKING_ACTION); - - try { - await this.deletePackage(); - - const returnTo = - !this.groupListUrl || document.referrer.includes(this.projectName) - ? this.projectListUrl - : this.groupListUrl; // to avoid security issue url are supplied from backend - - const modalQuery = objectToQuery({ [SHOW_DELETE_SUCCESS_ALERT]: true }); + const modalQuery = objectToQuery({ [SHOW_DELETE_SUCCESS_ALERT]: true }); - window.location.replace(`${returnTo}?${modalQuery}`); - } catch (error) { - createFlash({ - message: DELETE_PACKAGE_ERROR_MESSAGE, - type: 'warning', - captureError: true, - error, - }); - } + window.location.replace(`${returnTo}?${modalQuery}`); }, async deletePackageFile(id) { try { @@ -322,26 +297,33 @@ export default { </gl-tab> </gl-tabs> - <gl-modal - ref="deleteModal" - modal-id="delete-modal" - data-testid="delete-modal" - :action-primary="$options.modal.packageDeletePrimaryAction" - :action-cancel="$options.modal.cancelAction" - @primary="confirmPackageDeletion" - @canceled="track($options.trackingActions.CANCEL_DELETE_PACKAGE)" + <delete-package + @start="track($options.trackingActions.DELETE_PACKAGE_TRACKING_ACTION)" + @end="navigateToListWithSuccessModal" > - <template #modal-title>{{ $options.i18n.deleteModalTitle }}</template> - <gl-sprintf :message="$options.i18n.deleteModalContent"> - <template #version> - <strong>{{ packageEntity.version }}</strong> - </template> + <template #default="{ deletePackage }"> + <gl-modal + ref="deleteModal" + modal-id="delete-modal" + data-testid="delete-modal" + :action-primary="$options.modal.packageDeletePrimaryAction" + :action-cancel="$options.modal.cancelAction" + @primary="deletePackage(packageEntity)" + @canceled="track($options.trackingActions.CANCEL_DELETE_PACKAGE)" + > + <template #modal-title>{{ $options.i18n.deleteModalTitle }}</template> + <gl-sprintf :message="$options.i18n.deleteModalContent"> + <template #version> + <strong>{{ packageEntity.version }}</strong> + </template> - <template #name> - <strong>{{ packageEntity.name }}</strong> - </template> - </gl-sprintf> - </gl-modal> + <template #name> + <strong>{{ packageEntity.name }}</strong> + </template> + </gl-sprintf> + </gl-modal> + </template> + </delete-package> <gl-modal ref="deleteFileModal" diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/functional/delete_package.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/functional/delete_package.vue new file mode 100644 index 00000000000..7a85fd3052e --- /dev/null +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/functional/delete_package.vue @@ -0,0 +1,62 @@ +<script> +import destroyPackageMutation from '~/packages_and_registries/package_registry/graphql/mutations/destroy_package.mutation.graphql'; +import createFlash from '~/flash'; +import { s__ } from '~/locale'; + +import { DELETE_PACKAGE_SUCCESS_MESSAGE } from '~/packages_and_registries/package_registry/constants'; + +export default { + props: { + refetchQueries: { + type: Array, + required: false, + default: null, + }, + showSuccessAlert: { + type: Boolean, + required: false, + default: false, + }, + }, + i18n: { + errorMessage: s__('PackageRegistry|Something went wrong while deleting the package.'), + successMessage: DELETE_PACKAGE_SUCCESS_MESSAGE, + }, + methods: { + async deletePackage(packageEntity) { + try { + this.$emit('start'); + const { data } = await this.$apollo.mutate({ + mutation: destroyPackageMutation, + variables: { + id: packageEntity.id, + }, + awaitRefetchQueries: Boolean(this.refetchQueries), + refetchQueries: this.refetchQueries, + }); + + if (data?.destroyPackage?.errors[0]) { + throw data.destroyPackage.errors[0]; + } + if (this.showSuccessAlert) { + createFlash({ + message: this.$options.i18n.successMessage, + type: 'success', + }); + } + } catch (error) { + createFlash({ + message: this.$options.i18n.errorMessage, + type: 'warning', + captureError: true, + error, + }); + } + this.$emit('end'); + }, + }, + render() { + return this.$scopedSlots.default({ deletePackage: this.deletePackage }); + }, +}; +</script> diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/list/app.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/list/app.vue index 08481ac5655..11eeaf933ff 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/list/app.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/list/app.vue @@ -1,33 +1,31 @@ <script> -/* - * The following component has several commented lines, this is because we are refactoring them piece by piece on several mrs - * For a complete overview of the plan please check: https://gitlab.com/gitlab-org/gitlab/-/issues/330846 - * This work is behind feature flag: https://gitlab.com/gitlab-org/gitlab/-/issues/341136 - */ -// import { GlEmptyState, GlLink, GlSprintf } from '@gitlab/ui'; +import { GlEmptyState, GlLink, GlSprintf } from '@gitlab/ui'; import createFlash from '~/flash'; import { historyReplaceState } from '~/lib/utils/common_utils'; import { s__ } from '~/locale'; -import { DELETE_PACKAGE_SUCCESS_MESSAGE } from '~/packages/list/constants'; import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants'; -import getPackagesQuery from '~/packages_and_registries/package_registry/graphql/queries/get_packages.query.graphql'; import { PROJECT_RESOURCE_TYPE, GROUP_RESOURCE_TYPE, - LIST_QUERY_DEBOUNCE_TIME, + GRAPHQL_PAGE_SIZE, + DELETE_PACKAGE_SUCCESS_MESSAGE, } from '~/packages_and_registries/package_registry/constants'; +import getPackagesQuery from '~/packages_and_registries/package_registry/graphql/queries/get_packages.query.graphql'; + +import DeletePackage from '~/packages_and_registries/package_registry/components/functional/delete_package.vue'; import PackageTitle from './package_title.vue'; import PackageSearch from './package_search.vue'; -// import PackageList from './packages_list.vue'; +import PackageList from './packages_list.vue'; export default { components: { - // GlEmptyState, - // GlLink, - // GlSprintf, - // PackageList, + GlEmptyState, + GlLink, + GlSprintf, + PackageList, PackageTitle, PackageSearch, + DeletePackage, }, inject: [ 'packageHelpUrl', @@ -41,6 +39,7 @@ export default { packages: {}, sort: '', filters: {}, + mutationLoading: false, }; }, apollo: { @@ -52,7 +51,9 @@ export default { update(data) { return data[this.graphqlResource].packages; }, - debounce: LIST_QUERY_DEBOUNCE_TIME, + skip() { + return !this.sort; + }, }, }, computed: { @@ -64,22 +65,40 @@ export default { groupSort: this.isGroupPage ? this.sort : undefined, packageName: this.filters?.packageName, packageType: this.filters?.packageType, + first: GRAPHQL_PAGE_SIZE, }; }, graphqlResource() { return this.isGroupPage ? GROUP_RESOURCE_TYPE : PROJECT_RESOURCE_TYPE; }, + pageInfo() { + return this.packages?.pageInfo ?? {}; + }, packagesCount() { return this.packages?.count; }, hasFilters() { return this.filters.packageName && this.filters.packageType; }, + emptySearch() { + return !this.filters.packageName && !this.filters.packageType; + }, emptyStateTitle() { return this.emptySearch ? this.$options.i18n.emptyPageTitle : this.$options.i18n.noResultsTitle; }, + isLoading() { + return this.$apollo.queries.packages.loading || this.mutationLoading; + }, + refetchQueriesData() { + return [ + { + query: getPackagesQuery, + variables: this.queryVariables, + }, + ]; + }, }, mounted() { this.checkDeleteAlert(); @@ -99,6 +118,35 @@ export default { this.sort = sort; this.filters = { ...filters }; }, + updateQuery(_, { fetchMoreResult }) { + return fetchMoreResult; + }, + fetchNextPage() { + const variables = { + ...this.queryVariables, + first: GRAPHQL_PAGE_SIZE, + last: null, + after: this.pageInfo?.endCursor, + }; + + this.$apollo.queries.packages.fetchMore({ + variables, + updateQuery: this.updateQuery, + }); + }, + fetchPreviousPage() { + const variables = { + ...this.queryVariables, + first: null, + last: GRAPHQL_PAGE_SIZE, + before: this.pageInfo?.startCursor, + }; + + this.$apollo.queries.packages.fetchMore({ + variables, + updateQuery: this.updateQuery, + }); + }, }, i18n: { widenFilters: s__('PackageRegistry|To widen your search, change or remove the filters above.'), @@ -116,19 +164,35 @@ export default { <package-title :help-url="packageHelpUrl" :count="packagesCount" /> <package-search @update="handleSearchUpdate" /> - <!-- <package-list @page:changed="onPageChanged" @package:delete="onPackageDeleteRequest"> - <template #empty-state> - <gl-empty-state :title="emptyStateTitle" :svg-path="emptyListIllustration"> - <template #description> - <gl-sprintf v-if="hasFilters" :message="$options.i18n.widenFilters" /> - <gl-sprintf v-else :message="$options.i18n.noResultsText"> - <template #noPackagesLink="{ content }"> - <gl-link :href="emptyListHelpUrl" target="_blank">{{ content }}</gl-link> + <delete-package + :refetch-queries="refetchQueriesData" + show-success-alert + @start="mutationLoading = true" + @end="mutationLoading = false" + > + <template #default="{ deletePackage }"> + <package-list + :list="packages.nodes" + :is-loading="isLoading" + :page-info="pageInfo" + @prev-page="fetchPreviousPage" + @next-page="fetchNextPage" + @package:delete="deletePackage" + > + <template #empty-state> + <gl-empty-state :title="emptyStateTitle" :svg-path="emptyListIllustration"> + <template #description> + <gl-sprintf v-if="hasFilters" :message="$options.i18n.widenFilters" /> + <gl-sprintf v-else :message="$options.i18n.noResultsText"> + <template #noPackagesLink="{ content }"> + <gl-link :href="emptyListHelpUrl" target="_blank">{{ content }}</gl-link> + </template> + </gl-sprintf> </template> - </gl-sprintf> + </gl-empty-state> </template> - </gl-empty-state> + </package-list> </template> - </package-list> --> + </delete-package> </div> </template> diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_search.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_search.vue index 836df59ca58..3483d23e251 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_search.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_search.vue @@ -1,6 +1,6 @@ <script> import { s__ } from '~/locale'; -import { sortableFields } from '~/packages/list/utils'; +import { sortableFields } from '~/packages_and_registries/package_registry/utils'; import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants'; import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue'; import UrlSync from '~/vue_shared/components/url_sync.vue'; diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_title.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_title.vue index 6e00a48586e..bf41c36e09b 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_title.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_title.vue @@ -1,6 +1,5 @@ <script> -import { n__ } from '~/locale'; -import { LIST_INTRO_TEXT, LIST_TITLE_TEXT } from '~/packages/list/constants'; +import { n__, s__ } from '~/locale'; import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue'; import TitleArea from '~/vue_shared/components/registry/title_area.vue'; @@ -29,11 +28,14 @@ export default { return n__(`%d Package`, `%d Packages`, this.count); }, infoMessages() { - return [{ text: LIST_INTRO_TEXT, link: this.helpUrl }]; + return [{ text: this.$options.i18n.LIST_INTRO_TEXT, link: this.helpUrl }]; }, }, i18n: { - LIST_TITLE_TEXT, + LIST_TITLE_TEXT: s__('PackageRegistry|Package Registry'), + LIST_INTRO_TEXT: s__( + 'PackageRegistry|Publish and share packages for a variety of common package managers. %{docLinkStart}More information%{docLinkEnd}', + ), }, }; </script> 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 25bac687dbf..2a946544c2f 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,82 +1,94 @@ <script> -import { GlPagination, GlModal, GlSprintf } from '@gitlab/ui'; -import { mapState, mapGetters } from 'vuex'; +import { GlModal, GlSprintf, GlKeysetPagination } from '@gitlab/ui'; import { s__ } from '~/locale'; -import PackagesListRow from '~/packages/shared/components/package_list_row.vue'; +import PackagesListRow from '~/packages_and_registries/package_registry/components/list/package_list_row.vue'; import PackagesListLoader from '~/packages/shared/components/packages_list_loader.vue'; -import { TrackingActions } from '~/packages/shared/constants'; -import { packageTypeToTrackCategory } from '~/packages/shared/utils'; +import { + DELETE_PACKAGE_TRACKING_ACTION, + REQUEST_DELETE_PACKAGE_TRACKING_ACTION, + CANCEL_DELETE_PACKAGE_TRACKING_ACTION, +} from '~/packages_and_registries/package_registry/constants'; +import { packageTypeToTrackCategory } from '~/packages_and_registries/package_registry/utils'; import Tracking from '~/tracking'; export default { components: { - GlPagination, + GlKeysetPagination, GlModal, GlSprintf, PackagesListLoader, PackagesListRow, }, mixins: [Tracking.mixin()], + props: { + list: { + type: Array, + required: false, + default: () => [], + }, + isLoading: { + type: Boolean, + required: false, + default: false, + }, + pageInfo: { + type: Object, + required: true, + }, + }, + data() { return { itemToBeDeleted: null, }; }, computed: { - ...mapState({ - perPage: (state) => state.pagination.perPage, - totalItems: (state) => state.pagination.total, - page: (state) => state.pagination.page, - isGroupPage: (state) => state.config.isGroupPage, - isLoading: 'isLoading', - }), - ...mapGetters({ list: 'getList' }), - currentPage: { - get() { - return this.page; - }, - set(value) { - this.$emit('page:changed', value); - }, - }, isListEmpty() { return !this.list || this.list.length === 0; }, - modalAction() { - return s__('PackageRegistry|Delete package'); - }, deletePackageName() { return this.itemToBeDeleted?.name ?? ''; }, tracking() { const category = this.itemToBeDeleted - ? packageTypeToTrackCategory(this.itemToBeDeleted.package_type) + ? packageTypeToTrackCategory(this.itemToBeDeleted.packageType) : undefined; return { category, }; }, + showPagination() { + return this.pageInfo.hasPreviousPage || this.pageInfo.hasNextPage; + }, + showDeleteModal: { + get() { + return Boolean(this.itemToBeDeleted); + }, + set(value) { + if (!value) { + this.itemToBeDeleted = null; + } + }, + }, }, methods: { setItemToBeDeleted(item) { this.itemToBeDeleted = { ...item }; - this.track(TrackingActions.REQUEST_DELETE_PACKAGE); - this.$refs.packageListDeleteModal.show(); + this.track(REQUEST_DELETE_PACKAGE_TRACKING_ACTION); }, deleteItemConfirmation() { this.$emit('package:delete', this.itemToBeDeleted); - this.track(TrackingActions.DELETE_PACKAGE); - this.itemToBeDeleted = null; + this.track(DELETE_PACKAGE_TRACKING_ACTION); }, deleteItemCanceled() { - this.track(TrackingActions.CANCEL_DELETE_PACKAGE); - this.itemToBeDeleted = null; + this.track(CANCEL_DELETE_PACKAGE_TRACKING_ACTION); }, }, i18n: { deleteModalContent: s__( 'PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?', ), + modalAction: s__('PackageRegistry|Delete package'), }, }; </script> @@ -95,29 +107,29 @@ export default { v-for="packageEntity in list" :key="packageEntity.id" :package-entity="packageEntity" - :package-link="packageEntity._links.web_path" - :is-group="isGroupPage" @packageToDelete="setItemToBeDeleted" /> </div> - <gl-pagination - v-model="currentPage" - :per-page="perPage" - :total-items="totalItems" - align="center" - class="gl-w-full gl-mt-3" - /> + <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> <gl-modal - ref="packageListDeleteModal" + v-model="showDeleteModal" modal-id="confirm-delete-pacakge" ok-variant="danger" @ok="deleteItemConfirmation" @cancel="deleteItemCanceled" > - <template #modal-title>{{ modalAction }}</template> - <template #modal-ok>{{ modalAction }}</template> + <template #modal-title>{{ $options.i18n.modalAction }}</template> + <template #modal-ok>{{ $options.i18n.modalAction }}</template> <gl-sprintf :message="$options.i18n.deleteModalContent"> <template #name> <strong>{{ deletePackageName }}</strong> diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/list/tokens/package_type_token.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/list/tokens/package_type_token.vue index 529a7893dfc..59354e77ee9 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/list/tokens/package_type_token.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/list/tokens/package_type_token.vue @@ -1,6 +1,6 @@ <script> import { GlFilteredSearchToken, GlFilteredSearchSuggestion } from '@gitlab/ui'; -import { PACKAGE_TYPES } from '~/packages/list/constants'; +import { PACKAGE_TYPES } from '~/packages_and_registries/package_registry/constants'; export default { components: { @@ -17,9 +17,9 @@ export default { <gl-filtered-search-suggestion v-for="(type, index) in $options.PACKAGE_TYPES" :key="index" - :value="type.type" + :value="type" > - {{ type.title }} + {{ type }} </gl-filtered-search-suggestion> </template> </gl-filtered-search-token> diff --git a/app/assets/javascripts/packages_and_registries/package_registry/constants.js b/app/assets/javascripts/packages_and_registries/package_registry/constants.js index 6a88880fa90..9fd8880861c 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/constants.js +++ b/app/assets/javascripts/packages_and_registries/package_registry/constants.js @@ -1,4 +1,4 @@ -import { s__ } from '~/locale'; +import { s__, __ } from '~/locale'; export const PACKAGE_TYPE_CONAN = 'CONAN'; export const PACKAGE_TYPE_MAVEN = 'MAVEN'; @@ -59,16 +59,7 @@ export const TRACKING_ACTION_COPY_COMPOSER_REGISTRY_INCLUDE_COMMAND = export const TRACKING_ACTION_COPY_COMPOSER_PACKAGE_INCLUDE_COMMAND = 'copy_composer_package_include_command'; -export const TrackingCategories = { - [PACKAGE_TYPE_MAVEN]: 'MavenPackages', - [PACKAGE_TYPE_NPM]: 'NpmPackages', - [PACKAGE_TYPE_CONAN]: 'ConanPackages', -}; - export const SHOW_DELETE_SUCCESS_ALERT = 'showSuccessDeleteAlert'; -export const DELETE_PACKAGE_ERROR_MESSAGE = s__( - 'PackageRegistry|Something went wrong while deleting the package.', -); export const DELETE_PACKAGE_FILE_ERROR_MESSAGE = s__( 'PackageRegistry|Something went wrong while deleting the package file.', ); @@ -79,6 +70,8 @@ export const FETCH_PACKAGE_DETAILS_ERROR_MESSAGE = s__( 'PackageRegistry|Failed to load the package data', ); +export const DELETE_PACKAGE_SUCCESS_MESSAGE = s__('PackageRegistry|Package deleted successfully'); + export const PACKAGE_ERROR_STATUS = 'ERROR'; export const PACKAGE_DEFAULT_STATUS = 'DEFAULT'; export const PACKAGE_HIDDEN_STATUS = 'HIDDEN'; @@ -92,4 +85,52 @@ export const INSTANCE_PACKAGE_ENDPOINT_TYPE = 'instance'; export const PROJECT_RESOURCE_TYPE = 'project'; export const GROUP_RESOURCE_TYPE = 'group'; -export const LIST_QUERY_DEBOUNCE_TIME = 50; +export const GRAPHQL_PAGE_SIZE = 20; + +export const LIST_KEY_NAME = 'name'; +export const LIST_KEY_PROJECT = 'project_path'; +export const LIST_KEY_VERSION = 'version'; +export const LIST_KEY_PACKAGE_TYPE = 'type'; +export const LIST_KEY_CREATED_AT = 'created_at'; + +export const LIST_LABEL_NAME = __('Name'); +export const LIST_LABEL_PROJECT = __('Project'); +export const LIST_LABEL_VERSION = __('Version'); +export const LIST_LABEL_PACKAGE_TYPE = __('Type'); +export const LIST_LABEL_CREATED_AT = __('Published'); + +export const SORT_FIELDS = [ + { + orderBy: LIST_KEY_NAME, + label: LIST_LABEL_NAME, + }, + { + orderBy: LIST_KEY_PROJECT, + label: LIST_LABEL_PROJECT, + }, + { + orderBy: LIST_KEY_VERSION, + label: LIST_LABEL_VERSION, + }, + { + orderBy: LIST_KEY_PACKAGE_TYPE, + label: LIST_LABEL_PACKAGE_TYPE, + }, + { + orderBy: LIST_KEY_CREATED_AT, + label: LIST_LABEL_CREATED_AT, + }, +]; + +export const PACKAGE_TYPES = [ + s__('PackageRegistry|Composer'), + s__('PackageRegistry|Conan'), + s__('PackageRegistry|Generic'), + s__('PackageRegistry|Maven'), + s__('PackageRegistry|npm'), + s__('PackageRegistry|NuGet'), + s__('PackageRegistry|PyPI'), + s__('PackageRegistry|RubyGems'), + s__('PackageRegistry|Debian'), + s__('PackageRegistry|Helm'), +]; diff --git a/app/assets/javascripts/packages_and_registries/package_registry/graphql/index.js b/app/assets/javascripts/packages_and_registries/package_registry/graphql/index.js index f8cb5c516e2..21d6fbc9e1f 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/graphql/index.js +++ b/app/assets/javascripts/packages_and_registries/package_registry/graphql/index.js @@ -17,7 +17,6 @@ export const apolloProvider = new VueApollo({ cacheConfig: { fragmentMatcher, }, - assumeImmutableResults: true, }, ), }); diff --git a/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_packages.query.graphql b/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_packages.query.graphql index 74e6de87866..e3115365f8b 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_packages.query.graphql +++ b/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_packages.query.graphql @@ -1,4 +1,5 @@ #import "~/packages_and_registries/package_registry/graphql/fragments/package_data.fragment.graphql" +#import "~/graphql_shared/fragments/pageInfo.fragment.graphql" query getPackages( $fullPath: ID! @@ -7,21 +8,47 @@ query getPackages( $groupSort: PackageGroupSort $packageName: String $packageType: PackageTypeEnum + $first: Int + $last: Int + $after: String + $before: String ) { project(fullPath: $fullPath) @skip(if: $isGroupPage) { - packages(sort: $sort, packageName: $packageName, packageType: $packageType) { + packages( + sort: $sort + packageName: $packageName + packageType: $packageType + after: $after + before: $before + first: $first + last: $last + ) { count nodes { ...PackageData } + pageInfo { + ...PageInfo + } } } group(fullPath: $fullPath) @include(if: $isGroupPage) { - packages(sort: $groupSort, packageName: $packageName, packageType: $packageType) { + packages( + sort: $groupSort + packageName: $packageName + packageType: $packageType + after: $after + before: $before + first: $first + last: $last + ) { count nodes { ...PackageData } + pageInfo { + ...PageInfo + } } } } diff --git a/app/assets/javascripts/packages_and_registries/package_registry/utils.js b/app/assets/javascripts/packages_and_registries/package_registry/utils.js index ae886952c3e..4ff8edb8f66 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/utils.js +++ b/app/assets/javascripts/packages_and_registries/package_registry/utils.js @@ -1,3 +1,4 @@ +import { capitalize } from 'lodash'; import { s__ } from '~/locale'; import { PACKAGE_TYPE_CONAN, @@ -10,6 +11,8 @@ import { PACKAGE_TYPE_GENERIC, PACKAGE_TYPE_DEBIAN, PACKAGE_TYPE_HELM, + LIST_KEY_PROJECT, + SORT_FIELDS, } from './constants'; export const getPackageTypeLabel = (packageType) => { @@ -38,3 +41,8 @@ export const getPackageTypeLabel = (packageType) => { return null; } }; + +export const packageTypeToTrackCategory = (type) => `UI::${capitalize(type)}Packages`; + +export const sortableFields = (isGroupPage) => + SORT_FIELDS.filter((f) => f.orderBy !== LIST_KEY_PROJECT || isGroupPage); |