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

+ 5 - 5
apps/app/src/pages/[[...path]]/index.page.tsx

@@ -25,7 +25,6 @@ import {
 import { useHydratePageAtoms } from '~/states/page/hydrate';
 import { useRedirectFrom } from '~/states/page/redirect';
 import { useRendererConfig } from '~/states/server-configurations';
-import { useHydrateServerConfigurationAtoms } from '~/states/server-configurations/hydrate';
 import { useSetupGlobalSocket, useSetupGlobalSocketForPage } from '~/states/socket-io';
 import { useEditingMarkdown } from '~/states/ui/editor';
 import { useHydrateSidebarAtoms } from '~/states/ui/sidebar/hydrate';
@@ -33,9 +32,10 @@ import { useSWRMUTxCurrentPageYjsData } from '~/stores/yjs';
 
 import type { NextPageWithLayout } from '../_app.page';
 import type { UserUISettingsProps } from '../common-props';
-import type { InitialProps, SidebarConfigProps } from '../general-page';
+import type { GeneralPageInitialProps, SidebarConfigProps } from '../general-page';
 import { useInitialCSRFetch } from '../general-page';
 import { registerPageToShowRevisionWithMeta } from '../general-page/superjson';
+import { useHydrateServerConfigurationAtoms } from '../general-page/use-hydrate-server-configurations';
 import { NextjsRoutingType, detectNextjsRoutingType } from '../utils/nextjs-routing-utils';
 import { useCustomTitleForPage } from '../utils/page-title-customization';
 
@@ -74,10 +74,10 @@ const ConflictDiffModal = dynamic(() => import('~/client/components/PageEditor/C
 
 const EditablePageEffects = dynamic(() => import('~/client/components/Page/EditablePageEffects').then(mod => mod.EditablePageEffects), { ssr: false });
 
+type InitialProps = EachProps & GeneralPageInitialProps & UserUISettingsProps & SidebarConfigProps;
+type Props = EachProps | InitialProps;
 
-type Props = EachProps | (EachProps & InitialProps & UserUISettingsProps & SidebarConfigProps);
-
-const isInitialProps = (props: Props): props is (UserUISettingsProps & SidebarConfigProps & InitialProps & EachProps) => {
+const isInitialProps = (props: Props): props is InitialProps => {
   return 'isNextjsRoutingTypeInitial' in props && props.isNextjsRoutingTypeInitial;
 };
 

+ 2 - 2
apps/app/src/pages/[[...path]]/page-data-props.ts

@@ -9,7 +9,7 @@ import type { PageModel } from '~/server/models/page';
 import type { IPageRedirect, PageRedirectModel } from '~/server/models/page-redirect';
 
 import type { CommonEachProps } from '../common-props';
-import type { InitialProps } from '../general-page';
+import type { GeneralPageInitialProps } from '../general-page';
 
 import type { EachProps } from './types';
 
@@ -59,7 +59,7 @@ async function resolvePathAndCheckIdentical(
 export async function getPageDataForInitial(
     context: GetServerSidePropsContext,
 ): Promise<GetServerSidePropsResult<
-  Pick<InitialProps, 'pageWithMeta' | 'isNotFound' | 'isNotCreatable' | 'isForbidden' | 'skipSSR'> &
+  Pick<GeneralPageInitialProps, 'pageWithMeta' | 'isNotFound' | 'isNotCreatable' | 'isForbidden' | 'skipSSR'> &
   Pick<EachProps, 'currentPathname' | 'isIdenticalPathPage' | 'redirectFrom'>
 >> {
   const req: CrowiRequest = context.req as CrowiRequest;

+ 4 - 3
apps/app/src/pages/[[...path]]/server-side-props.ts

@@ -3,11 +3,12 @@ import type { GetServerSidePropsContext, GetServerSidePropsResult } from 'next';
 import {
   getServerSideI18nProps, getServerSideUserUISettingsProps, getServerSideCommonInitialProps, getServerSideCommonEachProps, isValidCommonEachRouteProps,
 } from '../common-props';
-import type { InitialProps } from '../general-page';
+import type { GeneralPageInitialProps } from '../general-page';
 import {
-  getServerSideConfigurationProps, getServerSideRendererConfigProps, getServerSideSidebarConfigProps,
+  getServerSideRendererConfigProps, getServerSideSidebarConfigProps,
   getActivityAction, isValidInitialAndSameRouteProps,
 } from '../general-page';
+import { getServerSideConfigurationProps } from '../general-page/configuration-props';
 import { addActivity } from '../utils/activity';
 import { mergeGetServerSidePropsResults } from '../utils/server-side-props';
 
@@ -22,7 +23,7 @@ const nextjsRoutingProps = {
   },
 };
 
-export async function getServerSidePropsForInitial(context: GetServerSidePropsContext): Promise<GetServerSidePropsResult<InitialProps & EachProps>> {
+export async function getServerSidePropsForInitial(context: GetServerSidePropsContext): Promise<GetServerSidePropsResult<GeneralPageInitialProps & EachProps>> {
   //
   // STAGE 1
   //

+ 9 - 9
apps/app/src/pages/general-page/type-guards.ts

@@ -3,25 +3,25 @@ import loggerFactory from '~/utils/logger';
 import type { CommonEachProps } from '../common-props';
 import { isValidCommonEachRouteProps } from '../common-props';
 
-import type { InitialProps } from './types';
+import type { GeneralPageInitialProps } from './types';
 
 const logger = loggerFactory('growi:pages:general-page:type-guards');
 
 /**
- * Type guard for InitialProps & SameRouteEachProps validation
- * First validates SameRouteEachProps, then checks InitialProps-specific properties
+ * Type guard for GeneralPageInitialProps & CommonEachProps validation
+ * First validates CommonEachProps, then checks GeneralPageGeneralPageInitialProps-specific properties
  */
-export function isValidInitialAndSameRouteProps(props: unknown): props is InitialProps & CommonEachProps {
-  // First, validate SameRouteEachProps
+export function isValidInitialAndSameRouteProps(props: unknown): props is GeneralPageInitialProps & CommonEachProps {
+  // First, validate CommonEachProps
   if (!isValidCommonEachRouteProps(props)) {
-    logger.warn('isValidInitialAndSameRouteProps: SameRouteEachProps validation failed');
+    logger.warn('isValidInitialAndSameRouteProps: CommonEachProps validation failed');
     return false;
   }
 
   const p = props as Record<string, unknown>;
 
-  // Then validate InitialProps-specific properties
-  // CommonInitialProps
+  // Then validate GeneralPageInitialProps-specific properties
+  // CommonPageInitialProps
   if (p.isNextjsRoutingTypeInitial !== true) {
     logger.warn('isValidInitialAndSameRouteProps: isNextjsRoutingTypeInitial is not true', { isNextjsRoutingTypeInitial: p.isNextjsRoutingTypeInitial });
     return false;
@@ -31,7 +31,7 @@ export function isValidInitialAndSameRouteProps(props: unknown): props is Initia
     return false;
   }
 
-  // InitialProps specific page state
+  // GeneralPageInitialProps specific page state
   if (typeof p.isNotFound !== 'boolean') {
     logger.warn('isValidInitialAndSameRouteProps: isNotFound is not a boolean', { isNotFound: p.isNotFound });
     return false;

+ 27 - 3
apps/app/src/pages/general-page/types.ts

@@ -5,7 +5,6 @@ import type {
 import type { RendererConfig } from '~/interfaces/services/renderer';
 import type { ISidebarConfig } from '~/interfaces/sidebar-config';
 import type { PageDocument } from '~/server/models/page';
-import type { ServerConfigurationHyderateArgs } from '~/states/server-configurations/hydrate';
 
 import type { CommonInitialProps } from '../common-props';
 
@@ -20,10 +19,35 @@ export type RendererConfigProps = {
 }
 
 export type ServerConfigurationProps = {
-  serverConfig: ServerConfigurationHyderateArgs,
+  serverConfig: {
+    aiEnabled: boolean;
+    limitLearnablePageCountPerAssistant: number;
+    isUsersHomepageDeletionEnabled: boolean;
+    adminPreferredIndentSize: number;
+    isSearchServiceConfigured: boolean;
+    isSearchServiceReachable: boolean;
+    isSearchScopeChildrenAsDefault: boolean;
+    elasticsearchMaxBodyLengthToIndex: number;
+    isRomUserAllowedToComment: boolean;
+    drawioUri: string | null;
+    isAllReplyShown: boolean;
+    showPageSideAuthors: boolean;
+    isContainerFluid: boolean;
+    isEnabledStaleNotification: boolean;
+    disableLinkSharing: boolean;
+    isIndentSizeForced: boolean;
+    isEnabledAttachTitleHeader: boolean;
+    isSlackConfigured: boolean;
+    isAclEnabled: boolean;
+    isUploadEnabled: boolean;
+    isUploadAllFileAllowed: boolean;
+    isBulkExportPagesEnabled: boolean;
+    isPdfBulkExportEnabled: boolean;
+    isLocalAccountRegistrationEnabled: boolean;
+  },
 }
 
-export type InitialProps = CommonInitialProps & RendererConfigProps & ServerConfigurationProps & {
+export type GeneralPageInitialProps = CommonInitialProps & RendererConfigProps & ServerConfigurationProps & {
   pageWithMeta: IPageToShowRevisionWithMeta | null,
   skipSSR?: boolean,
 

+ 70 - 0
apps/app/src/pages/general-page/use-hydrate-server-configurations.ts

@@ -0,0 +1,70 @@
+import { useHydrateAtoms } from 'jotai/utils';
+
+import type { RendererConfig } from '~/interfaces/services/renderer';
+import {
+  aiEnabledAtom,
+  limitLearnablePageCountPerAssistantAtom,
+  isUsersHomepageDeletionEnabledAtom,
+  defaultIndentSizeAtom,
+  isSearchScopeChildrenAsDefaultAtom,
+  elasticsearchMaxBodyLengthToIndexAtom,
+  isRomUserAllowedToCommentAtom,
+  drawioUriAtom,
+  isAllReplyShownAtom,
+  showPageSideAuthorsAtom,
+  isContainerFluidAtom,
+  isEnabledStaleNotificationAtom,
+  disableLinkSharingAtom,
+  isIndentSizeForcedAtom,
+  isEnabledAttachTitleHeaderAtom,
+  isSearchServiceConfiguredAtom,
+  isSearchServiceReachableAtom,
+  isSlackConfiguredAtom,
+  isAclEnabledAtom,
+  isUploadAllFileAllowedAtom,
+  isUploadEnabledAtom,
+  isBulkExportPagesEnabledAtom,
+  isPdfBulkExportEnabledAtom,
+  isLocalAccountRegistrationEnabledAtom,
+  rendererConfigAtom,
+} from '~/states/server-configurations/server-configurations';
+
+import type { ServerConfigurationProps } from './types';
+
+/**
+ * Hook for hydrating server configuration atoms with server-side data
+ * This should be called early in the app component to ensure atoms are properly initialized before rendering
+ */
+export const useHydrateServerConfigurationAtoms = (
+    serverConfig: ServerConfigurationProps['serverConfig'] | undefined,
+    rendererConfigs: RendererConfig | undefined,
+): void => {
+  // Hydrate server configuration atoms with server-side data
+  useHydrateAtoms(serverConfig == null || rendererConfigs == null ? [] : [
+    [aiEnabledAtom, serverConfig.aiEnabled],
+    [limitLearnablePageCountPerAssistantAtom, serverConfig.limitLearnablePageCountPerAssistant],
+    [isUsersHomepageDeletionEnabledAtom, serverConfig.isUsersHomepageDeletionEnabled],
+    [defaultIndentSizeAtom, serverConfig.adminPreferredIndentSize],
+    [isSearchScopeChildrenAsDefaultAtom, serverConfig.isSearchScopeChildrenAsDefault],
+    [elasticsearchMaxBodyLengthToIndexAtom, serverConfig.elasticsearchMaxBodyLengthToIndex],
+    [isRomUserAllowedToCommentAtom, serverConfig.isRomUserAllowedToComment],
+    [drawioUriAtom, serverConfig.drawioUri],
+    [isAllReplyShownAtom, serverConfig.isAllReplyShown],
+    [showPageSideAuthorsAtom, serverConfig.showPageSideAuthors],
+    [isContainerFluidAtom, serverConfig.isContainerFluid],
+    [isEnabledStaleNotificationAtom, serverConfig.isEnabledStaleNotification],
+    [disableLinkSharingAtom, serverConfig.disableLinkSharing],
+    [isIndentSizeForcedAtom, serverConfig.isIndentSizeForced],
+    [isEnabledAttachTitleHeaderAtom, serverConfig.isEnabledAttachTitleHeader],
+    [isSearchServiceConfiguredAtom, serverConfig.isSearchServiceConfigured],
+    [isSearchServiceReachableAtom, serverConfig.isSearchServiceReachable],
+    [isSlackConfiguredAtom, serverConfig.isSlackConfigured],
+    [isAclEnabledAtom, serverConfig.isAclEnabled],
+    [isUploadAllFileAllowedAtom, serverConfig.isUploadAllFileAllowed],
+    [isUploadEnabledAtom, serverConfig.isUploadEnabled],
+    [isBulkExportPagesEnabledAtom, serverConfig.isBulkExportPagesEnabled],
+    [isPdfBulkExportEnabledAtom, serverConfig.isPdfBulkExportEnabled],
+    [isLocalAccountRegistrationEnabledAtom, serverConfig.isLocalAccountRegistrationEnabled],
+    [rendererConfigAtom, rendererConfigs],
+  ]);
+};

+ 5 - 4
apps/app/src/pages/share/[[...path]]/index.page.tsx

@@ -19,13 +19,13 @@ import {
 } from '~/states/page';
 import { useHydratePageAtoms } from '~/states/page/hydrate';
 import { useDisableLinkSharing, useRendererConfig } from '~/states/server-configurations';
-import { useHydrateServerConfigurationAtoms } from '~/states/server-configurations/hydrate';
 import loggerFactory from '~/utils/logger';
 
 import type { NextPageWithLayout } from '../../_app.page';
-import type { InitialProps } from '../../general-page';
+import type { GeneralPageInitialProps } from '../../general-page';
 import { useInitialCSRFetch } from '../../general-page';
 import { registerPageToShowRevisionWithMeta } from '../../general-page/superjson';
+import { useHydrateServerConfigurationAtoms } from '../../general-page/use-hydrate-server-configurations';
 
 import { NEXT_JS_ROUTING_PAGE } from './consts';
 import { getServerSidePropsForInitial, getServerSidePropsForSameRoute } from './server-side-props';
@@ -40,9 +40,10 @@ const GrowiContextualSubNavigation = dynamic(() => import('~/client/components/N
 
 const logger = loggerFactory('growi:next-page:share');
 
-type Props = CommonEachProps | (CommonEachProps & InitialProps & ShareLinkInitialProps);
+type InitialProps = CommonEachProps & GeneralPageInitialProps & ShareLinkInitialProps;
+type Props = CommonEachProps | InitialProps;
 
-const isInitialProps = (props: Props): props is (ShareLinkInitialProps & InitialProps & CommonEachProps) => {
+const isInitialProps = (props: Props): props is InitialProps => {
   return 'isNextjsRoutingTypeInitial' in props && props.isNextjsRoutingTypeInitial;
 };
 

+ 4 - 3
apps/app/src/pages/share/[[...path]]/server-side-props.ts

@@ -4,9 +4,10 @@ import type { CommonEachProps } from '../../common-props';
 import {
   getServerSideI18nProps, getServerSideCommonInitialProps, getServerSideCommonEachProps,
 } from '../../common-props';
-import type { InitialProps } from '../../general-page';
+import type { GeneralPageInitialProps } from '../../general-page';
 import {
-  getServerSideConfigurationProps, getServerSideRendererConfigProps,
+  getServerSideConfigurationProps,
+  getServerSideRendererConfigProps,
   getActivityAction, isValidInitialAndSameRouteProps,
 } from '../../general-page';
 import { addActivity } from '../../utils/activity';
@@ -32,7 +33,7 @@ const basisProps = {
 };
 
 export async function getServerSidePropsForInitial(context: GetServerSidePropsContext):
-    Promise<GetServerSidePropsResult<InitialProps & ShareLinkInitialProps & CommonEachProps>> {
+    Promise<GetServerSidePropsResult<GeneralPageInitialProps & ShareLinkInitialProps & CommonEachProps>> {
 
   //
   // STAGE 1

+ 2 - 2
apps/app/src/pages/share/[[...path]]/types.ts

@@ -1,7 +1,7 @@
 import type { IShareLinkHasId } from '~/interfaces/share-link';
-import type { InitialProps } from '~/pages/general-page';
+import type { GeneralPageInitialProps } from '~/pages/general-page';
 
-export type ShareLinkInitialProps = Pick<InitialProps, 'pageWithMeta' | 'skipSSR'> & (
+export type ShareLinkInitialProps = Pick<GeneralPageInitialProps, 'pageWithMeta' | 'skipSSR'> & (
   {
     isNotFound: true,
     isExpired: undefined,

+ 0 - 101
apps/app/src/states/server-configurations/hydrate.ts

@@ -1,101 +0,0 @@
-import { useHydrateAtoms } from 'jotai/utils';
-
-import type { RendererConfig } from '~/interfaces/services/renderer';
-
-import {
-  aiEnabledAtom,
-  limitLearnablePageCountPerAssistantAtom,
-  isUsersHomepageDeletionEnabledAtom,
-  defaultIndentSizeAtom,
-  isSearchScopeChildrenAsDefaultAtom,
-  elasticsearchMaxBodyLengthToIndexAtom,
-  isRomUserAllowedToCommentAtom,
-  drawioUriAtom,
-  isAllReplyShownAtom,
-  showPageSideAuthorsAtom,
-  isContainerFluidAtom,
-  isEnabledStaleNotificationAtom,
-  disableLinkSharingAtom,
-  isIndentSizeForcedAtom,
-  isEnabledAttachTitleHeaderAtom,
-  isSearchServiceConfiguredAtom,
-  isSearchServiceReachableAtom,
-  isSlackConfiguredAtom,
-  isAclEnabledAtom,
-  isUploadAllFileAllowedAtom,
-  isUploadEnabledAtom,
-  isBulkExportPagesEnabledAtom,
-  isPdfBulkExportEnabledAtom,
-  isLocalAccountRegistrationEnabledAtom,
-  rendererConfigAtom,
-} from './server-configurations';
-
-/**
- * Type for server configuration initial props
- */
-export type ServerConfigurationHyderateArgs = {
-  aiEnabled: boolean;
-  limitLearnablePageCountPerAssistant: number;
-  isUsersHomepageDeletionEnabled: boolean;
-  adminPreferredIndentSize: number;
-  isSearchServiceConfigured: boolean;
-  isSearchServiceReachable: boolean;
-  isSearchScopeChildrenAsDefault: boolean;
-  elasticsearchMaxBodyLengthToIndex: number;
-  isRomUserAllowedToComment: boolean;
-  drawioUri: string | null;
-  isAllReplyShown: boolean;
-  showPageSideAuthors: boolean;
-  isContainerFluid: boolean;
-  isEnabledStaleNotification: boolean;
-  disableLinkSharing: boolean;
-  isIndentSizeForced: boolean;
-  isEnabledAttachTitleHeader: boolean;
-  isSlackConfigured: boolean;
-  isAclEnabled: boolean;
-  isUploadEnabled: boolean;
-  isUploadAllFileAllowed: boolean;
-  isBulkExportPagesEnabled: boolean;
-  isPdfBulkExportEnabled: boolean;
-  isLocalAccountRegistrationEnabled: boolean;
-};
-
-/**
- * Hook for hydrating server configuration atoms with server-side data
- * This should be called early in the app component to ensure atoms are properly initialized before rendering
- *
- * @param serverConfigs - Server-side server configuration properties
- */
-export const useHydrateServerConfigurationAtoms = (
-    serverConfigs: ServerConfigurationHyderateArgs | undefined,
-    rendererConfigs: RendererConfig | undefined,
-): void => {
-  // Hydrate server configuration atoms with server-side data
-  useHydrateAtoms(serverConfigs == null || rendererConfigs == null ? [] : [
-    [aiEnabledAtom, serverConfigs.aiEnabled],
-    [limitLearnablePageCountPerAssistantAtom, serverConfigs.limitLearnablePageCountPerAssistant],
-    [isUsersHomepageDeletionEnabledAtom, serverConfigs.isUsersHomepageDeletionEnabled],
-    [defaultIndentSizeAtom, serverConfigs.adminPreferredIndentSize],
-    [isSearchScopeChildrenAsDefaultAtom, serverConfigs.isSearchScopeChildrenAsDefault],
-    [elasticsearchMaxBodyLengthToIndexAtom, serverConfigs.elasticsearchMaxBodyLengthToIndex],
-    [isRomUserAllowedToCommentAtom, serverConfigs.isRomUserAllowedToComment],
-    [drawioUriAtom, serverConfigs.drawioUri],
-    [isAllReplyShownAtom, serverConfigs.isAllReplyShown],
-    [showPageSideAuthorsAtom, serverConfigs.showPageSideAuthors],
-    [isContainerFluidAtom, serverConfigs.isContainerFluid],
-    [isEnabledStaleNotificationAtom, serverConfigs.isEnabledStaleNotification],
-    [disableLinkSharingAtom, serverConfigs.disableLinkSharing],
-    [isIndentSizeForcedAtom, serverConfigs.isIndentSizeForced],
-    [isEnabledAttachTitleHeaderAtom, serverConfigs.isEnabledAttachTitleHeader],
-    [isSearchServiceConfiguredAtom, serverConfigs.isSearchServiceConfigured],
-    [isSearchServiceReachableAtom, serverConfigs.isSearchServiceReachable],
-    [isSlackConfiguredAtom, serverConfigs.isSlackConfigured],
-    [isAclEnabledAtom, serverConfigs.isAclEnabled],
-    [isUploadAllFileAllowedAtom, serverConfigs.isUploadAllFileAllowed],
-    [isUploadEnabledAtom, serverConfigs.isUploadEnabled],
-    [isBulkExportPagesEnabledAtom, serverConfigs.isBulkExportPagesEnabled],
-    [isPdfBulkExportEnabledAtom, serverConfigs.isPdfBulkExportEnabled],
-    [isLocalAccountRegistrationEnabledAtom, serverConfigs.isLocalAccountRegistrationEnabled],
-    [rendererConfigAtom, rendererConfigs],
-  ]);
-};