Commit cdb4424e authored by Kushal Pandya's avatar Kushal Pandya

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
parents 9ba797e6 dfc2d02c
......@@ -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"
......
<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; }
......
---
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 ""
......
......@@ -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
......
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"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment