SidebarNav.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import React, {
  2. FC, memo, useCallback,
  3. } from 'react';
  4. import Link from 'next/link';
  5. import { useUserUISettings } from '~/client/services/user-ui-settings';
  6. import { SidebarContentsType } from '~/interfaces/ui';
  7. import { useIsAdmin, useGrowiCloudUri } from '~/stores/context';
  8. import { useCurrentSidebarContents } from '~/stores/ui';
  9. import styles from './SidebarNav.module.scss';
  10. type PrimaryItemProps = {
  11. contents: SidebarContentsType,
  12. label: string,
  13. iconName: string,
  14. onItemSelected: (contents: SidebarContentsType) => void,
  15. }
  16. const PrimaryItem: FC<PrimaryItemProps> = (props: PrimaryItemProps) => {
  17. const {
  18. contents, label, iconName, onItemSelected,
  19. } = props;
  20. const { data: currentContents, mutate } = useCurrentSidebarContents();
  21. const { scheduleToPut } = useUserUISettings();
  22. const isSelected = contents === currentContents;
  23. const itemSelectedHandler = useCallback(() => {
  24. if (onItemSelected != null) {
  25. onItemSelected(contents);
  26. }
  27. mutate(contents, false);
  28. scheduleToPut({ currentSidebarContents: contents });
  29. }, [contents, mutate, onItemSelected, scheduleToPut]);
  30. const labelForTestId = label.toLowerCase().replace(' ', '-');
  31. return (
  32. <button
  33. type="button"
  34. data-testid={`grw-sidebar-nav-primary-${labelForTestId}`}
  35. className={`d-block btn btn-primary ${isSelected ? 'active' : ''}`}
  36. onClick={itemSelectedHandler}
  37. >
  38. <i className="material-icons">{iconName}</i>
  39. </button>
  40. );
  41. };
  42. type SecondaryItemProps = {
  43. label: string,
  44. href: string,
  45. iconName: string,
  46. isBlank?: boolean,
  47. }
  48. const SecondaryItem: FC<SecondaryItemProps> = memo((props: SecondaryItemProps) => {
  49. const { iconName, href, isBlank } = props;
  50. return (
  51. <Link
  52. href={href}
  53. className="d-block btn btn-primary"
  54. target={`${isBlank ? '_blank' : ''}`}
  55. prefetch={false}
  56. >
  57. <i className="material-icons">{iconName}</i>
  58. </Link>
  59. );
  60. });
  61. SecondaryItem.displayName = 'SecondaryItem';
  62. type Props = {
  63. onItemSelected: (contents: SidebarContentsType) => void,
  64. }
  65. export const SidebarNav: FC<Props> = (props: Props) => {
  66. const { data: isAdmin } = useIsAdmin();
  67. const { data: growiCloudUri } = useGrowiCloudUri();
  68. const { onItemSelected } = props;
  69. return (
  70. <div className={`grw-sidebar-nav ${styles['grw-sidebar-nav']}`}>
  71. <div className="grw-sidebar-nav-primary-container" data-vrt-blackout-sidebar-nav>
  72. {/* eslint-disable max-len */}
  73. <PrimaryItem contents={SidebarContentsType.TREE} label="Page Tree" iconName="format_list_bulleted" onItemSelected={onItemSelected} />
  74. <PrimaryItem contents={SidebarContentsType.CUSTOM} label="Custom Sidebar" iconName="code" onItemSelected={onItemSelected} />
  75. <PrimaryItem contents={SidebarContentsType.RECENT} label="Recent Changes" iconName="update" onItemSelected={onItemSelected} />
  76. {/* <PrimaryItem id="tag" label="Tags" iconName="icon-tag" /> */}
  77. {/* <PrimaryItem id="favorite" label="Favorite" iconName="fa fa-bookmark-o" /> */}
  78. <PrimaryItem contents={SidebarContentsType.TAG} label="Tags" iconName="local_offer" onItemSelected={onItemSelected} />
  79. {/* <PrimaryItem id="favorite" label="Favorite" iconName="icon-star" /> */}
  80. {/* eslint-enable max-len */}
  81. <PrimaryItem contents={SidebarContentsType.BOOKMARKS} label="Bookmarks" iconName="bookmark" onItemSelected={onItemSelected} />
  82. </div>
  83. <div className="grw-sidebar-nav-secondary-container">
  84. {isAdmin && <SecondaryItem label="Admin" iconName="settings" href="/admin" />}
  85. {/* <SecondaryItem label="Draft" iconName="file_copy" href="/me/drafts" /> */}
  86. <SecondaryItem label="Help" iconName="help" href={ growiCloudUri != null ? 'https://growi.cloud/help/' : 'https://docs.growi.org' } isBlank />
  87. <SecondaryItem label="Trash" iconName="delete" href="/trash" />
  88. </div>
  89. </div>
  90. );
  91. };