Merge branch '62966-embed-zoom-call-in-issue-mvc' into 'master'
Resolve "Embed Zoom Call in Issue MVC" Closes #62966 See merge request gitlab-org/gitlab-ce!29454
This commit is contained in:
commit
cdb4424ec0
|
@ -11,6 +11,7 @@ import titleComponent from './title.vue';
|
|||
import descriptionComponent from './description.vue';
|
||||
import editedComponent from './edited.vue';
|
||||
import formComponent from './form.vue';
|
||||
import PinnedLinks from './pinned_links.vue';
|
||||
import recaptchaModalImplementor from '../../vue_shared/mixins/recaptcha_modal_implementor';
|
||||
|
||||
export default {
|
||||
|
@ -19,6 +20,7 @@ export default {
|
|||
titleComponent,
|
||||
editedComponent,
|
||||
formComponent,
|
||||
PinnedLinks,
|
||||
},
|
||||
mixins: [recaptchaModalImplementor],
|
||||
props: {
|
||||
|
@ -340,6 +342,7 @@ export default {
|
|||
:title-text="state.titleText"
|
||||
:show-inline-edit-button="showInlineEditButton"
|
||||
/>
|
||||
<pinned-links :description-html="state.descriptionHtml" />
|
||||
<description-component
|
||||
v-if="state.descriptionHtml"
|
||||
:can-update="canUpdate"
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<script>
|
||||
import { GlLink } from '@gitlab/ui';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Icon,
|
||||
GlLink,
|
||||
},
|
||||
props: {
|
||||
descriptionHtml: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
linksInDescription() {
|
||||
const el = document.createElement('div');
|
||||
el.innerHTML = this.descriptionHtml;
|
||||
return [...el.querySelectorAll('a')].map(a => a.href);
|
||||
},
|
||||
// Detect links matching the following formats:
|
||||
// Zoom Start links: https://zoom.us/s/<meeting-id>
|
||||
// Zoom Join links: https://zoom.us/j/<meeting-id>
|
||||
// Personal Zoom links: https://zoom.us/my/<meeting-id>
|
||||
// Vanity Zoom links: https://gitlab.zoom.us/j/<meeting-id> (also /s and /my)
|
||||
zoomHref() {
|
||||
const zoomRegex = /^https:\/\/([\w\d-]+\.)?zoom\.us\/(s|j|my)\/.+/;
|
||||
return this.linksInDescription.reduce((acc, currentLink) => {
|
||||
let lastLink = acc;
|
||||
if (zoomRegex.test(currentLink)) {
|
||||
lastLink = currentLink;
|
||||
}
|
||||
return lastLink;
|
||||
}, '');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="zoomHref" class="border-bottom mb-3 mt-n2">
|
||||
<gl-link
|
||||
:href="zoomHref"
|
||||
target="_blank"
|
||||
class="btn btn-inverted btn-secondary btn-sm text-dark mb-3"
|
||||
>
|
||||
<icon name="brand-zoom" :size="14" />
|
||||
<strong class="vertical-align-top">{{ __('Join Zoom meeting') }}</strong>
|
||||
</gl-link>
|
||||
</div>
|
||||
</template>
|
|
@ -416,6 +416,7 @@ img.emoji {
|
|||
.center { text-align: center; }
|
||||
.block { display: block; }
|
||||
.flex { display: flex; }
|
||||
.vertical-align-top { vertical-align: top; }
|
||||
.vertical-align-middle { vertical-align: middle; }
|
||||
.vertical-align-sub { vertical-align: sub; }
|
||||
.flex-align-self-center { align-self: center; }
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add Join meeting button to issues with Zoom links
|
||||
merge_request: 29454
|
||||
author:
|
||||
type: added
|
|
@ -5597,6 +5597,9 @@ msgstr ""
|
|||
msgid "Job|with"
|
||||
msgstr ""
|
||||
|
||||
msgid "Join Zoom meeting"
|
||||
msgstr ""
|
||||
|
||||
msgid "Jul"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
"@babel/plugin-syntax-import-meta": "^7.2.0",
|
||||
"@babel/preset-env": "^7.4.4",
|
||||
"@gitlab/csslab": "^1.9.0",
|
||||
"@gitlab/svgs": "^1.63.0",
|
||||
"@gitlab/svgs": "^1.64.0",
|
||||
"@gitlab/ui": "^4.0.0",
|
||||
"apollo-cache-inmemory": "^1.5.1",
|
||||
"apollo-client": "^2.5.1",
|
||||
|
|
|
@ -92,6 +92,19 @@ describe "User creates issue" do
|
|||
.and have_content(label_titles.first)
|
||||
end
|
||||
end
|
||||
|
||||
context "with Zoom link" do
|
||||
it "adds Zoom button" do
|
||||
issue_title = "Issue containing Zoom meeting link"
|
||||
zoom_url = "https://gitlab.zoom.us/j/123456789"
|
||||
|
||||
fill_in("Title", with: issue_title)
|
||||
fill_in("Description", with: zoom_url)
|
||||
click_button("Submit issue")
|
||||
|
||||
expect(page).to have_link('Join Zoom meeting', href: zoom_url)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when signed in as user with special characters in their name" do
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
||||
import { GlLink } from '@gitlab/ui';
|
||||
import PinnedLinks from '~/issue_show/components/pinned_links.vue';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
|
||||
const plainZoomUrl = 'https://zoom.us/j/123456789';
|
||||
const vanityZoomUrl = 'https://gitlab.zoom.us/j/123456789';
|
||||
const startZoomUrl = 'https://zoom.us/s/123456789';
|
||||
const personalZoomUrl = 'https://zoom.us/my/hunter-zoloman';
|
||||
const randomUrl = 'https://zoom.us.com';
|
||||
|
||||
describe('PinnedLinks', () => {
|
||||
let wrapper;
|
||||
|
||||
const link = {
|
||||
get text() {
|
||||
return wrapper.find(GlLink).text();
|
||||
},
|
||||
get href() {
|
||||
return wrapper.find(GlLink).attributes('href');
|
||||
},
|
||||
};
|
||||
|
||||
const createComponent = props => {
|
||||
wrapper = shallowMount(localVue.extend(PinnedLinks), {
|
||||
localVue,
|
||||
sync: false,
|
||||
propsData: {
|
||||
descriptionHtml: '',
|
||||
...props,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
it('displays Zoom link', () => {
|
||||
createComponent({
|
||||
descriptionHtml: `<a href="${plainZoomUrl}">Zoom</a>`,
|
||||
});
|
||||
|
||||
expect(link.text).toBe('Join Zoom meeting');
|
||||
});
|
||||
|
||||
it('detects plain Zoom link', () => {
|
||||
createComponent({
|
||||
descriptionHtml: `<a href="${plainZoomUrl}">Zoom</a>`,
|
||||
});
|
||||
|
||||
expect(link.href).toBe(plainZoomUrl);
|
||||
});
|
||||
|
||||
it('detects vanity Zoom link', () => {
|
||||
createComponent({
|
||||
descriptionHtml: `<a href="${vanityZoomUrl}">Zoom</a>`,
|
||||
});
|
||||
|
||||
expect(link.href).toBe(vanityZoomUrl);
|
||||
});
|
||||
|
||||
it('detects Zoom start meeting link', () => {
|
||||
createComponent({
|
||||
descriptionHtml: `<a href="${startZoomUrl}">Zoom</a>`,
|
||||
});
|
||||
|
||||
expect(link.href).toBe(startZoomUrl);
|
||||
});
|
||||
|
||||
it('detects personal Zoom room link', () => {
|
||||
createComponent({
|
||||
descriptionHtml: `<a href="${personalZoomUrl}">Zoom</a>`,
|
||||
});
|
||||
|
||||
expect(link.href).toBe(personalZoomUrl);
|
||||
});
|
||||
|
||||
it('only renders final Zoom link in description', () => {
|
||||
createComponent({
|
||||
descriptionHtml: `<a href="${plainZoomUrl}">Zoom</a><a href="${vanityZoomUrl}">Zoom</a>`,
|
||||
});
|
||||
|
||||
expect(link.href).toBe(vanityZoomUrl);
|
||||
});
|
||||
|
||||
it('does not render for other links', () => {
|
||||
createComponent({
|
||||
descriptionHtml: `<a href="${randomUrl}">Some other link</a>`,
|
||||
});
|
||||
|
||||
expect(wrapper.find(GlLink).exists()).toBe(false);
|
||||
});
|
||||
});
|
|
@ -700,10 +700,10 @@
|
|||
dependencies:
|
||||
requireindex "~1.1.0"
|
||||
|
||||
"@gitlab/svgs@^1.63.0":
|
||||
version "1.63.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.63.0.tgz#9dd544026d203e4ce6efed72b05db68f710c4d49"
|
||||
integrity sha512-YztrReFTg31B7v5wtUC5j15KHNcMebtW+kACytEU42XomMaIwk4USIbygqWlq0VRHA2VHJrHApfJHIjxiCCQcA==
|
||||
"@gitlab/svgs@^1.64.0":
|
||||
version "1.64.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.64.0.tgz#1370bcbe9ca0ecc9fb919956cd4241bea090ddd3"
|
||||
integrity sha512-y9p73NGDnQJc18Dtk0oJfgxedancBT6UceATcnZMceLV6iWylzdMbQWxCl4O2aBXwsAoCrLUJQ9jhRkbNicYNA==
|
||||
|
||||
"@gitlab/ui@^4.0.0":
|
||||
version "4.0.0"
|
||||
|
|
Loading…
Reference in New Issue