|
@@ -1,7 +1,7 @@
|
|
|
import { format } from 'date-fns/format';
|
|
import { format } from 'date-fns/format';
|
|
|
import { useAtomValue } from 'jotai';
|
|
import { useAtomValue } from 'jotai';
|
|
|
import { useTranslation } from 'next-i18next';
|
|
import { useTranslation } from 'next-i18next';
|
|
|
-import { type JSX, useState } from 'react';
|
|
|
|
|
|
|
+import { type JSX, useCallback, useMemo, useState } from 'react';
|
|
|
import { Modal, ModalBody, ModalHeader } from 'reactstrap';
|
|
import { Modal, ModalBody, ModalHeader } from 'reactstrap';
|
|
|
import { apiv3Post } from '~/client/util/apiv3-client';
|
|
import { apiv3Post } from '~/client/util/apiv3-client';
|
|
|
import { toastError, toastSuccess } from '~/client/util/toastr';
|
|
import { toastError, toastSuccess } from '~/client/util/toastr';
|
|
@@ -13,9 +13,8 @@ import {
|
|
|
usePageBulkExportSelectModalStatus,
|
|
usePageBulkExportSelectModalStatus,
|
|
|
} from '../states/modal';
|
|
} from '../states/modal';
|
|
|
|
|
|
|
|
-const PageBulkExportSelectModal = (): JSX.Element => {
|
|
|
|
|
|
|
+const PageBulkExportSelectModalSubstance = (): JSX.Element => {
|
|
|
const { t } = useTranslation();
|
|
const { t } = useTranslation();
|
|
|
- const status = usePageBulkExportSelectModalStatus();
|
|
|
|
|
const { close } = usePageBulkExportSelectModalActions();
|
|
const { close } = usePageBulkExportSelectModalActions();
|
|
|
const currentPagePath = useCurrentPagePath();
|
|
const currentPagePath = useCurrentPagePath();
|
|
|
const isPdfBulkExportEnabled = useAtomValue(isPdfBulkExportEnabledAtom);
|
|
const isPdfBulkExportEnabled = useAtomValue(isPdfBulkExportEnabledAtom);
|
|
@@ -28,7 +27,7 @@ const PageBulkExportSelectModal = (): JSX.Element => {
|
|
|
{ createdAt: string } | undefined
|
|
{ createdAt: string } | undefined
|
|
|
>(undefined);
|
|
>(undefined);
|
|
|
|
|
|
|
|
- const startBulkExport = async (format: PageBulkExportFormat) => {
|
|
|
|
|
|
|
+ const startBulkExport = useCallback(async (format: PageBulkExportFormat) => {
|
|
|
try {
|
|
try {
|
|
|
setFormatMemoForRestart(format);
|
|
setFormatMemoForRestart(format);
|
|
|
await apiv3Post('/page-bulk-export', { path: currentPagePath, format });
|
|
await apiv3Post('/page-bulk-export', { path: currentPagePath, format });
|
|
@@ -43,9 +42,9 @@ const PageBulkExportSelectModal = (): JSX.Element => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
close();
|
|
close();
|
|
|
- };
|
|
|
|
|
|
|
+ }, [close, currentPagePath, t]);
|
|
|
|
|
|
|
|
- const restartBulkExport = async () => {
|
|
|
|
|
|
|
+ const restartBulkExport = useCallback(async () => {
|
|
|
if (formatMemoForRestart != null) {
|
|
if (formatMemoForRestart != null) {
|
|
|
try {
|
|
try {
|
|
|
await apiv3Post('/page-bulk-export', {
|
|
await apiv3Post('/page-bulk-export', {
|
|
@@ -54,60 +53,74 @@ const PageBulkExportSelectModal = (): JSX.Element => {
|
|
|
restartJob: true,
|
|
restartJob: true,
|
|
|
});
|
|
});
|
|
|
toastSuccess(t('page_export.bulk_export_started'));
|
|
toastSuccess(t('page_export.bulk_export_started'));
|
|
|
- } catch (e) {
|
|
|
|
|
|
|
+ } catch {
|
|
|
toastError(t('page_export.failed_to_export'));
|
|
toastError(t('page_export.failed_to_export'));
|
|
|
}
|
|
}
|
|
|
setIsRestartModalOpened(false);
|
|
setIsRestartModalOpened(false);
|
|
|
}
|
|
}
|
|
|
- };
|
|
|
|
|
|
|
+ }, [currentPagePath, formatMemoForRestart, t]);
|
|
|
|
|
+
|
|
|
|
|
+ const handleCloseRestartModal = useCallback(() => {
|
|
|
|
|
+ setIsRestartModalOpened(false);
|
|
|
|
|
+ }, []);
|
|
|
|
|
+
|
|
|
|
|
+ // Memoize format display text to prevent recalculation
|
|
|
|
|
+ const formatDisplayText = useMemo(() => {
|
|
|
|
|
+ if (!formatMemoForRestart) return '';
|
|
|
|
|
+ return formatMemoForRestart === PageBulkExportFormat.md
|
|
|
|
|
+ ? t('page_export.markdown')
|
|
|
|
|
+ : 'PDF';
|
|
|
|
|
+ }, [formatMemoForRestart, t]);
|
|
|
|
|
+
|
|
|
|
|
+ // Memoize formatted date to prevent recalculation
|
|
|
|
|
+ const formattedCreatedAt = useMemo(() => {
|
|
|
|
|
+ if (!duplicateJobInfo?.createdAt) return '';
|
|
|
|
|
+ return format(new Date(duplicateJobInfo.createdAt), 'MM/dd HH:mm');
|
|
|
|
|
+ }, [duplicateJobInfo?.createdAt]);
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<>
|
|
<>
|
|
|
- {status != null && (
|
|
|
|
|
- <Modal isOpen={status.isOpened} toggle={close} size="lg">
|
|
|
|
|
- <ModalHeader tag="h4" toggle={close}>
|
|
|
|
|
- {t('page_export.bulk_export')}
|
|
|
|
|
- </ModalHeader>
|
|
|
|
|
- <ModalBody>
|
|
|
|
|
- <p className="card custom-card bg-warning-subtle pt-3 px-3">
|
|
|
|
|
- {t('page_export.bulk_export_download_explanation')}
|
|
|
|
|
- <span className="mt-3">
|
|
|
|
|
- <span className="material-symbols-outlined me-1">warning</span>
|
|
|
|
|
- {t('Warning')}
|
|
|
|
|
- </span>
|
|
|
|
|
- <ul className="mt-2">
|
|
|
|
|
- <li>{t('page_export.bulk_export_exec_time_warning')}</li>
|
|
|
|
|
- <li>{t('page_export.large_bulk_export_warning')}</li>
|
|
|
|
|
- </ul>
|
|
|
|
|
- </p>
|
|
|
|
|
- {t('page_export.choose_export_format')}:
|
|
|
|
|
- <div className="d-flex justify-content-center mt-3">
|
|
|
|
|
- <button
|
|
|
|
|
- className="btn btn-primary"
|
|
|
|
|
- type="button"
|
|
|
|
|
- onClick={() => startBulkExport(PageBulkExportFormat.md)}
|
|
|
|
|
- >
|
|
|
|
|
- {t('page_export.markdown')}
|
|
|
|
|
- </button>
|
|
|
|
|
- {isPdfBulkExportEnabled && (
|
|
|
|
|
- <button
|
|
|
|
|
- className="btn btn-primary ms-2"
|
|
|
|
|
- type="button"
|
|
|
|
|
- onClick={() => startBulkExport(PageBulkExportFormat.pdf)}
|
|
|
|
|
- >
|
|
|
|
|
- PDF
|
|
|
|
|
- </button>
|
|
|
|
|
- )}
|
|
|
|
|
- </div>
|
|
|
|
|
- </ModalBody>
|
|
|
|
|
- </Modal>
|
|
|
|
|
- )}
|
|
|
|
|
|
|
+ <ModalHeader tag="h4" toggle={close}>
|
|
|
|
|
+ {t('page_export.bulk_export')}
|
|
|
|
|
+ </ModalHeader>
|
|
|
|
|
+ <ModalBody>
|
|
|
|
|
+ <p className="card custom-card bg-warning-subtle pt-3 px-3">
|
|
|
|
|
+ {t('page_export.bulk_export_download_explanation')}
|
|
|
|
|
+ <span className="mt-3">
|
|
|
|
|
+ <span className="material-symbols-outlined me-1">warning</span>
|
|
|
|
|
+ {t('Warning')}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <ul className="mt-2">
|
|
|
|
|
+ <li>{t('page_export.bulk_export_exec_time_warning')}</li>
|
|
|
|
|
+ <li>{t('page_export.large_bulk_export_warning')}</li>
|
|
|
|
|
+ </ul>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ {t('page_export.choose_export_format')}:
|
|
|
|
|
+ <div className="d-flex justify-content-center mt-3">
|
|
|
|
|
+ <button
|
|
|
|
|
+ className="btn btn-primary"
|
|
|
|
|
+ type="button"
|
|
|
|
|
+ onClick={() => startBulkExport(PageBulkExportFormat.md)}
|
|
|
|
|
+ >
|
|
|
|
|
+ {t('page_export.markdown')}
|
|
|
|
|
+ </button>
|
|
|
|
|
+ {isPdfBulkExportEnabled && (
|
|
|
|
|
+ <button
|
|
|
|
|
+ className="btn btn-primary ms-2"
|
|
|
|
|
+ type="button"
|
|
|
|
|
+ onClick={() => startBulkExport(PageBulkExportFormat.pdf)}
|
|
|
|
|
+ >
|
|
|
|
|
+ PDF
|
|
|
|
|
+ </button>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </ModalBody>
|
|
|
|
|
|
|
|
<Modal
|
|
<Modal
|
|
|
isOpen={isRestartModalOpened}
|
|
isOpen={isRestartModalOpened}
|
|
|
- toggle={() => setIsRestartModalOpened(false)}
|
|
|
|
|
|
|
+ toggle={handleCloseRestartModal}
|
|
|
>
|
|
>
|
|
|
- <ModalHeader tag="h4" toggle={() => setIsRestartModalOpened(false)}>
|
|
|
|
|
|
|
+ <ModalHeader tag="h4" toggle={handleCloseRestartModal}>
|
|
|
{t('page_export.export_in_progress')}
|
|
{t('page_export.export_in_progress')}
|
|
|
</ModalHeader>
|
|
</ModalHeader>
|
|
|
<ModalBody>
|
|
<ModalBody>
|
|
@@ -120,15 +133,11 @@ const PageBulkExportSelectModal = (): JSX.Element => {
|
|
|
<ul>
|
|
<ul>
|
|
|
{formatMemoForRestart && (
|
|
{formatMemoForRestart && (
|
|
|
<li>
|
|
<li>
|
|
|
- {t('page_export.format')}:{' '}
|
|
|
|
|
- {formatMemoForRestart === PageBulkExportFormat.md
|
|
|
|
|
- ? t('page_export.markdown')
|
|
|
|
|
- : 'PDF'}
|
|
|
|
|
|
|
+ {t('page_export.format')}: {formatDisplayText}
|
|
|
</li>
|
|
</li>
|
|
|
)}
|
|
)}
|
|
|
<li>
|
|
<li>
|
|
|
- {t('page_export.started_on')}:{' '}
|
|
|
|
|
- {format(new Date(duplicateJobInfo.createdAt), 'MM/dd HH:mm')}
|
|
|
|
|
|
|
+ {t('page_export.started_on')}: {formattedCreatedAt}
|
|
|
</li>
|
|
</li>
|
|
|
</ul>
|
|
</ul>
|
|
|
</div>
|
|
</div>
|
|
@@ -137,7 +146,7 @@ const PageBulkExportSelectModal = (): JSX.Element => {
|
|
|
<button
|
|
<button
|
|
|
className="btn btn-primary"
|
|
className="btn btn-primary"
|
|
|
type="button"
|
|
type="button"
|
|
|
- onClick={() => restartBulkExport()}
|
|
|
|
|
|
|
+ onClick={restartBulkExport}
|
|
|
>
|
|
>
|
|
|
{t('page_export.restart')}
|
|
{t('page_export.restart')}
|
|
|
</button>
|
|
</button>
|
|
@@ -148,4 +157,19 @@ const PageBulkExportSelectModal = (): JSX.Element => {
|
|
|
);
|
|
);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+const PageBulkExportSelectModal = (): JSX.Element => {
|
|
|
|
|
+ const status = usePageBulkExportSelectModalStatus();
|
|
|
|
|
+
|
|
|
|
|
+ // Early return for performance optimization
|
|
|
|
|
+ if (!status?.isOpened) {
|
|
|
|
|
+ return <></>;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <Modal isOpen={status.isOpened} size="lg">
|
|
|
|
|
+ <PageBulkExportSelectModalSubstance />
|
|
|
|
|
+ </Modal>
|
|
|
|
|
+ );
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
export default PageBulkExportSelectModal;
|
|
export default PageBulkExportSelectModal;
|