amazon-connect-reference-dialer 1.0.0 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of amazon-connect-reference-dialer might be problematic. Click here for more details.

Files changed (239) hide show
  1. package/.babelrc +10 -0
  2. package/.eslintrc +24 -0
  3. package/Dockerfile +12 -0
  4. package/LICENSE +21 -0
  5. package/README.md +8 -0
  6. package/README.salesforce.md +50 -0
  7. package/config/appconfig.json +10 -0
  8. package/config/config.js +46 -0
  9. package/docker-compose.yml +16 -0
  10. package/index.js +46 -0
  11. package/nodemon.json +3 -0
  12. package/package.json +5 -4
  13. package/src/client/App.js +20 -0
  14. package/src/client/api/acManager.js +79 -0
  15. package/src/client/api/agentHandler.js +46 -0
  16. package/src/client/api/audioFrequencyMonitor.js +62 -0
  17. package/src/client/api/csioHandler.js +204 -0
  18. package/src/client/api/databaseManager.js +59 -0
  19. package/src/client/api/eventhandler.js +278 -0
  20. package/src/client/api/feedbackHandler.js +21 -0
  21. package/src/client/api/manager/agent.js +203 -0
  22. package/src/client/api/manager/connection.js +181 -0
  23. package/src/client/api/manager/contact.js +114 -0
  24. package/src/client/api/mediaManager.js +138 -0
  25. package/src/client/api/networkStrengthMonitor.js +64 -0
  26. package/src/client/api/precalltest.js +37 -0
  27. package/src/client/api/sessionManager.js +312 -0
  28. package/src/client/configs/consts.js +158 -0
  29. package/src/client/container/agentduration/duration.js +63 -0
  30. package/src/client/container/agentduration/index.js +3 -0
  31. package/src/client/container/agentview/conferenceconnection/agentview.css +100 -0
  32. package/src/client/container/agentview/conferenceconnection/components/bothhold.js +20 -0
  33. package/src/client/container/agentview/conferenceconnection/components/bothjoined.js +25 -0
  34. package/src/client/container/agentview/conferenceconnection/components/dialnumber.js +21 -0
  35. package/src/client/container/agentview/conferenceconnection/components/holdall.js +20 -0
  36. package/src/client/container/agentview/conferenceconnection/components/join.js +21 -0
  37. package/src/client/container/agentview/conferenceconnection/components/oneHoldOtherConnected.js +37 -0
  38. package/src/client/container/agentview/conferenceconnection/components/resumeall.js +21 -0
  39. package/src/client/container/agentview/conferenceconnection/components/swap.js +21 -0
  40. package/src/client/container/agentview/conferenceconnection/components/togglemute.js +23 -0
  41. package/src/client/container/agentview/conferenceconnection/index.js +3 -0
  42. package/src/client/container/agentview/conferenceconnection/lowerBody.js +154 -0
  43. package/src/client/container/agentview/conferenceconnection/main.js +22 -0
  44. package/src/client/container/agentview/conferenceconnection/primaryconnection.js +109 -0
  45. package/src/client/container/agentview/conferenceconnection/quickFeedback.js +118 -0
  46. package/src/client/container/agentview/conferenceconnection/thirdpartyconnection.js +107 -0
  47. package/src/client/container/agentview/conferenceconnection/upperBody.js +36 -0
  48. package/src/client/container/agentview/footer.js +190 -0
  49. package/src/client/container/agentview/index.js +3 -0
  50. package/src/client/container/agentview/main.js +39 -0
  51. package/src/client/container/agentview/primaryconnection/agentMutedLabel.js +23 -0
  52. package/src/client/container/agentview/primaryconnection/agentStatusAndAudioLabel.js +28 -0
  53. package/src/client/container/agentview/primaryconnection/agentview.css +73 -0
  54. package/src/client/container/agentview/primaryconnection/index.js +3 -0
  55. package/src/client/container/agentview/primaryconnection/lowerBody.js +159 -0
  56. package/src/client/container/agentview/primaryconnection/main.js +22 -0
  57. package/src/client/container/agentview/primaryconnection/peerAndAgentDuration.js +48 -0
  58. package/src/client/container/agentview/primaryconnection/quickFeedback.js +123 -0
  59. package/src/client/container/agentview/primaryconnection/upperBody.js +59 -0
  60. package/src/client/container/agentview/thirdparyconnection/agentMutedLabel.js +23 -0
  61. package/src/client/container/agentview/thirdparyconnection/agentStatusAndAudioLabel.js +28 -0
  62. package/src/client/container/agentview/thirdparyconnection/agentview.css +73 -0
  63. package/src/client/container/agentview/thirdparyconnection/index.js +3 -0
  64. package/src/client/container/agentview/thirdparyconnection/lowerBody.js +139 -0
  65. package/src/client/container/agentview/thirdparyconnection/main.js +22 -0
  66. package/src/client/container/agentview/thirdparyconnection/peerAndAgentDuration.js +49 -0
  67. package/src/client/container/agentview/thirdparyconnection/quickFeedback.js +118 -0
  68. package/src/client/container/agentview/thirdparyconnection/upperBody.js +59 -0
  69. package/src/client/container/audiolabelview/controller.js +104 -0
  70. package/src/client/container/audiolabelview/localaudiolevel.js +157 -0
  71. package/src/client/container/audiolabelview/noaudio.js +86 -0
  72. package/src/client/container/audiolabelview/remoteaudiolevel.js +110 -0
  73. package/src/client/container/audiolabelview/settingpageaudiolevel.js +154 -0
  74. package/src/client/container/common/contactField.js +30 -0
  75. package/src/client/container/common/each.contact.js +41 -0
  76. package/src/client/container/common/findContact.js +31 -0
  77. package/src/client/container/connectivitycheckview/body.js +113 -0
  78. package/src/client/container/connectivitycheckview/components/fractionalLoss.js +57 -0
  79. package/src/client/container/connectivitycheckview/components/mediaConnectivity.js +41 -0
  80. package/src/client/container/connectivitycheckview/components/roundTripTime.js +57 -0
  81. package/src/client/container/connectivitycheckview/components/rttgraph/rttgraph.js +176 -0
  82. package/src/client/container/connectivitycheckview/components/rttgraph/utils.js +96 -0
  83. package/src/client/container/connectivitycheckview/components/throughput.js +53 -0
  84. package/src/client/container/connectivitycheckview/components/throughputMessage.js +36 -0
  85. package/src/client/container/connectivitycheckview/connectivitycheck.css +44 -0
  86. package/src/client/container/connectivitycheckview/footer.js +43 -0
  87. package/src/client/container/connectivitycheckview/index.js +3 -0
  88. package/src/client/container/connectivitycheckview/loading/loading.css +73 -0
  89. package/src/client/container/connectivitycheckview/loading/loading.js +15 -0
  90. package/src/client/container/connectivitycheckview/main.js +19 -0
  91. package/src/client/container/dialerview/body.js +135 -0
  92. package/src/client/container/dialerview/dialpad.css +104 -0
  93. package/src/client/container/dialerview/dialpad.js +29 -0
  94. package/src/client/container/dialerview/index.js +3 -0
  95. package/src/client/container/dialerview/main.js +19 -0
  96. package/src/client/container/errors/error.css +30 -0
  97. package/src/client/container/errors/error.js +58 -0
  98. package/src/client/container/errors/index.js +3 -0
  99. package/src/client/container/footer/components/acceptOrReject.js +26 -0
  100. package/src/client/container/footer/components/availableOrEnd.js +28 -0
  101. package/src/client/container/footer/components/connectivitycheck.js +21 -0
  102. package/src/client/container/footer/components/downloadlogs.js +23 -0
  103. package/src/client/container/footer/components/info.js +22 -0
  104. package/src/client/container/footer/components/language.js +22 -0
  105. package/src/client/container/footer/components/reportcall.js +35 -0
  106. package/src/client/container/footer/components/version.js +22 -0
  107. package/src/client/container/header/header.css +46 -0
  108. package/src/client/container/header/header.js +135 -0
  109. package/src/client/container/header/index.js +3 -0
  110. package/src/client/container/home.js +129 -0
  111. package/src/client/container/login/body.js +67 -0
  112. package/src/client/container/login/ccpinputbox.js +23 -0
  113. package/src/client/container/login/footer.js +19 -0
  114. package/src/client/container/login/index.js +2 -0
  115. package/src/client/container/login/login.css +134 -0
  116. package/src/client/container/login/main.js +23 -0
  117. package/src/client/container/networkstrengthview/index.js +3 -0
  118. package/src/client/container/networkstrengthview/loading/loading.css +74 -0
  119. package/src/client/container/networkstrengthview/loading/loading.js +15 -0
  120. package/src/client/container/networkstrengthview/networkstrength.js +102 -0
  121. package/src/client/container/popups/confirmreport/confirmreport.css +47 -0
  122. package/src/client/container/popups/confirmreport/confirmreport.js +55 -0
  123. package/src/client/container/popups/quality/quality.css +32 -0
  124. package/src/client/container/popups/quality/quality.js +44 -0
  125. package/src/client/container/quickconnects/body.js +141 -0
  126. package/src/client/container/quickconnects/close.js +23 -0
  127. package/src/client/container/quickconnects/index.js +3 -0
  128. package/src/client/container/quickconnects/main.js +18 -0
  129. package/src/client/container/quickconnects/quickconnects.css +95 -0
  130. package/src/client/container/reportissueview/body.js +73 -0
  131. package/src/client/container/reportissueview/feedbackRatings.js +37 -0
  132. package/src/client/container/reportissueview/footer.js +20 -0
  133. package/src/client/container/reportissueview/index.js +3 -0
  134. package/src/client/container/reportissueview/issueNotes.js +22 -0
  135. package/src/client/container/reportissueview/issues.js +44 -0
  136. package/src/client/container/reportissueview/main.js +105 -0
  137. package/src/client/container/reportissueview/predefinedIssues.js +38 -0
  138. package/src/client/container/reportissueview/reportissue.css +102 -0
  139. package/src/client/container/settingsview/body.js +156 -0
  140. package/src/client/container/settingsview/components/audiooutputdevice.js +25 -0
  141. package/src/client/container/settingsview/components/deskphone.js +29 -0
  142. package/src/client/container/settingsview/components/desktopsettings.js +38 -0
  143. package/src/client/container/settingsview/components/dropdown-options.js +44 -0
  144. package/src/client/container/settingsview/components/phonetype.js +14 -0
  145. package/src/client/container/settingsview/components/settings.js +23 -0
  146. package/src/client/container/settingsview/components/softphone.js +30 -0
  147. package/src/client/container/settingsview/components/softphonesettings.js +35 -0
  148. package/src/client/container/settingsview/footer.js +96 -0
  149. package/src/client/container/settingsview/index.js +3 -0
  150. package/src/client/container/settingsview/main.js +20 -0
  151. package/src/client/container/settingsview/settings.css +126 -0
  152. package/src/client/container/statechangeview/body.js +61 -0
  153. package/src/client/container/statechangeview/footer.js +43 -0
  154. package/src/client/container/statechangeview/index.js +3 -0
  155. package/src/client/container/statechangeview/main.js +21 -0
  156. package/src/client/container/statechangeview/statuschange.css +47 -0
  157. package/src/client/container/transfercall/body.js +139 -0
  158. package/src/client/container/transfercall/close.js +23 -0
  159. package/src/client/container/transfercall/index.js +3 -0
  160. package/src/client/container/transfercall/main.js +18 -0
  161. package/src/client/container/transfercall/transfercall.css +99 -0
  162. package/src/client/index.js +13 -0
  163. package/src/client/reducers/acReducer.js +277 -0
  164. package/src/client/reducers/reducer.js +8 -0
  165. package/src/client/reducers.js +2 -0
  166. package/src/client/res/images/agent-voice-freq-icon.svg +61 -0
  167. package/src/client/res/images/change-status-icon.svg +16 -0
  168. package/src/client/res/images/csio-logo.png +0 -0
  169. package/src/client/res/images/csioLogo.png +0 -0
  170. package/src/client/res/images/dialer-setting-icon.svg +15 -0
  171. package/src/client/res/images/fa-circle-mark.svg +3 -0
  172. package/src/client/res/images/fa-circle-unmark.svg +3 -0
  173. package/src/client/res/images/fa-close-or-dismiss.svg +17 -0
  174. package/src/client/res/images/fa-danger.svg +3 -0
  175. package/src/client/res/images/fa-dial-button.svg +13 -0
  176. package/src/client/res/images/fa-dial-number.svg +15 -0
  177. package/src/client/res/images/fa-download.svg +3 -0
  178. package/src/client/res/images/fa-hold.svg +13 -0
  179. package/src/client/res/images/fa-ico-join.svg +27 -0
  180. package/src/client/res/images/fa-ico-swap.svg +27 -0
  181. package/src/client/res/images/fa-info.svg +3 -0
  182. package/src/client/res/images/fa-input-sound.svg +5 -0
  183. package/src/client/res/images/fa-language.svg +3 -0
  184. package/src/client/res/images/fa-mark-false.svg +3 -0
  185. package/src/client/res/images/fa-mark-true.svg +3 -0
  186. package/src/client/res/images/fa-mic-freq-temporary.gif +0 -0
  187. package/src/client/res/images/fa-mic.svg +3 -0
  188. package/src/client/res/images/fa-mini-endcall.svg +48 -0
  189. package/src/client/res/images/fa-mini-hold.svg +47 -0
  190. package/src/client/res/images/fa-mini-resume.svg +45 -0
  191. package/src/client/res/images/fa-mute.svg +13 -0
  192. package/src/client/res/images/fa-network-strength-1.svg +5 -0
  193. package/src/client/res/images/fa-network-strength-2.svg +6 -0
  194. package/src/client/res/images/fa-network-strength-3.svg +6 -0
  195. package/src/client/res/images/fa-network-strength-4.svg +6 -0
  196. package/src/client/res/images/fa-network-strength-5.svg +5 -0
  197. package/src/client/res/images/fa-network-strength-unknown-2.svg +9 -0
  198. package/src/client/res/images/fa-network-strength-unknown.svg +6 -0
  199. package/src/client/res/images/fa-quick-connect.svg +15 -0
  200. package/src/client/res/images/fa-refresh.svg +3 -0
  201. package/src/client/res/images/fa-resume.svg +3 -0
  202. package/src/client/res/images/fa-return.svg +3 -0
  203. package/src/client/res/images/fa-three-dots.svg +32 -0
  204. package/src/client/res/images/fa-tick-green.svg +3 -0
  205. package/src/client/res/images/fa-tick-mark.svg +3 -0
  206. package/src/client/res/images/fa-transfer.svg +3 -0
  207. package/src/client/res/images/fa-version.svg +4 -0
  208. package/src/client/res/images/fa-voice-no-freq.svg +5 -0
  209. package/src/client/res/images/favicon.ico +0 -0
  210. package/src/client/res/images/muted-icon.svg +13 -0
  211. package/src/client/res/images/network-strength-icon.svg +13 -0
  212. package/src/client/res/images/peer-voice-freq-icon.svg +26 -0
  213. package/src/client/res/images/star-white.svg +6 -0
  214. package/src/client/res/images/star-yellow.svg +6 -0
  215. package/src/client/res/scss/global.css +14 -0
  216. package/src/client/router.js +17 -0
  217. package/src/client/store.js +11 -0
  218. package/src/client/utils/acutils.js +114 -0
  219. package/src/client/utils/agetStateMap.js +36 -0
  220. package/src/client/utils/feedback.js +3 -0
  221. package/src/client/utils/initialStateManager.js +14 -0
  222. package/src/server/index.js +53 -0
  223. package/src/server/logger.js +93 -0
  224. package/src/server/public/fonts/AmazonEmber_Lt.ttf +0 -0
  225. package/src/server/public/fonts/AmazonEmber_Rg.ttf +0 -0
  226. package/src/server/public/img/favicon.ico +0 -0
  227. package/src/server/public/js/amazon-connect-pre-shim.js +2 -0
  228. package/src/server/router/compare.js +36 -0
  229. package/src/server/router/index.js +36 -0
  230. package/src/server/router/stock.js +33 -0
  231. package/src/server/views/_heap_prod.ejs +8 -0
  232. package/src/server/views/_hotjar_prod.ejs +14 -0
  233. package/src/server/views/_hotjar_test.ejs +12 -0
  234. package/src/server/views/compare.ejs +69 -0
  235. package/src/server/views/index.ejs +69 -0
  236. package/src/server/views/stock.ejs +101 -0
  237. package/webpack.common.config.js +48 -0
  238. package/webpack.dev.config.js +21 -0
  239. package/webpack.prod.config.js +10 -0
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import EachContact from '../common/each.contact';
5
+
6
+ const ContactField = ({ contactList = [], dialContact, onHover, styles }) => (
7
+ <div className={`row ml-0 mr-0 mt-2 ${styles.contactListBox}`} onMouseOver={() => onHover(true)} onMouseOut={() => onHover(false)} >
8
+ <div className={`col-12`}>
9
+ { contactList.map((currentContact, index) => (
10
+ <EachContact
11
+ key={`contact-list-${index}`}
12
+ currentContact={currentContact}
13
+ dialContact={dialContact}
14
+ styles={styles}
15
+ />
16
+ ))
17
+ }
18
+ </div>
19
+ </div>
20
+ );
21
+
22
+ ContactField.propTypes = {
23
+ contactList: PropTypes.array,
24
+ dialContact: PropTypes.func.isRequired,
25
+ onHover: PropTypes.func.isRequired
26
+ };
27
+ ContactField.defaultProps = {
28
+ onHover: () => {}
29
+ }
30
+ export default ContactField;
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import { truncate } from '../../utils/acutils';
5
+
6
+ class EachContact extends React.Component {
7
+ constructor (props) {
8
+ super(props);
9
+ this.tooltipRef = React.createRef();
10
+ }
11
+ componentDidMount () {
12
+ $(this.tooltipRef.current).tooltip();
13
+ }
14
+ render () {
15
+ return (
16
+ <div className={`row ${this.props.styles.contactItem}`}>
17
+ <div className={`col-9 pl-1 pr-0 ml-0 mr-0`}>
18
+ <a className={`btn pl-0 ml-0 pr-0 mr-0 ${this.props.styles.contactName}`}
19
+ ref={this.tooltipRef}
20
+ title={this.props.currentContact.name}
21
+ data-placement="top">
22
+ { truncate(`${this.props.currentContact.name}`, 30) }
23
+ </a>
24
+ </div>
25
+ <div className={`col-3 text-right pr-0`}>
26
+ <a id='dialer_quick_connects_list_item_dial' className={`btn ${this.props.styles.dialButton}`} onClick={() => this.props.dialContact(this.props.currentContact)}>
27
+ Dial
28
+ </a>
29
+ </div>
30
+ </div>
31
+ );
32
+ }
33
+ }
34
+
35
+ EachContact.propTypes = {
36
+ currentContact: PropTypes.object.isRequired,
37
+ dialContact: PropTypes.func.isRequired,
38
+ styles: PropTypes.object.isRequired
39
+ };
40
+
41
+ export default EachContact;
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ const FindContact = ({ contactChange, dialNumber, contactValue = '', isContactListHover, styles }) => (
5
+ <div className='row mt-3'>
6
+ <div className='col-9 pr-0 mr-0'>
7
+ <div className='input-group flex-nowrap'>
8
+ <input type='text'
9
+ className={`form-control ${styles.quickConnectSearch}`}
10
+ placeholder='Find a contact'
11
+ aria-label='contact'
12
+ value={contactValue}
13
+ onChange={contactChange}
14
+ aria-describedby='addon-wrapping'/>
15
+ </div>
16
+ </div>
17
+ <div className={`col-3 text-right pl-0 mr-0`}>
18
+ <a id='dialer_quick_connects_search_dial' className={`btn ${styles.callPhoneDialButton} ${isContactListHover ? 'd-none' : ''}`} onClick={dialNumber}>
19
+ Dial
20
+ </a>
21
+ </div>
22
+ </div>
23
+ );
24
+
25
+ FindContact.propTypes = {
26
+ contactChange: PropTypes.func.isRequired,
27
+ dialNumber: PropTypes.func.isRequired,
28
+ contactValue: PropTypes.string,
29
+ isContactListHover: PropTypes.bool.isRequired
30
+ };
31
+ export default FindContact;
@@ -0,0 +1,113 @@
1
+ import React, { Component } from 'react';
2
+ import { connect } from 'react-redux';
3
+ import PropTypes from 'prop-types';
4
+ import lo from 'lodash';
5
+
6
+ import closeIcon from '../../res/images/fa-close-or-dismiss.svg';
7
+ import rerunIcon from '../../res/images/fa-return.svg';
8
+
9
+ import {
10
+ onRequestConnectivityCheck
11
+ } from '../../reducers/acReducer';
12
+
13
+ import csioHandler from '../../api/csioHandler';
14
+ import MediaConnectivity from './components/mediaConnectivity';
15
+ import RoundTripTime from './components/roundTripTime';
16
+ import FractionalLoss from './components/fractionalLoss';
17
+ import Throughput from './components/throughput';
18
+ import ThroughputMessage from './components/throughputMessage';
19
+ import databaseManager from '../../api/databaseManager';
20
+
21
+ import RTTGraph from './components/rttgraph/rttgraph';
22
+ import {
23
+ postProcess
24
+ } from './components/rttgraph/utils';
25
+
26
+ import styles from './connectivitycheck.css';
27
+ import Loading from './loading/loading';
28
+
29
+ class Body extends Component {
30
+ constructor (props) {
31
+ super(props);
32
+ this.state = {
33
+ pctResult: databaseManager.getPrecallTestResult(),
34
+ inProgress: false
35
+ };
36
+ }
37
+
38
+ requestConnectivityCheck (phoneType) {
39
+ this.props.requestConnectivityCheck();
40
+ }
41
+
42
+ closeSetting () {
43
+ this.props.closeSetting();
44
+ }
45
+
46
+ doPrecalTest () {
47
+ this.setState({
48
+ inProgress: true
49
+ });
50
+ csioHandler.doPrecallTest().then(result => {
51
+ this.setState({
52
+ inProgress: false,
53
+ pctResult: result
54
+ });
55
+ });
56
+ }
57
+
58
+ render () {
59
+ const { pctResult, unit, stepSize } = postProcess(this.state.pctResult);
60
+ return (
61
+ <div className={`card-body ${styles.cardBody}`}>
62
+ <div className="row ">
63
+ <div className="col-7 mr-0 pr-0">
64
+ <p className={`m-0 p-0 ${styles.connectivityCheck}`}>Connectivity check</p>
65
+ </div>
66
+ <div className="col-3 p-0 m-0">
67
+ {this.state.inProgress ? <Loading/>
68
+ : <a id='dialer_connect_check_rerun' className={`btn text-left p-0 m-0 ${styles.reRunButton} ${styles.cursor}`}
69
+ onClick={() => this.doPrecalTest()}>
70
+ <img className="fa-dial-button" src={rerunIcon}/> Rerun </a>
71
+ }
72
+ </div>
73
+ <div className={`col-2 ${styles.cursor}`}
74
+ onClick={() => this.closeSetting()}>
75
+ <img className="p-0 m-0" src={closeIcon}/>
76
+ </div>
77
+ </div>
78
+ <MediaConnectivity pctResult={this.state.pctResult}/>
79
+ <RoundTripTime pctResult={this.state.pctResult}/>
80
+ <FractionalLoss pctResult={this.state.pctResult}/>
81
+ <Throughput pctResult={this.state.pctResult}/>
82
+ <ThroughputMessage pctResult={this.state.pctResult}/>
83
+ <RTTGraph pctResult={pctResult}
84
+ lastSCT={lo.last(this.state.pctResult)}
85
+ stepSize={stepSize}
86
+ unit={unit}/>
87
+ </div>
88
+ );
89
+ }
90
+ }
91
+
92
+ Body.propTypes = {
93
+ closeSetting: PropTypes.func.isRequired,
94
+ requestConnectivityCheck: PropTypes.func.isRequired,
95
+ rttRecords: PropTypes.array.isRequired
96
+ };
97
+ const mapStateToProps = state => ({
98
+ rttRecords: state.acReducer.rttRecords || [{ rtt: 1, itr: 1 }]
99
+ });
100
+
101
+ const mapDispatchToProps = dispatch => ({
102
+ closeSetting: () => {
103
+ dispatch(onRequestConnectivityCheck('close'));
104
+ },
105
+ requestConnectivityCheck: () => {
106
+ dispatch(onRequestConnectivityCheck('complete'));
107
+ }
108
+ });
109
+
110
+ export default connect(
111
+ mapStateToProps,
112
+ mapDispatchToProps
113
+ )(Body);
@@ -0,0 +1,57 @@
1
+ import React from 'react';
2
+ import { connect } from 'react-redux';
3
+ import PropTypes from 'prop-types';
4
+
5
+ import tickGreenIcon from '../../../res/images/fa-tick-green.svg';
6
+ import dangerIcon from '../../../res/images/fa-danger.svg';
7
+
8
+ import lo from 'lodash';
9
+ import styles from './../connectivitycheck.css';
10
+
11
+ const getLatestResultFractionalLoss = (pctResult) => {
12
+ let lastRecord = lo.last(pctResult) || {};
13
+ if ('fractionalLoss' in lastRecord) {
14
+ return lastRecord.fractionalLoss;
15
+ }
16
+ return -1;
17
+ };
18
+
19
+ const isOK = (pctResult) => {
20
+ let latestResult = getLatestResultFractionalLoss(pctResult);
21
+ // console.warn('---->', latestResult, latestResult > -1 && latestResult < 0.05);
22
+ return latestResult > -1 && latestResult < 0.05;
23
+ };
24
+
25
+ const formatValue = (value = 0) => {
26
+ value = Math.max(value, 0);
27
+ return parseFloat(value).toFixed(2);
28
+ };
29
+
30
+ const FractionalLoss = ({ pctResult = {} }) => (
31
+ <div className="row mt-1">
32
+ <div className="col-12">
33
+ <div className="row">
34
+ <div className="col-8">
35
+ <span className={styles.resultText}>
36
+ <img src={isOK(pctResult) ? tickGreenIcon : dangerIcon}/>
37
+ <span className="ml-1">Packet loss</span></span>
38
+ </div>
39
+ <div className="col-4 text-right">
40
+ <span className={styles.resultValue}>
41
+ {formatValue(getLatestResultFractionalLoss(pctResult))} % </span>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ );
47
+
48
+ FractionalLoss.propTypes = {
49
+ pctResult: PropTypes.array
50
+ };
51
+ const mapStateToProps = state => ({});
52
+ const mapDispatchToProps = dispatch => ({});
53
+
54
+ export default connect(
55
+ mapStateToProps,
56
+ mapDispatchToProps
57
+ )(FractionalLoss);
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ import { connect } from 'react-redux';
3
+ import PropTypes from 'prop-types';
4
+
5
+ import tickGreenIcon from '../../../res/images/fa-tick-green.svg';
6
+ import dangerIcon from '../../../res/images/fa-danger.svg';
7
+
8
+ import lo from 'lodash';
9
+ import styles from './../connectivitycheck.css';
10
+
11
+ const isOK = (pctResult) => {
12
+ let latestResult = lo.last(pctResult);
13
+ // console.warn('media connectivity ', latestResult);
14
+ return latestResult && latestResult.mediaConnectivity === true;
15
+ };
16
+
17
+ const MediaConnectivity = ({ pctResult = {} }) => (
18
+ <div className="row mt-3">
19
+ <div className="col-12">
20
+ <div className="row">
21
+ <div className="col-8">
22
+ <span className={styles.resultText}>
23
+ {<img src={isOK(pctResult) ? tickGreenIcon : dangerIcon}/>}
24
+ <span className="ml-1">Media connectivity</span></span>
25
+ </div>
26
+ <div className="col-4"/>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ );
31
+
32
+ MediaConnectivity.propTypes = {
33
+ pctResult: PropTypes.array
34
+ };
35
+ const mapStateToProps = state => ({});
36
+ const mapDispatchToProps = dispatch => ({});
37
+
38
+ export default connect(
39
+ mapStateToProps,
40
+ mapDispatchToProps
41
+ )(MediaConnectivity);
@@ -0,0 +1,57 @@
1
+ import React from 'react';
2
+ import { connect } from 'react-redux';
3
+ import PropTypes from 'prop-types';
4
+
5
+ import tickGreenIcon from '../../../res/images/fa-tick-green.svg';
6
+ import dangerIcon from '../../../res/images/fa-danger.svg';
7
+
8
+ import lo from 'lodash';
9
+ import styles from './../connectivitycheck.css';
10
+
11
+ const getLatestResultRTT = (pctResult) => {
12
+ let lastRecord = lo.last(pctResult) || {};
13
+ if ('rtt' in lastRecord) {
14
+ return lastRecord.rtt;
15
+ }
16
+ return -1;
17
+ };
18
+
19
+ const isOK = (pctResult) => {
20
+ let latestResult = getLatestResultRTT(pctResult);
21
+ return latestResult > 0 && latestResult < 240;
22
+ };
23
+
24
+ const formatValue = (value = 0) => {
25
+ value = Math.max(value, 0);
26
+ return parseFloat(value).toFixed(2);
27
+ };
28
+
29
+ const RoundTripTime = ({ pctResult = {} }) => (
30
+ <div className="row mt-1">
31
+ <div className="col-12">
32
+ <div className="row">
33
+ <div className="col-8">
34
+ <span className={styles.resultText}>
35
+ <img src={isOK(pctResult) ? tickGreenIcon : dangerIcon}/>
36
+ <span className="ml-1">Round trip time</span>
37
+ </span>
38
+ </div>
39
+ <div className="col-4 text-right">
40
+ <span className={styles.resultValue}>
41
+ {formatValue(getLatestResultRTT(pctResult))} ms </span>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ );
47
+
48
+ RoundTripTime.propTypes = {
49
+ pctResult: PropTypes.array
50
+ };
51
+ const mapStateToProps = state => ({});
52
+ const mapDispatchToProps = dispatch => ({});
53
+
54
+ export default connect(
55
+ mapStateToProps,
56
+ mapDispatchToProps
57
+ )(RoundTripTime);
@@ -0,0 +1,176 @@
1
+ import React from 'react';
2
+ import { connect } from 'react-redux';
3
+ import PropTypes from 'prop-types';
4
+ import { Line } from 'react-chartjs-2';
5
+ import lo from 'lodash';
6
+
7
+ const TOTAL_SEGMENT = 3;
8
+ const ONE_MINUTE_IN_MS = 60000;
9
+ const ONE_HOUR_IN_MS = 3600000;
10
+ const ONE_DAY_IN_MS = 86400000;
11
+
12
+ const getStepSize = (first = {}, last = {}) => {
13
+ let startTimeInMs = lo.get(first, 'epochTime', 0);
14
+ let endTimeInMs = lo.get(last, 'epochTime', 0);
15
+
16
+ let totalDayInMillis = Math.max(Math.abs(startTimeInMs - endTimeInMs), ONE_DAY_IN_MS);
17
+ let stepSizeInMillis = Math.round(totalDayInMillis / TOTAL_SEGMENT);
18
+ // console.warn('->', first, last, totalDayInMillis, stepSizeInMillis);
19
+ return stepSizeInMillis;
20
+ };
21
+
22
+ const getUnit = (first = {}, last = {}) => {
23
+ let startTimeInMs = lo.get(first, 'epochTime', 0);
24
+ let endTimeInMs = lo.get(last, 'epochTime', 0);
25
+ let diffInMs = Math.abs(startTimeInMs - endTimeInMs);
26
+ if (diffInMs < ONE_HOUR_IN_MS) {
27
+ let stepSize = Math.floor(diffInMs / 1000 / 60 / 3);
28
+ return { unit: 'minute', stepSize };
29
+ }
30
+ if (diffInMs < ONE_DAY_IN_MS) {
31
+ let stepSize = Math.floor(diffInMs / 1000 / 60 / 60 / 3);
32
+ return { unit: 'minute', stepSize };
33
+ }
34
+ let stepSize = Math.floor(diffInMs / 1000 / 60 / 60 / 24 / 3);
35
+ return { unit: 'day', stepSize };
36
+ };
37
+
38
+ // will distributed to 50 points
39
+ const getChartOptions = (pctResult = [], unit = undefined, stepSize) => {
40
+ // const stepSize = getStepSize(lo.first(pctResult), lo.last(pctResult));
41
+ // console.warn('~getChartOptions', pctResult, stepSize);
42
+ // const {unit, stepSize} = getUnit(lo.first(pctResult), lo.last(pctResult));
43
+ // console.warn('->', 'pctResult', pctResult, unit);
44
+ const chartOptions = {
45
+ scaleShowValues: true,
46
+ legend: {
47
+ display: false
48
+ },
49
+ tooltips: {
50
+ callbacks: {
51
+ label: function (tooltipItem) {
52
+ return `${tooltipItem.yLabel.toFixed(2)} kbps`;
53
+ }
54
+ }
55
+ },
56
+ scales: {
57
+ xAxes: [{
58
+ display: true,
59
+ type: 'time',
60
+ distribution: 'series',
61
+ autoSkip: false,
62
+ beginAtZero: true,
63
+ // stepSize: stepSize,
64
+ // unitStepSize: stepSize,
65
+ // unit: 'hour',
66
+ time: {
67
+ tooltipFormat: 'MMM D, h:mm:ss a',
68
+ // unit: unit,
69
+ // unitStepSize: stepSize,
70
+ // stepSize: stepSize,
71
+ beginAtZero: true,
72
+ autoSkip: false,
73
+ displayFormats: {
74
+ 'millisecond': 'HH:mm:ss',
75
+ 'second': 'HH:mm:ss',
76
+ 'minute': 'HH:mm:ss',
77
+ 'hour': 'HH:mm',
78
+ 'day': 'DD MMM'
79
+ }
80
+ }
81
+ }],
82
+ yAxes: [{
83
+ display: true,
84
+ scaleLabel: {
85
+ display: false
86
+ },
87
+ ticks: {
88
+ callback: function (value) {
89
+ return `${value} kbps`;
90
+ // return Math.round(value);
91
+ },
92
+ // min: 0,
93
+ // max: 3000,
94
+ autoSkip: true
95
+ // stepSize: 150
96
+ }
97
+ }]
98
+ }
99
+ };
100
+
101
+ return chartOptions;
102
+ };
103
+
104
+ const getLabels = (pctRecords) => {
105
+ let labels = pctRecords.map((item) => {
106
+ return item.epochTime;
107
+ });
108
+ // console.warn('->labels', labels);
109
+ return labels || [];
110
+ };
111
+ const getRTT = (pctRecords) => {
112
+ let rtts = pctRecords.map((item) => {
113
+ let rtt = parseFloat(item.rtt || 0);
114
+ return rtt;
115
+ });
116
+ // console.warn('-> total rtts', rtts.length);
117
+ return rtts || [];
118
+ };
119
+
120
+ const getThroughput = (pctRecords) => {
121
+ let throughput = pctRecords.map((item) => {
122
+ let throughput = parseFloat(item.throughput || 0);
123
+ return throughput;
124
+ });
125
+ // console.warn('data ',throughput);
126
+ return throughput || [];
127
+ };
128
+
129
+ const getChartData = (pctRecords) => {
130
+ const chartData = {
131
+ labels: getLabels(pctRecords),
132
+ datasets: [{
133
+ label: 'Throughput timeline',
134
+ // backgroundColor: '#6c757d',
135
+ // borderColor: '#6c757d',
136
+ borderWidth: 0,
137
+ pointRadius: 1,
138
+ lineTension: 0,
139
+ // hoverBackgroundColor: 'rgba(255,99,132,0.4)',
140
+ // hoverBorderColor: 'rgba(255,99,132,1)',
141
+ data: getThroughput(pctRecords)
142
+ }]
143
+ };
144
+ return chartData;
145
+ };
146
+
147
+ const getLatestResultThroughput = (lastRecord = {}) => {
148
+ return lastRecord.throughput || 0;
149
+ };
150
+
151
+ const isBad = (pctResult) => {
152
+ let latestResult = getLatestResultThroughput(pctResult);
153
+ return latestResult < 20;
154
+ };
155
+
156
+ const RTTGraph = ({ pctResult = {}, lastSCT = {}, unit = undefined, stepSize = 0 }) => (
157
+ <div className={`row mt-${isBad(lastSCT) ? 1 : 3}`}>
158
+ <div className="col-12" style={{ position: 'relative', height: '100px' }}>
159
+ <Line data={getChartData(pctResult)} options={getChartOptions(pctResult, unit, stepSize)}/>
160
+ </div>
161
+ </div>
162
+ );
163
+
164
+ RTTGraph.propTypes = {
165
+ pctResult: PropTypes.array,
166
+ lastSCT: PropTypes.object,
167
+ unit: PropTypes.string,
168
+ stepSize: PropTypes.number
169
+ };
170
+ const mapStateToProps = state => ({});
171
+ const mapDispatchToProps = dispatch => ({});
172
+
173
+ export default connect(
174
+ mapStateToProps,
175
+ mapDispatchToProps
176
+ )(RTTGraph);
@@ -0,0 +1,96 @@
1
+ import lo from 'lodash';
2
+
3
+ const ONE_MINUTE_IN_MS = 60000;
4
+ const ONE_HOUR_IN_MS = 3600000;
5
+ const ONE_DAY_IN_MS = 86400000;
6
+ const THREE_DAYS_MS = 259200000;
7
+ const STEP_SIZE = 5;
8
+
9
+ const getRecords = (currentTime = 0, at, data = [], timeSegmentInMs = ONE_DAY_IN_MS) => {
10
+ let last = currentTime - timeSegmentInMs;
11
+
12
+ let throughput = [];
13
+ for (let i = at; i >= 0; i -= 1) {
14
+ let currentResult = data[i];
15
+ if (currentResult.epochTime && currentResult.epochTime < last) {
16
+ return {
17
+ throughput: throughput,
18
+ lastIndex: i
19
+ };
20
+ }
21
+ throughput.push(currentResult);
22
+ }
23
+ // console.warn('-> ', throughput);
24
+ return {
25
+ throughput: throughput,
26
+ lastIndex: -1
27
+ };
28
+ };
29
+
30
+ const getMedianRTT = (data = []) => {
31
+ let len = data.length;
32
+ let pivot = Math.floor(len / 2);
33
+
34
+ let retval = len < 1 ? 0 : len % 2 !== 0 ? data[pivot].rtt : 0.5 * (data[pivot - 1].rtt + data[pivot].rtt);
35
+ // console.warn('media', data, retval);
36
+ return retval;
37
+ };
38
+
39
+ const getMedianThroughput = (data = []) => {
40
+ let len = data.length;
41
+ let pivot = Math.floor(len / 2);
42
+
43
+ let retval = len < 1 ? 0 : len % 2 !== 0 ? data[pivot].throughput : 0.5 * (data[pivot - 1].throughput + data[pivot].throughput);
44
+ // console.warn('media', data, retval);
45
+ return retval;
46
+ };
47
+
48
+ const getTimeRange = (first = {}, last = {}) => {
49
+ let startTimeInMs = lo.get(first, 'epochTime', 0);
50
+ let endTimeInMs = lo.get(last, 'epochTime', 0);
51
+ let diffInMs = Math.abs(startTimeInMs - endTimeInMs);
52
+ let unit = 'day';
53
+ if (diffInMs <= ONE_HOUR_IN_MS) {
54
+ unit = 'minute';
55
+ } else if (diffInMs <= ONE_DAY_IN_MS) {
56
+ unit = 'hour';
57
+ }
58
+ return { now: endTimeInMs, upto: startTimeInMs, unit };
59
+ };
60
+
61
+ export const postProcess = (pctResult = []) => {
62
+ // let now = (new Date).getTime();
63
+ let retval = [];
64
+
65
+ let { now, upto, unit } = getTimeRange(lo.first(pctResult), lo.last(pctResult));
66
+ // console.warn(now, upto, now-THREE_DAYS_MS)
67
+ upto = Math.max(now - THREE_DAYS_MS, upto);
68
+
69
+ let diffInMs = Math.abs(now - upto);
70
+ let timeSegmentInMs = diffInMs / 15;
71
+
72
+ // console.warn('-> ', timeSegmentInMs);
73
+ let prvIndex = pctResult.length;
74
+ retval.push({ throughput: lo.first(pctResult) ? (lo.first(pctResult).throughput || 0) : 0, epochTime: now });
75
+ for (let currentTime = now, at = prvIndex - 1; currentTime >= upto && at >= 0; currentTime -= timeSegmentInMs) {
76
+ let result = getRecords(currentTime, at, pctResult, timeSegmentInMs);
77
+
78
+ let { throughput, lastIndex } = result;
79
+
80
+ // if (prvIndex === lastIndex) {
81
+ // continue;
82
+ // }
83
+ prvIndex = lastIndex;
84
+ at = lastIndex;
85
+ let medianThroughput = getMedianThroughput(throughput);
86
+ let epochTime = currentTime;
87
+
88
+ // console.warn('->', result, medianThroughput, epochTime, medianThroughput);
89
+ retval.push({ throughput: medianThroughput, epochTime });
90
+ }
91
+ retval = retval.sort((l, r) => {
92
+ return l.epochTime < r.epochTime ? -1 : l.epochTime > r.epochTime ? 1 : 0;
93
+ });
94
+
95
+ return { pctResult: retval, unit, stepSize: timeSegmentInMs };
96
+ };