summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/registry/explorer/pages
diff options
context:
space:
mode:
authorRobert Speicher <rspeicher@gmail.com>2021-01-20 13:34:23 -0600
committerRobert Speicher <rspeicher@gmail.com>2021-01-20 13:34:23 -0600
commit6438df3a1e0fb944485cebf07976160184697d72 (patch)
tree00b09bfd170e77ae9391b1a2f5a93ef6839f2597 /app/assets/javascripts/registry/explorer/pages
parent42bcd54d971da7ef2854b896a7b34f4ef8601067 (diff)
downloadgitlab-ce-6438df3a1e0fb944485cebf07976160184697d72.tar.gz
Add latest changes from gitlab-org/gitlab@13-8-stable-eev13.8.0-rc42
Diffstat (limited to 'app/assets/javascripts/registry/explorer/pages')
-rw-r--r--app/assets/javascripts/registry/explorer/pages/details.vue15
-rw-r--r--app/assets/javascripts/registry/explorer/pages/list.vue138
2 files changed, 104 insertions, 49 deletions
diff --git a/app/assets/javascripts/registry/explorer/pages/details.vue b/app/assets/javascripts/registry/explorer/pages/details.vue
index 540f02d58d4..0894fd6fcfa 100644
--- a/app/assets/javascripts/registry/explorer/pages/details.vue
+++ b/app/assets/javascripts/registry/explorer/pages/details.vue
@@ -22,9 +22,11 @@ import {
ALERT_DANGER_TAGS,
GRAPHQL_PAGE_SIZE,
FETCH_IMAGES_LIST_ERROR_MESSAGE,
+ UNFINISHED_STATUS,
} from '../constants/index';
export default {
+ name: 'RegistryDetailsPage',
components: {
DeleteAlert,
PartialCleanupAlert,
@@ -35,11 +37,11 @@ export default {
TagsLoader,
EmptyTagsState,
},
- inject: ['breadCrumbState', 'config'],
directives: {
GlResizeObserver: GlResizeObserverDirective,
},
mixins: [Tracking.mixin()],
+ inject: ['breadCrumbState', 'config'],
apollo: {
image: {
query: getContainerRepositoryDetailsQuery,
@@ -83,7 +85,10 @@ export default {
return this.image?.tags?.nodes || [];
},
showPartialCleanupWarning() {
- return this.image?.expirationPolicyStartedAt && !this.dismissPartialCleanupWarning;
+ return (
+ this.image?.expirationPolicyCleanupStatus === UNFINISHED_STATUS &&
+ !this.dismissPartialCleanupWarning
+ );
},
tracking() {
return {
@@ -97,7 +102,7 @@ export default {
},
methods: {
deleteTags(toBeDeleted) {
- this.itemsToBeDeleted = this.tags.filter(tag => toBeDeleted[tag.name]);
+ this.itemsToBeDeleted = this.tags.filter((tag) => toBeDeleted[tag.name]);
this.track('click_button');
this.$refs.deleteModal.show();
},
@@ -111,7 +116,7 @@ export default {
mutation: deleteContainerRepositoryTagsMutation,
variables: {
id: this.queryVariables.id,
- tagNames: itemsToBeDeleted.map(i => i.name),
+ tagNames: itemsToBeDeleted.map((i) => i.name),
},
awaitRefetchQueries: true,
refetchQueries: [
@@ -183,7 +188,7 @@ export default {
@dismiss="dismissPartialCleanupWarning = true"
/>
- <details-header :image="image" />
+ <details-header :image="image" :metadata-loading="isLoading" />
<tags-loader v-if="isLoading" />
<template v-else>
diff --git a/app/assets/javascripts/registry/explorer/pages/list.vue b/app/assets/javascripts/registry/explorer/pages/list.vue
index 3192ba82db8..336a997d629 100644
--- a/app/assets/javascripts/registry/explorer/pages/list.vue
+++ b/app/assets/javascripts/registry/explorer/pages/list.vue
@@ -9,17 +9,13 @@ import {
GlSkeletonLoader,
GlSearchBoxByClick,
} from '@gitlab/ui';
+import { get } from 'lodash';
+import getContainerRepositoriesQuery from 'shared_queries/container_registry/get_container_repositories.query.graphql';
import Tracking from '~/tracking';
import createFlash from '~/flash';
-
-import ProjectEmptyState from '../components/list_page/project_empty_state.vue';
-import GroupEmptyState from '../components/list_page/group_empty_state.vue';
import RegistryHeader from '../components/list_page/registry_header.vue';
-import ImageList from '../components/list_page/image_list.vue';
-import CliCommands from '../components/list_page/cli_commands.vue';
-import getProjectContainerRepositoriesQuery from '../graphql/queries/get_project_container_repositories.query.graphql';
-import getGroupContainerRepositoriesQuery from '../graphql/queries/get_group_container_repositories.query.graphql';
+import getContainerRepositoriesDetails from '../graphql/queries/get_container_repositories_details.query.graphql';
import deleteContainerRepositoryMutation from '../graphql/mutations/delete_container_repository.mutation.graphql';
import {
@@ -38,12 +34,25 @@ import {
} from '../constants/index';
export default {
- name: 'RegistryListApp',
+ name: 'RegistryListPage',
components: {
GlEmptyState,
- ProjectEmptyState,
- GroupEmptyState,
- ImageList,
+ ProjectEmptyState: () =>
+ import(
+ /* webpackChunkName: 'container_registry_components' */ '../components/list_page/project_empty_state.vue'
+ ),
+ GroupEmptyState: () =>
+ import(
+ /* webpackChunkName: 'container_registry_components' */ '../components/list_page/group_empty_state.vue'
+ ),
+ ImageList: () =>
+ import(
+ /* webpackChunkName: 'container_registry_components' */ '../components/list_page/image_list.vue'
+ ),
+ CliCommands: () =>
+ import(
+ /* webpackChunkName: 'container_registry_components' */ '../components/list_page/cli_commands.vue'
+ ),
GlModal,
GlSprintf,
GlLink,
@@ -51,13 +60,12 @@ export default {
GlSkeletonLoader,
GlSearchBoxByClick,
RegistryHeader,
- CliCommands,
},
- inject: ['config'],
directives: {
GlTooltip: GlTooltipDirective,
},
mixins: [Tracking.mixin()],
+ inject: ['config'],
loader: {
repeat: 10,
width: 1000,
@@ -74,10 +82,8 @@ export default {
EMPTY_RESULT_MESSAGE,
},
apollo: {
- images: {
- query() {
- return this.graphQlQuery;
- },
+ baseImages: {
+ query: getContainerRepositoriesQuery,
variables() {
return this.queryVariables;
},
@@ -92,10 +98,26 @@ export default {
createFlash({ message: FETCH_IMAGES_LIST_ERROR_MESSAGE });
},
},
+ additionalDetails: {
+ skip() {
+ return !this.fetchAdditionalDetails;
+ },
+ query: getContainerRepositoriesDetails,
+ variables() {
+ return this.queryVariables;
+ },
+ update(data) {
+ return data[this.graphqlResource]?.containerRepositories.nodes;
+ },
+ error() {
+ createFlash({ message: FETCH_IMAGES_LIST_ERROR_MESSAGE });
+ },
+ },
},
data() {
return {
- images: [],
+ baseImages: [],
+ additionalDetails: [],
pageInfo: {},
containerRepositoriesCount: 0,
itemToDelete: {},
@@ -103,21 +125,24 @@ export default {
searchValue: null,
name: null,
mutationLoading: false,
+ fetchAdditionalDetails: false,
};
},
computed: {
+ images() {
+ return this.baseImages.map((image, index) => ({
+ ...image,
+ ...get(this.additionalDetails, index, {}),
+ }));
+ },
graphqlResource() {
return this.config.isGroupPage ? 'group' : 'project';
},
- graphQlQuery() {
- return this.config.isGroupPage
- ? getGroupContainerRepositoriesQuery
- : getProjectContainerRepositoriesQuery;
- },
queryVariables() {
return {
name: this.name,
fullPath: this.config.isGroupPage ? this.config.groupPath : this.config.projectPath,
+ isGroupPage: this.config.isGroupPage,
first: GRAPHQL_PAGE_SIZE,
};
},
@@ -127,7 +152,7 @@ export default {
};
},
isLoading() {
- return this.$apollo.queries.images.loading || this.mutationLoading;
+ return this.$apollo.queries.baseImages.loading || this.mutationLoading;
},
showCommands() {
return Boolean(!this.isLoading && !this.config?.isGroupPage && this.images?.length);
@@ -141,6 +166,13 @@ export default {
: DELETE_IMAGE_ERROR_MESSAGE;
},
},
+ mounted() {
+ // 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
+ setTimeout(() => {
+ this.fetchAdditionalDetails = true;
+ }, 200);
+ },
methods: {
deleteImage(item) {
this.track('click_button');
@@ -175,30 +207,46 @@ export default {
this.deleteAlertType = null;
this.itemToDelete = {};
},
- fetchNextPage() {
+ updateQuery(_, { fetchMoreResult }) {
+ return fetchMoreResult;
+ },
+ async fetchNextPage() {
if (this.pageInfo?.hasNextPage) {
- this.$apollo.queries.images.fetchMore({
- variables: {
- after: this.pageInfo?.endCursor,
- first: GRAPHQL_PAGE_SIZE,
- },
- updateQuery(previousResult, { fetchMoreResult }) {
- return fetchMoreResult;
- },
+ 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,
});
}
},
- fetchPreviousPage() {
+ async fetchPreviousPage() {
if (this.pageInfo?.hasPreviousPage) {
- this.$apollo.queries.images.fetchMore({
- variables: {
- first: null,
- before: this.pageInfo?.startCursor,
- last: GRAPHQL_PAGE_SIZE,
- },
- updateQuery(previousResult, { fetchMoreResult }) {
- return fetchMoreResult;
- },
+ 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,
});
}
},
@@ -230,7 +278,7 @@ export default {
<template #description>
<p>
<gl-sprintf :message="$options.i18n.CONNECTION_ERROR_MESSAGE">
- <template #docLink="{content}">
+ <template #docLink="{ content }">
<gl-link :href="`${config.helpPagePath}#docker-connection-error`" target="_blank">
{{ content }}
</gl-link>
@@ -242,6 +290,7 @@ export default {
<template v-else>
<registry-header
+ :metadata-loading="isLoading"
:images-count="containerRepositoriesCount"
:expiration-policy="config.expirationPolicy"
:help-page-path="config.helpPagePath"
@@ -285,6 +334,7 @@ export default {
<image-list
v-if="images.length"
:images="images"
+ :metadata-loading="$apollo.queries.additionalDetails.loading"
:page-info="pageInfo"
@delete="deleteImage"
@prev-page="fetchPreviousPage"