summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/registry/explorer/components
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/components
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/components')
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/delete_alert.vue2
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/details_header.vue60
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/partial_cleanup_alert.vue4
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/tags_list.vue5
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue4
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/cli_commands.vue2
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/group_empty_state.vue4
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/image_list.vue6
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue23
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/project_empty_state.vue8
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue12
-rw-r--r--app/assets/javascripts/registry/explorer/components/registry_breadcrumb.vue81
12 files changed, 141 insertions, 70 deletions
diff --git a/app/assets/javascripts/registry/explorer/components/details_page/delete_alert.vue b/app/assets/javascripts/registry/explorer/components/details_page/delete_alert.vue
index 8bdf043a106..56d2ff86fb7 100644
--- a/app/assets/javascripts/registry/explorer/components/details_page/delete_alert.vue
+++ b/app/assets/javascripts/registry/explorer/components/details_page/delete_alert.vue
@@ -60,7 +60,7 @@ export default {
@dismiss="$emit('change', null)"
>
<gl-sprintf :message="deleteAlertConfig.message">
- <template #docLink="{content}">
+ <template #docLink="{ content }">
<gl-link :href="garbageCollectionHelpPagePath" target="_blank">
{{ content }}
</gl-link>
diff --git a/app/assets/javascripts/registry/explorer/components/details_page/details_header.vue b/app/assets/javascripts/registry/explorer/components/details_page/details_header.vue
index 3eeb7b29386..ed02aa264ed 100644
--- a/app/assets/javascripts/registry/explorer/components/details_page/details_header.vue
+++ b/app/assets/javascripts/registry/explorer/components/details_page/details_header.vue
@@ -1,12 +1,29 @@
<script>
import { GlSprintf } from '@gitlab/ui';
-import { sprintf } from '~/locale';
+import { sprintf, n__ } from '~/locale';
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue';
import timeagoMixin from '~/vue_shared/mixins/timeago';
-import { DETAILS_PAGE_TITLE, UPDATED_AT } from '../../constants/index';
+import {
+ DETAILS_PAGE_TITLE,
+ UPDATED_AT,
+ CLEANUP_UNSCHEDULED_TEXT,
+ CLEANUP_SCHEDULED_TEXT,
+ CLEANUP_ONGOING_TEXT,
+ CLEANUP_UNFINISHED_TEXT,
+ CLEANUP_DISABLED_TEXT,
+ CLEANUP_SCHEDULED_TOOLTIP,
+ CLEANUP_ONGOING_TOOLTIP,
+ CLEANUP_UNFINISHED_TOOLTIP,
+ CLEANUP_DISABLED_TOOLTIP,
+ UNFINISHED_STATUS,
+ UNSCHEDULED_STATUS,
+ SCHEDULED_STATUS,
+ ONGOING_STATUS,
+} from '../../constants/index';
export default {
+ name: 'DetailsHeader',
components: { GlSprintf, TitleArea, MetadataItem },
mixins: [timeagoMixin],
props: {
@@ -14,6 +31,11 @@ export default {
type: Object,
required: true,
},
+ metadataLoading: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
computed: {
visibilityIcon() {
@@ -25,6 +47,24 @@ export default {
updatedText() {
return sprintf(UPDATED_AT, { time: this.timeAgo });
},
+ tagCountText() {
+ return n__('%d tag', '%d tags', this.image.tagsCount);
+ },
+ cleanupTextAndTooltip() {
+ if (!this.image.project.containerExpirationPolicy?.enabled) {
+ return { text: CLEANUP_DISABLED_TEXT, tooltip: CLEANUP_DISABLED_TOOLTIP };
+ }
+ return {
+ [UNSCHEDULED_STATUS]: {
+ text: sprintf(CLEANUP_UNSCHEDULED_TEXT, {
+ time: this.timeFormatted(this.image.project.containerExpirationPolicy.nextRunAt),
+ }),
+ },
+ [SCHEDULED_STATUS]: { text: CLEANUP_SCHEDULED_TEXT, tooltip: CLEANUP_SCHEDULED_TOOLTIP },
+ [ONGOING_STATUS]: { text: CLEANUP_ONGOING_TEXT, tooltip: CLEANUP_ONGOING_TOOLTIP },
+ [UNFINISHED_STATUS]: { text: CLEANUP_UNFINISHED_TEXT, tooltip: CLEANUP_UNFINISHED_TOOLTIP },
+ }[this.image?.expirationPolicyCleanupStatus];
+ },
},
i18n: {
DETAILS_PAGE_TITLE,
@@ -33,7 +73,7 @@ export default {
</script>
<template>
- <title-area>
+ <title-area :metadata-loading="metadataLoading">
<template #title>
<gl-sprintf :message="$options.i18n.DETAILS_PAGE_TITLE">
<template #imageName>
@@ -41,6 +81,20 @@ export default {
</template>
</gl-sprintf>
</template>
+ <template #metadata-tags-count>
+ <metadata-item icon="tag" :text="tagCountText" data-testid="tags-count" />
+ </template>
+
+ <template #metadata-cleanup>
+ <metadata-item
+ icon="expire"
+ :text="cleanupTextAndTooltip.text"
+ :text-tooltip="cleanupTextAndTooltip.tooltip"
+ size="xl"
+ data-testid="cleanup"
+ />
+ </template>
+
<template #metadata-updated>
<metadata-item
:icon="visibilityIcon"
diff --git a/app/assets/javascripts/registry/explorer/components/details_page/partial_cleanup_alert.vue b/app/assets/javascripts/registry/explorer/components/details_page/partial_cleanup_alert.vue
index d13d815a59e..12095655126 100644
--- a/app/assets/javascripts/registry/explorer/components/details_page/partial_cleanup_alert.vue
+++ b/app/assets/javascripts/registry/explorer/components/details_page/partial_cleanup_alert.vue
@@ -23,12 +23,12 @@ export default {
<template>
<gl-alert variant="warning" :title="$options.i18n.DELETE_ALERT_TITLE" @dismiss="$emit('dismiss')">
<gl-sprintf :message="$options.i18n.DELETE_ALERT_LINK_TEXT">
- <template #adminLink="{content}">
+ <template #adminLink="{ content }">
<gl-link data-testid="run-link" :href="runCleanupPoliciesHelpPagePath" target="_blank">{{
content
}}</gl-link>
</template>
- <template #docLink="{content}">
+ <template #docLink="{ content }">
<gl-link data-testid="help-link" :href="cleanupPoliciesHelpPagePath" target="_blank">{{
content
}}</gl-link>
diff --git a/app/assets/javascripts/registry/explorer/components/details_page/tags_list.vue b/app/assets/javascripts/registry/explorer/components/details_page/tags_list.vue
index ad39a898e7b..1e0736c4a53 100644
--- a/app/assets/javascripts/registry/explorer/components/details_page/tags_list.vue
+++ b/app/assets/javascripts/registry/explorer/components/details_page/tags_list.vue
@@ -4,6 +4,7 @@ import TagsListRow from './tags_list_row.vue';
import { REMOVE_TAGS_BUTTON_TITLE, TAGS_LIST_TITLE } from '../../constants/index';
export default {
+ name: 'TagsList',
components: {
GlButton,
TagsListRow,
@@ -31,10 +32,10 @@ export default {
},
computed: {
hasSelectedItems() {
- return this.tags.some(tag => this.selectedItems[tag.name]);
+ return this.tags.some((tag) => this.selectedItems[tag.name]);
},
showMultiDeleteButton() {
- return this.tags.some(tag => tag.canDelete) && !this.isMobile;
+ return this.tags.some((tag) => tag.canDelete) && !this.isMobile;
},
},
methods: {
diff --git a/app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue b/app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue
index 3a5cccc7d08..2e4a489f2cb 100644
--- a/app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue
+++ b/app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue
@@ -140,9 +140,7 @@ export default {
<template #left-secondary>
<span data-testid="size">
{{ formattedSize }}
- <template v-if="formattedSize && layers"
- >&middot;</template
- >
+ <template v-if="formattedSize && layers">&middot;</template>
{{ layers }}
</span>
</template>
diff --git a/app/assets/javascripts/registry/explorer/components/list_page/cli_commands.vue b/app/assets/javascripts/registry/explorer/components/list_page/cli_commands.vue
index 319666210d6..07ee3c6083b 100644
--- a/app/assets/javascripts/registry/explorer/components/list_page/cli_commands.vue
+++ b/app/assets/javascripts/registry/explorer/components/list_page/cli_commands.vue
@@ -19,8 +19,8 @@ export default {
GlDropdown,
CodeInstruction,
},
- inject: ['config', 'dockerBuildCommand', 'dockerPushCommand', 'dockerLoginCommand'],
mixins: [Tracking.mixin({ label: trackingLabel })],
+ inject: ['config', 'dockerBuildCommand', 'dockerPushCommand', 'dockerLoginCommand'],
trackingLabel,
i18n: {
QUICK_START,
diff --git a/app/assets/javascripts/registry/explorer/components/list_page/group_empty_state.vue b/app/assets/javascripts/registry/explorer/components/list_page/group_empty_state.vue
index 26e9fee63af..a68c4de5aa6 100644
--- a/app/assets/javascripts/registry/explorer/components/list_page/group_empty_state.vue
+++ b/app/assets/javascripts/registry/explorer/components/list_page/group_empty_state.vue
@@ -3,12 +3,12 @@ import { GlEmptyState, GlSprintf, GlLink } from '@gitlab/ui';
export default {
name: 'GroupEmptyState',
- inject: ['config'],
components: {
GlEmptyState,
GlSprintf,
GlLink,
},
+ inject: ['config'],
};
</script>
<template>
@@ -25,7 +25,7 @@ export default {
)
"
>
- <template #docLink="{content}">
+ <template #docLink="{ content }">
<gl-link :href="config.helpPagePath" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
diff --git a/app/assets/javascripts/registry/explorer/components/list_page/image_list.vue b/app/assets/javascripts/registry/explorer/components/list_page/image_list.vue
index f8b3233438f..10ad99d5956 100644
--- a/app/assets/javascripts/registry/explorer/components/list_page/image_list.vue
+++ b/app/assets/javascripts/registry/explorer/components/list_page/image_list.vue
@@ -13,6 +13,11 @@ export default {
type: Array,
required: true,
},
+ metadataLoading: {
+ type: Boolean,
+ default: false,
+ required: false,
+ },
pageInfo: {
type: Object,
required: true,
@@ -33,6 +38,7 @@ export default {
:key="index"
:item="listItem"
:first="index === 0"
+ :metadata-loading="metadataLoading"
@delete="$emit('delete', $event)"
/>
<div class="gl-display-flex gl-justify-content-center">
diff --git a/app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue b/app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue
index 3fe61dc231a..264a3c27cde 100644
--- a/app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue
+++ b/app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue
@@ -1,5 +1,5 @@
<script>
-import { GlTooltipDirective, GlIcon, GlSprintf } from '@gitlab/ui';
+import { GlTooltipDirective, GlIcon, GlSprintf, GlSkeletonLoader } from '@gitlab/ui';
import { n__ } from '~/locale';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
@@ -18,13 +18,14 @@ import {
} from '../../constants/index';
export default {
- name: 'ImageListrow',
+ name: 'ImageListRow',
components: {
ClipboardButton,
DeleteButton,
GlSprintf,
GlIcon,
ListItem,
+ GlSkeletonLoader,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -34,6 +35,11 @@ export default {
type: Object,
required: true,
},
+ metadataLoading: {
+ type: Boolean,
+ default: false,
+ required: false,
+ },
},
i18n: {
LIST_DELETE_BUTTON_DISABLED,
@@ -107,7 +113,11 @@ export default {
/>
</template>
<template #left-secondary>
- <span class="gl-display-flex gl-align-items-center" data-testid="tagsCount">
+ <span
+ v-if="!metadataLoading"
+ class="gl-display-flex gl-align-items-center"
+ data-testid="tags-count"
+ >
<gl-icon name="tag" class="gl-mr-2" />
<gl-sprintf :message="tagsCountText">
<template #count>
@@ -115,6 +125,13 @@ export default {
</template>
</gl-sprintf>
</span>
+
+ <div v-else class="gl-w-full">
+ <gl-skeleton-loader :width="900" :height="16" preserve-aspect-ratio="xMinYMax meet">
+ <circle cx="6" cy="8" r="6" />
+ <rect x="16" y="4" width="100" height="8" rx="4" />
+ </gl-skeleton-loader>
+ </div>
</template>
<template #right-action>
<delete-button
diff --git a/app/assets/javascripts/registry/explorer/components/list_page/project_empty_state.vue b/app/assets/javascripts/registry/explorer/components/list_page/project_empty_state.vue
index 5308b025cc0..5aa04419ca0 100644
--- a/app/assets/javascripts/registry/explorer/components/list_page/project_empty_state.vue
+++ b/app/assets/javascripts/registry/explorer/components/list_page/project_empty_state.vue
@@ -45,7 +45,7 @@ export default {
<template #description>
<p>
<gl-sprintf :message="$options.i18n.introText">
- <template #docLink="{content}">
+ <template #docLink="{ content }">
<gl-link :href="config.helpPagePath" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
@@ -53,10 +53,10 @@ export default {
<h5>{{ $options.i18n.quickStart }}</h5>
<p>
<gl-sprintf :message="$options.i18n.notLoggedInMessage">
- <template #twofaDocLink="{content}">
+ <template #twofaDocLink="{ content }">
<gl-link :href="config.twoFactorAuthHelpLink" target="_blank">{{ content }}</gl-link>
</template>
- <template #personalAccessTokensDocLink="{content}">
+ <template #personalAccessTokensDocLink="{ content }">
<gl-link :href="config.personalAccessTokensHelpLink" target="_blank">{{
content
}}</gl-link>
@@ -81,7 +81,7 @@ export default {
<p class="gl-mb-4">
{{ $options.i18n.addImageText }}
</p>
- <gl-form-input-group class="gl-mb-4 ">
+ <gl-form-input-group class="gl-mb-4">
<gl-form-input
:value="dockerBuildCommand"
readonly
diff --git a/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue b/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue
index c2bd01701df..f01e3c9d24a 100644
--- a/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue
+++ b/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue
@@ -13,6 +13,7 @@ import {
} from '../../constants/index';
export default {
+ name: 'ListHeader',
components: {
TitleArea,
MetadataItem,
@@ -43,6 +44,11 @@ export default {
required: false,
default: false,
},
+ metadataLoading: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
loader: {
repeat: 10,
@@ -92,7 +98,11 @@ export default {
</script>
<template>
- <title-area :title="$options.i18n.CONTAINER_REGISTRY_TITLE" :info-messages="infoMessages">
+ <title-area
+ :title="$options.i18n.CONTAINER_REGISTRY_TITLE"
+ :info-messages="infoMessages"
+ :metadata-loading="metadataLoading"
+ >
<template #right-actions>
<slot name="commands"></slot>
</template>
diff --git a/app/assets/javascripts/registry/explorer/components/registry_breadcrumb.vue b/app/assets/javascripts/registry/explorer/components/registry_breadcrumb.vue
index 1cedcc41b2b..e77eda31596 100644
--- a/app/assets/javascripts/registry/explorer/components/registry_breadcrumb.vue
+++ b/app/assets/javascripts/registry/explorer/components/registry_breadcrumb.vue
@@ -1,66 +1,51 @@
<script>
-/* eslint-disable vue/no-v-html */
-// We are forced to use `v-html` untill this gitlab-ui issue is resolved: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1079
-// then we can re-write this to use gl-breadcrumb
-import { initial, first, last } from 'lodash';
-import { sanitize } from '~/lib/dompurify';
+// We are using gl-breadcrumb only at the last child of the handwritten breadcrumb
+// until this gitlab-ui issue is resolved: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1079
+//
+// See the CSS workaround in app/assets/stylesheets/pages/registry.scss when this file is changed.
+import { GlBreadcrumb, GlIcon } from '@gitlab/ui';
export default {
- props: {
- crumbs: {
- type: Array,
- required: true,
- },
+ components: {
+ GlBreadcrumb,
+ GlIcon,
},
computed: {
- parsedCrumbs() {
- return this.crumbs.map(c => ({ ...c, innerHTML: sanitize(c.innerHTML) }));
- },
rootRoute() {
- return this.$router.options.routes.find(r => r.meta.root);
+ return this.$router.options.routes.find((r) => r.meta.root);
+ },
+ detailsRoute() {
+ return this.$router.options.routes.find((r) => r.name === 'details');
},
isRootRoute() {
return this.$route.name === this.rootRoute.name;
},
- rootCrumbs() {
- return initial(this.parsedCrumbs);
- },
- divider() {
- const { classList, tagName, innerHTML } = first(this.crumbs).querySelector('svg');
- return { classList: [...classList], tagName, innerHTML: sanitize(innerHTML) };
+ isLoaded() {
+ return this.isRootRoute || this.$store?.state.imageDetails?.name;
},
- lastCrumb() {
- const { children } = last(this.crumbs);
- const { tagName, className } = first(children);
- return {
- tagName,
- className,
- text: this.$route.meta.nameGenerator(),
- path: { to: this.$route.name },
- };
+ allCrumbs() {
+ const crumbs = [
+ {
+ text: this.rootRoute.meta.nameGenerator(),
+ to: this.rootRoute.path,
+ },
+ ];
+ if (!this.isRootRoute) {
+ crumbs.push({
+ text: this.detailsRoute.meta.nameGenerator(),
+ href: this.detailsRoute.meta.path,
+ });
+ }
+ return crumbs;
},
},
};
</script>
<template>
- <ul>
- <li
- v-for="(crumb, index) in rootCrumbs"
- :key="index"
- :class="crumb.className"
- v-html="crumb.innerHTML"
- ></li>
- <li v-if="!isRootRoute">
- <router-link ref="rootRouteLink" :to="rootRoute.path">
- {{ rootRoute.meta.nameGenerator() }}
- </router-link>
- <component :is="divider.tagName" :class="divider.classList" v-html="divider.innerHTML" />
- </li>
- <li>
- <component :is="lastCrumb.tagName" ref="lastCrumb" :class="lastCrumb.className">
- <router-link ref="childRouteLink" :to="lastCrumb.path">{{ lastCrumb.text }}</router-link>
- </component>
- </li>
- </ul>
+ <gl-breadcrumb :key="isLoaded" :items="allCrumbs">
+ <template #separator>
+ <gl-icon name="angle-right" :size="8" />
+ </template>
+ </gl-breadcrumb>
</template>