Răsfoiți Sursa

Merge pull request #10720 from growilabs/feat/174755-hide-user-page-search-checkbox

feat: Block option to include user pages in search when hiding setting is turned on
Yuki Takei 2 luni în urmă
părinte
comite
40cf9ccb72

+ 6 - 1
apps/app/src/features/search/client/components/PrivateLegacyPages.tsx

@@ -7,6 +7,7 @@ import React, {
   useState,
 } from 'react';
 import { LoadingSpinner } from '@growi/ui/dist/components';
+import { useAtomValue } from 'jotai';
 import { useTranslation } from 'next-i18next';
 import {
   DropdownItem,
@@ -35,6 +36,7 @@ import type { PageMigrationErrorData } from '~/interfaces/websocket';
 import { SocketEventName } from '~/interfaces/websocket';
 import { useIsAdmin } from '~/states/context';
 import { useSearchKeyword, useSetSearchKeyword } from '~/states/search';
+import { isHidingUserPagesAtom } from '~/states/server-configurations';
 import { useGlobalSocket } from '~/states/socket-io';
 import type { ILegacyPrivatePage } from '~/states/ui/modal/private-legacy-pages-migration';
 import { usePrivateLegacyPagesMigrationModalActions } from '~/states/ui/modal/private-legacy-pages-migration';
@@ -268,6 +270,8 @@ const PrivateLegacyPages = (): JSX.Element => {
   const keyword = useSearchKeyword();
   const setSearchKeyword = useSetSearchKeyword('/_private-legacy-pages');
 
+  const isHidingUserPages = useAtomValue(isHidingUserPagesAtom);
+
   const [offset, setOffset] = useState<number>(0);
   const [limit, setLimit] = useState<number>(INITIAL_PAGING_SIZE);
   const [isOpenConvertModal, setOpenConvertModal] = useState<boolean>(false);
@@ -515,6 +519,7 @@ const PrivateLegacyPages = (): JSX.Element => {
   const searchControl = useMemo(() => {
     return (
       <SearchControl
+        isHidingUserPages={isHidingUserPages}
         isEnableSort={false}
         isEnableFilter={false}
         initialSearchConditions={{ keyword: initQ, limit: INITIAL_PAGING_SIZE }}
@@ -522,7 +527,7 @@ const PrivateLegacyPages = (): JSX.Element => {
         extraControls={extraControls}
       />
     );
-  }, [searchInvokedHandler, extraControls]);
+  }, [searchInvokedHandler, extraControls, isHidingUserPages]);
 
   const searchResultListHead = useMemo(() => {
     if (data == null) {

+ 25 - 18
apps/app/src/features/search/client/components/SearchPage/SearchControl.tsx

@@ -12,6 +12,7 @@ import SortControl from './SortControl';
 type Props = {
   isEnableSort: boolean;
   isEnableFilter: boolean;
+  isHidingUserPages: boolean;
   initialSearchConditions: Partial<ISearchConditions>;
 
   onSearchInvoked?: (
@@ -29,6 +30,7 @@ const SearchControl = React.memo((props: Props): JSX.Element => {
   const {
     isEnableSort,
     isEnableFilter,
+    isHidingUserPages,
     initialSearchConditions,
     onSearchInvoked,
     extraControls,
@@ -152,25 +154,29 @@ const SearchControl = React.memo((props: Props): JSX.Element => {
               </button>
             </div>
             <div className="d-none d-lg-flex align-items-center search-control-include-options">
-              <div className="px-2 py-1">
-                <div className="form-check form-check-succsess">
-                  <input
-                    className="form-check-input me-2"
-                    type="checkbox"
-                    id="flexCheckDefault"
-                    defaultChecked={includeUserPages}
-                    onChange={(e) =>
-                      changeIncludeUserPagesHandler(e.target.checked)
-                    }
-                  />
-                  <label
-                    className="form-label form-check-label mb-0 d-flex align-items-center text-secondary with-no-font-weight"
-                    htmlFor="flexCheckDefault"
-                  >
-                    {t('Include Subordinated Target Page', { target: '/user' })}
-                  </label>
+              {isHidingUserPages === false && (
+                <div className="px-2 py-1">
+                  <div className="form-check form-check-succsess">
+                    <input
+                      className="form-check-input me-2"
+                      type="checkbox"
+                      id="flexCheckDefault"
+                      defaultChecked={includeUserPages}
+                      onChange={(e) =>
+                        changeIncludeUserPagesHandler(e.target.checked)
+                      }
+                    />
+                    <label
+                      className="form-label form-check-label mb-0 d-flex align-items-center text-secondary with-no-font-weight"
+                      htmlFor="flexCheckDefault"
+                    >
+                      {t('Include Subordinated Target Page', {
+                        target: '/user',
+                      })}
+                    </label>
+                  </div>
                 </div>
-              </div>
+              )}
               <div className="px-2 py-1">
                 <div className="form-check form-check-succsess">
                   <input
@@ -206,6 +212,7 @@ const SearchControl = React.memo((props: Props): JSX.Element => {
       <SearchOptionModalLazyLoaded
         isOpen={isFileterOptionModalShown || false}
         onClose={() => setIsFileterOptionModalShown(false)}
+        isHidingUserPages={isHidingUserPages}
         includeUserPages={includeUserPages}
         includeTrashPages={includeTrashPages}
         onIncludeUserPagesSwitched={setIncludeUserPages}

+ 17 - 16
apps/app/src/features/search/client/components/SearchPage/SearchOptionModal/SearchOptionModal.tsx

@@ -6,6 +6,7 @@ type Props = {
   isOpen: boolean;
   includeUserPages: boolean;
   includeTrashPages: boolean;
+  isHidingUserPages: boolean;
   onClose?: () => void;
   onIncludeUserPagesSwitched?: (isChecked: boolean) => void;
   onIncludeTrashPagesSwitched?: (isChecked: boolean) => void;
@@ -18,6 +19,7 @@ export const SearchOptionModal: FC<Props> = (props: Props) => {
     isOpen,
     includeUserPages,
     includeTrashPages,
+    isHidingUserPages,
     onClose,
     onIncludeUserPagesSwitched,
     onIncludeTrashPagesSwitched,
@@ -31,9 +33,9 @@ export const SearchOptionModal: FC<Props> = (props: Props) => {
   }, [onClose]);
 
   const includeUserPagesChangeHandler = useCallback(
-    (isChecked: boolean) => {
+    (e: React.ChangeEvent<HTMLInputElement>) => {
       if (onIncludeUserPagesSwitched != null) {
-        onIncludeUserPagesSwitched(isChecked);
+        onIncludeUserPagesSwitched(e.target.checked);
       }
     },
     [onIncludeUserPagesSwitched],
@@ -55,20 +57,19 @@ export const SearchOptionModal: FC<Props> = (props: Props) => {
       </ModalHeader>
       <ModalBody>
         <div className="d-flex p-2">
-          <div className="me-3">
-            <label className="form-label px-3 py-2 mb-0 d-flex align-items-center">
-              <input
-                className="me-2"
-                type="checkbox"
-                onChange={useCallback(
-                  (e) => includeUserPagesChangeHandler(e.target.checked),
-                  [includeUserPagesChangeHandler],
-                )}
-                checked={includeUserPages}
-              />
-              {t('Include Subordinated Target Page', { target: '/user' })}
-            </label>
-          </div>
+          {!isHidingUserPages && (
+            <div className="me-3">
+              <label className="form-label px-3 py-2 mb-0 d-flex align-items-center">
+                <input
+                  className="me-2"
+                  type="checkbox"
+                  onChange={includeUserPagesChangeHandler}
+                  checked={includeUserPages}
+                />
+                {t('Include Subordinated Target Page', { target: '/user' })}
+              </label>
+            </div>
+          )}
           <div className="">
             <label className="form-label px-3 py-2 mb-0 d-flex align-items-center">
               <input

+ 1 - 0
apps/app/src/features/search/client/components/SearchPage/SearchOptionModal/dynamic.tsx

@@ -6,6 +6,7 @@ type SearchOptionModalProps = {
   isOpen: boolean;
   includeUserPages: boolean;
   includeTrashPages: boolean;
+  isHidingUserPages: boolean;
   onClose?: () => void;
   onIncludeUserPagesSwitched?: (isChecked: boolean) => void;
   onIncludeTrashPagesSwitched?: (isChecked: boolean) => void;

+ 11 - 1
apps/app/src/features/search/client/components/SearchPage/SearchPage.tsx

@@ -10,8 +10,14 @@ import type {
   ISelectableAndIndeterminatable,
 } from '~/client/interfaces/selectable-all';
 import type { IFormattedSearchResult } from '~/interfaces/search';
+import type { RendererConfig } from '~/interfaces/services/renderer';
+import type { ServerConfigurationProps } from '~/pages/_search/types';
+import { useHydrateServerConfigurationAtoms } from '~/pages/_search/use-hydrate-server-configurations';
 import { useSearchKeyword, useSetSearchKeyword } from '~/states/search';
-import { showPageLimitationLAtom } from '~/states/server-configurations';
+import {
+  isHidingUserPagesAtom,
+  showPageLimitationLAtom,
+} from '~/states/server-configurations';
 import {
   type ISearchConditions,
   type ISearchConfigurations,
@@ -106,6 +112,8 @@ export const SearchPage = (): JSX.Element => {
   const keyword = useSearchKeyword();
   const setSearchKeyword = useSetSearchKeyword();
 
+  const isHidingUserPages = useAtomValue(isHidingUserPagesAtom);
+
   const [offset, setOffset] = useState<number>(0);
   const [limit, setLimit] = useState<number>(
     showPageLimitationL ?? INITIAL_PAGIONG_SIZE,
@@ -286,6 +294,7 @@ export const SearchPage = (): JSX.Element => {
       <SearchControl
         isEnableSort
         isEnableFilter
+        isHidingUserPages={isHidingUserPages}
         initialSearchConditions={initialSearchConditions}
         onSearchInvoked={searchInvokedHandler}
         extraControls={extraControls}
@@ -298,6 +307,7 @@ export const SearchPage = (): JSX.Element => {
     collapseContents,
     initialSearchConditions,
     isCollapsed,
+    isHidingUserPages,
     searchInvokedHandler,
   ]);
 

+ 3 - 0
apps/app/src/pages/_search/get-server-side-props/index.ts

@@ -31,6 +31,9 @@ const getServerSideConfigurationProps: GetServerSideProps<
         showPageLimitationL: configManager.getConfig(
           'customize:showPageLimitationL',
         ),
+        isHidingUserPages: configManager.getConfig(
+          'security:isHidingUserPages',
+        ),
       },
     },
   };

+ 1 - 0
apps/app/src/pages/_search/types.ts

@@ -2,5 +2,6 @@ export type ServerConfigurationProps = {
   serverConfig: {
     isContainerFluid: boolean;
     showPageLimitationL: number;
+    isHidingUserPages: boolean;
   };
 };

+ 2 - 0
apps/app/src/pages/_search/use-hydrate-server-configurations.ts

@@ -3,6 +3,7 @@ import { useHydrateAtoms } from 'jotai/utils';
 import type { RendererConfig } from '~/interfaces/services/renderer';
 import {
   isContainerFluidAtom,
+  isHidingUserPagesAtom,
   rendererConfigAtom,
   showPageLimitationLAtom,
 } from '~/states/server-configurations';
@@ -25,6 +26,7 @@ export const useHydrateServerConfigurationAtoms = (
           [isContainerFluidAtom, serverConfig.isContainerFluid],
           [showPageLimitationLAtom, serverConfig.showPageLimitationL],
           [rendererConfigAtom, rendererConfigs],
+          [isHidingUserPagesAtom, serverConfig.isHidingUserPages],
         ],
   );
 };

+ 3 - 1
apps/app/src/pages/general-page/configuration-props.ts

@@ -28,7 +28,6 @@ export const getServerSideRendererConfigProps: GetServerSideProps<
         isIndentSizeForced: configManager.getConfig(
           'markdown:isIndentSizeForced',
         ),
-
         drawioUri: configManager.getConfig('app:drawioUri'),
         plantumlUri: configManager.getConfig('app:plantumlUri'),
 
@@ -121,6 +120,9 @@ export const getServerSideGeneralPageProps: GetServerSideProps<
         isEnabledAttachTitleHeader: configManager.getConfig(
           'customize:isEnabledAttachTitleHeader',
         ),
+        isHidingUserPages: configManager.getConfig(
+          'security:isHidingUserPages',
+        ),
       },
     },
   };

+ 2 - 0
apps/app/src/pages/general-page/hydrate.ts

@@ -13,6 +13,7 @@ import {
   isContainerFluidAtom,
   isEnabledAttachTitleHeaderAtom,
   isEnabledStaleNotificationAtom,
+  isHidingUserPagesAtom,
   isIndentSizeForcedAtom,
   isLocalAccountRegistrationEnabledAtom,
   isPdfBulkExportEnabledAtom,
@@ -84,6 +85,7 @@ export const useHydrateGeneralPageConfigurationAtoms = (
             serverConfig.isLocalAccountRegistrationEnabled,
           ],
           [rendererConfigAtom, rendererConfigs],
+          [isHidingUserPagesAtom, serverConfig.isHidingUserPages],
         ],
   );
 };

+ 1 - 0
apps/app/src/pages/general-page/types.ts

@@ -32,6 +32,7 @@ export type ServerConfigurationProps = {
     isEnabledStaleNotification: boolean;
     disableLinkSharing: boolean;
     isIndentSizeForced: boolean;
+    isHidingUserPages: boolean;
     isEnabledAttachTitleHeader: boolean;
     isSlackConfigured: boolean;
     isAclEnabled: boolean;

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

@@ -143,6 +143,11 @@ export const isBulkExportPagesEnabledAtom = atom<boolean>(false);
  */
 export const isPdfBulkExportEnabledAtom = atom<boolean>(false);
 
+/**
+ * Atom for hiding user pages setting enabled
+ */
+export const isHidingUserPagesAtom = atom<boolean>(false);
+
 /**
  * Atom for local account registration enabled
  */