EditorNavbarBottom.jsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import React, { useState } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { Collapse, Button } from 'reactstrap';
  4. import NavigationContainer from '../../services/NavigationContainer';
  5. import EditorContainer from '../../services/EditorContainer';
  6. import AppContainer from '../../services/AppContainer';
  7. import SlackNotification from '../SlackNotification';
  8. import SlackLogo from '../SlackLogo';
  9. import { withUnstatedContainers } from '../UnstatedUtils';
  10. import SavePageControls from '../SavePageControls';
  11. import OptionsSelector from './OptionsSelector';
  12. const EditorNavbarBottom = (props) => {
  13. const [isExpanded, setExpanded] = useState(false);
  14. const [isSlackExpanded, setSlackExpanded] = useState(false);
  15. const hasSlackConfig = props.appContainer.getConfig().hasSlackConfig;
  16. const {
  17. navigationContainer,
  18. } = props;
  19. const { editorMode, isDeviceSmallerThanMd } = navigationContainer.state;
  20. const additionalClasses = ['grw-editor-navbar-bottom'];
  21. const renderDrawerButton = () => (
  22. <button type="button" className="btn btn-outline-secondary border-0" onClick={() => navigationContainer.toggleDrawer()}>
  23. <i className="icon-menu"></i>
  24. </button>
  25. );
  26. const slackEnabledFlagChangedHandler = (isSlackEnabled) => {
  27. props.editorContainer.setState({ isSlackEnabled });
  28. };
  29. const slackChannelsChangedHandler = (slackChannels) => {
  30. props.editorContainer.setState({ slackChannels });
  31. };
  32. // eslint-disable-next-line react/prop-types
  33. const renderExpandButton = () => (
  34. <div className="d-md-none ml-2">
  35. <button
  36. type="button"
  37. className={`btn btn-outline-secondary btn-expand border-0 ${isExpanded ? 'expand' : ''}`}
  38. onClick={() => setExpanded(!isExpanded)}
  39. >
  40. <i className="icon-arrow-up"></i>
  41. </button>
  42. </div>
  43. );
  44. const isOptionsSelectorEnabled = editorMode !== 'hackmd';
  45. const isCollapsedOptionsSelectorEnabled = isOptionsSelectorEnabled && isDeviceSmallerThanMd;
  46. return (
  47. <div className={`${isCollapsedOptionsSelectorEnabled ? 'fixed-bottom' : ''} `}>
  48. {/* Collapsed SlackNotification */}
  49. {hasSlackConfig && (
  50. <Collapse isOpen={isSlackExpanded && isDeviceSmallerThanMd}>
  51. <nav className={`navbar navbar-expand-lg border-top ${additionalClasses.join(' ')}`}>
  52. <SlackNotification
  53. isSlackEnabled={props.editorContainer.state.isSlackEnabled}
  54. slackChannels={props.editorContainer.state.slackChannels}
  55. onEnabledFlagChange={slackEnabledFlagChangedHandler}
  56. onChannelChange={slackChannelsChangedHandler}
  57. id="idForEditorNavbarBottomForMobile"
  58. popUp
  59. />
  60. </nav>
  61. </Collapse>
  62. )
  63. }
  64. <div className={`navbar navbar-expand border-top px-2 px-md-3 ${additionalClasses.join(' ')}`}>
  65. <form className="form-inline">
  66. { isDeviceSmallerThanMd && renderDrawerButton() }
  67. { isOptionsSelectorEnabled && !isDeviceSmallerThanMd && <OptionsSelector /> }
  68. </form>
  69. <form className="form-inline flex-nowrap ml-auto">
  70. {/* Responsive Design for the SlackNotification */}
  71. {/* Button or the normal Slack banner */}
  72. {hasSlackConfig && (isDeviceSmallerThanMd ? (
  73. <Button
  74. className="grw-btn-slack border mr-2"
  75. onClick={() => (setSlackExpanded(!isSlackExpanded))}
  76. >
  77. <div className="grw-slack-logo">
  78. <SlackLogo />
  79. <span className="grw-btn-slack-triangle fa fa-caret-up ml-2"></span>
  80. </div>
  81. </Button>
  82. ) : (
  83. <div className="mr-2">
  84. <SlackNotification
  85. isSlackEnabled={props.editorContainer.state.isSlackEnabled}
  86. slackChannels={props.editorContainer.state.slackChannels}
  87. onEnabledFlagChange={slackEnabledFlagChangedHandler}
  88. onChannelChange={slackChannelsChangedHandler}
  89. id="idForEditorNavbarBottom"
  90. popUp={false}
  91. />
  92. </div>
  93. ))}
  94. <SavePageControls />
  95. { isCollapsedOptionsSelectorEnabled && renderExpandButton() }
  96. </form>
  97. </div>
  98. {/* Collapsed OptionsSelector */}
  99. { isCollapsedOptionsSelectorEnabled && (
  100. <Collapse isOpen={isExpanded}>
  101. <div className="px-2"> {/* set padding for border-top */}
  102. <div className={`navbar navbar-expand border-top px-0 ${additionalClasses.join(' ')}`}>
  103. <form className="form-inline ml-auto">
  104. <OptionsSelector />
  105. </form>
  106. </div>
  107. </div>
  108. </Collapse>
  109. ) }
  110. </div>
  111. );
  112. };
  113. EditorNavbarBottom.propTypes = {
  114. navigationContainer: PropTypes.instanceOf(NavigationContainer).isRequired,
  115. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  116. editorContainer: PropTypes.instanceOf(EditorContainer).isRequired,
  117. };
  118. export default withUnstatedContainers(EditorNavbarBottom, [NavigationContainer, EditorContainer, AppContainer]);