SentEditMenu.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import { Button, Dropdown, Tooltip, message } from "antd";
  2. import { useState } from "react";
  3. import {
  4. EditOutlined,
  5. CopyOutlined,
  6. MoreOutlined,
  7. FieldTimeOutlined,
  8. LinkOutlined,
  9. FileMarkdownOutlined,
  10. DeleteOutlined,
  11. } from "@ant-design/icons";
  12. import type { MenuProps } from "antd";
  13. import { ISentence } from "../SentEdit";
  14. import SentHistoryModal from "../../corpus/SentHistoryModal";
  15. import {
  16. CommentOutlinedIcon,
  17. HandOutlinedIcon,
  18. JsonOutlinedIcon,
  19. PasteOutLinedIcon,
  20. } from "../../../assets/icon";
  21. import { useIntl } from "react-intl";
  22. interface IWidget {
  23. data?: ISentence;
  24. children?: React.ReactNode;
  25. isPr?: boolean;
  26. onModeChange?: Function;
  27. onConvert?: Function;
  28. onMenuClick?: Function;
  29. }
  30. const SentEditMenuWidget = ({
  31. data,
  32. children,
  33. isPr = false,
  34. onModeChange,
  35. onConvert,
  36. onMenuClick,
  37. }: IWidget) => {
  38. const [isHover, setIsHover] = useState(false);
  39. const [timelineOpen, setTimelineOpen] = useState(false);
  40. const intl = useIntl();
  41. const onClick: MenuProps["onClick"] = (e) => {
  42. if (typeof onMenuClick !== "undefined") {
  43. onMenuClick(e.key);
  44. }
  45. switch (e.key) {
  46. case "json":
  47. if (typeof onConvert !== "undefined") {
  48. onConvert("json");
  49. }
  50. break;
  51. case "markdown":
  52. if (typeof onConvert !== "undefined") {
  53. onConvert("markdown");
  54. }
  55. break;
  56. case "timeline":
  57. setTimelineOpen(true);
  58. break;
  59. default:
  60. break;
  61. }
  62. };
  63. const items: MenuProps["items"] = [
  64. {
  65. key: "timeline",
  66. label: intl.formatMessage({
  67. id: "buttons.timeline",
  68. }),
  69. icon: <FieldTimeOutlined />,
  70. disabled: isPr,
  71. },
  72. {
  73. type: "divider",
  74. },
  75. {
  76. key: "suggestion",
  77. label: "suggestion",
  78. icon: <HandOutlinedIcon />,
  79. disabled: isPr,
  80. },
  81. {
  82. key: "discussion",
  83. label: "discussion",
  84. icon: <CommentOutlinedIcon />,
  85. disabled: isPr,
  86. },
  87. {
  88. type: "divider",
  89. },
  90. {
  91. key: "markdown",
  92. label: "To Markdown",
  93. icon: <FileMarkdownOutlined />,
  94. disabled: !data || data.contentType === "markdown" || isPr,
  95. },
  96. {
  97. key: "json",
  98. label: "To Json",
  99. icon: <JsonOutlinedIcon />,
  100. disabled: !data || data.contentType === "json" || isPr,
  101. },
  102. {
  103. type: "divider",
  104. },
  105. {
  106. key: "copy-link",
  107. label: intl.formatMessage({
  108. id: "buttons.copy.link",
  109. }),
  110. icon: <LinkOutlined />,
  111. },
  112. {
  113. key: "delete",
  114. label: intl.formatMessage({
  115. id: "buttons.delete",
  116. }),
  117. icon: <DeleteOutlined />,
  118. danger: true,
  119. disabled: !isPr,
  120. },
  121. ];
  122. return (
  123. <div
  124. onMouseEnter={() => {
  125. setIsHover(true);
  126. }}
  127. onMouseLeave={() => {
  128. setIsHover(false);
  129. }}
  130. >
  131. <SentHistoryModal
  132. open={timelineOpen}
  133. onClose={() => setTimelineOpen(false)}
  134. sentId={data?.id}
  135. />
  136. <div
  137. style={{
  138. marginTop: 0,
  139. right: 30,
  140. position: "absolute",
  141. display: isHover ? "block" : "none",
  142. }}
  143. >
  144. <Tooltip title="编辑">
  145. <Button
  146. icon={<EditOutlined />}
  147. size="small"
  148. onClick={() => {
  149. if (typeof onModeChange !== "undefined") {
  150. onModeChange("edit");
  151. }
  152. }}
  153. />
  154. </Tooltip>
  155. <Tooltip title="复制">
  156. <Button
  157. icon={<CopyOutlined />}
  158. size="small"
  159. onClick={() => {
  160. if (data?.content) {
  161. navigator.clipboard.writeText(data.content).then(() => {
  162. message.success("已经拷贝到剪贴板");
  163. });
  164. } else {
  165. message.success("内容为空");
  166. }
  167. }}
  168. />
  169. </Tooltip>
  170. <Tooltip title="粘贴">
  171. <Button
  172. icon={<PasteOutLinedIcon />}
  173. size="small"
  174. onClick={() => {
  175. if (typeof onMenuClick !== "undefined") {
  176. onMenuClick("paste");
  177. }
  178. }}
  179. />
  180. </Tooltip>
  181. <Dropdown
  182. disabled={data ? false : true}
  183. menu={{ items, onClick }}
  184. placement="bottomRight"
  185. >
  186. <Button icon={<MoreOutlined />} size="small" />
  187. </Dropdown>
  188. </div>
  189. {children}
  190. </div>
  191. );
  192. };
  193. export default SentEditMenuWidget;