trash.page.tsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import type { ReactNode, JSX } from 'react';
  2. import type { IUser } from '@growi/core';
  3. import type { GetServerSideProps, GetServerSidePropsContext } from 'next';
  4. import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
  5. import dynamic from 'next/dynamic';
  6. import Head from 'next/head';
  7. import { PagePathNavTitle } from '~/components/Common/PagePathNavTitle';
  8. import { BasicLayout } from '~/components/Layout/BasicLayout';
  9. import { GroundGlassBar } from '~/components/Navbar/GroundGlassBar';
  10. import type { CrowiRequest } from '~/interfaces/crowi-request';
  11. import type { RendererConfig } from '~/interfaces/services/renderer';
  12. import type { ISidebarConfig } from '~/interfaces/sidebar-config';
  13. import {
  14. useCurrentUser, useCurrentPathname, useGrowiCloudUri,
  15. useIsSearchServiceConfigured, useIsSearchServiceReachable,
  16. useIsSearchScopeChildrenAsDefault, useIsSearchPage, useShowPageLimitationXL,
  17. } from '~/stores-universal/context';
  18. import { useCurrentPageId, useSWRxCurrentPage } from '~/stores/page';
  19. import type { NextPageWithLayout } from './_app.page';
  20. import type { CommonProps } from './utils/commons';
  21. import {
  22. getServerSideCommonProps, getNextI18NextConfig, generateCustomTitleForPage, useInitSidebarConfig,
  23. } from './utils/commons';
  24. const TrashPageList = dynamic(() => import('~/client/components/TrashPageList').then(mod => mod.TrashPageList), { ssr: false });
  25. const EmptyTrashModal = dynamic(() => import('~/client/components/EmptyTrashModal'), { ssr: false });
  26. type Props = CommonProps & {
  27. currentUser: IUser,
  28. isSearchServiceConfigured: boolean,
  29. isSearchServiceReachable: boolean,
  30. isSearchScopeChildrenAsDefault: boolean,
  31. showPageLimitationXL: number,
  32. rendererConfig: RendererConfig,
  33. sidebarConfig: ISidebarConfig,
  34. };
  35. const TrashPage: NextPageWithLayout<CommonProps> = (props: Props) => {
  36. useCurrentUser(props.currentUser ?? null);
  37. // clear the cache for the current page
  38. // in order to fix https://redmine.weseek.co.jp/issues/135811
  39. useSWRxCurrentPage(null);
  40. useCurrentPageId(null);
  41. useCurrentPathname('/trash');
  42. useGrowiCloudUri(props.growiCloudUri);
  43. useIsSearchServiceConfigured(props.isSearchServiceConfigured);
  44. useIsSearchServiceReachable(props.isSearchServiceReachable);
  45. useIsSearchScopeChildrenAsDefault(props.isSearchScopeChildrenAsDefault);
  46. useIsSearchPage(false);
  47. // init sidebar config with UserUISettings and sidebarConfig
  48. useInitSidebarConfig(props.sidebarConfig, props.userUISettings);
  49. useShowPageLimitationXL(props.showPageLimitationXL);
  50. const title = generateCustomTitleForPage(props, '/trash');
  51. return (
  52. <>
  53. <Head>
  54. <title>{title}</title>
  55. </Head>
  56. <div className="dynamic-layout-root">
  57. <GroundGlassBar className="sticky-top py-4"></GroundGlassBar>
  58. <div className="main ps-sidebar">
  59. <div className="container-lg wide-gutter-x-lg">
  60. <PagePathNavTitle pagePath="/trash" />
  61. <TrashPageList />
  62. </div>
  63. </div>
  64. </div>
  65. </>
  66. );
  67. };
  68. type LayoutProps = Props & {
  69. children?: ReactNode,
  70. }
  71. const Layout = ({ children, ...props }: LayoutProps): JSX.Element => {
  72. // init sidebar config with UserUISettings and sidebarConfig
  73. useInitSidebarConfig(props.sidebarConfig, props.userUISettings);
  74. return <BasicLayout>{children}</BasicLayout>;
  75. };
  76. TrashPage.getLayout = function getLayout(page) {
  77. return (
  78. <>
  79. <Layout {...page.props}>
  80. {page}
  81. </Layout>
  82. <EmptyTrashModal />
  83. </>
  84. );
  85. };
  86. function injectServerConfigurations(context: GetServerSidePropsContext, props: Props): void {
  87. const req: CrowiRequest = context.req as CrowiRequest;
  88. const { crowi } = req;
  89. const {
  90. searchService, configManager,
  91. } = crowi;
  92. props.isSearchServiceConfigured = searchService.isConfigured;
  93. props.isSearchServiceReachable = searchService.isReachable;
  94. props.isSearchScopeChildrenAsDefault = configManager.getConfig('customize:isSearchScopeChildrenAsDefault');
  95. props.showPageLimitationXL = crowi.configManager.getConfig('customize:showPageLimitationXL');
  96. props.sidebarConfig = {
  97. isSidebarCollapsedMode: configManager.getConfig('customize:isSidebarCollapsedMode'),
  98. isSidebarClosedAtDockMode: configManager.getConfig('customize:isSidebarClosedAtDockMode'),
  99. };
  100. }
  101. /**
  102. * for Server Side Translations
  103. * @param context
  104. * @param props
  105. * @param namespacesRequired
  106. */
  107. async function injectNextI18NextConfigurations(context: GetServerSidePropsContext, props: Props, namespacesRequired?: string[] | undefined): Promise<void> {
  108. const nextI18NextConfig = await getNextI18NextConfig(serverSideTranslations, context, namespacesRequired);
  109. props._nextI18Next = nextI18NextConfig._nextI18Next;
  110. }
  111. export const getServerSideProps: GetServerSideProps = async(context: GetServerSidePropsContext) => {
  112. const req = context.req as CrowiRequest;
  113. const { user } = req;
  114. const result = await getServerSideCommonProps(context);
  115. if (!('props' in result)) {
  116. throw new Error('invalid getSSP result');
  117. }
  118. const props: Props = result.props as Props;
  119. if (user != null) {
  120. props.currentUser = user.toObject();
  121. }
  122. injectServerConfigurations(context, props);
  123. await injectNextI18NextConfigurations(context, props, ['translation']);
  124. return {
  125. props,
  126. };
  127. };
  128. export default TrashPage;