diff --git a/apps/app/public/static/locales/en_US/translation.json b/apps/app/public/static/locales/en_US/translation.json index 64dcaa9db8c..a64c7561b33 100644 --- a/apps/app/public/static/locales/en_US/translation.json +++ b/apps/app/public/static/locales/en_US/translation.json @@ -786,6 +786,11 @@ "updatedAt": "Last update date" } }, + "help_dropdown": { + "show_shortcuts": "Show shortcuts", + "growi_cloud_help": "GROWI.cloud Help", + "growi_version": "GROWI version" + }, "private_legacy_pages": { "title": "Private Legacy Pages", "bulk_operation": "Bulk operation", diff --git a/apps/app/public/static/locales/fr_FR/translation.json b/apps/app/public/static/locales/fr_FR/translation.json index 3a6f2792703..6313bcebda0 100644 --- a/apps/app/public/static/locales/fr_FR/translation.json +++ b/apps/app/public/static/locales/fr_FR/translation.json @@ -780,6 +780,11 @@ "updatedAt": "Dernière modification" } }, + "help_dropdown": { + "show_shortcuts": "Afficher les raccourcis", + "growi_cloud_help": "Aide GROWI.cloud", + "growi_version": "Version GROWI" + }, "private_legacy_pages": { "title": "Anciennes pages privées", "bulk_operation": "Opération de masse", diff --git a/apps/app/public/static/locales/ja_JP/translation.json b/apps/app/public/static/locales/ja_JP/translation.json index 3afef6febc5..d214e7c9eae 100644 --- a/apps/app/public/static/locales/ja_JP/translation.json +++ b/apps/app/public/static/locales/ja_JP/translation.json @@ -819,6 +819,11 @@ "updatedAt": "更新日時" } }, + "help_dropdown": { + "show_shortcuts": "ショートカットを表示", + "growi_cloud_help": "GROWI.cloud ヘルプ", + "growi_version": "GROWI バージョン" + }, "private_legacy_pages": { "title": "旧形式のプライベートページ", "bulk_operation": "一括操作", diff --git a/apps/app/public/static/locales/ko_KR/translation.json b/apps/app/public/static/locales/ko_KR/translation.json index 6951b1f0b41..619aac42b99 100644 --- a/apps/app/public/static/locales/ko_KR/translation.json +++ b/apps/app/public/static/locales/ko_KR/translation.json @@ -746,6 +746,11 @@ "updatedAt": "마지막 업데이트일" } }, + "help_dropdown": { + "show_shortcuts": "단축키 표시", + "growi_cloud_help": "GROWI.cloud 도움말", + "growi_version": "GROWI 버전" + }, "private_legacy_pages": { "title": "비공개 레거시 페이지", "bulk_operation": "대량 작업", diff --git a/apps/app/public/static/locales/zh_CN/translation.json b/apps/app/public/static/locales/zh_CN/translation.json index fa2d3ef01ca..6e481c19623 100644 --- a/apps/app/public/static/locales/zh_CN/translation.json +++ b/apps/app/public/static/locales/zh_CN/translation.json @@ -791,6 +791,11 @@ "updatedAt": "按更新日期排序" } }, + "help_dropdown": { + "show_shortcuts": "显示快捷键", + "growi_cloud_help": "GROWI.cloud 帮助", + "growi_version": "GROWI 版本" + }, "private_legacy_pages": { "title": "私人遗留页面", "bulk_operation": "批量操作", diff --git a/apps/app/src/client/components/ShortcutsModal/ShortcutsModal.tsx b/apps/app/src/client/components/ShortcutsModal/ShortcutsModal.tsx index e7383a097da..7c2c1011d69 100644 --- a/apps/app/src/client/components/ShortcutsModal/ShortcutsModal.tsx +++ b/apps/app/src/client/components/ShortcutsModal/ShortcutsModal.tsx @@ -19,8 +19,8 @@ const ShortcutsModalSubstance = (): React.JSX.Element => { // Memoize OS-specific class const additionalClassByOs = useMemo(() => { - const platform = window.navigator.platform.toLowerCase(); - const isMac = platform.indexOf('mac') > -1; + const userAgent = window.navigator.userAgent.toLowerCase(); + const isMac = userAgent.indexOf('mac') > -1; return isMac ? 'mac' : 'win'; }, []); diff --git a/apps/app/src/client/components/Sidebar/SidebarNav/HelpDropdown.module.scss b/apps/app/src/client/components/Sidebar/SidebarNav/HelpDropdown.module.scss new file mode 100644 index 00000000000..540796f8746 --- /dev/null +++ b/apps/app/src/client/components/Sidebar/SidebarNav/HelpDropdown.module.scss @@ -0,0 +1,14 @@ +@use '@growi/core-styles/scss/helpers/modifier-keys'; + +.help-dropdown :global { + @include modifier-keys.modifier-key; +} + +.help-dropdown-menu :global { + @include modifier-keys.modifier-key; +} + +.help-dropdown-menu :global { + --bs-dropdown-font-size: 14px; + min-width: 240px; +} diff --git a/apps/app/src/client/components/Sidebar/SidebarNav/HelpDropdown.tsx b/apps/app/src/client/components/Sidebar/SidebarNav/HelpDropdown.tsx new file mode 100644 index 00000000000..6b08b3d82e6 --- /dev/null +++ b/apps/app/src/client/components/Sidebar/SidebarNav/HelpDropdown.tsx @@ -0,0 +1,97 @@ +import type { FC } from 'react'; +import { memo } from 'react'; +import { useTranslation } from 'next-i18next'; +import { + DropdownItem, + DropdownMenu, + DropdownToggle, + UncontrolledDropdown, +} from 'reactstrap'; + +import { useGrowiCloudUri, useGrowiVersion } from '~/states/global'; +import { useShortcutsModalActions } from '~/states/ui/modal/shortcuts'; + +import { SkeletonItem } from './SkeletonItem'; + +import styles from './HelpDropdown.module.scss'; + +export const HelpDropdown: FC = memo(() => { + const { t } = useTranslation(); + const growiVersion = useGrowiVersion(); + const { open: openShortcutsModal } = useShortcutsModalActions(); + const growiCloudUri = useGrowiCloudUri(); + + if (growiVersion == null) { + return ; + } + + // add classes to cmd-key by OS + const userAgent = window.navigator.userAgent.toLowerCase(); + const isMac = userAgent.indexOf('mac') > -1; + const os = isMac ? 'mac' : 'win'; + + // Cloud users see Help, others see Docs + const isCloudUser = growiCloudUri != null; + const helpUrl = isCloudUser + ? 'https://growi.cloud/help/' + : 'https://docs.growi.org'; + const helpLabel = isCloudUser ? t('Help') : 'GROWI Docs'; + + return ( + + + help + + + + + {t('Help')} + + + + {helpLabel} + external_link + + + + openShortcutsModal()}> + + + {t('help_dropdown.show_shortcuts')} + + + +  + / + + + + + + + + + + {' '} + {t('help_dropdown.growi_version')} + + {growiVersion} + + + + + ); +}); diff --git a/apps/app/src/client/components/Sidebar/SidebarNav/SecondaryItems.tsx b/apps/app/src/client/components/Sidebar/SidebarNav/SecondaryItems.tsx index cfe43118e18..97e24e4af6b 100644 --- a/apps/app/src/client/components/Sidebar/SidebarNav/SecondaryItems.tsx +++ b/apps/app/src/client/components/Sidebar/SidebarNav/SecondaryItems.tsx @@ -4,8 +4,8 @@ import dynamic from 'next/dynamic'; import Link from 'next/link'; import { useIsAdmin, useIsGuestUser } from '~/states/context'; -import { useGrowiCloudUri } from '~/states/global'; +import { HelpDropdown } from './HelpDropdown'; import { SkeletonItem } from './SkeletonItem'; import styles from './SecondaryItems.module.scss'; @@ -42,21 +42,11 @@ const SecondaryItem: FC = (props: SecondaryItemProps) => { export const SecondaryItems: FC = memo(() => { const isAdmin = useIsAdmin(); - const growiCloudUri = useGrowiCloudUri(); const isGuestUser = useIsGuestUser(); return (
- + {isAdmin && ( )} diff --git a/apps/app/src/client/components/SystemVersion.module.scss b/apps/app/src/client/components/SystemVersion.module.scss deleted file mode 100644 index b845e5c5f4e..00000000000 --- a/apps/app/src/client/components/SystemVersion.module.scss +++ /dev/null @@ -1,10 +0,0 @@ -@use '@growi/core-styles/scss/helpers/modifier-keys'; - -.system-version :global { - position: fixed; - right: 0.5em; - bottom: 0; - opacity: 0.6; - - @include modifier-keys.modifier-key; -} diff --git a/apps/app/src/client/components/SystemVersion.tsx b/apps/app/src/client/components/SystemVersion.tsx deleted file mode 100644 index 95c483fb0cc..00000000000 --- a/apps/app/src/client/components/SystemVersion.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import React, { type JSX } from 'react'; - -import { useGrowiVersion } from '~/states/global'; -import { useShortcutsModalActions } from '~/states/ui/modal/shortcuts'; - -import styles from './SystemVersion.module.scss'; - -type Props = { - showShortcutsButton?: boolean; -}; - -const SystemVersion = (props: Props): JSX.Element => { - const { showShortcutsButton } = props; - - const { open: openShortcutsModal } = useShortcutsModalActions(); - - const growiVersion = useGrowiVersion(); - // add classes to cmd-key by OS - const platform = window.navigator.platform.toLowerCase(); - const isMac = platform.indexOf('mac') > -1; - const os = isMac ? 'mac' : 'win'; - - return ( - <> -
- - GROWI {growiVersion} - - {showShortcutsButton && ( - - )} -
- - ); -}; - -export default SystemVersion; diff --git a/apps/app/src/components/Layout/AdminLayout.tsx b/apps/app/src/components/Layout/AdminLayout.tsx index 4b882d9d6db..744f736b38d 100644 --- a/apps/app/src/components/Layout/AdminLayout.tsx +++ b/apps/app/src/components/Layout/AdminLayout.tsx @@ -20,11 +20,6 @@ const PageCreateModal = dynamic( () => import('~/client/components/PageCreateModal'), { ssr: false }, ); -const SystemVersion = dynamic( - // biome-ignore lint/style/noRestrictedImports: no-problem dynamic import - () => import('~/client/components/SystemVersion'), - { ssr: false }, -); const HotkeysManager = dynamic( // biome-ignore lint/style/noRestrictedImports: no-problem dynamic import () => import('~/client/components/Hotkeys/HotkeysManager'), @@ -60,7 +55,6 @@ const AdminLayout = ({ children, componentTitle }: Props): JSX.Element => {
- diff --git a/apps/app/src/components/Layout/BasicLayout.tsx b/apps/app/src/components/Layout/BasicLayout.tsx index 2a12d541eab..ec7aa33ea40 100644 --- a/apps/app/src/components/Layout/BasicLayout.tsx +++ b/apps/app/src/components/Layout/BasicLayout.tsx @@ -43,10 +43,6 @@ const GrowiNavbarBottom = dynamic( ), { ssr: false }, ); -const SystemVersion = dynamic( - () => import('~/client/components/SystemVersion'), - { ssr: false }, -); // Page modals const PageCreateModal = dynamic( () => import('~/client/components/PageCreateModal'), @@ -100,7 +96,6 @@ export const BasicLayout = ({ children, className }: Props): JSX.Element => { - ); }; diff --git a/apps/app/src/components/Layout/ShareLinkLayout.tsx b/apps/app/src/components/Layout/ShareLinkLayout.tsx index 02bef313065..8067c257f0c 100644 --- a/apps/app/src/components/Layout/ShareLinkLayout.tsx +++ b/apps/app/src/components/Layout/ShareLinkLayout.tsx @@ -18,10 +18,6 @@ const GrowiNavbarBottom = dynamic( ), { ssr: false }, ); -const SystemVersion = dynamic( - () => import('~/client/components/SystemVersion'), - { ssr: false }, -); // biome-ignore-end lint/style/noRestrictedImports: no-problem dynamic import type Props = { @@ -37,7 +33,6 @@ export const ShareLinkLayout = ({ children }: Props): JSX.Element => { - ); };