From a02a7eccda31271322c5f489dd8b3c0266bb45af Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Fri, 28 Oct 2022 14:10:07 +0000 Subject: [PATCH 1/4] use react tabs in connection status modal / lint issues --- .../connection-status/modal/component.jsx | 154 ++++++++++-------- .../connection-status/modal/styles.js | 131 ++++++++++++++- 2 files changed, 215 insertions(+), 70 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx b/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx index 46279f5b59..238e62c923 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx @@ -158,7 +158,7 @@ class ConnectionStatusComponent extends PureComponent { this.help = Service.getHelp(); this.state = { - selectedTab: '1', + selectedTab: 0, dataPage: '1', dataSaving: props.dataSaving, hasNetworkData: false, @@ -187,6 +187,7 @@ class ConnectionStatusComponent extends PureComponent { this.audioDownloadLabel = intl.formatMessage(intlMessages.audioDownloadRate); this.videoUploadLabel = intl.formatMessage(intlMessages.videoUploadRate); this.videoDownloadLabel = intl.formatMessage(intlMessages.videoDownloadRate); + this.handleSelectTab = this.handleSelectTab.bind(this); } async componentDidMount() { @@ -197,12 +198,24 @@ class ConnectionStatusComponent extends PureComponent { Meteor.clearInterval(this.rateInterval); } + handleSelectTab(tab) { + this.setState({ + selectedTab: tab, + }); + } + handleDataSavingChange(key) { const { dataSaving } = this.state; dataSaving[key] = !dataSaving[key]; this.setState(dataSaving); } + setButtonMessage(msg) { + this.setState({ + copyButtonText: msg, + }); + } + /** * Start monitoring the network data. * @return {Promise} A Promise that resolves when process started. @@ -262,6 +275,43 @@ class ConnectionStatusComponent extends PureComponent { }, NETWORK_MONITORING_INTERVAL_MS); } + displaySettingsStatus(status) { + const { intl } = this.props; + + return ( + + {status ? intl.formatMessage(intlMessages.on) + : intl.formatMessage(intlMessages.off)} + + ); + } + + /** + * Copy network data to clipboard + * @return {Promise} A Promise that is resolved after data is copied. + * + * + */ + async copyNetworkData() { + const { intl } = this.props; + const { + networkData, + hasNetworkData, + } = this.state; + + if (!hasNetworkData) return; + + this.setButtonMessage(intl.formatMessage(intlMessages.copied)); + + const data = JSON.stringify(networkData, null, 2); + + await navigator.clipboard.writeText(data); + + this.copyNetworkDataTimeout = setTimeout(() => { + this.setButtonMessage(intl.formatMessage(intlMessages.copy)); + }, MIN_TIMEOUT); + } + renderEmpty() { const { intl } = this.props; @@ -278,52 +328,6 @@ class ConnectionStatusComponent extends PureComponent { ); } - displaySettingsStatus(status) { - const { intl } = this.props; - - return ( - - {status ? intl.formatMessage(intlMessages.on) - : intl.formatMessage(intlMessages.off)} - - ); - } - - setButtonMessage(msg) { - this.setState({ - copyButtonText: msg, - }); - } - - /** - * Copy network data to clipboard - * @param {Object} e Event object from click event - * @return {Promise} A Promise that is resolved after data is copied. - * - * - */ - async copyNetworkData(e) { - const { intl } = this.props; - const { - networkData, - hasNetworkData, - } = this.state; - - if (!hasNetworkData) return; - - const { target: copyButton } = e; - - this.setButtonMessage(intl.formatMessage(intlMessages.copied)); - - const data = JSON.stringify(networkData, null, 2); - - await navigator.clipboard.writeText(data); - - this.copyNetworkDataTimeout = setTimeout(() => { - this.setButtonMessage(intl.formatMessage(intlMessages.copy)); - }, MIN_TIMEOUT); - } - renderConnections() { const { connectionStatus, @@ -345,7 +349,7 @@ class ConnectionStatusComponent extends PureComponent { return ( @@ -521,6 +525,7 @@ class ConnectionStatusComponent extends PureComponent { - {this.state.copyButtonText} + {copyButtonText} ); @@ -667,6 +671,7 @@ class ConnectionStatusComponent extends PureComponent { onClick={handleTabClick} onKeyDown={handleTabClick} role="button" + tabIndex={0} > {intl.formatMessage(intlMessages.connectionStats)} @@ -675,6 +680,7 @@ class ConnectionStatusComponent extends PureComponent { onClick={handleTabClick} onKeyDown={handleTabClick} role="button" + tabIndex={0} > {intl.formatMessage(intlMessages.myLogs)} @@ -685,6 +691,7 @@ class ConnectionStatusComponent extends PureComponent { onClick={handleTabClick} onKeyDown={handleTabClick} role="button" + tabIndex={0} > {intl.formatMessage(intlMessages.sessionLogs)} @@ -715,18 +722,35 @@ class ConnectionStatusComponent extends PureComponent { {intl.formatMessage(intlMessages.title)} - {this.renderNavigation()} - - - {selectedTab === '1' - ? this.renderNetworkData() - : this.renderConnections() - } - - {selectedTab === '1' && - this.renderCopyDataButton() - } - + + + + + {'Connection Status'} + + + {'My Logs'} + + + {'Session Logs'} + + + +
+ {this.renderNetworkData()} + {this.renderCopyDataButton()} +
+
+ +
{this.renderConnections()}
+
+ +
{this.renderConnections()}
+
+
); diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js b/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js index f10aac0f2d..db0a3eef5b 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js +++ b/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js @@ -7,10 +7,12 @@ import { colorGrayLabel, colorGrayLightest, colorPrimary, + colorWhite, } from '/imports/ui/stylesheets/styled-components/palette'; import { smPaddingX, smPaddingY, + mdPaddingY, lgPaddingY, lgPaddingX, titlePositionLeft, @@ -26,7 +28,11 @@ import { hasPhoneDimentions, mediumDown, hasPhoneWidth, + smallOnly, } from '/imports/ui/stylesheets/styled-components/breakpoints'; +import { + Tab, Tabs, TabList, TabPanel, +} from 'react-tabs'; const Item = styled.div` display: flex; @@ -276,11 +282,12 @@ const Helper = styled.div` flex-direction: column; justify-content: center; align-items: center; + padding: .5rem; @media ${mediumDown} { - ${({ page }) => page === '1' + ${({ page }) => (page === '1' ? 'display: flex;' - : 'display: none;'} + : 'display: none;')} } `; @@ -291,9 +298,9 @@ const NetworkDataContent = styled.div` flex-grow: 1; @media ${mediumDown} { - ${({ page }) => page === '2' + ${({ page }) => (page === '2' ? 'display: flex;' - : 'display: none;'} + : 'display: none;')} } `; @@ -328,6 +335,7 @@ const Navigation = styled.div` user-select: none; overflow-y: auto; scrollbar-width: none; + padding: 4px; &::-webkit-scrollbar { display: none; @@ -344,6 +352,15 @@ const Navigation = styled.div` color: ${colorPrimary}; } + div { + padding: .1rem .25rem; + + &:focus { + outline: 2px solid ${colorPrimary}; + border-radius: 4px; + } + } + & * { cursor: pointer; white-space: nowrap; @@ -399,8 +416,9 @@ const Button = styled.button` opacity: .75; } + &:hover, &:focus { - outline: none; + outline: 2px solid ${colorPrimary}; } @media ${hasPhoneWidth} { @@ -436,6 +454,105 @@ const Chevron = styled.svg` } `; +const ConnectionTabs = styled(Tabs)` + display: flex; + flex-flow: column; + justify-content: flex-start; + + @media ${smallOnly} { + width: 100%; + flex-flow: column; + } +`; + +const ConnectionTabList = styled(TabList)` + display: flex; + flex-flow: row; + margin: 0; + margin-bottom: .5rem; + border: none; + padding: 0; + width: calc(100% / 3); + + @media ${smallOnly} { + width: 100%; + flex-flow: row; + flex-wrap: wrap; + justify-content: center; + } +`; + +const ConnectionTabPanel = styled(TabPanel)` + display: none; + margin: 0 0 0 1rem; + height: 13rem; + + [dir="rtl"] & { + margin: 0 1rem 0 0; + } + + &.is-selected { + display: block; + } + + @media ${smallOnly} { + width: 100%; + margin: 0; + padding-left: 1rem; + padding-right: 1rem; + } +`; + +const ConnectionTabSelector = styled(Tab)` + display: flex; + flex-flow: row; + font-size: 0.9rem; + flex: 0 0 auto; + justify-content: flex-start; + border: none !important; + padding: ${mdPaddingY} ${mdPaddingX}; + + border-radius: .2rem; + cursor: pointer; + margin-bottom: ${smPaddingY}; + align-items: center; + flex-grow: 0; + min-width: 0; + + & > span { + min-width: 0; + display: inline-block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + @media ${smallOnly} { + max-width: 100%; + margin: 0 ${smPaddingX} 0 0; + & > i { + display: none; + } + + [dir="rtl"] & { + margin: 0 0 0 ${smPaddingX}; + } + } + + span { + border-bottom: 2px solid ${colorWhite}; + } + + &.is-selected { + border: none; + color: ${colorPrimary}; + + span { + border-bottom: 2px solid ${colorPrimary}; + } + } +`; + export default { Item, Left, @@ -476,4 +593,8 @@ export default { ButtonLeft, ButtonRight, Chevron, + ConnectionTabs, + ConnectionTabList, + ConnectionTabSelector, + ConnectionTabPanel, }; From 03a27e9932bfd31535c7057335c8485e547aaf8a Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Fri, 28 Oct 2022 15:58:32 +0000 Subject: [PATCH 2/4] add formatted strings --- .../ui/components/connection-status/modal/component.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx b/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx index 238e62c923..828887faa5 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx @@ -729,13 +729,13 @@ class ConnectionStatusComponent extends PureComponent { > - {'Connection Status'} + {intl.formatMessage(intlMessages.title)} - {'My Logs'} + {intl.formatMessage(intlMessages.myLogs)} - {'Session Logs'} + {intl.formatMessage(intlMessages.sessionLogs)} From d9160072ccb230519270976d008b816419c3bd11 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Fri, 28 Oct 2022 16:07:06 +0000 Subject: [PATCH 3/4] add moderator check --- .../connection-status/modal/component.jsx | 79 ++++--------------- .../connection-status/modal/styles.js | 48 ----------- 2 files changed, 14 insertions(+), 113 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx b/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx index 828887faa5..794fd6aac3 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx @@ -642,65 +642,6 @@ class ConnectionStatusComponent extends PureComponent { ); } - /** - * The navigation bar. - * @returns {Object} The component to be renderized. - */ - renderNavigation() { - const { intl } = this.props; - - const handleTabClick = (event) => { - const activeTabElement = document.querySelector('.activeConnectionStatusTab'); - const { target } = event; - - if (activeTabElement) { - activeTabElement.classList.remove('activeConnectionStatusTab'); - } - - target.classList.add('activeConnectionStatusTab'); - this.setState({ - selectedTab: target.dataset.tab, - }); - } - - return ( - -
- {intl.formatMessage(intlMessages.connectionStats)} -
-
- {intl.formatMessage(intlMessages.myLogs)} -
- {Service.isModerator() - && ( -
- {intl.formatMessage(intlMessages.sessionLogs)} -
- ) - } -
- ); - } - render() { const { closeModal, @@ -734,9 +675,13 @@ class ConnectionStatusComponent extends PureComponent { {intl.formatMessage(intlMessages.myLogs)} - - {intl.formatMessage(intlMessages.sessionLogs)} - + {Service.isModerator() + && ( + + {intl.formatMessage(intlMessages.sessionLogs)} + + ) + }
@@ -747,9 +692,13 @@ class ConnectionStatusComponent extends PureComponent {
{this.renderConnections()}
- -
{this.renderConnections()}
-
+ {Service.isModerator() + && ( + +
{this.renderConnections()}
+
+ ) + } diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js b/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js index db0a3eef5b..f876d75cbd 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js +++ b/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js @@ -14,7 +14,6 @@ import { smPaddingY, mdPaddingY, lgPaddingY, - lgPaddingX, titlePositionLeft, mdPaddingX, borderSizeLarge, @@ -328,52 +327,6 @@ const Body = styled.div` position: relative; `; -const Navigation = styled.div` - display: flex; - border: none; - border-bottom: 1px solid ${colorOffWhite}; - user-select: none; - overflow-y: auto; - scrollbar-width: none; - padding: 4px; - - &::-webkit-scrollbar { - display: none; - } - - & :not(:last-child) { - margin: 0; - margin-right: ${lgPaddingX}; - } - - .activeConnectionStatusTab { - border: none; - border-bottom: 2px solid ${colorPrimary}; - color: ${colorPrimary}; - } - - div { - padding: .1rem .25rem; - - &:focus { - outline: 2px solid ${colorPrimary}; - border-radius: 4px; - } - } - - & * { - cursor: pointer; - white-space: nowrap; - } - - [dir="rtl"] & { - & :not(:last-child) { - margin: 0; - margin-left: ${lgPaddingX}; - } - } -`; - const Prev = styled.div` display: none; margin: 0 .5rem 0 .25rem; @@ -585,7 +538,6 @@ export default { NetworkDataContent, Main, Body, - Navigation, FullName, DataColumn, Prev, From 0c99f4a30c657a064fc40954a918cebd6010a192 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Fri, 18 Nov 2022 19:54:00 +0000 Subject: [PATCH 4/4] improve spacing in connection status modal --- .../imports/ui/components/connection-status/modal/styles.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js b/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js index a0f001e1dc..83b7549aac 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js +++ b/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js @@ -178,6 +178,7 @@ const NetworkDataContainer = styled.div` width: 100%; height: 100%; display: flex; + padding-bottom: 1.25rem; @media ${mediumDown} { justify-content: space-between; @@ -207,6 +208,8 @@ const CopyContainer = styled.div` const ConnectionStatusModal = styled(Modal)` padding: 1rem; + height: 28rem; + `; const Container = styled.div` @@ -440,7 +443,8 @@ const ConnectionTabPanel = styled(TabPanel)` } &.is-selected { - display: block; + display: flex; + flex-flow: column; } @media ${smallOnly} {