DescendantsPageListModal.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import React, { useState, useMemo, useEffect } from 'react';
  2. import { useTranslation } from 'next-i18next';
  3. import dynamic from 'next/dynamic';
  4. import { useRouter } from 'next/router';
  5. import {
  6. Modal, ModalHeader, ModalBody,
  7. } from 'reactstrap';
  8. import { useIsSharedUser } from '~/stores-universal/context';
  9. import { useDescendantsPageListModal } from '~/stores/modal';
  10. import { useIsDeviceLargerThanLg } from '~/stores/ui';
  11. import { CustomNavDropdown, CustomNavTab } from './CustomNavigation/CustomNav';
  12. import CustomTabContent from './CustomNavigation/CustomTabContent';
  13. import type { DescendantsPageListProps } from './DescendantsPageList';
  14. import ExpandOrContractButton from './ExpandOrContractButton';
  15. import styles from './DescendantsPageListModal.module.scss';
  16. const DescendantsPageList = dynamic<DescendantsPageListProps>(() => import('./DescendantsPageList').then(mod => mod.DescendantsPageList), { ssr: false });
  17. const PageTimeline = dynamic(() => import('./PageTimeline').then(mod => mod.PageTimeline), { ssr: false });
  18. export const DescendantsPageListModal = (): JSX.Element => {
  19. const { t } = useTranslation();
  20. const [activeTab, setActiveTab] = useState('pagelist');
  21. const [isWindowExpanded, setIsWindowExpanded] = useState(false);
  22. const { data: isSharedUser } = useIsSharedUser();
  23. const { data: status, close } = useDescendantsPageListModal();
  24. const { events } = useRouter();
  25. const { data: isDeviceLargerThanLg } = useIsDeviceLargerThanLg();
  26. useEffect(() => {
  27. events.on('routeChangeStart', close);
  28. return () => {
  29. events.off('routeChangeStart', close);
  30. };
  31. }, [close, events]);
  32. const navTabMapping = useMemo(() => {
  33. return {
  34. pagelist: {
  35. Icon: () => <span className="material-symbols-outlined">subject</span>,
  36. Content: () => {
  37. if (status == null || status.path == null || !status.isOpened) {
  38. return <></>;
  39. }
  40. return <DescendantsPageList path={status.path} />;
  41. },
  42. i18n: t('page_list'),
  43. isLinkEnabled: () => !isSharedUser,
  44. },
  45. timeline: {
  46. Icon: () => <span data-testid="timeline-tab-button" className="material-symbols-outlined">timeline</span>,
  47. Content: () => {
  48. if (status == null || !status.isOpened) {
  49. return <></>;
  50. }
  51. return <PageTimeline />;
  52. },
  53. i18n: t('Timeline View'),
  54. isLinkEnabled: () => !isSharedUser,
  55. },
  56. };
  57. }, [isSharedUser, status, t]);
  58. const buttons = useMemo(() => (
  59. <span className="me-3">
  60. <ExpandOrContractButton
  61. isWindowExpanded={isWindowExpanded}
  62. expandWindow={() => setIsWindowExpanded(true)}
  63. contractWindow={() => setIsWindowExpanded(false)}
  64. />
  65. <button type="button" className="btn btn-close ms-2" onClick={close} aria-label="Close"></button>
  66. </span>
  67. ), [close, isWindowExpanded]);
  68. if (status == null) {
  69. return <></>;
  70. }
  71. const { isOpened } = status;
  72. return (
  73. <Modal
  74. size="xl"
  75. isOpen={isOpened}
  76. toggle={close}
  77. data-testid="descendants-page-list-modal"
  78. className={`grw-descendants-page-list-modal ${styles['grw-descendants-page-list-modal']} ${isWindowExpanded ? 'grw-modal-expanded' : ''} `}
  79. >
  80. <ModalHeader className={isDeviceLargerThanLg ? 'p-0' : ''} toggle={close} close={buttons}>
  81. {isDeviceLargerThanLg && (
  82. <CustomNavTab
  83. activeTab={activeTab}
  84. navTabMapping={navTabMapping}
  85. breakpointToHideInactiveTabsDown="md"
  86. onNavSelected={v => setActiveTab(v)}
  87. hideBorderBottom
  88. />
  89. )}
  90. </ModalHeader>
  91. <ModalBody>
  92. {!isDeviceLargerThanLg && (
  93. <CustomNavDropdown
  94. activeTab={activeTab}
  95. navTabMapping={navTabMapping}
  96. onNavSelected={v => setActiveTab(v)}
  97. />
  98. )}
  99. <CustomTabContent
  100. activeTab={activeTab}
  101. navTabMapping={navTabMapping}
  102. additionalClassNames={!isDeviceLargerThanLg ? ['grw-tab-content-style-md-down'] : undefined}
  103. />
  104. </ModalBody>
  105. </Modal>
  106. );
  107. };