GrowiSubNavigation.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import React, { useEffect, useState } from 'react';
  2. import dynamic from 'next/dynamic';
  3. import { IPageHasId } from '~/interfaces/page';
  4. import { IUser } from '~/interfaces/user';
  5. import {
  6. EditorMode, useEditorMode,
  7. } from '~/stores/ui';
  8. import { TagLabelsSkelton } from '../Page/TagLabels';
  9. import PagePathNav from '../PagePathNav';
  10. import { Skelton } from '../Skelton';
  11. import DrawerToggler from './DrawerToggler';
  12. import AuthorInfoStyles from './AuthorInfo.module.scss';
  13. import styles from './GrowiSubNavigation.module.scss';
  14. const TagLabels = dynamic(() => import('../Page/TagLabels'), {
  15. ssr: false,
  16. loading: () => <TagLabelsSkelton />,
  17. });
  18. const AuthorInfo = dynamic(() => import('./AuthorInfo'), {
  19. ssr: false,
  20. loading: () => <Skelton additionalClass={`${AuthorInfoStyles['grw-author-info-skelton']} py-1`} />,
  21. });
  22. export type GrowiSubNavigationProps = {
  23. page: Partial<IPageHasId>,
  24. showDrawerToggler?: boolean,
  25. showTagLabel?: boolean,
  26. showPageAuthors?: boolean,
  27. isGuestUser?: boolean,
  28. isDrawerMode?: boolean,
  29. isCompactMode?: boolean,
  30. tags?: string[],
  31. tagsUpdatedHandler?: (newTags: string[]) => Promise<void> | void,
  32. controls: React.FunctionComponent,
  33. additionalClasses?: string[],
  34. }
  35. export const GrowiSubNavigation = (props: GrowiSubNavigationProps): JSX.Element => {
  36. const { data: editorMode } = useEditorMode();
  37. const [isControls, setControls] = useState(false);
  38. const {
  39. page,
  40. showDrawerToggler, showTagLabel, showPageAuthors,
  41. isGuestUser, isDrawerMode, isCompactMode,
  42. tags, tagsUpdatedHandler,
  43. controls: Controls,
  44. additionalClasses = [],
  45. } = props;
  46. const isViewMode = editorMode === EditorMode.View;
  47. const isEditorMode = !isViewMode;
  48. const compactModeClasses = isCompactMode ? 'grw-subnav-compact d-print-none' : '';
  49. const {
  50. _id: pageId, path, creator, lastUpdateUser,
  51. createdAt, updatedAt,
  52. } = page;
  53. useEffect(() => {
  54. if (Controls != null) {
  55. setControls(true);
  56. }
  57. }, [Controls]);
  58. if (path == null) {
  59. return <></>;
  60. }
  61. return (
  62. <div className={`grw-subnav ${styles['grw-subnav']} d-flex align-items-center justify-content-between ${additionalClasses.join(' ')}
  63. ${compactModeClasses}`} >
  64. {/* Left side */}
  65. <div className="d-flex grw-subnav-left-side">
  66. { (showDrawerToggler && isDrawerMode) && (
  67. <div className={`d-none d-md-flex align-items-center ${isEditorMode ? 'mr-2 pr-2' : 'border-right mr-4 pr-4'}`}>
  68. <DrawerToggler />
  69. </div>
  70. ) }
  71. <div className="grw-path-nav-container">
  72. { (showTagLabel && !isCompactMode) && (
  73. <div className="grw-taglabels-container">
  74. <TagLabels tags={tags} isGuestUser={isGuestUser ?? false} tagsUpdateInvoked={tagsUpdatedHandler} />
  75. </div>
  76. ) }
  77. <PagePathNav pageId={pageId} pagePath={path} isSingleLineMode={isEditorMode} isCompactMode={isCompactMode} />
  78. </div>
  79. </div>
  80. {/* Right side */}
  81. <div className="d-flex">
  82. { isControls && <Controls /> }
  83. {/* Page Authors */}
  84. { (showPageAuthors && !isCompactMode) && (
  85. <ul className={`${AuthorInfoStyles['grw-author-info']} text-nowrap border-left d-none d-lg-block d-edit-none py-2 pl-4 mb-0 ml-3`}>
  86. <li className="pb-1">
  87. <AuthorInfo user={creator as IUser} date={createdAt} locate="subnav" />
  88. </li>
  89. <li className="mt-1 pt-1 border-top">
  90. <AuthorInfo user={lastUpdateUser as IUser} date={updatedAt} mode="update" locate="subnav" />
  91. </li>
  92. </ul>
  93. ) }
  94. </div>
  95. </div>
  96. );
  97. };