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

Merge pull request #6551 from weseek/fix/rendering-UserInfo

fix: Rendering UserInfo
ryoji-s 3 лет назад
Родитель
Сommit
c651ff9af5

+ 3 - 2
packages/app/src/components/Page/DisplaySwitcher.tsx

@@ -18,7 +18,7 @@ import PageListIcon from '../Icons/PageListIcon';
 import { Page } from '../Page';
 import { Page } from '../Page';
 // import PageEditorByHackmd from '../PageEditorByHackmd';
 // import PageEditorByHackmd from '../PageEditorByHackmd';
 import TableOfContents from '../TableOfContents';
 import TableOfContents from '../TableOfContents';
-import UserInfo from '../User/UserInfo';
+import { UserInfoProps } from '../User/UserInfo';
 
 
 
 
 import styles from './DisplaySwitcher.module.scss';
 import styles from './DisplaySwitcher.module.scss';
@@ -32,6 +32,7 @@ const EditorNavbarBottom = dynamic(() => import('../PageEditor/EditorNavbarBotto
 const HashChanged = dynamic(() => import('../EventListeneres/HashChanged'), { ssr: false });
 const HashChanged = dynamic(() => import('../EventListeneres/HashChanged'), { ssr: false });
 const ContentLinkButtons = dynamic(() => import('../ContentLinkButtons'), { ssr: false });
 const ContentLinkButtons = dynamic(() => import('../ContentLinkButtons'), { ssr: false });
 const NotFoundPage = dynamic(() => import('../NotFoundPage'), { ssr: false });
 const NotFoundPage = dynamic(() => import('../NotFoundPage'), { ssr: false });
+const UserInfo = dynamic<UserInfoProps>(() => import('../User/UserInfo').then(mod => mod.UserInfo), { ssr: false });
 
 
 
 
 const PageView = React.memo((): JSX.Element => {
 const PageView = React.memo((): JSX.Element => {
@@ -52,7 +53,7 @@ const PageView = React.memo((): JSX.Element => {
     <div className="d-flex flex-column flex-lg-row">
     <div className="d-flex flex-column flex-lg-row">
 
 
       <div className="flex-grow-1 flex-basis-0 mw-0">
       <div className="flex-grow-1 flex-basis-0 mw-0">
-        { isUserPage && <UserInfo pageUser={pageUser} />}
+        { isUserPage && pageUser != null && <UserInfo pageUser={pageUser} />}
         { !isNotFound && <Page /> }
         { !isNotFound && <Page /> }
         { isNotFound && <NotFoundPage /> }
         { isNotFound && <NotFoundPage /> }
       </div>
       </div>

+ 0 - 41
packages/app/src/components/User/UserInfo.jsx

@@ -1,41 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import { UserPicture } from '@growi/ui';
-
-const UserInfo = (props) => {
-  const { pageUser } = props;
-
-  // do not display when the user does not exist
-  if (pageUser == null) {
-    return null;
-  }
-
-  return (
-    <div className="grw-users-info d-flex align-items-center d-edit-none mb-5 pb-3 border-bottom">
-      <UserPicture user={pageUser} />
-
-      <div className="users-meta">
-        <h1 className="user-page-name">
-          {pageUser.name}
-        </h1>
-        <div className="user-page-meta mt-3 mb-0">
-          <span className="user-page-username mr-4"><i className="icon-user mr-1"></i>{pageUser.username}</span>
-          <span className="user-page-email mr-2">
-            <i className="icon-envelope mr-1"></i>
-            {pageUser.isEmailPublished ? pageUser.email : '*****'}
-          </span>
-          {pageUser.introduction && <span className="user-page-introduction">{pageUser.introduction}</span>}
-        </div>
-      </div>
-
-    </div>
-  );
-};
-
-
-UserInfo.propTypes = {
-  pageUser: PropTypes.object,
-};
-
-export default UserInfo;

+ 27 - 0
packages/app/src/components/User/UserInfo.module.scss

@@ -0,0 +1,27 @@
+@use '~/styles/bootstrap/init' as bs;
+
+.grw-users-info :global {
+  .users-meta {
+    margin-left: 30px;
+  }
+
+  .user-page-name {
+    margin: 0;
+    font-size: 2.5em;
+    color: bs.$secondary;
+  }
+
+  .picture {
+    width: 120px;
+    height: 120px;
+  }
+
+  div.user-page-meta {
+    padding-left: 0;
+    color: bs.$gray-400;
+
+    .user-page-username {
+      font-weight: bold;
+    }
+  }
+}

+ 46 - 0
packages/app/src/components/User/UserInfo.tsx

@@ -0,0 +1,46 @@
+import React from 'react';
+
+import { UserPicture } from '@growi/ui';
+
+import { IUserHasId } from '~/interfaces/user';
+
+import styles from './UserInfo.module.scss';
+
+export type UserInfoProps = {
+  pageUser: IUserHasId,
+}
+
+export const UserInfo = (props: UserInfoProps): JSX.Element => {
+
+  const { pageUser } = props;
+
+  // Do not display when the user does not exist
+  if (pageUser == null) {
+    return <></>;
+  }
+
+  return (
+    <div className={`${styles['grw-users-info']} grw-users-info d-flex align-items-center d-edit-none mb-5 pb-3 border-bottom`}>
+      <UserPicture user={pageUser} />
+      <div className="users-meta">
+        <h1 className="user-page-name">
+          {pageUser.name}
+        </h1>
+        <div className="user-page-meta mt-3 mb-0">
+          <span className="user-page-username mr-4"><i className="icon-user mr-1"></i>{pageUser.username}</span>
+          <span className="user-page-email mr-2">
+            <i className="icon-envelope mr-1"></i>
+            { pageUser.isEmailPublished
+              ? pageUser.email
+              : '*****'
+            }
+          </span>
+          { pageUser.introduction && (
+            <span className="user-page-introduction">{pageUser.introduction}</span>
+          ) }
+        </div>
+      </div>
+    </div>
+  );
+
+};

+ 7 - 5
packages/app/src/pages/[[...path]].page.tsx

@@ -62,7 +62,7 @@ import {
   useIsAclEnabled, useIsUserPage,
   useIsAclEnabled, useIsUserPage,
   useCsrfToken, useIsSearchScopeChildrenAsDefault, useCurrentPageId, useCurrentPathname,
   useCsrfToken, useIsSearchScopeChildrenAsDefault, useCurrentPageId, useCurrentPathname,
   useIsSlackConfigured, useRendererConfig, useEditingMarkdown,
   useIsSlackConfigured, useRendererConfig, useEditingMarkdown,
-  useEditorConfig, useIsAllReplyShown, useIsUploadableFile, useIsUploadableImage,
+  useEditorConfig, useIsAllReplyShown, useIsUploadableFile, useIsUploadableImage, usePageUser,
 } from '../stores/context';
 } from '../stores/context';
 
 
 import {
 import {
@@ -136,7 +136,7 @@ type Props = CommonProps & {
   isIdenticalPathPage?: boolean,
   isIdenticalPathPage?: boolean,
   isForbidden: boolean,
   isForbidden: boolean,
   isNotFound: boolean,
   isNotFound: boolean,
-  IsNotCreatablePage: boolean,
+  isNotCreatablePage: boolean,
   // isAbleToDeleteCompletely: boolean,
   // isAbleToDeleteCompletely: boolean,
 
 
   isSearchServiceConfigured: boolean,
   isSearchServiceConfigured: boolean,
@@ -251,6 +251,8 @@ const GrowiPage: NextPage<Props> = (props: Props) => {
   const { data: grantData } = useSWRxIsGrantNormalized(pageId);
   const { data: grantData } = useSWRxIsGrantNormalized(pageId);
   const { mutate: mutateSelectedGrant } = useSelectedGrant();
   const { mutate: mutateSelectedGrant } = useSelectedGrant();
 
 
+  usePageUser(pageWithMeta?.data.creator);
+
   // sync grant data
   // sync grant data
   useEffect(() => {
   useEffect(() => {
     mutateSelectedGrant(grantData?.grantData.currentPageGrant);
     mutateSelectedGrant(grantData?.grantData.currentPageGrant);
@@ -310,8 +312,8 @@ const GrowiPage: NextPage<Props> = (props: Props) => {
                   <>
                   <>
                     <PageAlerts />
                     <PageAlerts />
                     { props.isForbidden && <ForbiddenPage /> }
                     { props.isForbidden && <ForbiddenPage /> }
-                    { props.IsNotCreatablePage && <NotCreatablePage />}
-                    { !props.isForbidden && !props.IsNotCreatablePage && <DisplaySwitcher />}
+                    { props.isNotCreatablePage && <NotCreatablePage />}
+                    { !props.isForbidden && !props.isNotCreatablePage && <DisplaySwitcher />}
                     {/* <DisplaySwitcher /> */}
                     {/* <DisplaySwitcher /> */}
                     {/* <PageStatusAlert /> */}
                     {/* <PageStatusAlert /> */}
                   </>
                   </>
@@ -434,7 +436,7 @@ async function injectRoutingInformation(context: GetServerSidePropsContext, prop
   }
   }
   else if (page == null) {
   else if (page == null) {
     props.isNotFound = true;
     props.isNotFound = true;
-    props.IsNotCreatablePage = !isCreatablePage(currentPathname);
+    props.isNotCreatablePage = !isCreatablePage(currentPathname);
     // check the page is forbidden or just does not exist.
     // check the page is forbidden or just does not exist.
     const count = isPermalink ? await Page.count({ _id: pageId }) : await Page.count({ path: currentPathname });
     const count = isPermalink ? await Page.count({ _id: pageId }) : await Page.count({ path: currentPathname });
     props.isForbidden = count > 0;
     props.isForbidden = count > 0;

+ 3 - 3
packages/app/src/stores/context.tsx

@@ -11,7 +11,7 @@ import { GrowiThemes } from '~/interfaces/theme';
 import InterceptorManager from '~/services/interceptor-manager';
 import InterceptorManager from '~/services/interceptor-manager';
 
 
 import { TargetAndAncestors } from '../interfaces/page-listing-results';
 import { TargetAndAncestors } from '../interfaces/page-listing-results';
-import { IUser } from '../interfaces/user';
+import { IUser, IUserHasId } from '../interfaces/user';
 
 
 import { useStaticSWR } from './use-static-swr';
 import { useStaticSWR } from './use-static-swr';
 
 
@@ -98,8 +98,8 @@ export const useIsNotFound = (initialData?: boolean): SWRResponse<boolean, Error
   return useStaticSWR<boolean, Error>('isNotFound', initialData, { fallbackData: false });
   return useStaticSWR<boolean, Error>('isNotFound', initialData, { fallbackData: false });
 };
 };
 
 
-export const usePageUser = (initialData?: Nullable<any>): SWRResponse<Nullable<any>, Error> => {
-  return useStaticSWR<Nullable<any>, Error>('pageUser', initialData);
+export const usePageUser = (initialData?: IUserHasId): SWRResponse<IUserHasId, Error> => {
+  return useStaticSWR<IUserHasId, Error>('pageUser', initialData);
 };
 };
 
 
 export const useHasChildren = (initialData?: Nullable<any>): SWRResponse<Nullable<any>, Error> => {
 export const useHasChildren = (initialData?: Nullable<any>): SWRResponse<Nullable<any>, Error> => {

+ 0 - 26
packages/app/src/styles/_user.scss

@@ -8,32 +8,6 @@ $easeInOutCubic: cubic-bezier(0.65, 0, 0.35, 1);
 /*
 /*
  * Styles
  * Styles
  */
  */
-.grw-users-info {
-  .users-meta {
-    margin-left: 30px;
-  }
-
-  .user-page-name {
-    margin: 0;
-    font-size: 2.5em;
-    color: $secondary;
-  }
-
-  .picture {
-    width: 120px;
-    height: 120px;
-  }
-
-  div.user-page-meta {
-    padding-left: 0;
-    color: $gray-400;
-
-    .user-page-username {
-      font-weight: bold;
-    }
-  }
-}
-
 .grw-usermenu-notification-icon {
 .grw-usermenu-notification-icon {
   position: absolute;
   position: absolute;
   top: -4px;
   top: -4px;

+ 1 - 0
packages/core/src/interfaces/user.ts

@@ -19,6 +19,7 @@ export type IUser = {
   slackMemberId?: string,
   slackMemberId?: string,
   createdAt: Date,
   createdAt: Date,
   lastLoginAt?: Date,
   lastLoginAt?: Date,
+  introduction: string,
 }
 }
 
 
 export type IUserGroupRelation = {
 export type IUserGroupRelation = {

+ 2 - 2
packages/core/src/utils/page-path-utils.ts

@@ -63,8 +63,8 @@ export const isMovablePage = (path: string): boolean => {
  * @param path
  * @param path
  */
  */
 export const isUserPage = (path: string): boolean => {
 export const isUserPage = (path: string): boolean => {
-  // https://regex101.com/r/BSDdRr/1
-  if (path.match(/^\/user(\/.*)?$/)) {
+  // https://regex101.com/r/MwifLR/1
+  if (path.match(/^\/user\/.*?$/)) {
     return true;
     return true;
   }
   }