IndentForm.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /* eslint-disable react/no-danger */
  2. import React, { useCallback } from 'react';
  3. import { useTranslation } from 'next-i18next';
  4. import {
  5. DropdownItem,
  6. DropdownMenu,
  7. DropdownToggle,
  8. UncontrolledDropdown,
  9. } from 'reactstrap';
  10. import AdminMarkDownContainer from '~/client/services/AdminMarkDownContainer';
  11. import { toastError, toastSuccess } from '~/client/util/toastr';
  12. import loggerFactory from '~/utils/logger';
  13. import { withUnstatedContainers } from '../../UnstatedUtils';
  14. import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
  15. const logger = loggerFactory('growi:importer');
  16. type Props = {
  17. adminMarkDownContainer: AdminMarkDownContainer;
  18. };
  19. const IndentForm = (props: Props) => {
  20. const { t } = useTranslation('admin');
  21. const onClickSubmit = useCallback(
  22. async (props) => {
  23. try {
  24. await props.adminMarkDownContainer.updateIndentSetting();
  25. toastSuccess(
  26. t('toaster.update_successed', {
  27. target: t('markdown_settings.indent_header'),
  28. ns: 'commons',
  29. }),
  30. );
  31. } catch (err) {
  32. toastError(err);
  33. logger.error(err);
  34. }
  35. },
  36. [t],
  37. );
  38. const renderIndentSizeOption = (props) => {
  39. const { adminMarkDownContainer } = props;
  40. const { adminPreferredIndentSize } = adminMarkDownContainer.state;
  41. return (
  42. <div className="col">
  43. <div>
  44. <label htmlFor="adminPreferredIndentSize" className="form-label">
  45. {t('markdown_settings.indent_options.indentSize')}
  46. </label>
  47. <UncontrolledDropdown id="adminPreferredIndentSize">
  48. <DropdownToggle
  49. caret
  50. className="col-3 col-sm-2 col-md-5 col-lg-5 col-xl-3 text-end"
  51. >
  52. <span className="float-start">
  53. {adminPreferredIndentSize || 4}
  54. </span>
  55. </DropdownToggle>
  56. <DropdownMenu className="dropdown-menu" role="menu">
  57. {[2, 4].map((num) => {
  58. return (
  59. <DropdownItem
  60. key={num}
  61. role="presentation"
  62. onClick={() =>
  63. adminMarkDownContainer.setAdminPreferredIndentSize(num)
  64. }
  65. >
  66. <span>{num}</span>
  67. </DropdownItem>
  68. );
  69. })}
  70. </DropdownMenu>
  71. </UncontrolledDropdown>
  72. </div>
  73. <p className="form-text text-muted">
  74. {t('markdown_settings.indent_options.indentSize_desc')}
  75. </p>
  76. </div>
  77. );
  78. };
  79. const renderIndentForceOption = (props) => {
  80. const { adminMarkDownContainer } = props;
  81. const { isIndentSizeForced } = adminMarkDownContainer.state;
  82. const helpIndentInComment = {
  83. __html: t('markdown_settings.indent_options.disallow_indent_change_desc'),
  84. };
  85. return (
  86. <div className="col">
  87. <div className="form-check form-check-success">
  88. <input
  89. type="checkbox"
  90. className="form-check-input"
  91. id="isIndentSizeForced"
  92. checked={isIndentSizeForced || false}
  93. onChange={() => {
  94. adminMarkDownContainer.setState({
  95. isIndentSizeForced: !isIndentSizeForced,
  96. });
  97. }}
  98. />
  99. <label
  100. className="form-label form-check-label"
  101. htmlFor="isIndentSizeForced"
  102. >
  103. {t('markdown_settings.indent_options.disallow_indent_change')}
  104. </label>
  105. </div>
  106. <p
  107. className="form-text text-muted"
  108. // biome-ignore lint/security/noDangerouslySetInnerHtml: translation contains HTML markup
  109. dangerouslySetInnerHTML={helpIndentInComment}
  110. />
  111. </div>
  112. );
  113. };
  114. const { adminMarkDownContainer } = props;
  115. return (
  116. <React.Fragment>
  117. <fieldset className="row row-cols-1 row-cols-md-2 mx-3">
  118. {renderIndentSizeOption(props)}
  119. {renderIndentForceOption(props)}
  120. </fieldset>
  121. <AdminUpdateButtonRow
  122. onClick={() => onClickSubmit(props)}
  123. disabled={adminMarkDownContainer.state.retrieveError != null}
  124. />
  125. </React.Fragment>
  126. );
  127. };
  128. /**
  129. * Wrapper component for using unstated
  130. */
  131. const IndentFormWrapper = withUnstatedContainers(IndentForm, [
  132. AdminMarkDownContainer,
  133. ]);
  134. export default IndentFormWrapper;