PrimaryItems.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import { memo } from 'react';
  2. import dynamic from 'next/dynamic';
  3. import { useAtomValue } from 'jotai';
  4. import { useTranslation } from 'react-i18next';
  5. import { NotAvailable } from '~/client/components/NotAvailable';
  6. import { SidebarContentsType } from '~/interfaces/ui';
  7. import { useIsGuestUser } from '~/states/context';
  8. import { useGrowiAppIdForGrowiCloud, useGrowiCloudUri } from '~/states/global';
  9. import { aiEnabledAtom } from '~/states/server-configurations';
  10. import { useSidebarMode } from '~/states/ui/sidebar';
  11. import { PrimaryItem } from './PrimaryItem';
  12. import styles from './PrimaryItems.module.scss';
  13. // Do not SSR Socket.io to make it work
  14. const PrimaryItemForNotification = dynamic(
  15. () =>
  16. import('../InAppNotification/PrimaryItemForNotification').then(
  17. (mod) => mod.PrimaryItemForNotification,
  18. ),
  19. { ssr: false },
  20. );
  21. type Props = {
  22. onItemHover?: (contents: SidebarContentsType) => void;
  23. };
  24. export const PrimaryItems = memo((props: Props) => {
  25. const { onItemHover } = props;
  26. const { t } = useTranslation();
  27. const { sidebarMode } = useSidebarMode();
  28. const isAiEnabled = useAtomValue(aiEnabledAtom);
  29. const isGuestUser = useIsGuestUser();
  30. const growiCloudUri = useGrowiCloudUri();
  31. const growiAppIdForGrowiCloud = useGrowiAppIdForGrowiCloud();
  32. const isCloud = growiCloudUri != null && growiAppIdForGrowiCloud != null;
  33. if (sidebarMode == null) {
  34. return <></>;
  35. }
  36. const aiAssistantNotAvailableTitle = (
  37. <>
  38. <p className="mb-2">
  39. {t('default_ai_assistant.open_cloud_settings_to_enable')}
  40. </p>
  41. <a href={`${growiCloudUri}/my/apps/${growiAppIdForGrowiCloud}`}>
  42. <span
  43. className="material-symbols-outlined me-1"
  44. style={{ fontSize: '1rem', verticalAlign: 'middle' }}
  45. >
  46. share
  47. </span>
  48. {t('default_ai_assistant.to_cloud_settings')}
  49. </a>
  50. </>
  51. );
  52. return (
  53. <div className={`${styles['grw-primary-items']} mt-1`}>
  54. <PrimaryItem
  55. sidebarMode={sidebarMode}
  56. contents={SidebarContentsType.TREE}
  57. label="Page Tree"
  58. iconName="list"
  59. onHover={onItemHover}
  60. />
  61. <PrimaryItem
  62. sidebarMode={sidebarMode}
  63. contents={SidebarContentsType.CUSTOM}
  64. label="Custom Sidebar"
  65. iconName="code"
  66. onHover={onItemHover}
  67. />
  68. <PrimaryItem
  69. sidebarMode={sidebarMode}
  70. contents={SidebarContentsType.RECENT}
  71. label="Recent Changes"
  72. iconName="update"
  73. onHover={onItemHover}
  74. />
  75. <PrimaryItem
  76. sidebarMode={sidebarMode}
  77. contents={SidebarContentsType.BOOKMARKS}
  78. label="Bookmarks"
  79. iconName="bookmarks"
  80. onHover={onItemHover}
  81. />
  82. <PrimaryItem
  83. sidebarMode={sidebarMode}
  84. contents={SidebarContentsType.TAG}
  85. label="Tags"
  86. iconName="local_offer"
  87. onHover={onItemHover}
  88. />
  89. {isGuestUser === false && (
  90. <PrimaryItemForNotification
  91. sidebarMode={sidebarMode}
  92. onHover={onItemHover}
  93. />
  94. )}
  95. {isAiEnabled ? (
  96. <PrimaryItem
  97. sidebarMode={sidebarMode}
  98. contents={SidebarContentsType.AI_ASSISTANT}
  99. label="AI Assistant"
  100. iconName="growi_ai"
  101. isCustomIcon
  102. onHover={onItemHover}
  103. />
  104. ) : (
  105. isCloud && (
  106. <NotAvailable
  107. isDisabled
  108. title={aiAssistantNotAvailableTitle}
  109. placement="right"
  110. >
  111. <PrimaryItem
  112. sidebarMode={sidebarMode}
  113. contents={SidebarContentsType.AI_ASSISTANT}
  114. label="AI Assistant"
  115. iconName="growi_ai"
  116. isCustomIcon
  117. />
  118. </NotAvailable>
  119. )
  120. )}
  121. </div>
  122. );
  123. });