summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/registry/explorer/pages/details.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/registry/explorer/pages/details.vue')
-rw-r--r--app/assets/javascripts/registry/explorer/pages/details.vue157
1 files changed, 113 insertions, 44 deletions
diff --git a/app/assets/javascripts/registry/explorer/pages/details.vue b/app/assets/javascripts/registry/explorer/pages/details.vue
index 0894fd6fcfa..0403467468a 100644
--- a/app/assets/javascripts/registry/explorer/pages/details.vue
+++ b/app/assets/javascripts/registry/explorer/pages/details.vue
@@ -2,28 +2,32 @@
import { GlKeysetPagination, GlResizeObserverDirective } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
import createFlash from '~/flash';
-import Tracking from '~/tracking';
+import axios from '~/lib/utils/axios_utils';
import { joinPaths } from '~/lib/utils/url_utility';
+import Tracking from '~/tracking';
+import DeleteImage from '../components/delete_image.vue';
import DeleteAlert from '../components/details_page/delete_alert.vue';
-import PartialCleanupAlert from '../components/details_page/partial_cleanup_alert.vue';
import DeleteModal from '../components/details_page/delete_modal.vue';
import DetailsHeader from '../components/details_page/details_header.vue';
+import EmptyState from '../components/details_page/empty_state.vue';
+import PartialCleanupAlert from '../components/details_page/partial_cleanup_alert.vue';
+import StatusAlert from '../components/details_page/status_alert.vue';
import TagsList from '../components/details_page/tags_list.vue';
import TagsLoader from '../components/details_page/tags_loader.vue';
-import EmptyTagsState from '../components/details_page/empty_tags_state.vue';
-
-import getContainerRepositoryDetailsQuery from '../graphql/queries/get_container_repository_details.query.graphql';
-import deleteContainerRepositoryTagsMutation from '../graphql/mutations/delete_container_repository_tags.mutation.graphql';
import {
ALERT_SUCCESS_TAG,
ALERT_DANGER_TAG,
ALERT_SUCCESS_TAGS,
ALERT_DANGER_TAGS,
+ ALERT_DANGER_IMAGE,
GRAPHQL_PAGE_SIZE,
FETCH_IMAGES_LIST_ERROR_MESSAGE,
UNFINISHED_STATUS,
+ MISSING_OR_DELETE_IMAGE_BREADCRUMB,
} from '../constants/index';
+import deleteContainerRepositoryTagsMutation from '../graphql/mutations/delete_container_repository_tags.mutation.graphql';
+import getContainerRepositoryDetailsQuery from '../graphql/queries/get_container_repository_details.query.graphql';
export default {
name: 'RegistryDetailsPage',
@@ -35,7 +39,9 @@ export default {
DeleteModal,
TagsList,
TagsLoader,
- EmptyTagsState,
+ EmptyState,
+ StatusAlert,
+ DeleteImage,
},
directives: {
GlResizeObserver: GlResizeObserverDirective,
@@ -53,7 +59,7 @@ export default {
},
result({ data }) {
this.tagsPageInfo = data.containerRepository?.tags?.pageInfo;
- this.breadCrumbState.updateName(data.containerRepository?.name);
+ this.updateBreadcrumb();
},
error() {
createFlash({ message: FETCH_IMAGES_LIST_ERROR_MESSAGE });
@@ -68,7 +74,8 @@ export default {
isMobile: false,
mutationLoading: false,
deleteAlertType: null,
- dismissPartialCleanupWarning: false,
+ hidePartialCleanupWarning: false,
+ deleteImageAlert: false,
};
},
computed: {
@@ -86,8 +93,9 @@ export default {
},
showPartialCleanupWarning() {
return (
+ this.config.showUnfinishedTagCleanupCallout &&
this.image?.expirationPolicyCleanupStatus === UNFINISHED_STATUS &&
- !this.dismissPartialCleanupWarning
+ !this.hidePartialCleanupWarning
);
},
tracking() {
@@ -99,14 +107,32 @@ export default {
showPagination() {
return this.tagsPageInfo.hasPreviousPage || this.tagsPageInfo.hasNextPage;
},
+ hasNoTags() {
+ return this.tags.length === 0;
+ },
+ pageActionsAreDisabled() {
+ return Boolean(this.image?.status);
+ },
},
methods: {
+ updateBreadcrumb() {
+ const name = this.image?.name || MISSING_OR_DELETE_IMAGE_BREADCRUMB;
+ this.breadCrumbState.updateName(name);
+ },
deleteTags(toBeDeleted) {
+ this.deleteImageAlert = false;
this.itemsToBeDeleted = this.tags.filter((tag) => toBeDeleted[tag.name]);
this.track('click_button');
this.$refs.deleteModal.show();
},
- async handleDelete() {
+ confirmDelete() {
+ if (this.deleteImageAlert) {
+ this.$refs.deleteImage.doDelete();
+ } else {
+ this.handleDeleteTag();
+ }
+ },
+ async handleDeleteTag() {
this.track('confirm_delete');
const { itemsToBeDeleted } = this;
this.itemsToBeDeleted = [];
@@ -168,51 +194,94 @@ export default {
});
}
},
+ dismissPartialCleanupWarning() {
+ this.hidePartialCleanupWarning = true;
+ axios.post(this.config.userCalloutsPath, {
+ feature_name: this.config.userCalloutId,
+ });
+ },
+ deleteImage() {
+ this.deleteImageAlert = true;
+ this.itemsToBeDeleted = [{ path: this.image.path }];
+ this.$refs.deleteModal.show();
+ },
+ deleteImageError() {
+ this.deleteAlertType = ALERT_DANGER_IMAGE;
+ },
+ deleteImageIniit() {
+ this.itemsToBeDeleted = [];
+ this.mutationLoading = true;
+ },
},
};
</script>
<template>
<div v-gl-resize-observer="handleResize" class="gl-my-3">
- <delete-alert
- v-model="deleteAlertType"
- :garbage-collection-help-page-path="config.garbageCollectionHelpPagePath"
- :is-admin="config.isAdmin"
- class="gl-my-2"
- />
+ <template v-if="image">
+ <delete-alert
+ v-model="deleteAlertType"
+ :garbage-collection-help-page-path="config.garbageCollectionHelpPagePath"
+ :is-admin="config.isAdmin"
+ class="gl-my-2"
+ />
+
+ <partial-cleanup-alert
+ v-if="showPartialCleanupWarning"
+ :run-cleanup-policies-help-page-path="config.runCleanupPoliciesHelpPagePath"
+ :cleanup-policies-help-page-path="config.cleanupPoliciesHelpPagePath"
+ @dismiss="dismissPartialCleanupWarning"
+ />
- <partial-cleanup-alert
- v-if="showPartialCleanupWarning"
- :run-cleanup-policies-help-page-path="config.runCleanupPoliciesHelpPagePath"
- :cleanup-policies-help-page-path="config.cleanupPoliciesHelpPagePath"
- @dismiss="dismissPartialCleanupWarning = true"
- />
+ <status-alert v-if="image.status" :status="image.status" />
- <details-header :image="image" :metadata-loading="isLoading" />
+ <details-header
+ :image="image"
+ :metadata-loading="isLoading"
+ :disabled="pageActionsAreDisabled"
+ @delete="deleteImage"
+ />
- <tags-loader v-if="isLoading" />
- <template v-else>
- <empty-tags-state v-if="tags.length === 0" :no-containers-image="config.noContainersImage" />
+ <tags-loader v-if="isLoading" />
<template v-else>
- <tags-list :tags="tags" :is-mobile="isMobile" @delete="deleteTags" />
- <div class="gl-display-flex gl-justify-content-center">
- <gl-keyset-pagination
- v-if="showPagination"
- :has-next-page="tagsPageInfo.hasNextPage"
- :has-previous-page="tagsPageInfo.hasPreviousPage"
- class="gl-mt-3"
- @prev="fetchPreviousPage"
- @next="fetchNextPage"
+ <empty-state v-if="hasNoTags" :no-containers-image="config.noContainersImage" />
+ <template v-else>
+ <tags-list
+ :tags="tags"
+ :is-mobile="isMobile"
+ :disabled="pageActionsAreDisabled"
+ @delete="deleteTags"
/>
- </div>
+ <div class="gl-display-flex gl-justify-content-center">
+ <gl-keyset-pagination
+ v-if="showPagination"
+ :has-next-page="tagsPageInfo.hasNextPage"
+ :has-previous-page="tagsPageInfo.hasPreviousPage"
+ class="gl-mt-3"
+ @prev="fetchPreviousPage"
+ @next="fetchNextPage"
+ />
+ </div>
+ </template>
</template>
- </template>
- <delete-modal
- ref="deleteModal"
- :items-to-be-deleted="itemsToBeDeleted"
- @confirmDelete="handleDelete"
- @cancel="track('cancel_delete')"
- />
+ <delete-image
+ :id="image.id"
+ ref="deleteImage"
+ use-update-fn
+ @start="deleteImageIniit"
+ @error="deleteImageError"
+ @end="mutationLoading = false"
+ />
+
+ <delete-modal
+ ref="deleteModal"
+ :items-to-be-deleted="itemsToBeDeleted"
+ :delete-image="deleteImageAlert"
+ @confirmDelete="confirmDelete"
+ @cancel="track('cancel_delete')"
+ />
+ </template>
+ <empty-state v-else is-empty-image :no-containers-image="config.noContainersImage" />
</div>
</template>