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'; ...@@ -11,6 +11,7 @@ import titleComponent from './title.vue';
import descriptionComponent from './description.vue'; import descriptionComponent from './description.vue';
import editedComponent from './edited.vue'; import editedComponent from './edited.vue';
import formComponent from './form.vue'; import formComponent from './form.vue';
import PinnedLinks from './pinned_links.vue';
import recaptchaModalImplementor from '../../vue_shared/mixins/recaptcha_modal_implementor'; import recaptchaModalImplementor from '../../vue_shared/mixins/recaptcha_modal_implementor';
export default { export default {
...@@ -19,6 +20,7 @@ export default { ...@@ -19,6 +20,7 @@ export default {
titleComponent, titleComponent,
editedComponent, editedComponent,
formComponent, formComponent,
PinnedLinks,
}, },
mixins: [recaptchaModalImplementor], mixins: [recaptchaModalImplementor],
props: { props: {
...@@ -340,6 +342,7 @@ export default { ...@@ -340,6 +342,7 @@ export default {
:title-text="state.titleText" :title-text="state.titleText"
:show-inline-edit-button="showInlineEditButton" :show-inline-edit-button="showInlineEditButton"
/> />
<pinned-links :description-html="state.descriptionHtml" />
<description-component <description-component
v-if="state.descriptionHtml" v-if="state.descriptionHtml"
:can-update="canUpdate" :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 { ...@@ -416,6 +416,7 @@ img.emoji {
.center { text-align: center; } .center { text-align: center; }
.block { display: block; } .block { display: block; }
.flex { display: flex; } .flex { display: flex; }
.vertical-align-top { vertical-align: top; }
.vertical-align-middle { vertical-align: middle; } .vertical-align-middle { vertical-align: middle; }
.vertical-align-sub { vertical-align: sub; } .vertical-align-sub { vertical-align: sub; }
.flex-align-self-center { align-self: center; } .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 "" ...@@ -5597,6 +5597,9 @@ msgstr ""
msgid "Job|with" msgid "Job|with"
msgstr "" msgstr ""
msgid "Join Zoom meeting"
msgstr ""
msgid "Jul" msgid "Jul"
msgstr "" msgstr ""
......
...@@ -92,6 +92,19 @@ describe "User creates issue" do ...@@ -92,6 +92,19 @@ describe "User creates issue" do
.and have_content(label_titles.first) .and have_content(label_titles.first)
end end
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 end
context "when signed in as user with special characters in their name" do 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 @@ ...@@ -700,10 +700,10 @@
dependencies: dependencies:
requireindex "~1.1.0" requireindex "~1.1.0"
"@gitlab/svgs@^1.63.0": "@gitlab/svgs@^1.64.0":
version "1.63.0" version "1.64.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.63.0.tgz#9dd544026d203e4ce6efed72b05db68f710c4d49" resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.64.0.tgz#1370bcbe9ca0ecc9fb919956cd4241bea090ddd3"
integrity sha512-YztrReFTg31B7v5wtUC5j15KHNcMebtW+kACytEU42XomMaIwk4USIbygqWlq0VRHA2VHJrHApfJHIjxiCCQcA== integrity sha512-y9p73NGDnQJc18Dtk0oJfgxedancBT6UceATcnZMceLV6iWylzdMbQWxCl4O2aBXwsAoCrLUJQ9jhRkbNicYNA==
"@gitlab/ui@^4.0.0": "@gitlab/ui@^4.0.0":
version "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