Draft.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import React, { useState } from 'react';
  2. import { useTranslation } from 'next-i18next';
  3. import { CopyToClipboard } from 'react-copy-to-clipboard';
  4. import ReactMarkdown from 'react-markdown';
  5. import {
  6. Collapse,
  7. UncontrolledTooltip,
  8. } from 'reactstrap';
  9. import { useDraftOptions } from '~/stores/renderer';
  10. type DraftProps = {
  11. path: string,
  12. isExist: boolean,
  13. index: number,
  14. markdown: string,
  15. clearDraft: (path: string) => void,
  16. }
  17. export const Draft = (props: DraftProps): JSX.Element => {
  18. const {
  19. path, isExist, index, markdown, clearDraft,
  20. } = props;
  21. const { t } = useTranslation();
  22. const { data: rendererOptions } = useDraftOptions();
  23. const [isPanelExpanded, setIsPanelExpanded] = useState(false);
  24. const [showCopiedMessage, setShowCopiedMessage] = useState(false);
  25. const changeToolTipLabel = () => {
  26. setShowCopiedMessage(true);
  27. setTimeout(() => {
  28. setShowCopiedMessage(false);
  29. }, 1000);
  30. };
  31. const collapsePanelHandler = () => {
  32. setIsPanelExpanded(false);
  33. };
  34. const expandPanelHandler = () => {
  35. setIsPanelExpanded(true);
  36. };
  37. const Controls = () => {
  38. const tooltipTargetId = `draft-copied-tooltip_${index}`;
  39. return (
  40. <div className="icon-container">
  41. {isExist
  42. ? null
  43. : (
  44. <a
  45. href={`${path}#edit`}
  46. target="_blank"
  47. rel="noopener noreferrer"
  48. data-toggle="tooltip"
  49. title={t('Edit')}
  50. >
  51. <i className="mx-2 icon-note" />
  52. </a>
  53. )
  54. }
  55. <span id={tooltipTargetId}>
  56. <CopyToClipboard text={markdown} onCopy={changeToolTipLabel}>
  57. <a
  58. className="text-center draft-copy"
  59. >
  60. <i className="mx-2 ti-clipboard" />
  61. </a>
  62. </CopyToClipboard>
  63. </span>
  64. <UncontrolledTooltip placement="top" target={tooltipTargetId} fade={false} trigger="hover">
  65. { showCopiedMessage && (
  66. <strong>copied!</strong>
  67. ) }
  68. { !showCopiedMessage && (
  69. <span>{t('Copy')}</span>
  70. ) }
  71. </UncontrolledTooltip>
  72. <a
  73. className="text-danger text-center"
  74. data-toggle="tooltip"
  75. data-placement="top"
  76. title={t('Delete')}
  77. onClick={() => { return clearDraft(path) }}
  78. >
  79. <i className="mx-2 icon-trash" />
  80. </a>
  81. </div>
  82. );
  83. };
  84. const AccordionTitle = () => {
  85. const iconClass = isPanelExpanded ? 'fa-rotate-90' : '';
  86. return (
  87. <span>
  88. <span className="mr-2 draft-path" onClick={() => setIsPanelExpanded(!isPanelExpanded)}>
  89. <i className={`fa fa-fw fa-angle-right mr-2 ${iconClass}`}></i>
  90. {path}
  91. </span>
  92. { isExist && (
  93. <span className="badge badge-warning">{t('page exists')}</span>
  94. ) }
  95. { !isExist && (
  96. <span className="badge badge-info">draft</span>
  97. ) }
  98. <a className="ml-2" href={path}><i className="icon icon-login"></i></a>
  99. </span>
  100. );
  101. };
  102. return (
  103. <div className="accordion draft-list-item" role="tablist">
  104. <div className="card">
  105. <div className="card-header d-flex" role="tab">
  106. <AccordionTitle/>
  107. <div className="flex-grow-1"></div>
  108. <Controls/>
  109. </div>
  110. <Collapse isOpen={isPanelExpanded} onEntering={expandPanelHandler} onExiting={collapsePanelHandler}>
  111. <div className="card-body">
  112. { isPanelExpanded && (
  113. <ReactMarkdown {...rendererOptions} className='wiki'>
  114. {markdown}
  115. </ReactMarkdown>
  116. ) }
  117. </div>
  118. </Collapse>
  119. </div>
  120. </div>
  121. );
  122. };