PageBulkExportSettings.tsx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import { type JSX, useCallback, useEffect, useState } from 'react';
  2. import { LoadingSpinner } from '@growi/ui/dist/components';
  3. import { useTranslation } from 'next-i18next';
  4. import { apiv3Put } from '~/client/util/apiv3-client';
  5. import { toastError, toastSuccess } from '~/client/util/toastr';
  6. import { useSWRxAppSettings } from '~/stores/admin/app-settings';
  7. import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
  8. const PageBulkExportSettings = (): JSX.Element => {
  9. const { t } = useTranslation(['admin', 'commons']);
  10. const { data, error, mutate } = useSWRxAppSettings();
  11. const [isBulkExportPagesEnabled, setIsBulkExportPagesEnabled] = useState(
  12. data?.isBulkExportPagesEnabled,
  13. );
  14. const [
  15. bulkExportDownloadExpirationSeconds,
  16. setBulkExportDownloadExpirationSeconds,
  17. ] = useState(data?.bulkExportDownloadExpirationSeconds);
  18. const changeBulkExportDownloadExpirationSeconds = (
  19. bulkExportDownloadExpirationDays: number,
  20. ) => {
  21. const bulkExportDownloadExpirationSeconds =
  22. bulkExportDownloadExpirationDays * 24 * 60 * 60;
  23. setBulkExportDownloadExpirationSeconds(bulkExportDownloadExpirationSeconds);
  24. };
  25. const onSubmitHandler = useCallback(async () => {
  26. try {
  27. await apiv3Put('/app-settings/page-bulk-export-settings', {
  28. isBulkExportPagesEnabled,
  29. bulkExportDownloadExpirationSeconds,
  30. });
  31. toastSuccess(
  32. t('commons:toaster.update_successed', {
  33. target: t('app_setting.page_bulk_export_settings'),
  34. }),
  35. );
  36. } catch (err) {
  37. toastError(err);
  38. }
  39. mutate();
  40. }, [
  41. isBulkExportPagesEnabled,
  42. bulkExportDownloadExpirationSeconds,
  43. mutate,
  44. t,
  45. ]);
  46. useEffect(() => {
  47. if (data?.useOnlyEnvVarForFileUploadType) {
  48. setIsBulkExportPagesEnabled(data?.envIsBulkExportPagesEnabled);
  49. } else {
  50. setIsBulkExportPagesEnabled(data?.isBulkExportPagesEnabled);
  51. }
  52. setBulkExportDownloadExpirationSeconds(
  53. data?.bulkExportDownloadExpirationSeconds,
  54. );
  55. }, [data]);
  56. const isLoading = data === undefined && error === undefined;
  57. return (
  58. <>
  59. {isLoading && (
  60. <div className="text-muted text-center mb-5">
  61. <LoadingSpinner className="me-1 fs-3" />
  62. </div>
  63. )}
  64. {!isLoading && (
  65. <>
  66. <p className="card custom-card bg-warning-subtle my-3">
  67. {t('admin:app_setting.page_bulk_export_explanation')} <br />
  68. <span className="text-danger mt-1">
  69. {t('admin:app_setting.page_bulk_export_warning')}
  70. </span>
  71. </p>
  72. <div className="my-4 row">
  73. <div className="text-start text-md-end col-md-3 col-form-label"></div>
  74. <div className="col-md-6">
  75. <div className="form-check form-switch form-check-info">
  76. <input
  77. type="checkbox"
  78. className="form-check-input"
  79. id="cbIsPageBulkExportEnabled"
  80. checked={isBulkExportPagesEnabled}
  81. disabled={data?.useOnlyEnvVarsForIsBulkExportPagesEnabled}
  82. onChange={(e) =>
  83. setIsBulkExportPagesEnabled(e.target.checked)
  84. }
  85. />
  86. <label
  87. className="form-label form-check-label"
  88. htmlFor="cbIsPageBulkExportEnabled"
  89. >
  90. {t('app_setting.enable_page_bulk_export')}
  91. </label>
  92. </div>
  93. {data?.useOnlyEnvVarsForIsBulkExportPagesEnabled && (
  94. <p className="form-text text-muted">
  95. <b
  96. // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
  97. dangerouslySetInnerHTML={{
  98. __html: t('admin:app_setting.fixed_by_env_var', {
  99. envKey: 'BULK_EXPORT_PAGES_ENABLED',
  100. envVar: isBulkExportPagesEnabled,
  101. }),
  102. }}
  103. />
  104. </p>
  105. )}
  106. </div>
  107. </div>
  108. <div className="mb-4">
  109. <div className="row">
  110. <label
  111. className="text-start text-md-end col-md-3 col-form-label"
  112. htmlFor="admin-page-bulk-export-expiration"
  113. >
  114. {t('app_setting.page_bulk_export_storage_period')}
  115. </label>
  116. <div className="col-md-2">
  117. <select
  118. className="form-select"
  119. id="admin-page-bulk-export-expiration"
  120. value={
  121. (bulkExportDownloadExpirationSeconds ?? 0) / (24 * 60 * 60)
  122. }
  123. onChange={(e) => {
  124. changeBulkExportDownloadExpirationSeconds(
  125. Number(e.target.value),
  126. );
  127. }}
  128. >
  129. {Array.from({ length: 7 }, (_, i) => i + 1).map((number) => (
  130. <option
  131. key={`be-download-expiration-option-${number}`}
  132. value={number}
  133. >
  134. {number} {t('admin:days')}
  135. </option>
  136. ))}
  137. </select>
  138. </div>
  139. </div>
  140. </div>
  141. <AdminUpdateButtonRow onClick={onSubmitHandler} />
  142. </>
  143. )}
  144. </>
  145. );
  146. };
  147. export default PageBulkExportSettings;