Article.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import { Card, Collapse, Modal, Space } from "antd";
  2. import { Typography } from "antd";
  3. import { useState } from "react";
  4. import Article, { ArticleType } from "../article/Article";
  5. import { Link } from "react-router-dom";
  6. import { fullUrl } from "../../utils";
  7. import { useIntl } from "react-intl";
  8. const { Text } = Typography;
  9. export type TDisplayStyle =
  10. | "modal"
  11. | "card"
  12. | "toggle"
  13. | "link"
  14. | "window"
  15. | "popover";
  16. interface IWidgetChapterCtl {
  17. type?: ArticleType;
  18. id?: string;
  19. anthology?: string;
  20. book?: string;
  21. paragraphs?: string;
  22. channel?: string;
  23. parentChannels?: string[];
  24. title?: React.ReactNode;
  25. focus?: string | null;
  26. style?: TDisplayStyle;
  27. modalExtra?: React.ReactNode;
  28. }
  29. export const ArticleCtl = ({
  30. type,
  31. id,
  32. anthology,
  33. channel,
  34. parentChannels,
  35. title,
  36. focus,
  37. book,
  38. paragraphs,
  39. style = "modal",
  40. modalExtra,
  41. }: IWidgetChapterCtl) => {
  42. const intl = useIntl();
  43. const [isModalOpen, setIsModalOpen] = useState(false);
  44. const showModal = () => {
  45. setIsModalOpen(true);
  46. };
  47. const handleOk = () => {
  48. setIsModalOpen(false);
  49. };
  50. const handleCancel = () => {
  51. setIsModalOpen(false);
  52. };
  53. const aTitle = title ? title : "chapter" + id;
  54. console.log("anthology", anthology, channel);
  55. const article = (
  56. <Article
  57. active={true}
  58. type={type}
  59. articleId={id}
  60. anthologyId={anthology}
  61. book={book}
  62. para={paragraphs}
  63. channelId={channel}
  64. parentChannels={parentChannels}
  65. focus={focus}
  66. mode="read"
  67. hideInteractive={true}
  68. hideTitle={true}
  69. isSubWindow
  70. />
  71. );
  72. let output = <></>;
  73. let articleLink = `/article/${type}/${id}?mode=read`;
  74. articleLink += channel ? `&channel=${channel}` : "";
  75. switch (style) {
  76. case "modal":
  77. output = (
  78. <>
  79. <Typography.Link
  80. onClick={(event: React.MouseEvent<HTMLElement, MouseEvent>) => {
  81. if (event.ctrlKey || event.metaKey) {
  82. let link = `/article/${type}/${id}?mode=read`;
  83. link += channel ? `&channel=${channel}` : "";
  84. window.open(fullUrl(link), "_blank");
  85. } else {
  86. showModal();
  87. }
  88. }}
  89. >
  90. {aTitle}
  91. </Typography.Link>
  92. <Modal
  93. width={"80%"}
  94. style={{ maxWidth: 1000, top: 20 }}
  95. title={
  96. <div
  97. style={{
  98. display: "flex",
  99. justifyContent: "space-between",
  100. marginRight: 30,
  101. }}
  102. >
  103. <Text>{aTitle}</Text>
  104. <Space>
  105. <Link to={articleLink} target="_blank">
  106. {intl.formatMessage({
  107. id: "buttons.open.in.new.tab",
  108. })}
  109. </Link>
  110. {modalExtra}
  111. </Space>
  112. </div>
  113. }
  114. open={isModalOpen}
  115. onOk={handleOk}
  116. onCancel={handleCancel}
  117. footer={[]}
  118. >
  119. {article}
  120. </Modal>
  121. </>
  122. );
  123. break;
  124. case "card":
  125. output = <Card title={aTitle}>{article}</Card>;
  126. break;
  127. case "toggle":
  128. output = (
  129. <Collapse bordered={false}>
  130. <Collapse.Panel header={`${aTitle}`} key="parent2">
  131. {article}
  132. </Collapse.Panel>
  133. </Collapse>
  134. );
  135. break;
  136. case "link":
  137. let link = `/article/${type}/${id}?mode=read`;
  138. link += channel ? `&channel=${channel}` : "";
  139. output = (
  140. <Link to={link} target="_blank">
  141. {aTitle}
  142. </Link>
  143. );
  144. break;
  145. default:
  146. break;
  147. }
  148. return output;
  149. };
  150. interface IWidget {
  151. props: string;
  152. children?: React.ReactNode;
  153. }
  154. const ArticleWidget = ({ props, children }: IWidget) => {
  155. const prop = JSON.parse(atob(props)) as IWidgetChapterCtl;
  156. return <ArticleCtl {...prop} />;
  157. };
  158. export default ArticleWidget;