From 50cc876cf7efc329a2c19c7dd76e023059ad47cf Mon Sep 17 00:00:00 2001 From: Tainan Felipe Date: Tue, 10 Oct 2017 19:08:51 -0300 Subject: [PATCH] fix errors linter --- .../server/modifiers/initializeCursor.js | 1 - .../chat/chat-dropdown/component.jsx | 1 - .../imports/ui/components/chat/component.jsx | 6 +- .../chat/message-form/component.jsx | 8 +- .../ui/components/dropdown/list/component.jsx | 3 +- .../imports/ui/components/icon/component.jsx | 21 +-- .../imports/ui/components/media/component.jsx | 5 + .../imports/ui/components/modal/service.js | 10 +- .../ui/components/modal/simple/component.jsx | 26 +-- .../ui/components/nav-bar/component.jsx | 160 +++++++++--------- .../ui/components/nav-bar/container.jsx | 21 +-- .../nav-bar/recording-indicator/component.jsx | 14 +- .../ui/components/settings/component.jsx | 64 ++++--- .../imports/ui/components/settings/service.js | 6 +- .../submenus/application/container.jsx | 17 +- .../settings/submenus/base/component.jsx | 4 - .../submenus/participants/component.jsx | 23 ++- .../settings/submenus/video/component.jsx | 18 +- .../ui/components/user-avatar/component.jsx | 1 + .../ui/components/video-dock/component.jsx | 16 +- .../ui/components/video-dock/container.jsx | 21 +-- 21 files changed, 212 insertions(+), 234 deletions(-) diff --git a/bigbluebutton-html5/imports/api/2.0/cursor/server/modifiers/initializeCursor.js b/bigbluebutton-html5/imports/api/2.0/cursor/server/modifiers/initializeCursor.js index 30bcfe0e33..0c9df4a17c 100644 --- a/bigbluebutton-html5/imports/api/2.0/cursor/server/modifiers/initializeCursor.js +++ b/bigbluebutton-html5/imports/api/2.0/cursor/server/modifiers/initializeCursor.js @@ -1,4 +1,3 @@ -import Cursor from '/imports/api/2.0/cursor'; import updateCursor from './updateCursor'; export default function initializeCursor(meetingId) { diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/chat-dropdown/component.jsx index 894ec742b1..3e598f78f8 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-dropdown/component.jsx @@ -1,6 +1,5 @@ import React, { Component } from 'react'; import { defineMessages, injectIntl } from 'react-intl'; -import cx from 'classnames'; import { withModalMounter } from '/imports/ui/components/modal/service'; import Clipboard from 'clipboard'; import _ from 'lodash'; diff --git a/bigbluebutton-html5/imports/ui/components/chat/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/component.jsx index e40eb35f60..75ab3deedd 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/chat/component.jsx @@ -90,7 +90,7 @@ const Chat = (props) => { export default injectWbResizeEvent(injectIntl(Chat)); -Chat.propTypes = { +const propTypes = { chatID: PropTypes.string.isRequired, chatName: PropTypes.string.isRequired, title: PropTypes.string.isRequired, @@ -104,7 +104,7 @@ Chat.propTypes = { ]), ).isRequired, ).isRequired, - scrollPosition: PropTypes.number, + scrollPosition: PropTypes.number.isRequired, hasUnreadMessages: PropTypes.bool.isRequired, lastReadMessageTime: PropTypes.number.isRequired, partnerIsLoggedOut: PropTypes.bool.isRequired, @@ -121,3 +121,5 @@ Chat.propTypes = { formatMessage: PropTypes.func.isRequired, }).isRequired, }; + +Chat.propTypes = propTypes; diff --git a/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx index 7edd0d7e7d..dd28047679 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx @@ -1,12 +1,8 @@ import React, { Component } from 'react'; -import PropTypes from 'prop-types'; import { defineMessages, injectIntl } from 'react-intl'; -import { findDOMNode } from 'react-dom'; import cx from 'classnames'; -import styles from './styles'; - -import MessageFormActions from './message-form-actions/component'; import TextareaAutosize from 'react-autosize-textarea'; +import styles from './styles'; import Button from '../../button/component'; const propTypes = { @@ -142,7 +138,7 @@ class MessageForm extends Component { this.textarea = ref} + innerRef={ref => (this.textarea = ref)} placeholder={intl.formatMessage(messages.inputPlaceholder, { 0: chatName })} aria-controls={this.props.chatAreaId} aria-label={intl.formatMessage(messages.inputLabel, { 0: chatTitle })} diff --git a/bigbluebutton-html5/imports/ui/components/dropdown/list/component.jsx b/bigbluebutton-html5/imports/ui/components/dropdown/list/component.jsx index 2ac22a76d1..c630ce5812 100644 --- a/bigbluebutton-html5/imports/ui/components/dropdown/list/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/dropdown/list/component.jsx @@ -8,7 +8,8 @@ import ListSeparator from './separator/component'; import ListTitle from './title/component'; const propTypes = { - // We should recheck this proptype, sometimes we need to create an container and send to dropdown, but with this + /* We should recheck this proptype, sometimes we need to create an container and send to dropdown, + but with this */ // proptype, is not possible. children: PropTypes.arrayOf((propValue, key, componentName, location, propFullName) => { if (propValue[key].type !== ListItem && diff --git a/bigbluebutton-html5/imports/ui/components/icon/component.jsx b/bigbluebutton-html5/imports/ui/components/icon/component.jsx index b44a80f566..cfe4995a77 100644 --- a/bigbluebutton-html5/imports/ui/components/icon/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/icon/component.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; @@ -11,17 +11,14 @@ const defaultProps = { prependIconName: 'icon-bbb-', }; -export default class Icon extends Component { - render() { - const { className, prependIconName, iconName, ...otherProps } = this.props; - return ( - - ); - } -} +const Icon = ({ className, prependIconName, iconName, ...otherProps }) => ( + + ); + +export default Icon; Icon.propTypes = propTypes; Icon.defaultProps = defaultProps; diff --git a/bigbluebutton-html5/imports/ui/components/media/component.jsx b/bigbluebutton-html5/imports/ui/components/media/component.jsx index b0648d838d..c431576923 100644 --- a/bigbluebutton-html5/imports/ui/components/media/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/media/component.jsx @@ -7,6 +7,10 @@ const propTypes = { overlay: PropTypes.element, }; +const defaultProps = { + overlay: null, +}; + export default class Media extends Component { renderContent() { const { content } = this.props; @@ -44,3 +48,4 @@ export default class Media extends Component { } Media.propTypes = propTypes; +Media.defaultProps = defaultProps; diff --git a/bigbluebutton-html5/imports/ui/components/modal/service.js b/bigbluebutton-html5/imports/ui/components/modal/service.js index 0f676666c1..d920ec8390 100644 --- a/bigbluebutton-html5/imports/ui/components/modal/service.js +++ b/bigbluebutton-html5/imports/ui/components/modal/service.js @@ -20,14 +20,8 @@ export const getModal = () => { export const withModalMounter = ComponentToWrap => class ModalMounterWrapper extends Component { - constructor(props) { - super(props); - this.mount = this.mount.bind(this); - } - - mount(modalComponent) { + static mount(modalComponent) { showModal(null); - // defer the execution to a subsequent event loop setTimeout(() => showModal(modalComponent), 0); } @@ -35,7 +29,7 @@ export const withModalMounter = ComponentToWrap => render() { return (); } }; diff --git a/bigbluebutton-html5/imports/ui/components/modal/simple/component.jsx b/bigbluebutton-html5/imports/ui/components/modal/simple/component.jsx index 3fc68a761c..a36431489f 100644 --- a/bigbluebutton-html5/imports/ui/components/modal/simple/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/modal/simple/component.jsx @@ -1,9 +1,9 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import ModalBase, { withModalState } from '../base/component'; -import Button from '/imports/ui/components/button/component'; -import styles from './styles.scss'; import cx from 'classnames'; +import Button from '/imports/ui/components/button/component'; +import ModalBase, { withModalState } from '../base/component'; +import styles from './styles.scss'; const propTypes = { title: PropTypes.string.isRequired, @@ -24,6 +24,11 @@ const defaultProps = { }; class ModalSimple extends Component { + constructor(props) { + super(props); + this.handleDismiss = this.handleDismiss.bind(this); + } + handleDismiss() { this.props.modalHide(this.props.dismiss.callback); } @@ -34,14 +39,14 @@ class ModalSimple extends Component { dismiss, className, modalisOpen, - ...otherProps, + ...otherProps } = this.props; return ( @@ -51,10 +56,11 @@ class ModalSimple extends Component { className={styles.dismiss} label={dismiss.label} icon={'close'} - circle={true} - hideLabel={true} - onClick={this.handleDismiss.bind(this)} - aria-describedby={'modalDismissDescription'} /> + circle + hideLabel + onClick={this.handleDismiss} + aria-describedby={'modalDismissDescription'} + />
{this.props.children} @@ -63,7 +69,7 @@ class ModalSimple extends Component { ); } -}; +} ModalSimple.propTypes = propTypes; ModalSimple.defaultProps = defaultProps; diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx index a312d765e0..7e2b93d2a9 100644 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx @@ -2,10 +2,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import _ from 'lodash'; import cx from 'classnames'; -import styles from './styles.scss'; -import Button from '../button/component'; -import RecordingIndicator from './recording-indicator/component'; -import SettingsDropdownContainer from './settings-dropdown/container'; import Icon from '/imports/ui/components/icon/component'; import BreakoutJoinConfirmation from '/imports/ui/components/breakout-join-confirmation/component'; import Dropdown from '/imports/ui/components/dropdown/component'; @@ -15,6 +11,10 @@ import DropdownList from '/imports/ui/components/dropdown/list/component'; import DropdownListItem from '/imports/ui/components/dropdown/list/item/component'; import { withModalMounter } from '/imports/ui/components/modal/service'; import { defineMessages, injectIntl } from 'react-intl'; +import styles from './styles.scss'; +import Button from '../button/component'; +import RecordingIndicator from './recording-indicator/component'; +import SettingsDropdownContainer from './settings-dropdown/container'; const intlMessages = defineMessages({ toggleUserListLabel: { @@ -57,6 +57,35 @@ class NavBar extends Component { this.handleToggleUserList = this.handleToggleUserList.bind(this); } + componentDidUpdate() { + const { + breakouts, + getBreakoutJoinURL, + isBreakoutRoom, + } = this.props; + + breakouts.forEach((breakout) => { + if (!breakout.users) { + return; + } + + const breakoutURL = getBreakoutJoinURL(breakout); + + if (!this.state.didSendBreakoutInvite && !isBreakoutRoom) { + this.inviteUserToBreakout(breakout, breakoutURL); + } + }); + + if (!breakouts.length && this.state.didSendBreakoutInvite) { + // this.setState({ didSendBreakoutInvite: false }); + this.onUpdate(() => { + this.setState({ + didSendBreakoutInvite: false, + }); + }); + } + } + componendDidMount() { document.title = this.props.presentationTitle; } @@ -75,6 +104,55 @@ class NavBar extends Component { }); } + renderPresentationTitle() { + const { + breakouts, + isBreakoutRoom, + presentationTitle, + } = this.props; + + if (isBreakoutRoom || !breakouts.length) { + return ( +

{presentationTitle}

+ ); + } + + return ( + + +

+ {presentationTitle} +

+
+ + + {breakouts.map(breakout => this.renderBreakoutItem(breakout))} + + +
+ ); + } + + renderBreakoutItem(breakout) { + const { + getBreakoutJoinURL, + mountModal, + } = this.props; + + const breakoutName = breakout.name; + const breakoutURL = getBreakoutJoinURL(breakout); + + return ( + + ); + } render() { const { hasUnreadMessages, beingRecorded, isExpanded, intl } = this.props; @@ -111,80 +189,6 @@ class NavBar extends Component {
); } - - renderPresentationTitle() { - const { - breakouts, - isBreakoutRoom, - presentationTitle, - } = this.props; - - if (isBreakoutRoom || !breakouts.length) { - return ( -

{presentationTitle}

- ); - } - - return ( - - -

- {presentationTitle} -

-
- - - {breakouts.map(breakout => this.renderBreakoutItem(breakout))} - - -
- ); - } - - componentDidUpdate() { - const { - breakouts, - getBreakoutJoinURL, - isBreakoutRoom, - } = this.props; - - breakouts.forEach((breakout) => { - if (!breakout.users) { - return; - } - - const breakoutURL = getBreakoutJoinURL(breakout); - - if (!this.state.didSendBreakoutInvite && !isBreakoutRoom) { - this.inviteUserToBreakout(breakout, breakoutURL); - } - }); - - if (!breakouts.length && this.state.didSendBreakoutInvite) { - this.setState({ didSendBreakoutInvite: false }); - } - } - - renderBreakoutItem(breakout) { - const { - getBreakoutJoinURL, - mountModal, - } = this.props; - - const breakoutName = breakout.name; - const breakoutURL = getBreakoutJoinURL(breakout); - - return ( - - ); - } } NavBar.propTypes = propTypes; diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx index 71ad40e2bb..742708a609 100644 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx @@ -1,31 +1,22 @@ import React, { Component } from 'react'; -import PropTypes from 'prop-types'; import { createContainer } from 'meteor/react-meteor-data'; import { withRouter } from 'react-router'; import Meetings from '/imports/api/2.0/meetings'; import Auth from '/imports/ui/services/auth'; +import { meetingIsBreakout } from '/imports/ui/components/app/service'; import userListService from '../user-list/service'; import ChatService from '../chat/service'; import Service from './service'; -import { meetingIsBreakout } from '/imports/ui/components/app/service'; import NavBar from './component'; const CHAT_CONFIG = Meteor.settings.public.chat; const PUBLIC_CHAT_KEY = CHAT_CONFIG.public_id; -class NavBarContainer extends Component { - constructor(props) { - super(props); - } - - render() { - return ( - - {this.props.children} - - ); - } -} +const NavBarContainer = ({ children, ...props }) => ( + + {children} + +); export default withRouter(createContainer(({ location, router }) => { let meetingTitle; diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/recording-indicator/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/recording-indicator/component.jsx index fe2b594970..55101f7208 100644 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/recording-indicator/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/recording-indicator/component.jsx @@ -1,8 +1,7 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; +import React from 'react'; import styles from './styles.scss'; -export default class RecordingIndicator extends Component { +/* export default class RecordingIndicator extends Component { constructor(props) { super(props); } @@ -16,4 +15,11 @@ export default class RecordingIndicator extends Component { return (
); } -} +} */ + +const RecordingIndicator = ({ beingRecorded }) => { + if (!beingRecorded) return null; + return
; +}; + +export default RecordingIndicator; diff --git a/bigbluebutton-html5/imports/ui/components/settings/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/component.jsx index 31d5226a01..016f5e564f 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/settings/component.jsx @@ -2,12 +2,11 @@ import React, { Component } from 'react'; import Modal from '/imports/ui/components/modal/fullscreen/component'; import { Tab, Tabs, TabList, TabPanel } from 'react-tabs'; import { defineMessages, injectIntl } from 'react-intl'; -import { withModalMounter } from '../modal/service'; import ClosedCaptions from '/imports/ui/components/settings/submenus/closed-captions/component'; import Application from '/imports/ui/components/settings/submenus/application/container'; import Participants from '/imports/ui/components/settings/submenus/participants/component'; -import Video from '/imports/ui/components/settings/submenus/video/component'; import _ from 'lodash'; +import { withModalMounter } from '../modal/service'; import Icon from '../icon/component'; import styles from './styles'; @@ -59,6 +58,9 @@ const propTypes = { }; class Settings extends Component { + static setHtmlFontSize(size) { + document.getElementsByTagName('html')[0].style.fontSize = size; + } constructor(props) { super(props); @@ -94,37 +96,6 @@ class Settings extends Component { }); } - setHtmlFontSize(size) { - document.getElementsByTagName('html')[0].style.fontSize = size; - } - - render() { - const intl = this.props.intl; - - return ( - { - this.props.mountModal(null); - this.updateSettings(this.state.current); - }), - label: intl.formatMessage(intlMessages.SaveLabel), - description: intl.formatMessage(intlMessages.SaveLabelDesc), - }} - dismiss={{ - callback: (() => { - this.setHtmlFontSize(this.state.saved.application.fontSize); - }), - label: intl.formatMessage(intlMessages.CancelLabel), - description: intl.formatMessage(intlMessages.CancelLabelDesc), - }} - > - {this.renderModalContent()} - - ); - } - handleUpdateSettings(key, newSettings) { const settings = this.state; settings.current[key] = newSettings; @@ -201,6 +172,33 @@ class Settings extends Component { ); } + render() { + const intl = this.props.intl; + + return ( + { + this.props.mountModal(null); + this.updateSettings(this.state.current); + }), + label: intl.formatMessage(intlMessages.SaveLabel), + description: intl.formatMessage(intlMessages.SaveLabelDesc), + }} + dismiss={{ + callback: (() => { + this.setHtmlFontSize(this.state.saved.application.fontSize); + }), + label: intl.formatMessage(intlMessages.CancelLabel), + description: intl.formatMessage(intlMessages.CancelLabelDesc), + }} + > + {this.renderModalContent()} + + ); + } + } Settings.propTypes = propTypes; diff --git a/bigbluebutton-html5/imports/ui/components/settings/service.js b/bigbluebutton-html5/imports/ui/components/settings/service.js index 12c453221c..7f0b65e35b 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/service.js +++ b/bigbluebutton-html5/imports/ui/components/settings/service.js @@ -23,13 +23,11 @@ const getUserRoles = () => { }; const updateSettings = (obj) => { - Object.keys(obj).forEach(k => Settings[k] = obj[k]); + Object.keys(obj).forEach(k => (Settings[k] = obj[k])); Settings.save(); }; -const getAvailableLocales = function () { - return fetch('/html5client/locales').then(locales => locales.json()); -}; +const getAvailableLocales = () => fetch('/html5client/locales').then(locales => locales.json()); export { getClosedCaptionLocales, diff --git a/bigbluebutton-html5/imports/ui/components/settings/submenus/application/container.jsx b/bigbluebutton-html5/imports/ui/components/settings/submenus/application/container.jsx index f90e513da4..3320793888 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/submenus/application/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/settings/submenus/application/container.jsx @@ -1,19 +1,14 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; +import React from 'react'; import { createContainer } from 'meteor/react-meteor-data'; import Application from './component'; -// import Service from './service'; -class ApplicationContainer extends Component { - render() { - return ( - - {this.props.children} - +const ApplicationContainer = props => ( + + {props.children} + ); - } -} + export default createContainer(() => ({ fontSizes: [ '12px', diff --git a/bigbluebutton-html5/imports/ui/components/settings/submenus/base/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/submenus/base/component.jsx index 5098df29e7..62be2b14a7 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/submenus/base/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/settings/submenus/base/component.jsx @@ -1,8 +1,4 @@ import React from 'react'; -import Modal from 'react-modal'; -import Icon from '/imports/ui/components/icon/component'; -import Button from '/imports/ui/components/button/component'; -import styles from '../styles.scss'; export default class BaseMenu extends React.Component { constructor(props) { diff --git a/bigbluebutton-html5/imports/ui/components/settings/submenus/participants/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/submenus/participants/component.jsx index 00edec53dc..fb530fe3b5 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/submenus/participants/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/settings/submenus/participants/component.jsx @@ -1,14 +1,11 @@ import React from 'react'; -import Modal from 'react-modal'; -import Icon from '/imports/ui/components/icon/component'; -import Button from '/imports/ui/components/button/component'; -import BaseMenu from '../base/component'; -import ReactDOM from 'react-dom'; -import cx from 'classnames'; -import styles from '../styles.scss'; import Toggle from '/imports/ui/components/switch/component'; import Checkbox from '/imports/ui/components/checkbox/component'; +import cx from 'classnames'; import { defineMessages, injectIntl } from 'react-intl'; +import _ from 'lodash'; +import BaseMenu from '../base/component'; +import styles from '../styles.scss'; const intlMessages = defineMessages({ participantsTitle: { @@ -159,9 +156,9 @@ class ApplicationMenu extends BaseMenu {
-
@@ -181,9 +178,9 @@ class ApplicationMenu extends BaseMenu {
-
@@ -205,11 +202,12 @@ class ApplicationMenu extends BaseMenu { } renderLockItem({ label, key, ariaLabel, ariaLabelledBy, ariaDesc, ariaDescribedBy }, i) { + const formControlId = _.uniqueId('from-key-'); return (
-
@@ -225,6 +223,7 @@ class ApplicationMenu extends BaseMenu { ariaLabelledBy={ariaLabelledBy} ariaDesc={ariaDesc} ariaDescribedBy={ariaDescribedBy} + id={formControlId} />
diff --git a/bigbluebutton-html5/imports/ui/components/settings/submenus/video/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/submenus/video/component.jsx index d58aaf4a85..126daab6a2 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/submenus/video/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/settings/submenus/video/component.jsx @@ -1,9 +1,9 @@ -import React, { Component } from 'react'; -import BaseMenu from '../base/component'; -import styles from '../styles.scss'; -import { defineMessages, injectIntl } from 'react-intl'; +import React from 'react'; import Toggle from '/imports/ui/components/switch/component'; import cx from 'classnames'; +import { defineMessages, injectIntl } from 'react-intl'; +import BaseMenu from '../base/component'; +import styles from '../styles.scss'; const intlMessages = defineMessages({ videoSectionTitle: { @@ -58,10 +58,11 @@ class VideoMenu extends BaseMenu { className={styles.formElement} aria-label={intl.formatMessage(intlMessages.videoSourceLabel)} > -