Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/packages_and_registries/container_registry/explorer')
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue40
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue53
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue3
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/components/list_page/image_list.vue21
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/components/list_page/image_list_row.vue1
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js1
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue12
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/index.vue1
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue68
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/utils.js24
10 files changed, 109 insertions, 115 deletions
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue
index da88f768c03..75af0286e12 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue
@@ -1,5 +1,10 @@
<script>
-import { GlIcon, GlTooltipDirective, GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import {
+ GlDisclosureDropdown,
+ GlDisclosureDropdownItem,
+ GlIcon,
+ GlTooltipDirective,
+} from '@gitlab/ui';
import { sprintf, n__, s__ } from '~/locale';
import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue';
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
@@ -17,6 +22,8 @@ import {
CLEANUP_ONGOING_TOOLTIP,
CLEANUP_UNFINISHED_TOOLTIP,
CLEANUP_DISABLED_TOOLTIP,
+ DELETE_IMAGE_TEXT,
+ MORE_ACTIONS_TEXT,
UNFINISHED_STATUS,
UNSCHEDULED_STATUS,
SCHEDULED_STATUS,
@@ -29,7 +36,7 @@ import { getImageName } from '../../utils';
export default {
name: 'DetailsHeader',
- components: { GlIcon, TitleArea, MetadataItem, GlDropdown, GlDropdownItem },
+ components: { GlDisclosureDropdown, GlDisclosureDropdownItem, GlIcon, TitleArea, MetadataItem },
directives: {
GlTooltip: GlTooltipDirective,
},
@@ -108,6 +115,10 @@ export default {
return size ? numberToHumanSize(Number(size)) : null;
},
},
+ i18n: {
+ DELETE_IMAGE_TEXT,
+ MORE_ACTIONS_TEXT,
+ },
};
</script>
@@ -152,20 +163,23 @@ export default {
data-testid="created-and-visibility"
/>
</template>
- <template #right-actions>
- <gl-dropdown
- v-if="!deleteButtonDisabled"
- icon="ellipsis_v"
- text="More actions"
- :text-sr-only="true"
+ <template v-if="!deleteButtonDisabled" #right-actions>
+ <gl-disclosure-dropdown
category="tertiary"
+ icon="ellipsis_v"
+ placement="right"
+ :toggle-text="$options.i18n.MORE_ACTIONS_TEXT"
+ text-sr-only
no-caret
- right
>
- <gl-dropdown-item variant="danger" @click="$emit('delete')">
- {{ __('Delete image repository') }}
- </gl-dropdown-item>
- </gl-dropdown>
+ <gl-disclosure-dropdown-item @action="$emit('delete')">
+ <template #list-item>
+ <span class="gl-text-red-500">
+ {{ $options.i18n.DELETE_IMAGE_TEXT }}
+ </span>
+ </template>
+ </gl-disclosure-dropdown-item>
+ </gl-disclosure-dropdown>
</template>
</title-area>
</template>
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue
index 9ea1958a0d1..b58e2249829 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue
@@ -2,9 +2,11 @@
import { GlEmptyState } from '@gitlab/ui';
import { createAlert } from '~/alert';
import { n__ } from '~/locale';
+import { fetchPolicies } from '~/lib/graphql';
import { joinPaths } from '~/lib/utils/url_utility';
import Tracking from '~/tracking';
import RegistryList from '~/packages_and_registries/shared/components/registry_list.vue';
+import PersistedPagination from '~/packages_and_registries/shared/components/persisted_pagination.vue';
import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue';
import TagsLoader from '~/packages_and_registries/shared/components/tags_loader.vue';
import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants';
@@ -26,6 +28,7 @@ import {
import getContainerRepositoryTagsQuery from '../../graphql/queries/get_container_repository_tags.query.graphql';
import deleteContainerRepositoryTagsMutation from '../../graphql/mutations/delete_container_repository_tags.mutation.graphql';
import DeleteModal from '../delete_modal.vue';
+import { getPageParams, getNextPageParams, getPreviousPageParams } from '../../utils';
import TagsListRow from './tags_list_row.vue';
export default {
@@ -36,6 +39,7 @@ export default {
TagsListRow,
TagsLoader,
RegistryList,
+ PersistedPagination,
PersistedSearch,
},
mixins: [Tracking.mixin()],
@@ -61,7 +65,7 @@ export default {
required: false,
},
},
- searchConfig: { NAME_SORT_FIELD },
+ sortableFields: [NAME_SORT_FIELD],
i18n: {
REMOVE_TAGS_BUTTON_TITLE,
TAGS_LIST_TITLE,
@@ -69,6 +73,7 @@ export default {
apollo: {
containerRepository: {
query: getContainerRepositoryTagsQuery,
+ fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
skip() {
return !this.sort;
},
@@ -85,8 +90,9 @@ export default {
containerRepository: {},
filters: {},
itemsToBeDeleted: [],
- mutationLoading: false,
+ isDeleteInProgress: false,
sort: null,
+ pageParams: {},
};
},
computed: {
@@ -108,6 +114,7 @@ export default {
first: GRAPHQL_PAGE_SIZE,
name: this.filters?.name,
sort: this.sort,
+ ...this.pageParams,
};
},
hasNoTags() {
@@ -117,7 +124,7 @@ export default {
return (
this.isImageLoading ||
this.$apollo.queries.containerRepository.loading ||
- this.mutationLoading ||
+ this.isDeleteInProgress ||
!this.sort
);
},
@@ -149,7 +156,7 @@ export default {
async handleDeleteTag() {
this.track('confirm_delete');
const { itemsToBeDeleted } = this;
- this.mutationLoading = true;
+ this.isDeleteInProgress = true;
try {
const { data } = await this.$apollo.mutate({
mutation: deleteContainerRepositoryTagsMutation,
@@ -176,27 +183,17 @@ export default {
} catch (e) {
this.$emit('delete', itemsToBeDeleted.length === 1 ? ALERT_DANGER_TAG : ALERT_DANGER_TAGS);
} finally {
- this.mutationLoading = false;
+ this.isDeleteInProgress = false;
}
},
fetchNextPage() {
- this.$apollo.queries.containerRepository.fetchMore({
- variables: {
- after: this.tagsPageInfo?.endCursor,
- first: GRAPHQL_PAGE_SIZE,
- },
- });
+ this.pageParams = getNextPageParams(this.tagsPageInfo?.endCursor);
},
fetchPreviousPage() {
- this.$apollo.queries.containerRepository.fetchMore({
- variables: {
- first: null,
- before: this.tagsPageInfo?.startCursor,
- last: GRAPHQL_PAGE_SIZE,
- },
- });
+ this.pageParams = getPreviousPageParams(this.tagsPageInfo?.startCursor);
},
- handleSearchUpdate({ sort, filters }) {
+ handleSearchUpdate({ sort, filters, pageInfo }) {
+ this.pageParams = getPageParams(pageInfo);
this.sort = sort;
const parsed = {
@@ -223,10 +220,8 @@ export default {
<div>
<persisted-search
class="gl-mb-5"
- :sortable-fields="/* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ [
- $options.searchConfig.NAME_SORT_FIELD,
- ] /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */"
- :default-order="$options.searchConfig.NAME_SORT_FIELD.orderBy"
+ :sortable-fields="$options.sortableFields"
+ :default-order="$options.sortableFields[0].orderBy"
default-sort="asc"
@update="handleSearchUpdate"
/>
@@ -243,11 +238,8 @@ export default {
<registry-list
:hidden-delete="hideBulkDelete"
:title="listTitle"
- :pagination="tagsPageInfo"
:items="tags"
id-property="name"
- @prev-page="fetchPreviousPage"
- @next-page="fetchNextPage"
@delete="deleteTags"
>
<template #default="{ selectItem, isSelected, item, first }">
@@ -271,5 +263,14 @@ export default {
/>
</template>
</template>
+
+ <div v-if="!isDeleteInProgress" class="gl-display-flex gl-justify-content-center">
+ <persisted-pagination
+ class="gl-mt-3"
+ :pagination="tagsPageInfo"
+ @prev="fetchPreviousPage"
+ @next="fetchNextPage"
+ />
+ </div>
</div>
</template>
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue
index a3f58cc3323..c8a4f32d5a7 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue
@@ -81,7 +81,6 @@ export default {
extraAttrs: {
class: 'gl-text-red-500!',
'data-testid': 'single-delete-button',
- 'data-qa-selector': 'tag_delete_button',
},
action: () => {
this.$emit('delete');
@@ -143,7 +142,6 @@ export default {
<div
v-gl-tooltip="{ title: tag.name }"
data-testid="name"
- data-qa-selector="tag_name_content"
class="gl-text-overflow-ellipsis gl-overflow-hidden gl-white-space-nowrap"
:class="mobileClasses"
>
@@ -201,7 +199,6 @@ export default {
placement="right"
:class="{ 'gl-opacity-0 gl-pointer-events-none': disabled }"
data-testid="additional-actions"
- data-qa-selector="more_actions_menu"
:items="items"
/>
</template>
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/list_page/image_list.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/list_page/image_list.vue
index 6f1f67e251f..ffba64f58f8 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/list_page/image_list.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/list_page/image_list.vue
@@ -1,11 +1,9 @@
<script>
-import { GlKeysetPagination } from '@gitlab/ui';
import ImageListRow from './image_list_row.vue';
export default {
name: 'ImageList',
components: {
- GlKeysetPagination,
ImageListRow,
},
props: {
@@ -18,21 +16,12 @@ export default {
default: false,
required: false,
},
- pageInfo: {
- type: Object,
- required: true,
- },
expirationPolicy: {
type: Object,
default: () => ({}),
required: false,
},
},
- computed: {
- showPagination() {
- return this.pageInfo.hasPreviousPage || this.pageInfo.hasNextPage;
- },
- },
};
</script>
@@ -46,15 +35,5 @@ export default {
:expiration-policy="expirationPolicy"
@delete="$emit('delete', $event)"
/>
- <div class="gl-display-flex gl-justify-content-center">
- <gl-keyset-pagination
- v-if="showPagination"
- :has-next-page="pageInfo.hasNextPage"
- :has-previous-page="pageInfo.hasPreviousPage"
- class="gl-mt-3"
- @prev="$emit('prev-page')"
- @next="$emit('next-page')"
- />
- </div>
</div>
</template>
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/list_page/image_list_row.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/list_page/image_list_row.vue
index f6f816f435c..d7043626446 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/list_page/image_list_row.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/list_page/image_list_row.vue
@@ -133,7 +133,6 @@ export default {
ref="imageName"
class="gl-text-body gl-font-weight-bold"
data-testid="details-link"
- data-qa-selector="registry_image_content"
:to="{ name: 'details', params: { id } }"
>
{{ imageName }}
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js b/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js
index 3a5992d182a..ab848d209db 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js
@@ -93,6 +93,7 @@ export const DETAILS_DELETE_IMAGE_ERROR_MESSAGE = s__(
'ContainerRegistry|Something went wrong while scheduling the image for deletion.',
);
+export const DELETE_IMAGE_TEXT = s__('ContainerRegistry|Delete image repository');
export const DELETE_IMAGE_CONFIRMATION_TITLE = s__('ContainerRegistry|Delete image repository?');
export const DELETE_IMAGE_CONFIRMATION_TEXT = s__(
'ContainerRegistry|Deleting the image repository will delete all images and tags inside. This action cannot be undone. Please type the following to confirm: %{code}',
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue
index 3126af69c2c..c266dbf7e98 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue
@@ -1,11 +1,10 @@
<script>
-import { GlResizeObserverDirective, GlEmptyState } from '@gitlab/ui';
+import { GlResizeObserverDirective, GlEmptyState, GlSkeletonLoader } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
import { createAlert } from '~/alert';
import axios from '~/lib/utils/axios_utils';
import { joinPaths } from '~/lib/utils/url_utility';
import Tracking from '~/tracking';
-import TagsLoader from '~/packages_and_registries/shared/components/tags_loader.vue';
import DeleteImage from '../components/delete_image.vue';
import DeleteAlert from '../components/details_page/delete_alert.vue';
import DeleteModal from '../components/delete_modal.vue';
@@ -28,12 +27,12 @@ export default {
name: 'RegistryDetailsPage',
components: {
GlEmptyState,
+ GlSkeletonLoader,
DeleteAlert,
PartialCleanupAlert,
DetailsHeader,
DeleteModal,
TagsList,
- TagsLoader,
StatusAlert,
DeleteImage,
},
@@ -151,16 +150,17 @@ export default {
<status-alert v-if="containerRepository.status" :status="containerRepository.status" />
+ <div v-if="isLoading" class="gl-my-6">
+ <gl-skeleton-loader />
+ </div>
<details-header
- v-if="!isLoading"
+ v-else
:image="containerRepository"
:disabled="pageActionsAreDisabled"
@delete="deleteImage"
/>
- <tags-loader v-if="isLoading" />
<tags-list
- v-else
:id="$route.params.id"
:is-image-loading="isLoading"
:is-mobile="isMobile"
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/index.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/index.vue
index dca63e1a569..ca0261f1036 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/index.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/index.vue
@@ -1,3 +1,4 @@
+<!-- eslint-disable vue/multi-word-component-names -->
<template>
<div>
<router-view ref="router-view" />
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue
index fe29fa8fdd7..df87ee79111 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue
@@ -12,7 +12,9 @@ import { get } from 'lodash';
import getContainerRepositoriesQuery from 'shared_queries/container_registry/get_container_repositories.query.graphql';
import { createAlert } from '~/alert';
import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
+import { fetchPolicies } from '~/lib/graphql';
import Tracking from '~/tracking';
+import PersistedPagination from '~/packages_and_registries/shared/components/persisted_pagination.vue';
import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue';
import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants';
import DeleteImage from '../components/delete_image.vue';
@@ -32,6 +34,7 @@ import {
SETTINGS_TEXT,
} from '../constants/index';
import getContainerRepositoriesDetails from '../graphql/queries/get_container_repositories_details.query.graphql';
+import { getPageParams, getNextPageParams, getPreviousPageParams } from '../utils';
export default {
name: 'RegistryListPage',
@@ -61,6 +64,7 @@ export default {
GlSkeletonLoader,
RegistryHeader,
DeleteImage,
+ PersistedPagination,
PersistedSearch,
},
directives: {
@@ -87,6 +91,7 @@ export default {
return !this.fetchBaseQuery;
},
query: getContainerRepositoriesQuery,
+ fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
variables() {
return this.queryVariables;
},
@@ -109,6 +114,7 @@ export default {
return !this.fetchAdditionalDetails;
},
query: getContainerRepositoriesDetails,
+ fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
variables() {
return this.queryVariables;
},
@@ -133,6 +139,7 @@ export default {
mutationLoading: false,
fetchBaseQuery: false,
fetchAdditionalDetails: false,
+ pageParams: {},
};
},
computed: {
@@ -158,6 +165,7 @@ export default {
fullPath: this.config.isGroupPage ? this.config.groupPath : this.config.projectPath,
isGroupPage: this.config.isGroupPage,
first: GRAPHQL_PAGE_SIZE,
+ ...this.pageParams,
};
},
tracking() {
@@ -193,54 +201,18 @@ export default {
this.deleteAlertType = null;
this.itemToDelete = {};
},
- updateQuery(_, { fetchMoreResult }) {
- return fetchMoreResult;
+ fetchNextPage() {
+ this.pageParams = getNextPageParams(this.pageInfo?.endCursor);
},
- async fetchNextPage() {
- if (this.pageInfo?.hasNextPage) {
- const variables = {
- after: this.pageInfo?.endCursor,
- first: GRAPHQL_PAGE_SIZE,
- };
-
- this.$apollo.queries.baseImages.fetchMore({
- variables,
- updateQuery: this.updateQuery,
- });
-
- await this.$nextTick();
-
- this.$apollo.queries.additionalDetails.fetchMore({
- variables,
- updateQuery: this.updateQuery,
- });
- }
- },
- async fetchPreviousPage() {
- if (this.pageInfo?.hasPreviousPage) {
- const variables = {
- first: null,
- before: this.pageInfo?.startCursor,
- last: GRAPHQL_PAGE_SIZE,
- };
- this.$apollo.queries.baseImages.fetchMore({
- variables,
- updateQuery: this.updateQuery,
- });
-
- await this.$nextTick();
-
- this.$apollo.queries.additionalDetails.fetchMore({
- variables,
- updateQuery: this.updateQuery,
- });
- }
+ fetchPreviousPage() {
+ this.pageParams = getPreviousPageParams(this.pageInfo?.startCursor);
},
startDelete() {
this.track('confirm_delete');
this.mutationLoading = true;
},
- handleSearchUpdate({ sort, filters }) {
+ handleSearchUpdate({ sort, filters, pageInfo }) {
+ this.pageParams = getPageParams(pageInfo);
this.sorting = sort;
const search = filters.find((i) => i.type === FILTERED_SEARCH_TERM);
@@ -346,11 +318,8 @@ export default {
v-if="images.length"
:images="images"
:metadata-loading="$apollo.queries.additionalDetails.loading"
- :page-info="pageInfo"
:expiration-policy="config.expirationPolicy"
@delete="deleteImage"
- @prev-page="fetchPreviousPage"
- @next-page="fetchNextPage"
/>
<gl-empty-state
@@ -370,6 +339,15 @@ export default {
</template>
</template>
+ <div v-if="!mutationLoading" class="gl-display-flex gl-justify-content-center">
+ <persisted-pagination
+ class="gl-mt-3"
+ :pagination="pageInfo"
+ @prev="fetchPreviousPage"
+ @next="fetchNextPage"
+ />
+ </div>
+
<delete-image
:id="itemToDelete.id"
@start="startDelete"
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/utils.js b/app/assets/javascripts/packages_and_registries/container_registry/explorer/utils.js
index 751ab5180a1..7ed4ff52b06 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/utils.js
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/utils.js
@@ -1,4 +1,5 @@
import { approximateDuration, calculateRemainingMilliseconds } from '~/lib/utils/datetime_utility';
+import { GRAPHQL_PAGE_SIZE } from './constants/index';
export const getImageName = (image = {}) => {
return image.name || image.project?.path;
@@ -10,3 +11,26 @@ export const timeTilRun = (time) => {
const difference = calculateRemainingMilliseconds(time);
return approximateDuration(difference / 1000);
};
+
+export const getNextPageParams = (cursor) => ({
+ after: cursor,
+ first: GRAPHQL_PAGE_SIZE,
+});
+
+export const getPreviousPageParams = (cursor) => ({
+ first: null,
+ before: cursor,
+ last: GRAPHQL_PAGE_SIZE,
+});
+
+export const getPageParams = (pageInfo = {}) => {
+ if (pageInfo.before) {
+ return getPreviousPageParams(pageInfo.before);
+ }
+
+ if (pageInfo.after) {
+ return getNextPageParams(pageInfo.after);
+ }
+
+ return {};
+};