diff options
Diffstat (limited to 'app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue')
-rw-r--r-- | app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue | 84 |
1 files changed, 51 insertions, 33 deletions
diff --git a/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue b/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue index 080955b4322..57d19af614f 100644 --- a/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue +++ b/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue @@ -1,16 +1,9 @@ <script> -import { - GlAvatar, - GlBadge, - GlButton, - GlIcon, - GlLink, - GlSprintf, - GlTooltipDirective, -} from '@gitlab/ui'; -import { s__ } from '~/locale'; +import { GlAvatar, GlBadge, GlIcon, GlLink, GlSprintf, GlTooltipDirective } from '@gitlab/ui'; +import { s__, n__ } from '~/locale'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { formatDate, getTimeago } from '~/lib/utils/datetime_utility'; +import { cleanLeadingSeparator } from '~/lib/utils/url_utility'; import { CI_RESOURCE_DETAILS_PAGE_NAME } from '../../router/constants'; export default { @@ -21,7 +14,6 @@ export default { components: { GlAvatar, GlBadge, - GlButton, GlIcon, GlLink, GlSprintf, @@ -42,12 +34,27 @@ export default { authorProfileUrl() { return this.latestVersion.author.webUrl; }, + resourceId() { + return cleanLeadingSeparator(this.resource.webPath); + }, + detailsPageResolved() { + return this.$router.resolve({ + name: CI_RESOURCE_DETAILS_PAGE_NAME, + params: { id: this.resourceId }, + }); + }, + detailsPageHref() { + return decodeURIComponent(this.detailsPageResolved.href); + }, entityId() { return getIdFromGraphQLId(this.resource.id); }, starCount() { return this.resource?.starCount || 0; }, + starCountText() { + return n__('Star', 'Stars', this.starCount); + }, hasReleasedVersion() { return Boolean(this.latestVersion?.releasedAt); }, @@ -60,26 +67,33 @@ export default { releasedAt() { return getTimeago().format(this.latestVersion?.releasedAt); }, - resourcePath() { - return `${this.resource.rootNamespace?.name} / ${this.resource.rootNamespace?.fullPath} / `; - }, tagName() { return this.latestVersion?.tagName || this.$options.i18n.unreleased; }, + webPath() { + return cleanLeadingSeparator(this.resource?.webPath); + }, }, methods: { - navigateToDetailsPage() { - this.$router.push({ - name: CI_RESOURCE_DETAILS_PAGE_NAME, - params: { id: this.entityId }, - }); + navigateToDetailsPage(e) { + // Open link in a new tab if any of these modifier key is held down. + if (e?.ctrlKey || e?.metaKey) { + return; + } + + // Override the <a> tag if no modifier key is held down to use Vue router and not + // open a new tab. + e.preventDefault(); + + // Push to the decoded URL to avoid all the / being encoded + this.$router.push({ path: decodeURIComponent(this.resourceId) }); }, }, }; </script> <template> <li - class="gl-display-flex gl-display-flex-wrap gl-border-b-1 gl-border-gray-100 gl-border-b-solid gl-text-gray-500 gl-py-3" + class="gl-display-flex gl-display-flex-wrap gl-align-items-center gl-border-b-1 gl-border-gray-100 gl-border-b-solid gl-text-gray-500 gl-py-3" data-testid="catalog-resource-item" > <gl-avatar @@ -92,36 +106,40 @@ export default { @click="navigateToDetailsPage" /> <div class="gl-display-flex gl-flex-direction-column gl-flex-grow-1"> - <div class="gl-display-flex gl-flex-wrap gl-gap-2 gl-mb-2"> - <gl-button - variant="link" + <span class="gl-font-sm gl-mb-1">{{ webPath }}</span> + <div class="gl-display-flex gl-flex-wrap gl-gap-2 gl-mb-1"> + <gl-link class="gl-text-gray-900! gl-mr-1" + :href="detailsPageHref" data-testid="ci-resource-link" @click="navigateToDetailsPage" > - {{ resourcePath }} <b> {{ resource.name }}</b> - </gl-button> + <b> {{ resource.name }}</b> + </gl-link> <div class="gl-display-flex gl-flex-grow-1 gl-md-justify-content-space-between"> - <gl-badge size="sm">{{ tagName }}</gl-badge> + <gl-badge size="sm" class="gl-h-5 gl-align-self-center">{{ tagName }}</gl-badge> <span class="gl-display-flex gl-align-items-center gl-ml-5"> - <span class="gl--flex-center" data-testid="stats-favorites"> - <gl-icon name="star" :size="14" class="gl-mr-1" /> + <span + v-gl-tooltip.top + :title="starCountText" + class="gl--flex-center" + data-testid="stats-favorites" + > + <gl-icon name="star-o" :size="14" class="gl-mr-2" /> <span class="gl-mr-3">{{ starCount }}</span> </span> </span> </div> </div> <div - class="gl-display-flex gl-flex-direction-column gl-md-flex-direction-row gl-justify-content-space-between" + class="gl-display-flex gl-flex-direction-column gl-md-flex-direction-row gl-justify-content-space-between gl-font-sm" > - <span class="gl-display-flex gl-flex-basis-two-thirds gl-font-sm">{{ - resource.description - }}</span> + <span class="gl-display-flex gl-flex-basis-two-thirds">{{ resource.description }}</span> <div class="gl-display-flex gl-justify-content-end"> <span v-if="hasReleasedVersion"> <gl-sprintf :message="$options.i18n.releasedMessage"> <template #timeAgo> - <span v-gl-tooltip.bottom :title="formattedDate"> + <span v-gl-tooltip.top :title="formattedDate"> {{ releasedAt }} </span> </template> |