CustomSidebar.jsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import React, {
  2. useState, useCallback, useEffect,
  3. } from 'react';
  4. import PropTypes from 'prop-types';
  5. import loggerFactory from '@alias/logger';
  6. import { withUnstatedContainers } from '../UnstatedUtils';
  7. import AppContainer from '../../services/AppContainer';
  8. import RevisionRenderer from '../Page/RevisionRenderer';
  9. const logger = loggerFactory('growi:cli:CustomSidebar');
  10. const SidebarNotFound = () => {
  11. return (
  12. <div className="grw-sidebar-content-header h5 text-center p-3">
  13. <a href="/Sidebar#edit">
  14. <i className="icon-magic-wand"></i> Create <strong>/Sidebar</strong> page
  15. </a>
  16. </div>
  17. );
  18. };
  19. const CustomSidebar = (props) => {
  20. const { appContainer } = props;
  21. const { apiGet } = appContainer;
  22. const [isMounted, setMounted] = useState(false);
  23. const [markdown, setMarkdown] = useState();
  24. const growiRenderer = appContainer.getRenderer('sidebar');
  25. // TODO: refactor with SWR
  26. const fetchDataAndRenderHtml = useCallback(async() => {
  27. let page = null;
  28. try {
  29. const result = await apiGet('/pages.get', { path: '/Sidebar' });
  30. page = result.page;
  31. }
  32. catch (e) {
  33. logger.warn(e.message);
  34. return;
  35. }
  36. finally {
  37. setMounted(true);
  38. }
  39. setMarkdown(page.revision.body);
  40. }, [apiGet]);
  41. useEffect(() => {
  42. fetchDataAndRenderHtml();
  43. }, [fetchDataAndRenderHtml]);
  44. return (
  45. <>
  46. <div className="grw-sidebar-content-header p-3 d-flex">
  47. <h3 className="mb-0">
  48. Custom Sidebar
  49. <a className="h6 ml-2" href="/Sidebar"><i className="icon-pencil"></i></a>
  50. </h3>
  51. <button type="button" className="btn btn-sm btn-outline-secondary ml-auto" onClick={fetchDataAndRenderHtml}>
  52. <i className="icon icon-reload"></i>
  53. </button>
  54. </div>
  55. { isMounted && markdown == null && <SidebarNotFound /> }
  56. {/* eslint-disable-next-line react/no-danger */}
  57. { markdown != null && (
  58. <div className="p-3">
  59. <RevisionRenderer
  60. growiRenderer={growiRenderer}
  61. markdown={markdown}
  62. additionalClassName="grw-custom-sidebar-content"
  63. />
  64. </div>
  65. ) }
  66. </>
  67. );
  68. };
  69. CustomSidebar.propTypes = {
  70. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  71. };
  72. /**
  73. * Wrapper component for using unstated
  74. */
  75. const CustomSidebarWrapper = withUnstatedContainers(CustomSidebar, [AppContainer]);
  76. export default CustomSidebarWrapper;