WebhookList.tsx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. import { type ActionType, ProTable } from "@ant-design/pro-components";
  2. import { useIntl } from "react-intl";
  3. import { Link, useNavigate } from "react-router";
  4. import { message, Modal, Space, Typography } from "antd";
  5. import { Button, Dropdown } from "antd";
  6. import {
  7. PlusOutlined,
  8. ExclamationCircleOutlined,
  9. DeleteOutlined,
  10. StopOutlined,
  11. CheckCircleOutlined,
  12. WarningOutlined,
  13. } from "@ant-design/icons";
  14. import { delete_, get } from "../../request";
  15. import type { IDeleteResponse } from "../../api/Article";
  16. import { useRef } from "react";
  17. import type { IWebhookApiData, IWebhookListResponse } from "../../api/webhook";
  18. const { Text } = Typography;
  19. interface IWidget {
  20. channelId?: string;
  21. studioName?: string;
  22. }
  23. const WebhookListWidget = ({ channelId, studioName }: IWidget) => {
  24. const intl = useIntl();
  25. const navigate = useNavigate();
  26. const showDeleteConfirm = (id: string, title: string) => {
  27. Modal.confirm({
  28. icon: <ExclamationCircleOutlined />,
  29. title:
  30. intl.formatMessage({
  31. id: "message.delete.confirm",
  32. }) +
  33. intl.formatMessage({
  34. id: "message.irrevocable",
  35. }),
  36. content: title,
  37. okText: intl.formatMessage({
  38. id: "buttons.delete",
  39. }),
  40. okType: "danger",
  41. cancelText: intl.formatMessage({
  42. id: "buttons.no",
  43. }),
  44. onOk() {
  45. console.log("delete", id);
  46. return delete_<IDeleteResponse>(`/v2/webhook/${id}`)
  47. .then((json) => {
  48. if (json.ok) {
  49. message.success("删除成功");
  50. ref.current?.reload();
  51. } else {
  52. message.error(json.message);
  53. }
  54. })
  55. .catch((e) => console.log("Oops errors!", e));
  56. },
  57. });
  58. };
  59. const ref = useRef<ActionType | null>(null);
  60. return (
  61. <>
  62. <ProTable<IWebhookApiData>
  63. actionRef={ref}
  64. columns={[
  65. {
  66. title: intl.formatMessage({
  67. id: "forms.fields.url.label",
  68. }),
  69. dataIndex: "url",
  70. key: "url",
  71. tooltip: "过长会自动收缩",
  72. ellipsis: true,
  73. render: (_text, row, _index, _action) => {
  74. const url = row.url.split("?")[0];
  75. return (
  76. <Space>
  77. {row.status === "disable" ? (
  78. <StopOutlined style={{ color: "red" }} />
  79. ) : (
  80. <CheckCircleOutlined style={{ color: "green" }} />
  81. )}
  82. {url}
  83. <Text type="secondary" italic>
  84. <Space>{row.event}</Space>
  85. </Text>
  86. </Space>
  87. );
  88. },
  89. },
  90. {
  91. title: intl.formatMessage({
  92. id: "forms.fields.receiver.label",
  93. }),
  94. dataIndex: "receiver",
  95. key: "receiver",
  96. width: 100,
  97. search: false,
  98. },
  99. {
  100. title: intl.formatMessage({
  101. id: "forms.fields.fail.label",
  102. }),
  103. dataIndex: "fail",
  104. key: "fail",
  105. width: 100,
  106. search: false,
  107. render: (_text, row, _index, _action) => {
  108. return (
  109. <Space>
  110. {row.fail > 0 ? (
  111. <WarningOutlined style={{ color: "orange" }} />
  112. ) : undefined}
  113. {row.fail}
  114. </Space>
  115. );
  116. },
  117. },
  118. {
  119. title: intl.formatMessage({
  120. id: "forms.fields.success.label",
  121. }),
  122. dataIndex: "success",
  123. key: "success",
  124. width: 100,
  125. search: false,
  126. },
  127. {
  128. title: intl.formatMessage({
  129. id: "forms.fields.status.label",
  130. }),
  131. dataIndex: "status",
  132. key: "status",
  133. width: 100,
  134. search: false,
  135. },
  136. {
  137. title: intl.formatMessage({ id: "buttons.option" }),
  138. key: "option",
  139. width: 120,
  140. valueType: "option",
  141. render: (_text, row, index, _action) => {
  142. return [
  143. <Dropdown.Button
  144. key={index}
  145. type="link"
  146. trigger={["click", "contextMenu"]}
  147. menu={{
  148. items: [
  149. {
  150. key: "remove",
  151. label: intl.formatMessage({
  152. id: "buttons.delete",
  153. }),
  154. icon: <DeleteOutlined />,
  155. danger: true,
  156. },
  157. ],
  158. onClick: (e) => {
  159. switch (e.key) {
  160. case "remove":
  161. showDeleteConfirm(row.id, row.url);
  162. break;
  163. default:
  164. break;
  165. }
  166. },
  167. }}
  168. >
  169. <Link
  170. to={`/studio/${studioName}/channel/${channelId}/setting/webhooks/${row.id}`}
  171. >
  172. {intl.formatMessage({
  173. id: "buttons.edit",
  174. })}
  175. </Link>
  176. </Dropdown.Button>,
  177. ];
  178. },
  179. },
  180. ]}
  181. request={async (params = {}, sorter, filter) => {
  182. console.log(params, sorter, filter);
  183. let url = `/v2/webhook?view=channel&id=${channelId}`;
  184. const offset =
  185. ((params.current ? params.current : 1) - 1) *
  186. (params.pageSize ? params.pageSize : 20);
  187. url += `&limit=${params.pageSize}&offset=${offset}`;
  188. url += params.keyword ? "&search=" + params.keyword : "";
  189. console.log("url", url);
  190. const res: IWebhookListResponse = await get(url);
  191. return {
  192. total: res.data.count,
  193. succcess: true,
  194. data: res.data.rows,
  195. };
  196. }}
  197. rowKey="id"
  198. bordered
  199. pagination={{
  200. showQuickJumper: true,
  201. showSizeChanger: true,
  202. }}
  203. search={false}
  204. options={{
  205. search: true,
  206. }}
  207. toolBarRender={() => [
  208. <Button
  209. key="button"
  210. icon={<PlusOutlined />}
  211. type="primary"
  212. onClick={() =>
  213. navigate(
  214. `/studio/${studioName}/channel/${channelId}/setting/webhooks/new`
  215. )
  216. }
  217. >
  218. {intl.formatMessage({ id: "buttons.create" })}
  219. </Button>,
  220. ]}
  221. />
  222. </>
  223. );
  224. };
  225. export default WebhookListWidget;