MarkdownTableDataImportForm.tsx 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import React, { useState } from 'react';
  2. import { MarkdownTable } from '@growi/editor';
  3. import { useTranslation } from 'next-i18next';
  4. import {
  5. Button,
  6. Collapse,
  7. } from 'reactstrap';
  8. type MarkdownTableDataImportFormProps = {
  9. onCancel: () => void,
  10. onImport: (table: MarkdownTable) => void,
  11. }
  12. export const MarkdownTableDataImportForm = (props: MarkdownTableDataImportFormProps): JSX.Element => {
  13. const { onCancel, onImport } = props;
  14. const { t } = useTranslation('commons', { keyPrefix: 'handsontable_modal.data_import_form' });
  15. const [dataFormat, setDataFormat] = useState<string>('csv');
  16. const [data, setData] = useState<string>('');
  17. const [parserErrorMessage, setParserErrorMessage] = useState(null);
  18. const convertFormDataToMarkdownTable = () => {
  19. let result;
  20. switch (dataFormat) {
  21. case 'csv':
  22. result = MarkdownTable.fromDSV(data, ',');
  23. break;
  24. case 'tsv':
  25. result = MarkdownTable.fromDSV(data, '\t');
  26. break;
  27. case 'html':
  28. result = MarkdownTable.fromHTMLTableTag(data);
  29. break;
  30. }
  31. return result.normalizeCells();
  32. };
  33. const importButtonHandler = () => {
  34. try {
  35. const markdownTable = convertFormDataToMarkdownTable();
  36. onImport(markdownTable);
  37. setParserErrorMessage(null);
  38. }
  39. catch (e) {
  40. setParserErrorMessage(e.message);
  41. }
  42. };
  43. return (
  44. <form className="data-import-form">
  45. <div>
  46. <label htmlFor="data-import-form-type-select" className="form-label">{t('select_data_format')}</label>
  47. <select
  48. id="data-import-form-type-select"
  49. className="form-select"
  50. placeholder="select"
  51. value={dataFormat}
  52. onChange={(e) => { return setDataFormat(e.target.value) }}
  53. >
  54. <option value="csv">CSV</option>
  55. <option value="tsv">TSV</option>
  56. <option value="html">HTML</option>
  57. </select>
  58. </div>
  59. <div className="mt-2">
  60. <label htmlFor="data-import-form-type-textarea" className="form-label">{t('import_data')}</label>
  61. <textarea
  62. id="data-import-form-type-textarea"
  63. className="form-control"
  64. placeholder={t('paste_table_data')}
  65. rows={8}
  66. onChange={(e) => { return setData(e.target.value) }}
  67. />
  68. </div>
  69. <Collapse isOpen={parserErrorMessage != null}>
  70. <div>
  71. <label htmlFor="data-import-form-type-textarea-alert" className="form-label">{t('parse_error')}</label>
  72. <textarea
  73. id="data-import-form-type-textarea-alert"
  74. className="form-control"
  75. rows={4}
  76. value={parserErrorMessage || ''}
  77. readOnly
  78. />
  79. </div>
  80. </Collapse>
  81. <div className="mt-3 d-flex justify-content-end">
  82. <Button color="outline-neutral-secondary me-2" onClick={onCancel}>{t('cancel')}</Button>
  83. <Button color="primary" onClick={importButtonHandler}>{t('import')}</Button>
  84. </div>
  85. </form>
  86. );
  87. };