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

Merge pull request #6335 from weseek/feat/render-page-list-and-timeline

Feat Render modal containing page list and timeline
Yohei Shiina 3 лет назад
Родитель
Сommit
1ce923bb3a

+ 3 - 3
packages/app/src/components/DescendantsPageList.tsx

@@ -103,7 +103,7 @@ export const DescendantsPageListSubstance = (props: SubstanceProps): JSX.Element
     );
     );
   }
   }
 
 
-  const showPager = pagingResult.items.length > pagingResult.limit;
+  const showPager = pagingResult.totalCount > pagingResult.limit;
 
 
   return (
   return (
     <>
     <>
@@ -130,11 +130,11 @@ export const DescendantsPageListSubstance = (props: SubstanceProps): JSX.Element
   );
   );
 };
 };
 
 
-type Props = {
+export type DescendantsPageListProps = {
   path: string,
   path: string,
 }
 }
 
 
-export const DescendantsPageList = (props: Props): JSX.Element => {
+export const DescendantsPageList = (props: DescendantsPageListProps): JSX.Element => {
   const { path } = props;
   const { path } = props;
 
 
   const [activePage, setActivePage] = useState(1);
   const [activePage, setActivePage] = useState(1);

+ 17 - 3
packages/app/src/components/DescendantsPageListModal.tsx

@@ -2,6 +2,7 @@
 import React, { useState, useMemo } from 'react';
 import React, { useState, useMemo } from 'react';
 
 
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
+import dynamic from 'next/dynamic';
 import {
 import {
   Modal, ModalHeader, ModalBody,
   Modal, ModalHeader, ModalBody,
 } from 'reactstrap';
 } from 'reactstrap';
@@ -11,12 +12,20 @@ import { useDescendantsPageListModal } from '~/stores/modal';
 
 
 import { CustomNavTab } from './CustomNavigation/CustomNav';
 import { CustomNavTab } from './CustomNavigation/CustomNav';
 import CustomTabContent from './CustomNavigation/CustomTabContent';
 import CustomTabContent from './CustomNavigation/CustomTabContent';
-import { DescendantsPageList } from './DescendantsPageList';
+import { DescendantsPageListProps } from './DescendantsPageList';
 import ExpandOrContractButton from './ExpandOrContractButton';
 import ExpandOrContractButton from './ExpandOrContractButton';
 import PageListIcon from './Icons/PageListIcon';
 import PageListIcon from './Icons/PageListIcon';
 import TimeLineIcon from './Icons/TimeLineIcon';
 import TimeLineIcon from './Icons/TimeLineIcon';
-import { PageTimeline } from './PageTimeline';
 
 
+const DescendantsPageList = (props: DescendantsPageListProps): JSX.Element => {
+  const DescendantsPageList = dynamic<DescendantsPageListProps>(() => import('./DescendantsPageList').then(mod => mod.DescendantsPageList), { ssr: false });
+  return <DescendantsPageList {...props}/>;
+};
+
+const PageTimeline = (): JSX.Element => {
+  const PageTimeline = dynamic(() => import('./PageTimeline').then(mod => mod.PageTimeline), { ssr: false });
+  return <PageTimeline />;
+};
 
 
 export const DescendantsPageListModal = (): JSX.Element => {
 export const DescendantsPageListModal = (): JSX.Element => {
   const { t } = useTranslation();
   const { t } = useTranslation();
@@ -44,7 +53,12 @@ export const DescendantsPageListModal = (): JSX.Element => {
       },
       },
       timeline: {
       timeline: {
         Icon: TimeLineIcon,
         Icon: TimeLineIcon,
-        Content: () => <PageTimeline />,
+        Content: () => {
+          if (status == null || !status.isOpened) {
+            return <></>;
+          }
+          return <PageTimeline />;
+        },
         i18n: t('Timeline View'),
         i18n: t('Timeline View'),
         index: 1,
         index: 1,
         isLinkEnabled: () => !isSharedUser,
         isLinkEnabled: () => !isSharedUser,

+ 0 - 6
packages/app/src/styles/_page-accessories-modal.scss → packages/app/src/components/PageAccessoriesModal.module.scss

@@ -16,9 +16,3 @@
     margin-bottom: 0rem;
     margin-bottom: 0rem;
   }
   }
 }
 }
-
-// revision-history
-// to stay d2h-code-side-line-number in the revision history diff area
-.d2h-wrapper {
-  position: relative;
-}

+ 2 - 1
packages/app/src/components/PageAccessoriesModal.tsx

@@ -21,6 +21,7 @@ import PageHistory from './PageHistory';
 import ShareLink from './ShareLink/ShareLink';
 import ShareLink from './ShareLink/ShareLink';
 import { withUnstatedContainers } from './UnstatedUtils';
 import { withUnstatedContainers } from './UnstatedUtils';
 
 
+import styles from './PageAccessoriesModal.module.scss';
 
 
 type Props = {
 type Props = {
   appContainer: AppContainer,
   appContainer: AppContainer,
@@ -107,7 +108,7 @@ const PageAccessoriesModal = (props: Props): JSX.Element => {
       isOpen={isOpened}
       isOpen={isOpened}
       toggle={close}
       toggle={close}
       data-testid="page-accessories-modal"
       data-testid="page-accessories-modal"
-      className={`grw-page-accessories-modal ${isWindowExpanded ? 'grw-modal-expanded' : ''} `}
+      className={`grw-page-accessories-modal ${styles['grw-page-accessories-modal']} ${isWindowExpanded ? 'grw-modal-expanded' : ''} `}
     >
     >
       <ModalHeader className="p-0" toggle={close} close={buttons}>
       <ModalHeader className="p-0" toggle={close} close={buttons}>
         <CustomNavTab
         <CustomNavTab

+ 1 - 1
packages/app/src/components/PageEditor/DrawioModal.jsx

@@ -136,7 +136,7 @@ class DrawioModal extends React.PureComponent {
         isOpen={this.state.show}
         isOpen={this.state.show}
         toggle={this.cancel}
         toggle={this.cancel}
         backdrop="static"
         backdrop="static"
-        className="drawio-modal"
+        className="drawio-modal grw-body-only-modal-expanded"
         size="xl"
         size="xl"
         keyboard={false}
         keyboard={false}
       >
       >

+ 1 - 1
packages/app/src/components/PagePresentationModal.jsx

@@ -17,7 +17,7 @@ const PagePresentationModal = () => {
       isOpen={presentationData.isOpened}
       isOpen={presentationData.isOpened}
       toggle={closePresentationModal}
       toggle={closePresentationModal}
       data-testid="page-presentation-modal"
       data-testid="page-presentation-modal"
-      className={`grw-presentation-modal ${styles['grw-presentation-modal']}`}
+      className={`grw-presentation-modal ${styles['grw-presentation-modal']} grw-body-only-modal-expanded`}
       unmountOnClose={false}
       unmountOnClose={false}
     >
     >
       <ModalBody className="modal-body">
       <ModalBody className="modal-body">

+ 0 - 4
packages/app/src/components/PagePresentationModal.module.scss

@@ -1,8 +1,4 @@
-@use '~/styles/mixins' as mi;
-
 .grw-presentation-modal :global {
 .grw-presentation-modal :global {
-  @include mi.expand-modal-fullscreen(false, false);
-
   .modal-body {
   .modal-body {
     background: black;
     background: black;
 
 

+ 14 - 0
packages/app/src/components/PageTimeline.module.scss

@@ -0,0 +1,14 @@
+@use '../styles/bootstrap/variables' as var;
+
+.card-timeline {
+  :global {
+    border: 1px solid var.$gray-300;
+  }
+
+  &:global {
+    > .card-header {
+      background-color: var.$gray-300;
+    }
+  }
+}
+

+ 4 - 2
packages/app/src/components/PageTimeline.tsx

@@ -1,4 +1,4 @@
-import React, { useEffect, useState, useCallback } from 'react';
+import React, { useCallback, useEffect, useState } from 'react';
 
 
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 
 
@@ -10,6 +10,8 @@ import { useTimelineOptions } from '~/stores/renderer';
 import RevisionLoader from './Page/RevisionLoader';
 import RevisionLoader from './Page/RevisionLoader';
 import PaginationWrapper from './PaginationWrapper';
 import PaginationWrapper from './PaginationWrapper';
 
 
+import styles from './PageTimeline.module.scss';
+
 export const PageTimeline = (): JSX.Element => {
 export const PageTimeline = (): JSX.Element => {
   const [activePage, setActivePage] = useState(1);
   const [activePage, setActivePage] = useState(1);
   const [totalPageItems, setTotalPageItems] = useState(0);
   const [totalPageItems, setTotalPageItems] = useState(0);
@@ -51,7 +53,7 @@ export const PageTimeline = (): JSX.Element => {
       { pages.map((page) => {
       { pages.map((page) => {
         return (
         return (
           <div className="timeline-body" key={`key-${page._id}`}>
           <div className="timeline-body" key={`key-${page._id}`}>
-            <div className="card card-timeline">
+            <div className={`card card-timeline ${styles['card-timeline']}`}>
               <div className="card-header"><a href={page.path}>{page.path}</a></div>
               <div className="card-header"><a href={page.path}>{page.path}</a></div>
               <div className="card-body">
               <div className="card-body">
                 <RevisionLoader
                 <RevisionLoader

+ 2 - 3
packages/app/src/pages/[[...path]].page.tsx

@@ -44,16 +44,14 @@ import loggerFactory from '~/utils/logger';
 
 
 // import GrowiSubNavigation from '../client/js/components/Navbar/GrowiSubNavigation';
 // import GrowiSubNavigation from '../client/js/components/Navbar/GrowiSubNavigation';
 // import GrowiSubNavigationSwitcher from '../client/js/components/Navbar/GrowiSubNavigationSwitcher';
 // import GrowiSubNavigationSwitcher from '../client/js/components/Navbar/GrowiSubNavigationSwitcher';
+import { DescendantsPageListModal } from '../components/DescendantsPageListModal';
 import ForbiddenPage from '../components/ForbiddenPage';
 import ForbiddenPage from '../components/ForbiddenPage';
 import { BasicLayout } from '../components/Layout/BasicLayout';
 import { BasicLayout } from '../components/Layout/BasicLayout';
 import GrowiContextualSubNavigation from '../components/Navbar/GrowiContextualSubNavigation';
 import GrowiContextualSubNavigation from '../components/Navbar/GrowiContextualSubNavigation';
 import { NotCreatablePage } from '../components/NotCreatablePage';
 import { NotCreatablePage } from '../components/NotCreatablePage';
 import DisplaySwitcher from '../components/Page/DisplaySwitcher';
 import DisplaySwitcher from '../components/Page/DisplaySwitcher';
-
 // import { serializeUserSecurely } from '../server/models/serializers/user-serializer';
 // import { serializeUserSecurely } from '../server/models/serializers/user-serializer';
 // import PageStatusAlert from '../client/js/components/PageStatusAlert';
 // import PageStatusAlert from '../client/js/components/PageStatusAlert';
-
-
 import {
 import {
   useCurrentUser, useCurrentPagePath,
   useCurrentUser, useCurrentPagePath,
   useIsLatestRevision,
   useIsLatestRevision,
@@ -331,6 +329,7 @@ const GrowiPage: NextPage<Props> = (props: Props) => {
         </footer>
         </footer>
 
 
         <UnsavedAlertDialog />
         <UnsavedAlertDialog />
+        <DescendantsPageListModal />
         {shouldRenderPutbackPageModal && <PutbackPageModal />}
         {shouldRenderPutbackPageModal && <PutbackPageModal />}
 
 
       </BasicLayout>
       </BasicLayout>

+ 0 - 3
packages/app/src/styles/_drawio.scss

@@ -1,3 +0,0 @@
-.drawio-modal {
-  @include expand-modal-fullscreen(false, false);
-}

+ 0 - 27
packages/app/src/styles/_mixins.scss

@@ -85,33 +85,6 @@
   }
   }
 }
 }
 
 
-@mixin expand-modal-fullscreen($hasModalHeader: true, $hasModalFooter: true) {
-  // full-screen modal
-  width: auto;
-  max-width: unset !important;
-  height: calc(100vh - 30px);
-  margin: 15px !important;
-
-  .modal-content {
-    height: calc(100vh - 30px);
-  }
-
-  // expand .modal-body (with calculating height)
-  .modal-body {
-    $modal-header: 54px;
-    $modal-footer: 46px;
-
-    $margin: 0px;
-    @if $hasModalHeader {
-      $margin: $margin + $modal-header;
-    }
-    @if $hasModalFooter {
-      $margin: $margin + $modal-footer;
-    }
-    height: calc(100% - #{$margin});
-  }
-}
-
 @mixin apply-navigation-transition() {
 @mixin apply-navigation-transition() {
   transition-timing-function: cubic-bezier(0.25, 1, 0.5, 1);
   transition-timing-function: cubic-bezier(0.25, 1, 0.5, 1);
   transition-duration: 300ms;
   transition-duration: 300ms;

+ 32 - 0
packages/app/src/styles/_modal.scss

@@ -1,4 +1,36 @@
+@mixin expand-modal-fullscreen($hasModalHeader: true, $hasModalFooter: true) {
+  // full-screen modal
+  width: auto;
+  max-width: unset !important;
+  height: calc(100vh - 30px);
+  margin: 15px !important;
+
+  .modal-content {
+    height: calc(100vh - 30px);
+  }
+
+  // expand .modal-body (with calculating height)
+  .modal-body {
+    $modal-header: 54px;
+    $modal-footer: 46px;
+
+    $margin: 0px;
+    @if $hasModalHeader {
+      $margin: $margin + $modal-header;
+    }
+    @if $hasModalFooter {
+      $margin: $margin + $modal-footer;
+    }
+    height: calc(100% - #{$margin});
+  }
+}
+
 // expanded window layout
 // expanded window layout
 .modal-dialog.grw-modal-expanded {
 .modal-dialog.grw-modal-expanded {
   @include expand-modal-fullscreen(true, true);
   @include expand-modal-fullscreen(true, true);
 }
 }
+
+// expanded window layout without modal-header & modal-footer
+.modal-dialog.grw-body-only-modal-expanded {
+  @include expand-modal-fullscreen(false, false);
+}

+ 6 - 0
packages/app/src/styles/_page-history.scss

@@ -24,6 +24,12 @@
 .revision-history-diff {
 .revision-history-diff {
   color: $gray-900;
   color: $gray-900;
   table-layout: fixed;
   table-layout: fixed;
+
+  // revision-history
+  // to stay d2h-code-side-line-number in the revision history diff area
+  .d2h-wrapper {
+    position: relative;
+  }
 }
 }
 
 
 .comparison-header {
 .comparison-header {

+ 2 - 7
packages/app/src/styles/_page_list.scss

@@ -1,3 +1,5 @@
+@use './bootstrap/variables' as var;
+
 body .page-list {
 body .page-list {
   .page-list-container {
   .page-list-container {
     font-size: 15px;
     font-size: 15px;
@@ -96,10 +98,3 @@ body .page-list {
     }
     }
   }
   }
 }
 }
-
-.card-timeline {
-  border: 1px solid $gray-300;
-  > .card-header {
-    background-color: $gray-300;
-  }
-}

+ 5 - 5
packages/app/src/styles/style-next.scss

@@ -1,5 +1,7 @@
 @import './bootstrap/apply';
 @import './bootstrap/apply';
 
 
+@import 'mixins';
+
 // // override codemirror
 // // override codemirror
 // @import 'override-codemirror';
 // @import 'override-codemirror';
 
 
@@ -38,7 +40,6 @@
 // @import 'attachments';
 // @import 'attachments';
 // @import 'comment';
 // @import 'comment';
 // @import 'comment_growi';
 // @import 'comment_growi';
-// @import 'drawio';
 // @import 'create-page';
 // @import 'create-page';
 // @import 'draft';
 // @import 'draft';
 // @import 'editor-attachment';
 // @import 'editor-attachment';
@@ -49,14 +50,13 @@
 @import 'login';
 @import 'login';
 // @import 'me';
 // @import 'me';
 // @import 'mirror_mode';
 // @import 'mirror_mode';
-// @import 'modal';
+@import 'modal';
 // @import 'navbar';
 // @import 'navbar';
 // @import 'old-ios';
 // @import 'old-ios';
 @import 'on-edit';
 @import 'on-edit';
 // @import 'page-duplicate-modal';
 // @import 'page-duplicate-modal';
-// @import 'page_list';
-// @import 'page-accessories-control';
-// @import 'page-accessories-modal';
+@import 'page_list';
+
 // @import 'page-path';
 // @import 'page-path';
 // @import 'page-tree';
 // @import 'page-tree';
 // @import 'page';
 // @import 'page';