TaskStatusButton.tsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. import { DropdownButtonType } from "antd/lib/dropdown/dropdown-button";
  2. import {
  3. Dropdown,
  4. MenuProps,
  5. message,
  6. Popconfirm,
  7. PopconfirmProps,
  8. } from "antd";
  9. import { useIntl } from "react-intl";
  10. import {
  11. CheckOutlined,
  12. LoadingOutlined,
  13. DownOutlined,
  14. } from "@ant-design/icons";
  15. import {
  16. ITaskData,
  17. ITaskListResponse,
  18. ITaskUpdateRequest,
  19. TTaskStatus,
  20. } from "../api/task";
  21. import { patch } from "../../request";
  22. import TaskStatus from "./TaskStatus";
  23. import { useState } from "react";
  24. interface IStatusMenu {
  25. label: string;
  26. key: TTaskStatus;
  27. disabled?: boolean;
  28. }
  29. interface IWidget {
  30. type?: "button" | "tag";
  31. task?: ITaskData;
  32. buttonType?: DropdownButtonType;
  33. onChange?: (task: ITaskData[]) => void;
  34. }
  35. const TaskStatusButton = ({
  36. type = "button",
  37. task,
  38. buttonType = "primary",
  39. onChange,
  40. }: IWidget) => {
  41. const intl = useIntl();
  42. const [loading, setLoading] = useState(false);
  43. const setStatus = (setting: ITaskUpdateRequest) => {
  44. const url = `/v2/task-status/${setting.id}`;
  45. console.info("api request", url, setting);
  46. setLoading(true);
  47. patch<ITaskUpdateRequest, ITaskListResponse>(url, setting)
  48. .then((json) => {
  49. console.info("api response", json);
  50. if (json.ok) {
  51. message.success("Success");
  52. onChange && onChange(json.data.rows);
  53. } else {
  54. message.error(json.message);
  55. }
  56. })
  57. .finally(() => setLoading(false));
  58. };
  59. const handleMenuClick: MenuProps["onClick"] = (e) => {
  60. console.log("click", e);
  61. if (task?.id) {
  62. setStatus({
  63. id: task.id,
  64. status: e.key,
  65. studio_name: "",
  66. });
  67. }
  68. };
  69. const requested_restart_enable =
  70. task?.type === "instance" &&
  71. task.status === "running" &&
  72. task.pre_task &&
  73. task.pre_task?.length > 0;
  74. let menuEnable: TTaskStatus[] = [];
  75. switch (task?.status) {
  76. case "pending":
  77. menuEnable = ["published"];
  78. break;
  79. case "published":
  80. menuEnable = ["pending", "running"];
  81. break;
  82. case "running":
  83. menuEnable = [
  84. "done",
  85. requested_restart_enable ? "requested_restart" : "done",
  86. ];
  87. break;
  88. case "done":
  89. menuEnable = ["restarted"];
  90. break;
  91. case "restarted":
  92. menuEnable = ["done"];
  93. break;
  94. case "requested_restart":
  95. menuEnable = ["done"];
  96. break;
  97. }
  98. const items: IStatusMenu[] = [
  99. {
  100. key: "pending",
  101. label: intl.formatMessage({
  102. id: "buttons.task.status.change.to.pending",
  103. }),
  104. disabled: task?.type === "instance" && !menuEnable.includes("pending"),
  105. },
  106. {
  107. key: "published",
  108. label: intl.formatMessage({
  109. id: "buttons.task.status.change.to.published",
  110. }),
  111. disabled: task?.type === "instance" && !menuEnable.includes("published"),
  112. },
  113. {
  114. key: "running",
  115. label: intl.formatMessage({
  116. id: `buttons.task.status.change.to.running`,
  117. }),
  118. disabled: task?.type === "instance" && !menuEnable.includes("running"),
  119. },
  120. {
  121. key: "done",
  122. label: intl.formatMessage({
  123. id: `buttons.task.status.change.to.done`,
  124. }),
  125. disabled: task?.type === "instance" && !menuEnable.includes("done"),
  126. },
  127. {
  128. key: "restarted",
  129. label: intl.formatMessage({
  130. id: `buttons.task.status.change.to.restarted`,
  131. }),
  132. disabled: task?.type === "instance" && !menuEnable.includes("restarted"),
  133. },
  134. {
  135. key: "requested_restart",
  136. label: intl.formatMessage({
  137. id: `buttons.task.status.change.to.requested_restart`,
  138. }),
  139. disabled:
  140. task?.type === "instance" && !menuEnable.includes("requested_restart"),
  141. },
  142. ];
  143. const menuProps = {
  144. items: items,
  145. onClick: handleMenuClick,
  146. };
  147. const confirm: PopconfirmProps["onConfirm"] = (e) => {
  148. console.log(e);
  149. if (task?.id) {
  150. setStatus({
  151. id: task.id,
  152. status: newStatus,
  153. studio_name: "",
  154. });
  155. }
  156. };
  157. let newStatus: TTaskStatus = "pending";
  158. switch (task?.status) {
  159. case "pending":
  160. newStatus = "published";
  161. break;
  162. case "published":
  163. newStatus = "running";
  164. break;
  165. case "running":
  166. newStatus = "done";
  167. break;
  168. case "done":
  169. newStatus = "restarted";
  170. break;
  171. case "restarted":
  172. newStatus = "done";
  173. break;
  174. case "requested_restart":
  175. newStatus = "done";
  176. break;
  177. default:
  178. break;
  179. }
  180. let buttonText = intl.formatMessage({
  181. id: `buttons.task.status.change.to.${newStatus}`,
  182. defaultMessage: "unknown",
  183. });
  184. return type === "button" ? (
  185. <Popconfirm
  186. title={intl.formatMessage(
  187. { id: "message.task.status.change" },
  188. { status: newStatus }
  189. )}
  190. onConfirm={confirm}
  191. okText="Yes"
  192. cancelText="No"
  193. >
  194. <Dropdown.Button
  195. disabled={task?.type === "workflow"}
  196. type={buttonType}
  197. trigger={["click"]}
  198. icon={<DownOutlined />}
  199. menu={menuProps}
  200. >
  201. {loading ? (
  202. <LoadingOutlined />
  203. ) : newStatus === "done" ? (
  204. <CheckOutlined />
  205. ) : (
  206. <></>
  207. )}
  208. {buttonText}
  209. </Dropdown.Button>
  210. </Popconfirm>
  211. ) : (
  212. <Dropdown placement="bottomLeft" menu={menuProps}>
  213. <span>{loading ? <LoadingOutlined /> : <TaskStatus task={task} />}</span>
  214. </Dropdown>
  215. );
  216. };
  217. export default TaskStatusButton;