PrivateLegacyPagesMigrationModal.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import React, { useState, type JSX } from 'react';
  2. import { useTranslation } from 'next-i18next';
  3. import {
  4. Modal, ModalHeader, ModalBody, ModalFooter,
  5. } from 'reactstrap';
  6. import { apiv3Post } from '~/client/util/apiv3-client';
  7. import { usePrivateLegacyPagesMigrationModalActions, usePrivateLegacyPagesMigrationModalStatus } from '~/states/ui/modal/private-legacy-pages-migration';
  8. import ApiErrorMessageList from './PageManagement/ApiErrorMessageList';
  9. export const PrivateLegacyPagesMigrationModal = (): JSX.Element => {
  10. const { t } = useTranslation();
  11. const status = usePrivateLegacyPagesMigrationModalStatus();
  12. const { close } = usePrivateLegacyPagesMigrationModalActions();
  13. const isOpened = status?.isOpened ?? false;
  14. const [isRecursively, setIsRecursively] = useState(true);
  15. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  16. const [errs, setErrs] = useState<Error[] | null>(null);
  17. async function submit() {
  18. if (status == null || status.pages == null || status.pages.length === 0) {
  19. return;
  20. }
  21. const { pages, onSubmit } = status;
  22. const pageIds = pages.map(page => page.pageId);
  23. try {
  24. await apiv3Post<void>('/pages/legacy-pages-migration', {
  25. pageIds,
  26. isRecursively: isRecursively ? true : undefined,
  27. });
  28. if (onSubmit != null) {
  29. onSubmit(pages, isRecursively);
  30. }
  31. }
  32. catch (err) {
  33. setErrs([err]);
  34. }
  35. }
  36. function renderForm() {
  37. return (
  38. <div className="form-check form-check-warning">
  39. <input
  40. className="form-check-input"
  41. id="convertRecursively"
  42. type="checkbox"
  43. checked={isRecursively}
  44. onChange={(e) => {
  45. setIsRecursively(e.target.checked);
  46. }}
  47. />
  48. <label className="form-label form-check-label" htmlFor="convertRecursively">
  49. { t('private_legacy_pages.modal.convert_recursively_label') }
  50. <p className="form-text text-muted mt-0"> { t('private_legacy_pages.modal.convert_recursively_desc') }</p>
  51. </label>
  52. </div>
  53. );
  54. }
  55. const renderPageIds = () => {
  56. if (status != null && status.pages != null) {
  57. return status.pages.map(page => <div key={page.pageId}><code>{ page.path }</code></div>);
  58. }
  59. return <></>;
  60. };
  61. return (
  62. <Modal size="lg" isOpen={isOpened} toggle={close}>
  63. <ModalHeader tag="h4" toggle={close}>
  64. { t('private_legacy_pages.modal.title') }
  65. </ModalHeader>
  66. <ModalBody>
  67. <div className="grw-scrollable-modal-body pb-1">
  68. <label>{ t('private_legacy_pages.modal.converting_pages') }:</label><br />
  69. {/* Todo: change the way to show path on modal when too many pages are selected */}
  70. {/* https://redmine.weseek.co.jp/issues/82787 */}
  71. {renderPageIds()}
  72. </div>
  73. {renderForm()}
  74. </ModalBody>
  75. <ModalFooter>
  76. <ApiErrorMessageList errs={errs} />
  77. <button type="button" className="btn btn-primary" onClick={submit}>
  78. <span className="material-symbols-outlined" aria-hidden="true">refresh</span>
  79. { t('private_legacy_pages.modal.button_label') }
  80. </button>
  81. </ModalFooter>
  82. </Modal>
  83. );
  84. };