diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-18 20:02:30 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-18 20:02:30 +0000 |
commit | 41fe97390ceddf945f3d967b8fdb3de4c66b7dea (patch) | |
tree | 9c8d89a8624828992f06d892cd2f43818ff5dcc8 /app/assets/javascripts/packages_and_registries | |
parent | 0804d2dc31052fb45a1efecedc8e06ce9bc32862 (diff) | |
download | gitlab-ce-41fe97390ceddf945f3d967b8fdb3de4c66b7dea.tar.gz |
Add latest changes from gitlab-org/gitlab@14-9-stable-eev14.9.0-rc42
Diffstat (limited to 'app/assets/javascripts/packages_and_registries')
9 files changed, 79 insertions, 56 deletions
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue index 56d2ff86fb7..1b7d5af6134 100644 --- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue +++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue @@ -1,7 +1,11 @@ <script> import { GlSprintf, GlAlert, GlLink } from '@gitlab/ui'; -import { ALERT_MESSAGES, ADMIN_GARBAGE_COLLECTION_TIP } from '../../constants/index'; +import { + ALERT_MESSAGES, + ADMIN_GARBAGE_COLLECTION_TIP, + ALERT_DANGER_IMPORTING, +} from '../../constants/index'; export default { components: { @@ -23,6 +27,7 @@ export default { }, }, garbageCollectionHelpPagePath: { type: String, required: false, default: '' }, + containerRegistryImportingHelpPagePath: { type: String, required: false, default: '' }, isAdmin: { type: Boolean, default: false, @@ -48,6 +53,11 @@ export default { } return config; }, + alertHref() { + return this.deleteAlertType === ALERT_DANGER_IMPORTING + ? this.containerRegistryImportingHelpPagePath + : this.garbageCollectionHelpPagePath; + }, }, }; </script> @@ -61,7 +71,7 @@ export default { > <gl-sprintf :message="deleteAlertConfig.message"> <template #docLink="{ content }"> - <gl-link :href="garbageCollectionHelpPagePath" target="_blank"> + <gl-link :href="alertHref" target="_blank"> {{ content }} </gl-link> </template> 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 29c181f04fb..ab0418388cd 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 @@ -4,6 +4,7 @@ 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'; import timeagoMixin from '~/vue_shared/mixins/timeago'; +import { numberToHumanSize } from '~/lib/utils/number_utils'; import { UPDATED_AT, CLEANUP_UNSCHEDULED_TEXT, @@ -23,7 +24,7 @@ import { ROOT_IMAGE_TOOLTIP, } from '../../constants/index'; -import getContainerRepositoryTagsCountQuery from '../../graphql/queries/get_container_repository_tags_count.query.graphql'; +import getContainerRepositoryMetadata from '../../graphql/queries/get_container_repository_metadata.query.graphql'; export default { name: 'DetailsHeader', @@ -50,7 +51,7 @@ export default { }, apollo: { containerRepository: { - query: getContainerRepositoryTagsCountQuery, + query: getContainerRepositoryMetadata, variables() { return { id: this.image.id, @@ -101,6 +102,10 @@ export default { imageName() { return this.imageDetails.name || ROOT_IMAGE_TEXT; }, + formattedSize() { + const { size } = this.imageDetails; + return size ? numberToHumanSize(Number(size)) : null; + }, }, }; </script> @@ -119,10 +124,15 @@ export default { :aria-label="rootImageTooltip" /> </template> + <template #metadata-tags-count> <metadata-item icon="tag" :text="tagCountText" data-testid="tags-count" /> </template> + <template v-if="formattedSize" #metadata-size> + <metadata-item icon="disk" :text="formattedSize" data-testid="image-size" /> + </template> + <template #metadata-cleanup> <metadata-item icon="expire" 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 8b8769a884d..3c7f7ca9aa8 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,10 @@ export const DETAILS_DELETE_IMAGE_ERROR_MESSAGE = s__( 'ContainerRegistry|Something went wrong while scheduling the image for deletion.', ); +export const DETAILS_IMPORTING_ERROR_MESSAGE = s__( + 'ContainerRegistry|Tags temporarily cannot be marked for deletion. Please try again in a few minutes. %{docLinkStart}More details%{docLinkEnd}.', +); + 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}', @@ -133,6 +137,7 @@ export const ALERT_DANGER_TAG = 'danger_tag'; export const ALERT_SUCCESS_TAGS = 'success_tags'; export const ALERT_DANGER_TAGS = 'danger_tags'; export const ALERT_DANGER_IMAGE = 'danger_image'; +export const ALERT_DANGER_IMPORTING = 'danger_importing'; export const DELETE_SCHEDULED = 'DELETE_SCHEDULED'; export const DELETE_FAILED = 'DELETE_FAILED'; @@ -143,6 +148,7 @@ export const ALERT_MESSAGES = { [ALERT_SUCCESS_TAGS]: DELETE_TAGS_SUCCESS_MESSAGE, [ALERT_DANGER_TAGS]: DELETE_TAGS_ERROR_MESSAGE, [ALERT_DANGER_IMAGE]: DETAILS_DELETE_IMAGE_ERROR_MESSAGE, + [ALERT_DANGER_IMPORTING]: DETAILS_IMPORTING_ERROR_MESSAGE, }; export const UNFINISHED_STATUS = 'UNFINISHED'; diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags_count.query.graphql b/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_metadata.query.graphql index 9092a71edb0..f1f67b98407 100644 --- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags_count.query.graphql +++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_metadata.query.graphql @@ -1,6 +1,7 @@ -query getContainerRepositoryTagsCount($id: ID!) { +query getContainerRepositoryMetadata($id: ID!) { containerRepository(id: $id) { id tagsCount + size } } 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 931849c9918..71a85d8885e 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 @@ -20,6 +20,7 @@ import { ALERT_SUCCESS_TAGS, ALERT_DANGER_TAGS, ALERT_DANGER_IMAGE, + ALERT_DANGER_IMPORTING, FETCH_IMAGES_LIST_ERROR_MESSAGE, UNFINISHED_STATUS, MISSING_OR_DELETED_IMAGE_BREADCRUMB, @@ -32,6 +33,8 @@ import deleteContainerRepositoryTagsMutation from '../graphql/mutations/delete_c import getContainerRepositoryDetailsQuery from '../graphql/queries/get_container_repository_details.query.graphql'; import getContainerRepositoryTagsQuery from '../graphql/queries/get_container_repository_tags.query.graphql'; +const REPOSITORY_IMPORTING_ERROR_MESSAGE = 'repository importing'; + export default { name: 'RegistryDetailsPage', components: { @@ -147,12 +150,17 @@ export default { }); if (data?.destroyContainerRepositoryTags?.errors[0]) { - throw new Error(); + throw new Error(data.destroyContainerRepositoryTags.errors[0]); } this.deleteAlertType = itemsToBeDeleted.length === 0 ? ALERT_SUCCESS_TAG : ALERT_SUCCESS_TAGS; } catch (e) { - this.deleteAlertType = itemsToBeDeleted.length === 0 ? ALERT_DANGER_TAG : ALERT_DANGER_TAGS; + if (e.message === REPOSITORY_IMPORTING_ERROR_MESSAGE) { + this.deleteAlertType = ALERT_DANGER_IMPORTING; + } else { + this.deleteAlertType = + itemsToBeDeleted.length === 0 ? ALERT_DANGER_TAG : ALERT_DANGER_TAGS; + } } this.mutationLoading = false; @@ -188,6 +196,7 @@ export default { <delete-alert v-model="deleteAlertType" :garbage-collection-help-page-path="config.garbageCollectionHelpPagePath" + :container-registry-importing-help-page-path="config.containerRegistryImportingHelpPagePath" :is-admin="config.isAdmin" class="gl-my-2" /> 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 e2acebf39d6..5f9e614bebb 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 @@ -13,9 +13,8 @@ import getContainerRepositoriesQuery from 'shared_queries/container_registry/get import createFlash from '~/flash'; import CleanupPolicyEnabledAlert from '~/packages_and_registries/shared/components/cleanup_policy_enabled_alert.vue'; import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants'; -import { extractFilterAndSorting } from '~/packages_and_registries/shared/utils'; import Tracking from '~/tracking'; -import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue'; +import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue'; import DeleteImage from '../components/delete_image.vue'; import RegistryHeader from '../components/list_page/registry_header.vue'; @@ -61,8 +60,8 @@ export default { GlSkeletonLoader, RegistryHeader, DeleteImage, - RegistrySearch, CleanupPolicyEnabledAlert, + PersistedSearch, }, directives: { GlTooltip: GlTooltipDirective, @@ -130,8 +129,7 @@ export default { containerRepositoriesCount: 0, itemToDelete: {}, deleteAlertType: null, - filter: [], - sorting: { orderBy: 'UPDATED', sort: 'desc' }, + sorting: null, name: null, mutationLoading: false, fetchBaseQuery: false, @@ -154,7 +152,7 @@ export default { queryVariables() { return { name: this.name, - sort: this.sortBy, + sort: this.sorting, fullPath: this.config.isGroupPage ? this.config.groupPath : this.config.projectPath, isGroupPage: this.config.isGroupPage, first: GRAPHQL_PAGE_SIZE, @@ -182,24 +180,6 @@ export default { ? DELETE_IMAGE_SUCCESS_MESSAGE : DELETE_IMAGE_ERROR_MESSAGE; }, - sortBy() { - const { orderBy, sort } = this.sorting; - return `${orderBy}_${sort}`.toUpperCase(); - }, - }, - mounted() { - const { sorting, filters } = extractFilterAndSorting(this.$route.query); - - this.filter = [...filters]; - this.name = filters[0]?.value.data; - this.sorting = { ...this.sorting, ...sorting }; - - // If the two graphql calls - which are not batched - resolve togheter we will have a race - // condition when apollo sets the cache, with this we give the 'base' call an headstart - this.fetchBaseQuery = true; - setTimeout(() => { - this.fetchAdditionalDetails = true; - }, 200); }, methods: { deleteImage(item) { @@ -258,18 +238,20 @@ export default { this.track('confirm_delete'); this.mutationLoading = true; }, - updateSorting(value) { - this.sorting = { - ...this.sorting, - ...value, - }; - }, - doFilter() { - const search = this.filter.find((i) => i.type === FILTERED_SEARCH_TERM); + handleSearchUpdate({ sort, filters }) { + this.sorting = sort; + + const search = filters.find((i) => i.type === FILTERED_SEARCH_TERM); this.name = search?.value?.data; - }, - updateUrlQueryString(query) { - this.$router.push({ query }); + + if (!this.fetchBaseQuery && !this.fetchAdditionalDetails) { + // If the two graphql calls - which are not batched - resolve together we will have a race + // condition when apollo sets the cache, with this we give the 'base' call an headstart + this.fetchBaseQuery = true; + setTimeout(() => { + this.fetchAdditionalDetails = true; + }, 200); + } }, }, }; @@ -332,16 +314,12 @@ export default { /> </template> </registry-header> - - <registry-search - :filter="filter" - :sorting="sorting" - :tokens="[]" + <persisted-search + class="gl-mb-5" :sortable-fields="$options.searchConfig" - @sorting:changed="updateSorting" - @filter:changed="filter = $event" - @filter:submit="doFilter" - @query:changed="updateUrlQueryString" + :default-order="$options.searchConfig[0].orderBy" + default-sort="desc" + @update="handleSearchUpdate" /> <div v-if="isLoading" class="gl-mt-5"> diff --git a/app/assets/javascripts/packages_and_registries/settings/project/components/settings_form.vue b/app/assets/javascripts/packages_and_registries/settings/project/components/settings_form.vue index 6030af9d2c3..ae2d5f4fbc5 100644 --- a/app/assets/javascripts/packages_and_registries/settings/project/components/settings_form.vue +++ b/app/assets/javascripts/packages_and_registries/settings/project/components/settings_form.vue @@ -13,7 +13,6 @@ import { REMOVE_INFO_TEXT, EXPIRATION_SCHEDULE_LABEL, NAME_REGEX_LABEL, - NAME_REGEX_PLACEHOLDER, NAME_REGEX_DESCRIPTION, CADENCE_LABEL, EXPIRATION_POLICY_FOOTER_NOTE, @@ -68,7 +67,6 @@ export default { REMOVE_INFO_TEXT, EXPIRATION_SCHEDULE_LABEL, NAME_REGEX_LABEL, - NAME_REGEX_PLACEHOLDER, NAME_REGEX_DESCRIPTION, CADENCE_LABEL, EXPIRATION_POLICY_FOOTER_NOTE, @@ -141,6 +139,17 @@ export default { [model]: state, }; }, + encapsulateError(path, message) { + return { + graphQLErrors: [ + { + extensions: { + problems: [{ path: [path], message }], + }, + }, + ], + }; + }, submit() { this.track('submit_form'); this.apiErrors = {}; @@ -156,7 +165,8 @@ export default { .then(({ data }) => { const errorMessage = data?.updateContainerExpirationPolicy?.errors[0]; if (errorMessage) { - this.$toast.show(errorMessage); + const customError = this.encapsulateError('nameRegex', errorMessage); + throw customError; } else { this.$toast.show(UPDATE_SETTINGS_SUCCESS_MESSAGE); } @@ -273,7 +283,6 @@ export default { :error="apiErrors.nameRegex" :disabled="isFieldDisabled" :label="$options.i18n.NAME_REGEX_LABEL" - :placeholder="$options.i18n.NAME_REGEX_PLACEHOLDER" :description="$options.i18n.NAME_REGEX_DESCRIPTION" name="remove-regex" data-testid="remove-regex-input" diff --git a/app/assets/javascripts/packages_and_registries/settings/project/constants.js b/app/assets/javascripts/packages_and_registries/settings/project/constants.js index 4d477fbd05d..841585c5646 100644 --- a/app/assets/javascripts/packages_and_registries/settings/project/constants.js +++ b/app/assets/javascripts/packages_and_registries/settings/project/constants.js @@ -32,7 +32,6 @@ export const REMOVE_INFO_TEXT = s__( ); export const EXPIRATION_SCHEDULE_LABEL = s__('ContainerRegistry|Remove tags older than:'); export const NAME_REGEX_LABEL = s__('ContainerRegistry|Remove tags matching:'); -export const NAME_REGEX_PLACEHOLDER = '.*'; export const NAME_REGEX_DESCRIPTION = s__( 'ContainerRegistry|Tags with names that match this regex pattern are removed. %{linkStart}View regex examples.%{linkEnd}', ); diff --git a/app/assets/javascripts/packages_and_registries/settings/project/graphql/utils/cache_update.js b/app/assets/javascripts/packages_and_registries/settings/project/graphql/utils/cache_update.js index c4b2af13862..5e0be3834cb 100644 --- a/app/assets/javascripts/packages_and_registries/settings/project/graphql/utils/cache_update.js +++ b/app/assets/javascripts/packages_and_registries/settings/project/graphql/utils/cache_update.js @@ -10,6 +10,7 @@ export const updateContainerExpirationPolicy = (projectPath) => (client, { data: const data = produce(sourceData, (draftState) => { draftState.project.containerExpirationPolicy = { + ...draftState.project.containerExpirationPolicy, ...updatedData.updateContainerExpirationPolicy.containerExpirationPolicy, }; }); |