Просмотр исходного кода

refactor installer and invited page

Yuki Takei 7 месяцев назад
Родитель
Сommit
9eb42ff338
2 измененных файлов с 99 добавлено и 103 удалено
  1. 34 42
      apps/app/src/pages/installer.page.tsx
  2. 65 61
      apps/app/src/pages/invited.page.tsx

+ 34 - 42
apps/app/src/pages/installer.page.tsx

@@ -4,34 +4,30 @@ import type {
   NextPage, GetServerSideProps, GetServerSidePropsContext,
   NextPage, GetServerSideProps, GetServerSidePropsContext,
 } from 'next';
 } from 'next';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
-import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
 import dynamic from 'next/dynamic';
 import dynamic from 'next/dynamic';
 import Head from 'next/head';
 import Head from 'next/head';
 
 
 import { NoLoginLayout } from '~/components/Layout/NoLoginLayout';
 import { NoLoginLayout } from '~/components/Layout/NoLoginLayout';
 import type { CrowiRequest } from '~/interfaces/crowi-request';
 import type { CrowiRequest } from '~/interfaces/crowi-request';
-import {
-  useCsrfToken, useAppTitle, useSiteUrl, useConfidential, useGrowiCloudUri,
-} from '~/stores-universal/context';
 
 
-import type { CommonProps } from './common-props';
-import { getNextI18NextConfig, getServerSideCommonProps, generateCustomTitle } from './common-props';
+import type { CommonEachProps, CommonInitialProps } from './common-props';
+import {
+  getServerSideCommonEachProps, getServerSideCommonInitialProps, getServerSideI18nProps,
+} from './common-props';
+import { mergeGetServerSidePropsResults } from './utils/server-side-props';
+import { useCustomTitle } from './utils/page-title-customization';
 
 
 
 
 const InstallerForm = dynamic(() => import('~/client/components/InstallerForm'), { ssr: false });
 const InstallerForm = dynamic(() => import('~/client/components/InstallerForm'), { ssr: false });
 const DataTransferForm = dynamic(() => import('~/client/components/DataTransferForm'), { ssr: false });
 const DataTransferForm = dynamic(() => import('~/client/components/DataTransferForm'), { ssr: false });
 const CustomNavAndContents = dynamic(() => import('~/client/components/CustomNavigation/CustomNavAndContents'), { ssr: false });
 const CustomNavAndContents = dynamic(() => import('~/client/components/CustomNavigation/CustomNavAndContents'), { ssr: false });
 
 
-async function injectNextI18NextConfigurations(context: GetServerSidePropsContext, props: Props, namespacesRequired?: string[] | undefined): Promise<void> {
-  const nextI18NextConfig = await getNextI18NextConfig(serverSideTranslations, context, namespacesRequired, true);
-  props._nextI18Next = nextI18NextConfig._nextI18Next;
-}
-
-type Props = CommonProps & {
-  minPasswordLength: number,
-  pageWithMetaStr: string,
+type ServerConfigurationProps = {
+  minPasswordLength: number;
 };
 };
 
 
+type Props = CommonInitialProps & CommonEachProps & ServerConfigurationProps;
+
 const InstallerPage: NextPage<Props> = (props: Props) => {
 const InstallerPage: NextPage<Props> = (props: Props) => {
   const { t } = useTranslation();
   const { t } = useTranslation();
   const { t: tCommons } = useTranslation('commons');
   const { t: tCommons } = useTranslation('commons');
@@ -52,14 +48,7 @@ const InstallerPage: NextPage<Props> = (props: Props) => {
     };
     };
   }, [props.minPasswordLength, t, tCommons]);
   }, [props.minPasswordLength, t, tCommons]);
 
 
-  // commons
-  useAppTitle(props.appTitle);
-  useSiteUrl(props.siteUrl);
-  useConfidential(props.confidential);
-  useCsrfToken(props.csrfToken);
-  useGrowiCloudUri(props.growiCloudUri);
-
-  const title = generateCustomTitle(props, t('installer.title'));
+  const title = useCustomTitle(t('installer.title'));
   const classNames: string[] = [];
   const classNames: string[] = [];
 
 
   return (
   return (
@@ -74,31 +63,34 @@ const InstallerPage: NextPage<Props> = (props: Props) => {
   );
   );
 };
 };
 
 
-async function injectServerConfigurations(context: GetServerSidePropsContext, props: Props): Promise<void> {
-  const req: CrowiRequest = context.req as CrowiRequest;
+const getServerSideConfigurationProps: GetServerSideProps<ServerConfigurationProps> = async(context: GetServerSidePropsContext) => {
+  const req = context.req as CrowiRequest;
   const { crowi } = req;
   const { crowi } = req;
   const { configManager } = crowi;
   const { configManager } = crowi;
 
 
-  props.minPasswordLength = configManager.getConfig('app:minPasswordLength');
-}
-
-export const getServerSideProps: GetServerSideProps = async(context: GetServerSidePropsContext) => {
-  const result = await getServerSideCommonProps(context);
-
-  // check for presence
-  // see: https://github.com/vercel/next.js/issues/19271#issuecomment-730006862
-  if (!('props' in result)) {
-    throw new Error('invalid getSSP result');
-  }
-
-  const props: Props = result.props as Props;
-
-  await injectNextI18NextConfigurations(context, props, ['translation']);
-  injectServerConfigurations(context, props);
-
   return {
   return {
-    props,
+    props: {
+      minPasswordLength: configManager.getConfig('app:minPasswordLength'),
+    },
   };
   };
 };
 };
 
 
+export const getServerSideProps: GetServerSideProps = async(context: GetServerSidePropsContext) => {
+  const [
+    commonInitialResult,
+    commonEachResult,
+    serverConfigResult,
+    i18nPropsResult,
+  ] = await Promise.all([
+    getServerSideCommonInitialProps(context),
+    getServerSideCommonEachProps(context),
+    getServerSideConfigurationProps(context),
+    getServerSideI18nProps(context, ['translation']),
+  ]);
+
+  return mergeGetServerSidePropsResults(commonInitialResult,
+    mergeGetServerSidePropsResults(commonEachResult,
+      mergeGetServerSidePropsResults(serverConfigResult, i18nPropsResult)));
+};
+
 export default InstallerPage;
 export default InstallerPage;

+ 65 - 61
apps/app/src/pages/invited.page.tsx

@@ -1,36 +1,34 @@
 import React from 'react';
 import React from 'react';
 
 
-import type { IUser } from '@growi/core';
 import { USER_STATUS } from '@growi/core';
 import { USER_STATUS } from '@growi/core';
 import type { NextPage, GetServerSideProps, GetServerSidePropsContext } from 'next';
 import type { NextPage, GetServerSideProps, GetServerSidePropsContext } from 'next';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
-import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
 import dynamic from 'next/dynamic';
 import dynamic from 'next/dynamic';
 import Head from 'next/head';
 import Head from 'next/head';
 
 
 import { NoLoginLayout } from '~/components/Layout/NoLoginLayout';
 import { NoLoginLayout } from '~/components/Layout/NoLoginLayout';
 import type { CrowiRequest } from '~/interfaces/crowi-request';
 import type { CrowiRequest } from '~/interfaces/crowi-request';
-import { useCsrfToken, useCurrentPathname, useCurrentUser } from '~/stores-universal/context';
 
 
-import type { CommonProps } from './common-props';
-import { getServerSideCommonProps, generateCustomTitle, getNextI18NextConfig } from './common-props';
+import type { CommonEachProps, CommonInitialProps } from './common-props';
+import {
+  getServerSideCommonEachProps, getServerSideCommonInitialProps, getServerSideI18nProps,
+} from './common-props';
+import { mergeGetServerSidePropsResults } from './utils/server-side-props';
+import { useCustomTitle } from './utils/page-title-customization';
 
 
 const InvitedForm = dynamic(() => import('~/client/components/InvitedForm').then(mod => mod.InvitedForm), { ssr: false });
 const InvitedForm = dynamic(() => import('~/client/components/InvitedForm').then(mod => mod.InvitedForm), { ssr: false });
 
 
-type Props = CommonProps & {
-  currentUser: IUser,
-  invitedFormUsername: string,
-  invitedFormName: string,
-}
+type ServerConfigurationProps = {
+  invitedFormUsername: string;
+  invitedFormName: string;
+};
+
+type Props = CommonInitialProps & CommonEachProps & ServerConfigurationProps;
 
 
 const InvitedPage: NextPage<Props> = (props: Props) => {
 const InvitedPage: NextPage<Props> = (props: Props) => {
   const { t } = useTranslation();
   const { t } = useTranslation();
 
 
-  useCsrfToken(props.csrfToken);
-  useCurrentPathname(props.currentPathname);
-  useCurrentUser(props.currentUser);
-
-  const title = generateCustomTitle(props, t('invited.title'));
+  const title = useCustomTitle(t('invited.title'));
   const classNames: string[] = ['invited-page'];
   const classNames: string[] = ['invited-page'];
 
 
   return (
   return (
@@ -44,60 +42,66 @@ const InvitedPage: NextPage<Props> = (props: Props) => {
 
 
 };
 };
 
 
-async function injectServerConfigurations(context: GetServerSidePropsContext, props: Props): Promise<void> {
-  const req: CrowiRequest = context.req as CrowiRequest;
+const getServerSideConfigurationProps: GetServerSideProps<ServerConfigurationProps> = async(context: GetServerSidePropsContext) => {
+  const req = context.req as CrowiRequest;
   const { body: invitedForm } = req;
   const { body: invitedForm } = req;
 
 
-  if (props.invitedFormUsername != null) {
-    props.invitedFormUsername = invitedForm.username;
-  }
-  if (props.invitedFormName != null) {
-    props.invitedFormName = invitedForm.name;
-  }
-}
-
-/**
- * for Server Side Translations
- * @param context
- * @param props
- * @param namespacesRequired
- */
-async function injectNextI18NextConfigurations(context: GetServerSidePropsContext, props: Props, namespacesRequired?: string[] | undefined): Promise<void> {
-  const nextI18NextConfig = await getNextI18NextConfig(serverSideTranslations, context, namespacesRequired);
-  props._nextI18Next = nextI18NextConfig._nextI18Next;
-}
+  return {
+    props: {
+      invitedFormUsername: invitedForm?.username ?? '',
+      invitedFormName: invitedForm?.name ?? '',
+    },
+  };
+};
 
 
 export const getServerSideProps: GetServerSideProps = async(context: GetServerSidePropsContext) => {
 export const getServerSideProps: GetServerSideProps = async(context: GetServerSidePropsContext) => {
-  const req = context.req as CrowiRequest;
-  const { user } = req;
-  const result = await getServerSideCommonProps(context);
-
-  // check for presence
-  // see: https://github.com/vercel/next.js/issues/19271#issuecomment-730006862
-  if (!('props' in result)) {
-    throw new Error('invalid getSSP result');
+  //
+  // STAGE 1
+  //
+
+  const commonEachPropsResult = await getServerSideCommonEachProps(context);
+  // Handle early return cases (redirect/notFound)
+  if ('redirect' in commonEachPropsResult || 'notFound' in commonEachPropsResult) {
+    return commonEachPropsResult;
   }
   }
-  const props: Props = result.props as Props;
-
-  if (user != null) {
-    props.currentUser = user.toObject();
-
-    // Only invited user can access to /invited page
-    if (props.currentUser.status !== USER_STATUS.INVITED) {
-      return {
-        redirect: {
-          permanent: false,
-          destination: '/',
-        },
-      };
-    }
-
+  const commonEachProps = await commonEachPropsResult.props;
+
+  // Handle redirect destination from common props
+  if (commonEachProps.redirectDestination != null) {
+    return {
+      redirect: {
+        permanent: false,
+        destination: commonEachProps.redirectDestination,
+      },
+    };
   }
   }
 
 
-  await injectServerConfigurations(context, props);
-  await injectNextI18NextConfigurations(context, props, ['translation']);
+  // Only invited user can access to /invited page
+  if (commonEachProps.currentUser != null && commonEachProps.currentUser.status !== USER_STATUS.INVITED) {
+    return {
+      redirect: {
+        permanent: false,
+        destination: '/',
+      },
+    };
+  }
 
 
-  return { props };
+  //
+  // STAGE 2
+  //
+  const [
+    commonInitialResult,
+    serverConfigResult,
+    i18nPropsResult,
+  ] = await Promise.all([
+    getServerSideCommonInitialProps(context),
+    getServerSideConfigurationProps(context),
+    getServerSideI18nProps(context, ['translation']),
+  ]);
+
+  return mergeGetServerSidePropsResults(commonInitialResult,
+    mergeGetServerSidePropsResults(commonEachPropsResult,
+      mergeGetServerSidePropsResults(serverConfigResult, i18nPropsResult)));
 };
 };
 
 
 export default InvitedPage;
 export default InvitedPage;