Creates Vue component to render each release block
This commit is contained in:
parent
72feadce53
commit
4a1a801812
4 changed files with 307 additions and 0 deletions
145
app/assets/javascripts/releases/components/release_block.vue
Normal file
145
app/assets/javascripts/releases/components/release_block.vue
Normal file
|
@ -0,0 +1,145 @@
|
|||
<script>
|
||||
import { GlTooltipDirective, GlLink } from '@gitlab/ui';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
|
||||
import timeagoMixin from '~/vue_shared/mixins/timeago';
|
||||
import { sprintf } from '../../locale';
|
||||
|
||||
export default {
|
||||
name: 'ReleaseBlock',
|
||||
components: {
|
||||
GlLink,
|
||||
Icon,
|
||||
UserAvatarLink,
|
||||
},
|
||||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
mixins: [timeagoMixin],
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
tag: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
commit: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
author: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
createdAt: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
assetsCount: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0,
|
||||
},
|
||||
sources: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => [],
|
||||
},
|
||||
links: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
releasedTimeAgo() {
|
||||
return sprintf('released %{time}', {
|
||||
time: this.timeFormated(this.createdAt),
|
||||
});
|
||||
},
|
||||
userImageAltDescription() {
|
||||
return this.author && this.author.username
|
||||
? sprintf("%{username}'s avatar", { username: this.author.username })
|
||||
: null;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title mt-0">{{ name }}</h2>
|
||||
|
||||
<div class="card-subtitle d-flex flex-wrap text-secondary">
|
||||
<div class="append-right-8">
|
||||
<icon name="commit" class="align-middle" />
|
||||
<span v-gl-tooltip.bottom :title="commit.title">{{ commit.short_id }}</span>
|
||||
</div>
|
||||
|
||||
<div class="append-right-8">
|
||||
<icon name="tag" class="align-middle" />
|
||||
<span v-gl-tooltip.bottom :title="__('Tag')">{{ tag }}</span>
|
||||
</div>
|
||||
|
||||
<div class="append-right-4">
|
||||
•
|
||||
<span v-gl-tooltip.bottom :title="tooltipTitle(createdAt)">{{ releasedTimeAgo }}</span>
|
||||
</div>
|
||||
|
||||
<div class="d-flex">
|
||||
by
|
||||
<user-avatar-link
|
||||
class="prepend-left-4"
|
||||
:link-href="author.path"
|
||||
:img-src="author.avatar_url"
|
||||
:img-alt="userImageAltDescription"
|
||||
:tooltip-text="author.username"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-text prepend-top-default">
|
||||
<b>
|
||||
{{ __('Assets') }} <span class="js-assets-count badge badge-pill">{{ assetsCount }}</span>
|
||||
</b>
|
||||
|
||||
<ul class="pl-0 mb-0 prepend-top-8 list-unstyled js-assets-list">
|
||||
<li v-for="link in links" :key="link.name" class="append-bottom-8">
|
||||
<gl-link v-gl-tooltip.bottom :title="__('Download asset')" :href="link.url">
|
||||
<icon name="package" class="align-middle append-right-4" /> {{ link.name }}
|
||||
</gl-link>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="dropdown">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-link"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<icon name="doc-code" class="align-top append-right-4" /> {{ __('Source code') }}
|
||||
<icon name="arrow-down" />
|
||||
</button>
|
||||
|
||||
<div class="js-sources-dropdown dropdown-menu">
|
||||
<li v-for="asset in sources" :key="asset.url">
|
||||
<gl-link :href="asset.url">{{ __('Download') }} {{ asset.format }}</gl-link>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-text prepend-top-default"><div v-html="description"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
5
changelogs/unreleased/41766-vue-component.yml
Normal file
5
changelogs/unreleased/41766-vue-component.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Creates component for release block
|
||||
merge_request: 23697
|
||||
author:
|
||||
type: added
|
|
@ -711,6 +711,9 @@ msgstr ""
|
|||
msgid "Ask your group maintainer to set up a group Runner."
|
||||
msgstr ""
|
||||
|
||||
msgid "Assets"
|
||||
msgstr ""
|
||||
|
||||
msgid "Assign custom color like #FF0000"
|
||||
msgstr ""
|
||||
|
||||
|
@ -2587,6 +2590,9 @@ msgstr ""
|
|||
msgid "Download"
|
||||
msgstr ""
|
||||
|
||||
msgid "Download asset"
|
||||
msgstr ""
|
||||
|
||||
msgid "Download tar"
|
||||
msgstr ""
|
||||
|
||||
|
@ -6377,6 +6383,9 @@ msgstr ""
|
|||
msgid "System metrics (Kubernetes)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tag"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tags"
|
||||
msgstr ""
|
||||
|
||||
|
|
148
spec/javascripts/releases/components/release_block_spec.js
Normal file
148
spec/javascripts/releases/components/release_block_spec.js
Normal file
|
@ -0,0 +1,148 @@
|
|||
import Vue from 'vue';
|
||||
import component from '~/releases/components/release_block.vue';
|
||||
import timeagoMixin from '~/vue_shared/mixins/timeago';
|
||||
|
||||
import mountComponent from '../../helpers/vue_mount_component_helper';
|
||||
|
||||
describe('Release block', () => {
|
||||
const Component = Vue.extend(component);
|
||||
|
||||
const release = {
|
||||
name: 'Bionic Beaver',
|
||||
tag_name: '18.04',
|
||||
description: '## changelog\n\n* line 1\n* line2',
|
||||
description_html: '<div><h2>changelog</h2><ul><li>line1</li<li>line 2</li></ul></div>',
|
||||
author_name: 'Release bot',
|
||||
author_email: 'release-bot@example.com',
|
||||
created_at: '2012-05-28T05:00:00-07:00',
|
||||
commit: {
|
||||
id: '2695effb5807a22ff3d138d593fd856244e155e7',
|
||||
short_id: '2695effb',
|
||||
title: 'Initial commit',
|
||||
created_at: '2017-07-26T11:08:53.000+02:00',
|
||||
parent_ids: ['2a4b78934375d7f53875269ffd4f45fd83a84ebe'],
|
||||
message: 'Initial commit',
|
||||
author_name: 'John Smith',
|
||||
author_email: 'john@example.com',
|
||||
authored_date: '2012-05-28T04:42:42-07:00',
|
||||
committer_name: 'Jack Smith',
|
||||
committer_email: 'jack@example.com',
|
||||
committed_date: '2012-05-28T04:42:42-07:00',
|
||||
},
|
||||
assets: {
|
||||
count: 6,
|
||||
sources: [
|
||||
{
|
||||
format: 'zip',
|
||||
url: 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.zip',
|
||||
},
|
||||
{
|
||||
format: 'tar.gz',
|
||||
url:
|
||||
'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.gz',
|
||||
},
|
||||
{
|
||||
format: 'tar.bz2',
|
||||
url:
|
||||
'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.bz2',
|
||||
},
|
||||
{
|
||||
format: 'tar',
|
||||
url: 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar',
|
||||
},
|
||||
],
|
||||
links: [
|
||||
{
|
||||
name: 'release-18.04.dmg',
|
||||
url: 'https://my-external-hosting.example.com/scrambled-url/',
|
||||
external: true,
|
||||
},
|
||||
{
|
||||
name: 'binary-linux-amd64',
|
||||
url:
|
||||
'https://gitlab.com/gitlab-org/gitlab-ce/-/jobs/artifacts/v11.6.0-rc4/download?job=rspec-mysql+41%2F50',
|
||||
external: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const props = {
|
||||
name: release.name,
|
||||
tag: release.tag_name,
|
||||
commit: release.commit,
|
||||
description: release.description_html,
|
||||
author: {
|
||||
avatar_url: 'uploads/-/system/user/avatar/johndoe/avatar.png',
|
||||
id: 482476,
|
||||
name: 'John Doe',
|
||||
path: '/johndoe',
|
||||
state: 'active',
|
||||
status_tooltip_html: null,
|
||||
username: 'johndoe',
|
||||
web_url: 'https://gitlab.com/johndoe',
|
||||
},
|
||||
createdAt: release.created_at,
|
||||
assetsCount: release.assets.count,
|
||||
sources: release.assets.sources,
|
||||
links: release.assets.links,
|
||||
};
|
||||
|
||||
let vm;
|
||||
|
||||
beforeEach(() => {
|
||||
vm = mountComponent(Component, props);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
});
|
||||
|
||||
it('renders release name', () => {
|
||||
expect(vm.$el.textContent).toContain(release.name);
|
||||
});
|
||||
|
||||
it('renders commit sha', () => {
|
||||
expect(vm.$el.textContent).toContain(release.commit.short_id);
|
||||
});
|
||||
|
||||
it('renders tag name', () => {
|
||||
expect(vm.$el.textContent).toContain(release.tag_name);
|
||||
});
|
||||
|
||||
it('renders release date', () => {
|
||||
expect(vm.$el.textContent).toContain(timeagoMixin.methods.timeFormated(release.created_at));
|
||||
});
|
||||
|
||||
it('renders number of assets provided', () => {
|
||||
expect(vm.$el.querySelector('.js-assets-count').textContent).toContain(release.assets.count);
|
||||
});
|
||||
|
||||
it('renders dropdown with the sources', () => {
|
||||
expect(vm.$el.querySelectorAll('.js-sources-dropdown li').length).toEqual(
|
||||
release.assets.sources.length,
|
||||
);
|
||||
|
||||
expect(vm.$el.querySelector('.js-sources-dropdown li a').getAttribute('href')).toEqual(
|
||||
release.assets.sources[0].url,
|
||||
);
|
||||
|
||||
expect(vm.$el.querySelector('.js-sources-dropdown li a').textContent).toContain(
|
||||
release.assets.sources[0].format,
|
||||
);
|
||||
});
|
||||
|
||||
it('renders list with the links provided', () => {
|
||||
expect(vm.$el.querySelectorAll('.js-assets-list li').length).toEqual(
|
||||
release.assets.links.length,
|
||||
);
|
||||
|
||||
expect(vm.$el.querySelector('.js-assets-list li a').getAttribute('href')).toEqual(
|
||||
release.assets.links[0].url,
|
||||
);
|
||||
|
||||
expect(vm.$el.querySelector('.js-assets-list li a').textContent).toContain(
|
||||
release.assets.links[0].name,
|
||||
);
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue