2
0

SidebarNav.tsx 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import React, { FC, memo, useCallback } from 'react';
  2. import { scheduleToPutUserUISettings } from '~/client/services/user-ui-settings';
  3. import { SidebarContentsType } from '~/interfaces/ui';
  4. import { useCurrentUser, useIsSharedUser } from '~/stores/context';
  5. import { useCurrentSidebarContents } from '~/stores/ui';
  6. type PrimaryItemProps = {
  7. contents: SidebarContentsType,
  8. label: string,
  9. iconName: string,
  10. onItemSelected: (contents: SidebarContentsType) => void,
  11. }
  12. const PrimaryItem: FC<PrimaryItemProps> = (props: PrimaryItemProps) => {
  13. const {
  14. contents, iconName, onItemSelected,
  15. } = props;
  16. const { data: currentContents, mutate } = useCurrentSidebarContents();
  17. const isSelected = contents === currentContents;
  18. const itemSelectedHandler = useCallback(() => {
  19. if (onItemSelected != null) {
  20. onItemSelected(contents);
  21. }
  22. mutate(contents, false);
  23. scheduleToPutUserUISettings({ currentSidebarContents: contents });
  24. }, [contents, mutate, onItemSelected]);
  25. return (
  26. <button
  27. type="button"
  28. className={`d-block btn btn-primary ${isSelected ? 'active' : ''}`}
  29. onClick={itemSelectedHandler}
  30. >
  31. <i className="material-icons">{iconName}</i>
  32. </button>
  33. );
  34. };
  35. type SecondaryItemProps = {
  36. label: string,
  37. href: string,
  38. iconName: string,
  39. isBlank?: boolean,
  40. }
  41. const SecondaryItem: FC<SecondaryItemProps> = memo((props: SecondaryItemProps) => {
  42. const { iconName, href, isBlank } = props;
  43. return (
  44. <a href={href} className="d-block btn btn-primary" target={`${isBlank ? '_blank' : ''}`}>
  45. <i className="material-icons">{iconName}</i>
  46. </a>
  47. );
  48. });
  49. type Props = {
  50. onItemSelected: (contents: SidebarContentsType) => void,
  51. }
  52. const SidebarNav: FC<Props> = (props: Props) => {
  53. const { data: isSharedUser } = useIsSharedUser();
  54. const { data: currentUser } = useCurrentUser();
  55. const isAdmin = currentUser?.admin;
  56. const isLoggedIn = currentUser != null;
  57. const { onItemSelected } = props;
  58. return (
  59. <div className="grw-sidebar-nav">
  60. <div className="grw-sidebar-nav-primary-container">
  61. {!isSharedUser && <PrimaryItem contents={SidebarContentsType.CUSTOM} label="Custom Sidebar" iconName="code" onItemSelected={onItemSelected} />}
  62. {!isSharedUser && <PrimaryItem contents={SidebarContentsType.RECENT} label="Recent Changes" iconName="update" onItemSelected={onItemSelected} />}
  63. {!isSharedUser && <PrimaryItem contents={SidebarContentsType.TREE} label="Page Tree" iconName="format_list_bulleted" onItemSelected={onItemSelected} />}
  64. {/* <PrimaryItem id="tag" label="Tags" iconName="icon-tag" /> */}
  65. {/* <PrimaryItem id="favorite" label="Favorite" iconName="fa fa-bookmark-o" /> */}
  66. </div>
  67. <div className="grw-sidebar-nav-secondary-container">
  68. {isAdmin && <SecondaryItem label="Admin" iconName="settings" href="/admin" />}
  69. {isLoggedIn && <SecondaryItem label="Draft" iconName="file_copy" href="/me/drafts" />}
  70. <SecondaryItem label="Help" iconName="help" href="https://docs.growi.org" isBlank />
  71. <SecondaryItem label="Trash" iconName="delete" href="/trash" />
  72. </div>
  73. </div>
  74. );
  75. };
  76. export default SidebarNav;