Merge branch '41766-vue-component' into 'master'

Creates Vue component to render each release block

See merge request gitlab-org/gitlab-ce!23697
This commit is contained in:
Phil Hughes 2018-12-14 09:15:21 +00:00
commit 120df796ca
4 changed files with 307 additions and 0 deletions

View 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">
&bull;
<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>

View file

@ -0,0 +1,5 @@
---
title: Creates component for release block
merge_request: 23697
author:
type: added

View file

@ -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 ""

View 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,
);
});
});