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:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-06-20 13:43:29 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-06-20 13:43:29 +0300
commit3b1af5cc7ed2666ff18b718ce5d30fa5a2756674 (patch)
tree3bc4a40e0ee51ec27eabf917c537033c0c5b14d4 /app/assets/javascripts/packages_and_registries
parent9bba14be3f2c211bf79e15769cd9b77bc73a13bc (diff)
Add latest changes from gitlab-org/gitlab@16-1-stable-eev16.1.0-rc42
Diffstat (limited to 'app/assets/javascripts/packages_and_registries')
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js2
-rw-r--r--app/assets/javascripts/packages_and_registries/harbor_registry/constants/details.js2
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/package_files.vue31
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/list/components/packages_list_app.vue1
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue269
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue12
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/constants.js4
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/graphql/index.js3
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql15
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_files.query.graphql20
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue180
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/pages/list.vue1
-rw-r--r--app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy_form.vue2
13 files changed, 302 insertions, 240 deletions
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 7ac803a8ece..3a5992d182a 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
@@ -68,7 +68,7 @@ export const MISSING_MANIFEST_WARNING_TOOLTIP = s__(
export const CREATED_AT = s__('ContainerRegistry|Created %{time}');
export const NOT_AVAILABLE_TEXT = __('Not applicable.');
-export const NOT_AVAILABLE_SIZE = __('0 bytes');
+export const NOT_AVAILABLE_SIZE = __('0 B');
export const CLEANUP_UNSCHEDULED_TEXT = s__('ContainerRegistry|Cleanup will run %{time}');
export const CLEANUP_SCHEDULED_TEXT = s__('ContainerRegistry|Cleanup pending');
diff --git a/app/assets/javascripts/packages_and_registries/harbor_registry/constants/details.js b/app/assets/javascripts/packages_and_registries/harbor_registry/constants/details.js
index 5b4b85ec31e..ce98be914ae 100644
--- a/app/assets/javascripts/packages_and_registries/harbor_registry/constants/details.js
+++ b/app/assets/javascripts/packages_and_registries/harbor_registry/constants/details.js
@@ -16,7 +16,7 @@ export const DIGEST_LABEL = s__('HarborRegistry|Digest: %{imageId}');
export const CREATED_AT_LABEL = s__('HarborRegistry|Published %{timeInfo}');
export const NOT_AVAILABLE_TEXT = __('Not applicable.');
-export const NOT_AVAILABLE_SIZE = __('0 bytes');
+export const NOT_AVAILABLE_SIZE = __('0 B');
export const TOKEN_TYPE_TAG_NAME = 'tag_name';
diff --git a/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/package_files.vue b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/package_files.vue
index e45b88bc6d5..ecd1bfb8ebe 100644
--- a/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/package_files.vue
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/package_files.vue
@@ -1,5 +1,11 @@
<script>
-import { GlLink, GlTable, GlDropdownItem, GlDropdown, GlIcon, GlButton } from '@gitlab/ui';
+import {
+ GlLink,
+ GlTable,
+ GlDisclosureDropdownItem,
+ GlDisclosureDropdown,
+ GlButton,
+} from '@gitlab/ui';
import { last } from 'lodash';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import { __ } from '~/locale';
@@ -13,9 +19,8 @@ export default {
components: {
GlLink,
GlTable,
- GlIcon,
- GlDropdown,
- GlDropdownItem,
+ GlDisclosureDropdown,
+ GlDisclosureDropdownItem,
GlButton,
FileIcon,
TimeAgoTooltip,
@@ -136,14 +141,16 @@ export default {
</template>
<template #cell(actions)="{ item }">
- <gl-dropdown category="tertiary" right>
- <template #button-content>
- <gl-icon name="ellipsis_v" />
- </template>
- <gl-dropdown-item data-testid="delete-file" @click="$emit('delete-file', item)">
- {{ $options.i18n.deleteFile }}
- </gl-dropdown-item>
- </gl-dropdown>
+ <gl-disclosure-dropdown category="tertiary" right no-caret icon="ellipsis_v">
+ <gl-disclosure-dropdown-item
+ data-testid="delete-file"
+ @action="$emit('delete-file', item)"
+ >
+ <template #list-item>
+ {{ $options.i18n.deleteFile }}
+ </template>
+ </gl-disclosure-dropdown-item>
+ </gl-disclosure-dropdown>
</template>
<template #row-details="{ item }">
diff --git a/app/assets/javascripts/packages_and_registries/infrastructure_registry/list/components/packages_list_app.vue b/app/assets/javascripts/packages_and_registries/infrastructure_registry/list/components/packages_list_app.vue
index 6ea1fff9ef0..37fc326f902 100644
--- a/app/assets/javascripts/packages_and_registries/infrastructure_registry/list/components/packages_list_app.vue
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/list/components/packages_list_app.vue
@@ -81,7 +81,6 @@ export default {
const urlParams = new URLSearchParams(window.location.search);
const showAlert = urlParams.get(SHOW_DELETE_SUCCESS_ALERT);
if (showAlert) {
- // to be refactored to use gl-alert
createAlert({ message: DELETE_PACKAGE_SUCCESS_MESSAGE, variant: VARIANT_INFO });
const cleanUrl = window.location.href.split('?')[0];
historyReplaceState(cleanUrl);
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue
index 8eb8654cddd..3157653648b 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue
@@ -1,6 +1,17 @@
<script>
-import { GlLink, GlTable, GlDropdownItem, GlDropdown, GlButton, GlFormCheckbox } from '@gitlab/ui';
-import { last } from 'lodash';
+import {
+ GlAlert,
+ GlLink,
+ GlTable,
+ GlDropdownItem,
+ GlDropdown,
+ GlButton,
+ GlFormCheckbox,
+ GlLoadingIcon,
+ GlModal,
+ GlSprintf,
+} from '@gitlab/ui';
+import { createAlert, VARIANT_SUCCESS, VARIANT_WARNING } from '~/alert';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import { __, s__ } from '~/locale';
import FileSha from '~/packages_and_registries/package_registry/components/details/file_sha.vue';
@@ -9,69 +20,117 @@ import { packageTypeToTrackCategory } from '~/packages_and_registries/package_re
import FileIcon from '~/vue_shared/components/file_icon.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import {
+ FETCH_PACKAGE_FILES_ERROR_MESSAGE,
+ GRAPHQL_PACKAGE_FILES_PAGE_SIZE,
REQUEST_DELETE_SELECTED_PACKAGE_FILE_TRACKING_ACTION,
SELECT_PACKAGE_FILE_TRACKING_ACTION,
+ DOWNLOAD_PACKAGE_ASSET_TRACKING_ACTION,
+ CANCEL_DELETE_PACKAGE_FILE_TRACKING_ACTION,
+ DELETE_PACKAGE_FILE_TRACKING_ACTION,
+ REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION,
TRACKING_LABEL_PACKAGE_ASSET,
TRACKING_ACTION_EXPAND_PACKAGE_ASSET,
+ DELETE_PACKAGE_FILE_ERROR_MESSAGE,
+ DELETE_PACKAGE_FILE_SUCCESS_MESSAGE,
+ DELETE_PACKAGE_FILES_ERROR_MESSAGE,
+ DELETE_PACKAGE_FILES_SUCCESS_MESSAGE,
+ DELETE_PACKAGE_FILES_TRACKING_ACTION,
+ DELETE_ALL_PACKAGE_FILES_MODAL_CONTENT,
+ DELETE_LAST_PACKAGE_FILE_MODAL_CONTENT,
} from '~/packages_and_registries/package_registry/constants';
+import getPackageFilesQuery from '~/packages_and_registries/package_registry/graphql/queries/get_package_files.query.graphql';
+import destroyPackageFilesMutation from '~/packages_and_registries/package_registry/graphql/mutations/destroy_package_files.mutation.graphql';
export default {
name: 'PackageFiles',
components: {
+ GlAlert,
GlLink,
GlTable,
GlDropdown,
GlDropdownItem,
GlFormCheckbox,
GlButton,
+ GlLoadingIcon,
+ GlModal,
+ GlSprintf,
FileIcon,
TimeAgoTooltip,
FileSha,
},
mixins: [Tracking.mixin()],
+ trackingActions: {
+ DELETE_PACKAGE_FILE_TRACKING_ACTION,
+ REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION,
+ CANCEL_DELETE_PACKAGE_FILE_TRACKING_ACTION,
+ DOWNLOAD_PACKAGE_ASSET_TRACKING_ACTION,
+ },
props: {
canDelete: {
type: Boolean,
required: false,
default: false,
},
- isLoading: {
- type: Boolean,
- required: false,
- default: false,
+ packageId: {
+ type: String,
+ required: true,
+ },
+ packageType: {
+ type: String,
+ required: true,
},
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ },
+ apollo: {
packageFiles: {
- type: Array,
- required: false,
- default: () => [],
+ query: getPackageFilesQuery,
+ context: {
+ isSingleRequest: true,
+ },
+ variables() {
+ return this.queryVariables;
+ },
+ update(data) {
+ return data.package?.packageFiles ?? {};
+ },
+ error() {
+ this.fetchPackageFilesError = true;
+ },
},
},
data() {
return {
+ fetchPackageFilesError: false,
+ filesToDelete: [],
+ packageFiles: {},
+ mutationLoading: false,
selectedReferences: [],
};
},
computed: {
+ files() {
+ return this.packageFiles?.nodes ?? [];
+ },
areFilesSelected() {
return this.selectedReferences.length > 0;
},
areAllFilesSelected() {
- return this.packageFiles.every(this.isSelected);
+ return this.files.length > 0 && this.files.every(this.isSelected);
},
filesTableRows() {
- return this.packageFiles.map((pf) => ({
+ return this.files.map((pf) => ({
...pf,
size: this.formatSize(pf.size),
- pipeline: last(pf.pipelines),
}));
},
hasSelectedSomeFiles() {
return this.areFilesSelected && !this.areAllFilesSelected;
},
- showCommitColumn() {
- // note that this is always false for now since we do not return
- // pipelines associated to files for performance concerns
- return this.filesTableRows.some((row) => Boolean(row.pipeline?.id));
+ isLoading() {
+ return this.$apollo.queries.packageFiles.loading || this.mutationLoading;
},
filesTableHeaderFields() {
return [
@@ -86,11 +145,6 @@ export default {
label: __('Name'),
},
{
- key: 'commit',
- label: __('Commit'),
- hide: !this.showCommitColumn,
- },
- {
key: 'size',
label: __('Size'),
},
@@ -108,11 +162,40 @@ export default {
},
].filter((c) => !c.hide);
},
+ queryVariables() {
+ return {
+ id: this.packageId,
+ first: GRAPHQL_PACKAGE_FILES_PAGE_SIZE,
+ };
+ },
tracking() {
return {
category: packageTypeToTrackCategory(this.packageType),
};
},
+ refetchQueriesData() {
+ return [
+ {
+ query: getPackageFilesQuery,
+ variables: this.queryVariables,
+ },
+ ];
+ },
+ modalAction() {
+ return this.hasOneItem(this.filesToDelete)
+ ? this.$options.modal.fileDeletePrimaryAction
+ : this.$options.modal.filesDeletePrimaryAction;
+ },
+ modalTitle() {
+ return this.hasOneItem(this.filesToDelete)
+ ? this.$options.i18n.deleteFileModalTitle
+ : this.$options.i18n.deleteFilesModalTitle;
+ },
+ modalDescription() {
+ return this.hasOneItem(this.filesToDelete)
+ ? this.$options.i18n.deleteFileModalContent
+ : this.$options.i18n.deleteFilesModalContent;
+ },
},
methods: {
formatSize(size) {
@@ -135,13 +218,96 @@ export default {
},
handleFileDeleteSelected() {
this.track(REQUEST_DELETE_SELECTED_PACKAGE_FILE_TRACKING_ACTION);
- this.$emit('delete-files', this.selectedReferences);
+ this.handleFileDelete(this.selectedReferences);
+ },
+ async deletePackageFiles(ids) {
+ this.mutationLoading = true;
+ try {
+ const { data } = await this.$apollo.mutate({
+ mutation: destroyPackageFilesMutation,
+ variables: {
+ projectPath: this.projectPath,
+ ids,
+ },
+ awaitRefetchQueries: true,
+ refetchQueries: this.refetchQueriesData,
+ });
+ if (data?.destroyPackageFiles?.errors[0]) {
+ throw data.destroyPackageFiles.errors[0];
+ }
+ createAlert({
+ message: this.hasOneItem(ids)
+ ? DELETE_PACKAGE_FILE_SUCCESS_MESSAGE
+ : DELETE_PACKAGE_FILES_SUCCESS_MESSAGE,
+ variant: VARIANT_SUCCESS,
+ });
+ } catch (error) {
+ createAlert({
+ message: this.hasOneItem(ids)
+ ? DELETE_PACKAGE_FILE_ERROR_MESSAGE
+ : DELETE_PACKAGE_FILES_ERROR_MESSAGE,
+ variant: VARIANT_WARNING,
+ captureError: true,
+ error,
+ });
+ } finally {
+ this.mutationLoading = false;
+ this.filesToDelete = [];
+ this.selectedReferences = [];
+ }
+ },
+ handleFileDelete(files) {
+ this.track(REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION);
+ if (files.length === this.files.length && !this.packageFiles?.pageInfo?.hasNextPage) {
+ this.$emit(
+ 'delete-all-files',
+ this.hasOneItem(files)
+ ? DELETE_LAST_PACKAGE_FILE_MODAL_CONTENT
+ : DELETE_ALL_PACKAGE_FILES_MODAL_CONTENT,
+ );
+ } else {
+ this.filesToDelete = files;
+ this.$refs.deleteFilesModal.show();
+ }
+ },
+ hasOneItem(items) {
+ return items.length === 1;
+ },
+ confirmFilesDelete() {
+ if (this.hasOneItem(this.filesToDelete)) {
+ this.track(DELETE_PACKAGE_FILE_TRACKING_ACTION);
+ } else {
+ this.track(DELETE_PACKAGE_FILES_TRACKING_ACTION);
+ }
+ this.deletePackageFiles(this.filesToDelete.map((file) => file.id));
},
},
i18n: {
- deleteFile: __('Delete asset'),
+ deleteFile: s__('PackageRegistry|Delete asset'),
+ deleteFileModalTitle: s__('PackageRegistry|Delete package asset'),
+ deleteFileModalContent: s__(
+ 'PackageRegistry|You are about to delete %{filename}. This is a destructive action that may render your package unusable. Are you sure?',
+ ),
+ deleteFilesModalTitle: s__('PackageRegistry|Delete %{count} assets'),
+ deleteFilesModalContent: s__(
+ 'PackageRegistry|You are about to delete %{count} assets. This operation is irreversible.',
+ ),
deleteSelected: s__('PackageRegistry|Delete selected'),
moreActionsText: __('More actions'),
+ fetchPackageFilesErrorMessage: FETCH_PACKAGE_FILES_ERROR_MESSAGE,
+ },
+ modal: {
+ fileDeletePrimaryAction: {
+ text: __('Delete'),
+ attributes: { variant: 'danger', category: 'primary' },
+ },
+ filesDeletePrimaryAction: {
+ text: s__('PackageRegistry|Permanently delete assets'),
+ attributes: { variant: 'danger', category: 'primary' },
+ },
+ cancelAction: {
+ text: __('Cancel'),
+ },
},
};
</script>
@@ -151,7 +317,7 @@ export default {
<div class="gl-display-flex gl-align-items-center gl-justify-content-space-between">
<h3 class="gl-font-lg gl-mt-5">{{ __('Assets') }}</h3>
<gl-button
- v-if="canDelete"
+ v-if="!fetchPackageFilesError && canDelete"
:disabled="isLoading || !areFilesSelected"
category="secondary"
variant="danger"
@@ -161,7 +327,16 @@ export default {
{{ $options.i18n.deleteSelected }}
</gl-button>
</div>
+ <gl-alert
+ v-if="fetchPackageFilesError"
+ variant="danger"
+ @dismiss="fetchPackageFilesError = false"
+ >
+ {{ $options.i18n.fetchPackageFilesErrorMessage }}
+ </gl-alert>
<gl-table
+ v-else
+ :busy="isLoading"
:fields="filesTableHeaderFields"
:items="filesTableRows"
show-empty
@@ -171,6 +346,9 @@ export default {
:tbody-tr-attr="{ 'data-testid': 'file-row' }"
@row-selected="updateSelectedReferences"
>
+ <template #table-busy>
+ <gl-loading-icon size="lg" class="gl-my-5" />
+ </template>
<template #head(checkbox)="{ selectAllRows, clearSelected }">
<gl-form-checkbox
v-if="canDelete"
@@ -207,7 +385,7 @@ export default {
:href="item.downloadPath"
class="gl-text-gray-500"
data-testid="download-link"
- @click="$emit('download-file')"
+ @click="track($options.trackingActions.DOWNLOAD_PACKAGE_ASSET_TRACKING_ACTION)"
>
<file-icon
:file-name="item.fileName"
@@ -218,16 +396,6 @@ export default {
</gl-link>
</template>
- <template #cell(commit)="{ item }">
- <gl-link
- v-if="item.pipeline && item.pipeline"
- :href="item.pipeline.commitPath"
- class="gl-text-gray-500"
- data-testid="commit-link"
- >{{ item.pipeline.sha }}
- </gl-link>
- </template>
-
<template #cell(created)="{ item }">
<time-ago-tooltip :time="item.createdAt" />
</template>
@@ -241,7 +409,7 @@ export default {
no-caret
right
>
- <gl-dropdown-item data-testid="delete-file" @click="$emit('delete-files', [item])">
+ <gl-dropdown-item data-testid="delete-file" @click="handleFileDelete([item])">
{{ $options.i18n.deleteFile }}
</gl-dropdown-item>
</gl-dropdown>
@@ -262,5 +430,34 @@ export default {
</div>
</template>
</gl-table>
+
+ <gl-modal
+ ref="deleteFilesModal"
+ size="sm"
+ modal-id="delete-files-modal"
+ :action-primary="modalAction"
+ :action-cancel="$options.modal.cancelAction"
+ data-testid="delete-files-modal"
+ @primary="confirmFilesDelete"
+ @canceled="track($options.trackingActions.CANCEL_DELETE_PACKAGE_FILE)"
+ >
+ <template #modal-title>
+ <gl-sprintf :message="modalTitle">
+ <template #count>
+ {{ filesToDelete.length }}
+ </template>
+ </gl-sprintf>
+ </template>
+
+ <gl-sprintf :message="modalDescription">
+ <template #filename>
+ <strong>{{ filesToDelete[0].fileName }}</strong>
+ </template>
+
+ <template #count>
+ {{ filesToDelete.length }}
+ </template>
+ </gl-sprintf>
+ </gl-modal>
</div>
</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue
index cee976656f9..5eabcea9e15 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue
@@ -1,7 +1,6 @@
<script>
import { GlSprintf, GlBadge, GlResizeObserverDirective } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
-import { numberToHumanSize } from '~/lib/utils/number_utils';
import { __, s__, sprintf } from '~/locale';
import { formatDate } from '~/lib/utils/datetime_utility';
import PackageTags from '~/packages_and_registries/shared/components/package_tags.vue';
@@ -61,13 +60,6 @@ export default {
hasTagsToDisplay() {
return Boolean(this.packageEntity.tags?.nodes && this.packageEntity.tags?.nodes.length);
},
- totalSize() {
- return this.packageEntity.packageFiles
- ? numberToHumanSize(
- this.packageEntity.packageFiles.nodes.reduce((acc, p) => acc + Number(p.size), 0),
- )
- : '0';
- },
},
mounted() {
this.checkBreakpoints();
@@ -126,10 +118,6 @@ export default {
<metadata-item data-testid="package-type" icon="package" :text="packageTypeDisplay" />
</template>
- <template #metadata-size>
- <metadata-item data-testid="package-size" icon="disk" :text="totalSize" />
- </template>
-
<template v-if="isGroupPage && packagePipeline" #metadata-pipeline>
<metadata-item
data-testid="pipeline-project"
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 b4276d69ed6..80712c2991c 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/constants.js
+++ b/app/assets/javascripts/packages_and_registries/package_registry/constants.js
@@ -102,6 +102,9 @@ export const FETCH_PACKAGE_PIPELINES_ERROR_MESSAGE = s__(
export const FETCH_PACKAGE_METADATA_ERROR_MESSAGE = s__(
'PackageRegistry|Something went wrong while fetching the package metadata.',
);
+export const FETCH_PACKAGE_FILES_ERROR_MESSAGE = s__(
+ 'PackageRegistry|Something went wrong while fetching package assets.',
+);
export const DELETE_PACKAGES_TRACKING_ACTION = 'delete_packages';
export const REQUEST_DELETE_PACKAGES_TRACKING_ACTION = 'request_delete_packages';
@@ -232,3 +235,4 @@ export const REQUEST_FORWARDING_HELP_PAGE_PATH = helpPagePath(
);
export const GRAPHQL_PACKAGE_PIPELINES_PAGE_SIZE = 10;
+export const GRAPHQL_PACKAGE_FILES_PAGE_SIZE = 100;
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 39e5da54509..d05ff5daad4 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
@@ -21,6 +21,9 @@ export const apolloProvider = new VueApollo({
keyArgs: false,
merge: mergeVariables,
},
+ packageFiles: {
+ merge: mergeVariables,
+ },
},
},
},
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql b/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql
index 984996b829a..4c71de9ee20 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql
+++ b/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql
@@ -46,21 +46,6 @@ query getPackageDetails($id: PackagesPackageID!) {
}
}
}
- packageFiles(first: 100) {
- pageInfo {
- hasNextPage
- }
- nodes {
- id
- fileMd5
- fileName
- fileSha1
- fileSha256
- size
- createdAt
- downloadPath
- }
- }
versions {
count
}
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_files.query.graphql b/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_files.query.graphql
new file mode 100644
index 00000000000..e6f292ec1d3
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_files.query.graphql
@@ -0,0 +1,20 @@
+query getPackageFiles($id: PackagesPackageID!, $first: Int) {
+ package(id: $id) {
+ id
+ packageFiles(first: $first) {
+ pageInfo {
+ hasNextPage
+ }
+ nodes {
+ id
+ fileMd5
+ fileName
+ fileSha1
+ fileSha256
+ size
+ createdAt
+ downloadPath
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue b/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue
index 6d4979ac785..d96418571e1 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue
@@ -11,7 +11,7 @@ import {
GlTabs,
GlSprintf,
} from '@gitlab/ui';
-import { createAlert, VARIANT_SUCCESS, VARIANT_WARNING } from '~/alert';
+import { createAlert } from '~/alert';
import { TYPENAME_PACKAGES_PACKAGE } from '~/graphql_shared/constants';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { numberToHumanSize } from '~/lib/utils/number_utils';
@@ -21,10 +21,8 @@ import { packageTypeToTrackCategory } from '~/packages_and_registries/package_re
import AdditionalMetadata from '~/packages_and_registries/package_registry/components/details/additional_metadata.vue';
import DependencyRow from '~/packages_and_registries/package_registry/components/details/dependency_row.vue';
import InstallationCommands from '~/packages_and_registries/package_registry/components/details/installation_commands.vue';
-import PackageFiles from '~/packages_and_registries/package_registry/components/details/package_files.vue';
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 PackageVersionsList from '~/packages_and_registries/package_registry/components/details/package_versions_list.vue';
import DeletePackages from '~/packages_and_registries/package_registry/components/functional/delete_packages.vue';
import {
PACKAGE_TYPE_NUGET,
@@ -35,27 +33,15 @@ import {
DELETE_PACKAGE_TRACKING_ACTION,
REQUEST_DELETE_PACKAGE_TRACKING_ACTION,
CANCEL_DELETE_PACKAGE_TRACKING_ACTION,
- DELETE_PACKAGE_FILE_TRACKING_ACTION,
- DELETE_PACKAGE_FILES_TRACKING_ACTION,
- REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION,
REQUEST_FORWARDING_HELP_PAGE_PATH,
- CANCEL_DELETE_PACKAGE_FILE_TRACKING_ACTION,
SHOW_DELETE_SUCCESS_ALERT,
FETCH_PACKAGE_DETAILS_ERROR_MESSAGE,
- DELETE_PACKAGE_FILE_ERROR_MESSAGE,
- DELETE_PACKAGE_FILE_SUCCESS_MESSAGE,
- DELETE_PACKAGE_FILES_ERROR_MESSAGE,
- DELETE_PACKAGE_FILES_SUCCESS_MESSAGE,
DELETE_PACKAGE_REQUEST_FORWARDING_MODAL_CONTENT,
- DOWNLOAD_PACKAGE_ASSET_TRACKING_ACTION,
DELETE_MODAL_TITLE,
DELETE_MODAL_CONTENT,
- DELETE_ALL_PACKAGE_FILES_MODAL_CONTENT,
- DELETE_LAST_PACKAGE_FILE_MODAL_CONTENT,
GRAPHQL_PAGE_SIZE,
} from '~/packages_and_registries/package_registry/constants';
-import destroyPackageFilesMutation from '~/packages_and_registries/package_registry/graphql/mutations/destroy_package_files.mutation.graphql';
import getPackageDetails from '~/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql';
import getPackageVersionsQuery from '~/packages_and_registries/package_registry/graphql/queries/get_package_versions.query.graphql';
import Tracking from '~/tracking';
@@ -76,9 +62,13 @@ export default {
PackageHistory,
AdditionalMetadata,
InstallationCommands,
- PackageFiles,
+ PackageFiles: () =>
+ import('~/packages_and_registries/package_registry/components/details/package_files.vue'),
DeletePackages,
- PackageVersionsList,
+ PackageVersionsList: () =>
+ import(
+ '~/packages_and_registries/package_registry/components/details/package_versions_list.vue'
+ ),
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -90,10 +80,6 @@ export default {
DELETE_PACKAGE_TRACKING_ACTION,
REQUEST_DELETE_PACKAGE_TRACKING_ACTION,
CANCEL_DELETE_PACKAGE_TRACKING_ACTION,
- DELETE_PACKAGE_FILE_TRACKING_ACTION,
- REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION,
- CANCEL_DELETE_PACKAGE_FILE_TRACKING_ACTION,
- DOWNLOAD_PACKAGE_ASSET_TRACKING_ACTION,
},
data() {
return {
@@ -147,18 +133,12 @@ export default {
id: convertToGraphQLId(TYPENAME_PACKAGES_PACKAGE, this.packageId),
};
},
- packageFiles() {
- return this.packageEntity.packageFiles?.nodes;
- },
packageType() {
return this.packageEntity.packageType;
},
isLoading() {
return this.$apollo.queries.packageEntity.loading;
},
- packageFilesLoading() {
- return this.isLoading || this.mutationLoading;
- },
isValidPackage() {
return this.isLoading || Boolean(this.packageEntity.name);
},
@@ -194,14 +174,6 @@ export default {
PACKAGE_TYPE_PYPI,
].includes(this.packageType);
},
- refetchQueriesData() {
- return [
- {
- query: getPackageDetails,
- variables: this.queryVariables,
- },
- ];
- },
refetchVersionsQueryData() {
return [
{
@@ -228,71 +200,9 @@ export default {
window.location.replace(`${returnTo}?${modalQuery}`);
},
- async deletePackageFiles(ids) {
- this.mutationLoading = true;
- try {
- const { data } = await this.$apollo.mutate({
- mutation: destroyPackageFilesMutation,
- variables: {
- projectPath: this.projectPath,
- ids,
- },
- awaitRefetchQueries: true,
- refetchQueries: this.refetchQueriesData,
- });
- if (data?.destroyPackageFiles?.errors[0]) {
- throw data.destroyPackageFiles.errors[0];
- }
- createAlert({
- message: this.isLastItem(ids)
- ? DELETE_PACKAGE_FILE_SUCCESS_MESSAGE
- : DELETE_PACKAGE_FILES_SUCCESS_MESSAGE,
- variant: VARIANT_SUCCESS,
- });
- } catch (error) {
- createAlert({
- message: this.isLastItem(ids)
- ? DELETE_PACKAGE_FILE_ERROR_MESSAGE
- : DELETE_PACKAGE_FILES_ERROR_MESSAGE,
- variant: VARIANT_WARNING,
- captureError: true,
- error,
- });
- }
- this.mutationLoading = false;
- },
- handleFileDelete(files) {
- this.track(REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION);
- if (
- files.length === this.packageFiles.length &&
- !this.packageEntity.packageFiles?.pageInfo?.hasNextPage
- ) {
- if (this.isLastItem(files)) {
- this.deletePackageModalContent = DELETE_LAST_PACKAGE_FILE_MODAL_CONTENT;
- } else {
- this.deletePackageModalContent = DELETE_ALL_PACKAGE_FILES_MODAL_CONTENT;
- }
- this.$refs.deleteModal.show();
- } else {
- this.filesToDelete = files;
- if (this.isLastItem(files)) {
- this.$refs.deleteFileModal.show();
- } else if (files.length > 1) {
- this.$refs.deleteFilesModal.show();
- }
- }
- },
- isLastItem(items) {
- return items.length === 1;
- },
- confirmFilesDelete() {
- if (this.isLastItem(this.filesToDelete)) {
- this.track(DELETE_PACKAGE_FILE_TRACKING_ACTION);
- } else {
- this.track(DELETE_PACKAGE_FILES_TRACKING_ACTION);
- }
- this.deletePackageFiles(this.filesToDelete.map((file) => file.id));
- this.filesToDelete = [];
+ handleAllFilesDelete(content) {
+ this.deletePackageModalContent = content;
+ this.$refs.deleteModal.show();
},
resetDeleteModalContent() {
this.deletePackageModalContent = DELETE_MODAL_CONTENT;
@@ -300,10 +210,6 @@ export default {
},
i18n: {
DELETE_MODAL_TITLE,
- deleteFileModalTitle: s__(`PackageRegistry|Delete package asset`),
- deleteFileModalContent: s__(
- `PackageRegistry|You are about to delete %{filename}. This is a destructive action that may render your package unusable. Are you sure?`,
- ),
otherVersionsTabTitle: s__('PackageRegistry|Other versions'),
},
links: {
@@ -358,7 +264,7 @@ export default {
<gl-tabs>
<gl-tab :title="__('Detail')">
- <div v-if="!isLoading" data-qa-selector="package_information_content">
+ <div data-qa-selector="package_information_content">
<package-history :package-entity="packageEntity" :project-name="projectName" />
<installation-commands :package-entity="packageEntity" />
@@ -368,16 +274,16 @@ export default {
:package-id="packageEntity.id"
:package-type="packageType"
/>
- </div>
- <package-files
- v-if="showFiles"
- :can-delete="packageEntity.canDestroy"
- :is-loading="packageFilesLoading"
- :package-files="packageFiles"
- @download-file="track($options.trackingActions.DOWNLOAD_PACKAGE_ASSET_TRACKING_ACTION)"
- @delete-files="handleFileDelete"
- />
+ <package-files
+ v-if="showFiles"
+ :can-delete="packageEntity.canDestroy"
+ :package-id="packageEntity.id"
+ :package-type="packageType"
+ :project-path="projectPath"
+ @delete-all-files="handleAllFilesDelete"
+ />
+ </div>
</gl-tab>
<gl-tab v-if="showDependencies">
@@ -468,51 +374,5 @@ export default {
</gl-modal>
</template>
</delete-packages>
-
- <gl-modal
- ref="deleteFileModal"
- size="sm"
- modal-id="delete-file-modal"
- :action-primary="$options.modal.fileDeletePrimaryAction"
- :action-cancel="$options.modal.cancelAction"
- data-testid="delete-file-modal"
- @primary="confirmFilesDelete"
- @canceled="track($options.trackingActions.CANCEL_DELETE_PACKAGE_FILE)"
- >
- <template #modal-title>{{ $options.i18n.deleteFileModalTitle }}</template>
- <gl-sprintf v-if="isLastItem(filesToDelete)" :message="$options.i18n.deleteFileModalContent">
- <template #filename>
- <strong>{{ filesToDelete[0].fileName }}</strong>
- </template>
- </gl-sprintf>
- </gl-modal>
-
- <gl-modal
- ref="deleteFilesModal"
- size="sm"
- modal-id="delete-files-modal"
- :action-primary="$options.modal.filesDeletePrimaryAction"
- :action-cancel="$options.modal.cancelAction"
- data-testid="delete-files-modal"
- @primary="confirmFilesDelete"
- @canceled="track($options.trackingActions.CANCEL_DELETE_PACKAGE_FILE)"
- >
- <template #modal-title>{{
- n__(
- `PackageRegistry|Delete 1 asset`,
- `PackageRegistry|Delete %d assets`,
- filesToDelete.length,
- )
- }}</template>
- <span v-if="filesToDelete.length > 0">
- {{
- n__(
- `PackageRegistry|You are about to delete 1 asset. This operation is irreversible.`,
- `PackageRegistry|You are about to delete %d assets. This operation is irreversible.`,
- filesToDelete.length,
- )
- }}
- </span>
- </gl-modal>
</div>
</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/pages/list.vue b/app/assets/javascripts/packages_and_registries/package_registry/pages/list.vue
index 044ce4e6413..14d617a7a3c 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/pages/list.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/pages/list.vue
@@ -114,7 +114,6 @@ export default {
const urlParams = new URLSearchParams(window.location.search);
const showAlert = urlParams.get(SHOW_DELETE_SUCCESS_ALERT);
if (showAlert) {
- // to be refactored to use gl-alert
createAlert({ message: DELETE_PACKAGE_SUCCESS_MESSAGE, variant: VARIANT_INFO });
const cleanUrl = window.location.href.split('?')[0];
historyReplaceState(cleanUrl);
diff --git a/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy_form.vue b/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy_form.vue
index f95ec4336dc..80df8ef81e6 100644
--- a/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy_form.vue
+++ b/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy_form.vue
@@ -139,7 +139,7 @@ export default {
:form-options="$options.formOptions.keepNDuplicatedPackageFiles"
:label="$options.i18n.KEEP_N_DUPLICATED_PACKAGE_FILES_LABEL"
:description="$options.i18n.KEEP_N_DUPLICATED_PACKAGE_FILES_DESCRIPTION"
- dropdown-class="gl-md-max-w-50p gl-sm-pr-5"
+ dropdown-class="gl-md-max-w-50p"
name="keep-n-duplicated-package-files"
data-testid="keep-n-duplicated-package-files-dropdown"
@input="onModelChange($event, 'keepNDuplicatedPackageFiles')"