RightPanel.tsx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import { Affix, Button, Space, Tabs } from "antd";
  2. import { useEffect, useState } from "react";
  3. import { CloseOutlined } from "@ant-design/icons";
  4. import { FullscreenOutlined, FullscreenExitOutlined } from "@ant-design/icons";
  5. import type { IChannel } from "../channel/Channel";
  6. import DictComponent from "../dict/DictComponent";
  7. import type { ArticleType } from "./Article";
  8. import { useAppSelector } from "../../hooks";
  9. import { openPanel, rightPanel } from "../../reducers/right-panel";
  10. import store from "../../store";
  11. import DiscussionBox from "../discussion/DiscussionBox";
  12. import { show } from "../../reducers/discussion";
  13. import { useIntl } from "react-intl";
  14. import SuggestionBox from "../template/SentEdit/SuggestionBox";
  15. import ChannelMy from "../channel/ChannelMy";
  16. import GrammarBook from "../term/GrammarBook";
  17. interface IWidget {
  18. curr?: TPanelName;
  19. type: ArticleType;
  20. articleId: string;
  21. selectedChannelsId?: string[];
  22. onChannelSelect?: Function;
  23. onClose?: Function;
  24. onTabChange?: Function;
  25. }
  26. const RightPanelWidget = ({
  27. curr = "close",
  28. type,
  29. articleId,
  30. onChannelSelect,
  31. selectedChannelsId,
  32. onClose,
  33. onTabChange,
  34. }: IWidget) => {
  35. const [open, setOpen] = useState(false);
  36. const [activeTab, setActiveTab] = useState<string>("dict");
  37. const _openPanel = useAppSelector(rightPanel);
  38. const intl = useIntl();
  39. const divMinWidth = 400;
  40. const divMaxWidth = 700;
  41. const [divWidth, setDivWidth] = useState(divMinWidth);
  42. const tabInnerStyle: React.CSSProperties = {
  43. width: "100%",
  44. height: `calc(100vh - 96px)`,
  45. overflowY: "scroll",
  46. };
  47. useEffect(() => {
  48. console.log("panel", _openPanel);
  49. if (typeof _openPanel !== "undefined") {
  50. if (typeof onTabChange !== "undefined") {
  51. onTabChange(_openPanel);
  52. }
  53. store.dispatch(openPanel(undefined));
  54. }
  55. }, [_openPanel]);
  56. useEffect(() => {
  57. switch (curr) {
  58. case "open":
  59. setOpen(true);
  60. break;
  61. case "dict":
  62. setOpen(true);
  63. setActiveTab(curr);
  64. break;
  65. case "channel":
  66. setOpen(true);
  67. setActiveTab(curr);
  68. break;
  69. case "discussion":
  70. setOpen(true);
  71. setActiveTab(curr);
  72. break;
  73. case "suggestion":
  74. setOpen(true);
  75. setActiveTab(curr);
  76. break;
  77. case "grammar":
  78. setOpen(true);
  79. setActiveTab(curr);
  80. break;
  81. case "close":
  82. setOpen(false);
  83. break;
  84. default:
  85. setOpen(false);
  86. break;
  87. }
  88. }, [curr]);
  89. return (
  90. <Affix offsetTop={44}>
  91. <div
  92. key="panel"
  93. style={{
  94. width: divWidth,
  95. height: `calc(100vh - 44px)`,
  96. overflowY: "hidden",
  97. display: open ? "block" : "none",
  98. paddingLeft: 8,
  99. paddingTop: 8,
  100. }}
  101. >
  102. <Tabs
  103. type="card"
  104. size="small"
  105. defaultActiveKey={curr}
  106. activeKey={activeTab}
  107. onChange={(activeKey: string) => setActiveTab(activeKey)}
  108. tabBarExtraContent={{
  109. right: (
  110. <Space>
  111. {divWidth === divMinWidth ? (
  112. <Button
  113. type="link"
  114. icon={<FullscreenOutlined />}
  115. onClick={() => setDivWidth(divMaxWidth)}
  116. />
  117. ) : (
  118. <Button
  119. type="link"
  120. icon={<FullscreenExitOutlined />}
  121. onClick={() => setDivWidth(divMinWidth)}
  122. />
  123. )}
  124. <Button
  125. type="text"
  126. size="small"
  127. icon={<CloseOutlined />}
  128. onClick={() => {
  129. store.dispatch(
  130. show({
  131. type: "discussion",
  132. resType: "sentence",
  133. })
  134. );
  135. if (typeof onClose !== "undefined") {
  136. onClose();
  137. }
  138. }}
  139. />
  140. </Space>
  141. ),
  142. }}
  143. items={[
  144. {
  145. label: intl.formatMessage({
  146. id: "columns.library.dict.title",
  147. }),
  148. key: "dict",
  149. children: (
  150. <div className="dict_component" style={tabInnerStyle}>
  151. <DictComponent />
  152. </div>
  153. ),
  154. },
  155. {
  156. label: intl.formatMessage({
  157. id: "columns.studio.channel.title",
  158. }),
  159. key: "channel",
  160. children: (
  161. <div style={tabInnerStyle}>
  162. <ChannelMy
  163. type={type}
  164. articleId={articleId}
  165. selectedKeys={selectedChannelsId}
  166. onSelect={(e: IChannel[]) => {
  167. console.log(e);
  168. if (typeof onChannelSelect !== "undefined") {
  169. onChannelSelect(e);
  170. }
  171. }}
  172. />
  173. </div>
  174. ),
  175. },
  176. {
  177. label: intl.formatMessage({
  178. id: "buttons.discussion",
  179. }),
  180. key: "discussion",
  181. children: (
  182. <div style={tabInnerStyle}>
  183. <DiscussionBox />
  184. </div>
  185. ),
  186. },
  187. {
  188. label: intl.formatMessage({
  189. id: "buttons.suggestion",
  190. }),
  191. key: "suggestion",
  192. children: (
  193. <div style={tabInnerStyle}>
  194. <SuggestionBox />
  195. </div>
  196. ),
  197. },
  198. {
  199. label: intl.formatMessage({
  200. id: "columns.library.palihandbook.title",
  201. }),
  202. key: "grammar",
  203. children: (
  204. <div style={tabInnerStyle}>
  205. <GrammarBook />
  206. </div>
  207. ),
  208. },
  209. ]}
  210. />
  211. </div>
  212. </Affix>
  213. );
  214. };
  215. export default RightPanelWidget;