Yuki Takei 7 месяцев назад
Родитель
Сommit
b15199d0ca

+ 7 - 6
apps/app/src/client/components/Admin/ElasticsearchManagement/ElasticsearchManagement.tsx

@@ -1,12 +1,12 @@
 import React, { useEffect, useState, useCallback } from 'react';
 import React, { useEffect, useState, useCallback } from 'react';
 
 
+import { useAtomValue } from 'jotai';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 
 
-
 import { apiv3Get, apiv3Post, apiv3Put } from '~/client/util/apiv3-client';
 import { apiv3Get, apiv3Post, apiv3Put } from '~/client/util/apiv3-client';
 import { toastSuccess, toastError } from '~/client/util/toastr';
 import { toastSuccess, toastError } from '~/client/util/toastr';
 import { SocketEventName } from '~/interfaces/websocket';
 import { SocketEventName } from '~/interfaces/websocket';
-import { useIsSearchServiceReachable } from '~/states/server-configurations';
+import { isSearchServiceReachableAtom } from '~/states/server-configurations';
 import { useAdminSocket } from '~/stores/socket-io';
 import { useAdminSocket } from '~/stores/socket-io';
 
 
 import NormalizeIndicesControls from './NormalizeIndicesControls';
 import NormalizeIndicesControls from './NormalizeIndicesControls';
@@ -14,9 +14,10 @@ import RebuildIndexControls from './RebuildIndexControls';
 import ReconnectControls from './ReconnectControls';
 import ReconnectControls from './ReconnectControls';
 import StatusTable from './StatusTable';
 import StatusTable from './StatusTable';
 
 
-const ElasticsearchManagement = () => {
+const ElasticsearchManagement: React.FC = () => {
   const { t } = useTranslation('admin');
   const { t } = useTranslation('admin');
-  const [isSearchServiceReachable] = useIsSearchServiceReachable();
+  // Get search service reachable flag from atom
+  const isSearchServiceReachable = useAtomValue(isSearchServiceReachableAtom);
   const { data: socket } = useAdminSocket();
   const { data: socket } = useAdminSocket();
 
 
   const [isInitialized, setIsInitialized] = useState(false);
   const [isInitialized, setIsInitialized] = useState(false);
@@ -78,11 +79,11 @@ const ElasticsearchManagement = () => {
     if (socket == null) {
     if (socket == null) {
       return;
       return;
     }
     }
-    socket.on(SocketEventName.AddPageProgress, (data) => {
+    socket.on(SocketEventName.AddPageProgress, () => {
       setIsRebuildingProcessing(true);
       setIsRebuildingProcessing(true);
     });
     });
 
 
-    socket.on(SocketEventName.FinishAddPage, async(data) => {
+    socket.on(SocketEventName.FinishAddPage, async() => {
       await retrieveIndicesStatus();
       await retrieveIndicesStatus();
       setIsRebuildingProcessing(false);
       setIsRebuildingProcessing(false);
       setIsRebuildingCompleted(true);
       setIsRebuildingCompleted(true);

+ 4 - 2
apps/app/src/client/components/Admin/Notification/ManageGlobalNotification.tsx

@@ -2,6 +2,7 @@ import React, {
   useCallback, useMemo, useEffect, useState, type JSX,
   useCallback, useMemo, useEffect, useState, type JSX,
 } from 'react';
 } from 'react';
 
 
+import { useAtomValue } from 'jotai';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import Link from 'next/link';
 import Link from 'next/link';
 import { useRouter } from 'next/router';
 import { useRouter } from 'next/router';
@@ -9,7 +10,7 @@ import { useRouter } from 'next/router';
 import { NotifyType, TriggerEventType } from '~/client/interfaces/global-notification';
 import { NotifyType, TriggerEventType } from '~/client/interfaces/global-notification';
 import { apiv3Post } from '~/client/util/apiv3-client';
 import { apiv3Post } from '~/client/util/apiv3-client';
 import { toastError } from '~/client/util/toastr';
 import { toastError } from '~/client/util/toastr';
-import { useIsMailerSetup } from '~/states/server-configurations';
+import { isMailerSetupAtom } from '~/states/server-configurations';
 import { useSWRxGlobalNotification } from '~/stores/global-notification';
 import { useSWRxGlobalNotification } from '~/stores/global-notification';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
@@ -106,7 +107,8 @@ const ManageGlobalNotification = (props: Props): JSX.Element => {
   }, [emailToSend, notifyType, props.globalNotificationId, router, slackChannelToSend, triggerEvents, triggerPath, updateGlobalNotification]);
   }, [emailToSend, notifyType, props.globalNotificationId, router, slackChannelToSend, triggerEvents, triggerPath, updateGlobalNotification]);
 
 
 
 
-  const [isMailerSetup] = useIsMailerSetup();
+  // Mailer setup status (unused yet but kept for potential conditional logic)
+  const isMailerSetup = useAtomValue(isMailerSetupAtom);
   const { t } = useTranslation('admin');
   const { t } = useTranslation('admin');
 
 
   return (
   return (

+ 3 - 2
apps/app/src/client/components/Admin/UserGroup/UserGroupPage.tsx

@@ -4,6 +4,7 @@ import React, { useState, useCallback } from 'react';
 import {
 import {
   GroupType, getIdForRef, type IGrantedGroup, type IUserGroup, type IUserGroupHasId,
   GroupType, getIdForRef, type IGrantedGroup, type IUserGroup, type IUserGroupHasId,
 } from '@growi/core';
 } from '@growi/core';
+import { useAtomValue } from 'jotai';
 import dynamic from 'next/dynamic';
 import dynamic from 'next/dynamic';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
 
 
@@ -12,7 +13,7 @@ import { toastSuccess, toastError } from '~/client/util/toastr';
 import { ExternalGroupManagement } from '~/features/external-user-group/client/components/ExternalUserGroup/ExternalUserGroupManagement';
 import { ExternalGroupManagement } from '~/features/external-user-group/client/components/ExternalUserGroup/ExternalUserGroupManagement';
 import { useSWRxExternalUserGroupList } from '~/features/external-user-group/client/stores/external-user-group';
 import { useSWRxExternalUserGroupList } from '~/features/external-user-group/client/stores/external-user-group';
 import type { PageActionOnGroupDelete } from '~/interfaces/user-group';
 import type { PageActionOnGroupDelete } from '~/interfaces/user-group';
-import { useIsAclEnabled } from '~/states/server-configurations';
+import { isAclEnabledAtom } from '~/states/server-configurations';
 import { useSWRxUserGroupList, useSWRxChildUserGroupList, useSWRxUserGroupRelationList } from '~/stores/user-group';
 import { useSWRxUserGroupList, useSWRxChildUserGroupList, useSWRxUserGroupRelationList } from '~/stores/user-group';
 
 
 
 
@@ -23,7 +24,7 @@ const UserGroupTable = dynamic(() => import('./UserGroupTable').then(mod => mod.
 export const UserGroupPage: FC = () => {
 export const UserGroupPage: FC = () => {
   const { t } = useTranslation();
   const { t } = useTranslation();
 
 
-  const [isAclEnabled] = useIsAclEnabled();
+  const isAclEnabled = useAtomValue(isAclEnabledAtom);
 
 
   /*
   /*
    * Fetch
    * Fetch

+ 3 - 2
apps/app/src/client/components/Admin/UserGroupDetail/UserGroupDetailPage.tsx

@@ -6,6 +6,7 @@ import {
   GroupType, getIdStringForRef, type IGrantedGroup, type IUserGroup, type IUserGroupHasId,
   GroupType, getIdStringForRef, type IGrantedGroup, type IUserGroup, type IUserGroupHasId,
 } from '@growi/core';
 } from '@growi/core';
 import { objectIdUtils } from '@growi/core/dist/utils';
 import { objectIdUtils } from '@growi/core/dist/utils';
+import { useAtomValue } from 'jotai';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import dynamic from 'next/dynamic';
 import dynamic from 'next/dynamic';
 import Link from 'next/link';
 import Link from 'next/link';
@@ -18,7 +19,7 @@ import { toastSuccess, toastError } from '~/client/util/toastr';
 import type { IExternalUserGroupHasId } from '~/features/external-user-group/interfaces/external-user-group';
 import type { IExternalUserGroupHasId } from '~/features/external-user-group/interfaces/external-user-group';
 import type { PageActionOnGroupDelete, SearchType } from '~/interfaces/user-group';
 import type { PageActionOnGroupDelete, SearchType } from '~/interfaces/user-group';
 import { SearchTypes } from '~/interfaces/user-group';
 import { SearchTypes } from '~/interfaces/user-group';
-import { useIsAclEnabled } from '~/states/server-configurations';
+import { isAclEnabledAtom } from '~/states/server-configurations';
 import { useUpdateUserGroupConfirmModal } from '~/stores/modal';
 import { useUpdateUserGroupConfirmModal } from '~/stores/modal';
 import { useSWRxUserGroupPages, useSWRxSelectableParentUserGroups, useSWRxSelectableChildUserGroups } from '~/stores/user-group';
 import { useSWRxUserGroupPages, useSWRxSelectableParentUserGroups, useSWRxSelectableChildUserGroups } from '~/stores/user-group';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
@@ -104,7 +105,7 @@ const UserGroupDetailPage = (props: Props): JSX.Element => {
 
 
   const { data: ancestorUserGroups, mutate: mutateAncestorUserGroups } = useAncestorUserGroups(currentUserGroupId, isExternalGroup);
   const { data: ancestorUserGroups, mutate: mutateAncestorUserGroups } = useAncestorUserGroups(currentUserGroupId, isExternalGroup);
 
 
-  const [isAclEnabled] = useIsAclEnabled();
+  const isAclEnabled = useAtomValue(isAclEnabledAtom);
 
 
   const { open: openUpdateParentConfirmModal } = useUpdateUserGroupConfirmModal();
   const { open: openUpdateParentConfirmModal } = useUpdateUserGroupConfirmModal();
 
 

+ 1 - 1
apps/app/src/client/components/AlertSiteUrlUndefined.tsx

@@ -17,7 +17,7 @@ const isValidUrl = (str: string): boolean => {
 
 
 export const AlertSiteUrlUndefined = (): JSX.Element => {
 export const AlertSiteUrlUndefined = (): JSX.Element => {
   const { t } = useTranslation('commons');
   const { t } = useTranslation('commons');
-  const [siteUrl] = useSiteUrl();
+  const siteUrl = useSiteUrl();
 
 
   if (typeof siteUrl === 'string' && isValidUrl(siteUrl)) {
   if (typeof siteUrl === 'string' && isValidUrl(siteUrl)) {
     return <></>;
     return <></>;

+ 3 - 2
apps/app/src/client/components/InAppNotification/InAppNotificationPage.tsx

@@ -2,11 +2,12 @@ import type { FC } from 'react';
 import React, { useState } from 'react';
 import React, { useState } from 'react';
 
 
 import { LoadingSpinner } from '@growi/ui/dist/components';
 import { LoadingSpinner } from '@growi/ui/dist/components';
+import { useAtomValue } from 'jotai';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 
 
 import { apiv3Put } from '~/client/util/apiv3-client';
 import { apiv3Put } from '~/client/util/apiv3-client';
 import { InAppNotificationStatuses } from '~/interfaces/in-app-notification';
 import { InAppNotificationStatuses } from '~/interfaces/in-app-notification';
-import { useShowPageLimitationXL } from '~/states/server-configurations';
+import { showPageLimitationXLAtom } from '~/states/server-configurations';
 import { useSWRxInAppNotifications, useSWRxInAppNotificationStatus } from '~/stores/in-app-notification';
 import { useSWRxInAppNotifications, useSWRxInAppNotificationStatus } from '~/stores/in-app-notification';
 
 
 import CustomNavAndContents from '../CustomNavigation/CustomNavAndContents';
 import CustomNavAndContents from '../CustomNavigation/CustomNavAndContents';
@@ -17,7 +18,7 @@ import InAppNotificationList from './InAppNotificationList';
 export const InAppNotificationPage: FC = () => {
 export const InAppNotificationPage: FC = () => {
   const { t } = useTranslation('commons');
   const { t } = useTranslation('commons');
 
 
-  const [showPageLimitationXL] = useShowPageLimitationXL();
+  const showPageLimitationXL = useAtomValue(showPageLimitationXLAtom);
 
 
   const limit = showPageLimitationXL != null ? showPageLimitationXL : 20;
   const limit = showPageLimitationXL != null ? showPageLimitationXL : 20;
 
 

+ 3 - 2
apps/app/src/client/components/Me/BasicInfoSettings.tsx

@@ -1,16 +1,17 @@
 import React, { type JSX } from 'react';
 import React, { type JSX } from 'react';
 
 
+import { useAtomValue } from 'jotai';
 import { useTranslation, i18n } from 'next-i18next';
 import { useTranslation, i18n } from 'next-i18next';
 
 
 import { i18n as i18nConfig } from '^/config/next-i18next.config';
 import { i18n as i18nConfig } from '^/config/next-i18next.config';
 
 
 import { toastSuccess, toastError } from '~/client/util/toastr';
 import { toastSuccess, toastError } from '~/client/util/toastr';
-import { useRegistrationWhitelist } from '~/states/server-configurations';
+import { registrationWhitelistAtom } from '~/states/server-configurations';
 import { usePersonalSettings } from '~/stores/personal-settings';
 import { usePersonalSettings } from '~/stores/personal-settings';
 
 
 export const BasicInfoSettings = (): JSX.Element => {
 export const BasicInfoSettings = (): JSX.Element => {
   const { t } = useTranslation();
   const { t } = useTranslation();
-  const [registrationWhitelist] = useRegistrationWhitelist();
+  const registrationWhitelist = useAtomValue(registrationWhitelistAtom);
 
 
   const {
   const {
     data: personalSettingsInfo, mutate: mutatePersonalSettings, sync, updateBasicInfo, error,
     data: personalSettingsInfo, mutate: mutatePersonalSettings, sync, updateBasicInfo, error,

+ 20 - 17
apps/app/src/client/components/Navbar/GrowiContextualSubNavigation.tsx

@@ -11,6 +11,7 @@ import type {
 import { pagePathUtils } from '@growi/core/dist/utils';
 import { pagePathUtils } from '@growi/core/dist/utils';
 import { GlobalCodeMirrorEditorKey } from '@growi/editor';
 import { GlobalCodeMirrorEditorKey } from '@growi/editor';
 import { useCodeMirrorEditorIsolated } from '@growi/editor/dist/client/stores/codemirror-editor';
 import { useCodeMirrorEditorIsolated } from '@growi/editor/dist/client/stores/codemirror-editor';
+import { useAtomValue } from 'jotai';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import dynamic from 'next/dynamic';
 import dynamic from 'next/dynamic';
 import Link from 'next/link';
 import Link from 'next/link';
@@ -29,8 +30,10 @@ import { useCurrentPathname, useCurrentUser } from '~/states/global';
 import { useCurrentPageId, useFetchCurrentPage } from '~/states/page';
 import { useCurrentPageId, useFetchCurrentPage } from '~/states/page';
 import { useShareLinkId } from '~/states/page/hooks';
 import { useShareLinkId } from '~/states/page/hooks';
 import {
 import {
-  useDisableLinkSharing,
-  useIsBulkExportPagesEnabled, useIsLocalAccountRegistrationEnabled, useIsUploadEnabled,
+  disableLinkSharingAtom,
+  isBulkExportPagesEnabledAtom,
+  isLocalAccountRegistrationEnabledAtom,
+  isUploadEnabledAtom,
 } from '~/states/server-configurations';
 } from '~/states/server-configurations';
 import { useEditorMode } from '~/states/ui/editor';
 import { useEditorMode } from '~/states/ui/editor';
 import {
 import {
@@ -79,11 +82,11 @@ const PageOperationMenuItems = (props: PageOperationMenuItemsProps): JSX.Element
     pageId, revisionId, isLinkSharingDisabled,
     pageId, revisionId, isLinkSharingDisabled,
   } = props;
   } = props;
 
 
-  const [isGuestUser] = useIsGuestUser();
-  const [isReadOnlyUser] = useIsReadOnlyUser();
-  const [isSharedUser] = useIsSharedUser();
-  const [isBulkExportPagesEnabled] = useIsBulkExportPagesEnabled();
-  const [isUploadEnabled] = useIsUploadEnabled();
+  const isGuestUser = useIsGuestUser();
+  const isReadOnlyUser = useIsReadOnlyUser();
+  const isSharedUser = useIsSharedUser();
+  const isBulkExportPagesEnabled = useAtomValue(isBulkExportPagesEnabledAtom);
+  const isUploadEnabled = useAtomValue(isUploadEnabledAtom);
 
 
   const { open: openPresentationModal } = usePagePresentationModal();
   const { open: openPresentationModal } = usePagePresentationModal();
   const { open: openAccessoriesModal } = usePageAccessoriesModal();
   const { open: openAccessoriesModal } = usePageAccessoriesModal();
@@ -255,23 +258,23 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
 
 
   const router = useRouter();
   const router = useRouter();
 
 
-  const [shareLinkId] = useShareLinkId();
+  const shareLinkId = useShareLinkId();
   const { fetchCurrentPage } = useFetchCurrentPage();
   const { fetchCurrentPage } = useFetchCurrentPage();
 
 
-  const [currentPathname] = useCurrentPathname();
+  const currentPathname = useCurrentPathname();
   const isSharedPage = pagePathUtils.isSharedPage(currentPathname ?? '');
   const isSharedPage = pagePathUtils.isSharedPage(currentPathname ?? '');
 
 
   const revision = currentPage?.revision;
   const revision = currentPage?.revision;
   const revisionId = (revision != null && isPopulated(revision)) ? revision._id : undefined;
   const revisionId = (revision != null && isPopulated(revision)) ? revision._id : undefined;
 
 
   const { editorMode } = useEditorMode();
   const { editorMode } = useEditorMode();
-  const [pageId] = useCurrentPageId();
-  const [currentUser] = useCurrentUser();
-  const [isGuestUser] = useIsGuestUser();
-  const [isReadOnlyUser] = useIsReadOnlyUser();
-  const [isLocalAccountRegistrationEnabled] = useIsLocalAccountRegistrationEnabled();
-  const [isLinkSharingDisabled] = useDisableLinkSharing();
-  const [isSharedUser] = useIsSharedUser();
+  const pageId = useCurrentPageId();
+  const currentUser = useCurrentUser();
+  const isGuestUser = useIsGuestUser();
+  const isReadOnlyUser = useIsReadOnlyUser();
+  const isLocalAccountRegistrationEnabled = useAtomValue(isLocalAccountRegistrationEnabledAtom);
+  const isLinkSharingDisabled = useAtomValue(disableLinkSharingAtom);
+  const isSharedUser = useIsSharedUser();
 
 
   const shouldExpandContent = useShouldExpandContent(currentPage);
   const shouldExpandContent = useShouldExpandContent(currentPage);
 
 
@@ -373,7 +376,7 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
         }
         }
       </>
       </>
     );
     );
-  }, [isLinkSharingDisabled, isReadOnlyUser, pageId, revisionId]);
+  }, [isLinkSharingDisabled, pageId, revisionId, isReadOnlyUser]);
 
 
   // hide sub controls when sticky on mobile device
   // hide sub controls when sticky on mobile device
   const hideSubControls = useMemo(() => {
   const hideSubControls = useMemo(() => {

+ 5 - 4
apps/app/src/client/components/PageComment/CommentEditor.tsx

@@ -9,6 +9,7 @@ import { CodeMirrorEditorComment } from '@growi/editor/dist/client/components/Co
 import { useCodeMirrorEditorIsolated } from '@growi/editor/dist/client/stores/codemirror-editor';
 import { useCodeMirrorEditorIsolated } from '@growi/editor/dist/client/stores/codemirror-editor';
 import { useResolvedThemeForEditor } from '@growi/editor/dist/client/stores/use-resolved-theme';
 import { useResolvedThemeForEditor } from '@growi/editor/dist/client/stores/use-resolved-theme';
 import { UserPicture } from '@growi/ui/dist/components';
 import { UserPicture } from '@growi/ui/dist/components';
+import { useAtomValue } from 'jotai';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import dynamic from 'next/dynamic';
 import dynamic from 'next/dynamic';
 import {
 import {
@@ -20,7 +21,7 @@ import { uploadAttachments } from '~/client/services/upload-attachments';
 import { toastError } from '~/client/util/toastr';
 import { toastError } from '~/client/util/toastr';
 import { useCurrentUser } from '~/states/global';
 import { useCurrentUser } from '~/states/global';
 import { useCurrentPagePath } from '~/states/page';
 import { useCurrentPagePath } from '~/states/page';
-import { useIsSlackConfigured } from '~/states/server-configurations';
+import { isSlackConfiguredAtom } from '~/states/server-configurations';
 import { useAcceptedUploadFileType } from '~/stores-universal/context';
 import { useAcceptedUploadFileType } from '~/stores-universal/context';
 import { useNextThemes } from '~/stores-universal/use-next-themes';
 import { useNextThemes } from '~/stores-universal/use-next-themes';
 import { useSWRxPageComment } from '~/stores/comment';
 import { useSWRxPageComment } from '~/stores/comment';
@@ -77,13 +78,13 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => {
     currentCommentId, commentBody, onCanceled, onCommented,
     currentCommentId, commentBody, onCanceled, onCommented,
   } = props;
   } = props;
 
 
-  const [currentUser] = useCurrentUser();
-  const [currentPagePath] = useCurrentPagePath();
+  const currentUser = useCurrentUser();
+  const currentPagePath = useCurrentPagePath();
   const { update: updateComment, post: postComment } = useSWRxPageComment(pageId);
   const { update: updateComment, post: postComment } = useSWRxPageComment(pageId);
   const { data: isSlackEnabled, mutate: mutateIsSlackEnabled } = useIsSlackEnabled();
   const { data: isSlackEnabled, mutate: mutateIsSlackEnabled } = useIsSlackEnabled();
   const { data: acceptedUploadFileType } = useAcceptedUploadFileType();
   const { data: acceptedUploadFileType } = useAcceptedUploadFileType();
   const { data: slackChannelsData } = useSWRxSlackChannels(currentPagePath);
   const { data: slackChannelsData } = useSWRxSlackChannels(currentPagePath);
-  const [isSlackConfigured] = useIsSlackConfigured();
+  const isSlackConfigured = useAtomValue(isSlackConfiguredAtom);
   const { data: editorSettings } = useEditorSettings();
   const { data: editorSettings } = useEditorSettings();
   const { mutate: mutateIsEnabledUnsavedWarning } = useIsEnabledUnsavedWarning();
   const { mutate: mutateIsEnabledUnsavedWarning } = useIsEnabledUnsavedWarning();
   const {
   const {