TaskBuilderProp.tsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. import { Divider, Input, InputNumber } from "antd";
  2. import { ITaskData } from "../api/task";
  3. import "../article/article.css";
  4. import { useEffect, useState } from "react";
  5. import ChannelSelectWithToken from "../channel/ChannelSelectWithToken";
  6. type TParamType =
  7. | "number"
  8. | "string"
  9. | "channel:translation"
  10. | "channel:nissaya";
  11. export interface IParam {
  12. key: string;
  13. label: string;
  14. value: string;
  15. type: TParamType;
  16. initValue: number;
  17. step: number;
  18. }
  19. export interface IProp {
  20. taskTitle: string;
  21. taskId: string;
  22. param?: IParam[];
  23. }
  24. interface IWidget {
  25. workflow?: ITaskData[];
  26. channelsId?: string[];
  27. onChange?: (data: IProp[] | undefined) => void;
  28. }
  29. const TaskBuilderProp = ({ workflow, channelsId, onChange }: IWidget) => {
  30. //console.debug("TaskBuilderProp render");
  31. const [prop, setProp] = useState<IProp[]>();
  32. useEffect(() => {
  33. const newProp = workflow?.map((item) => {
  34. const num = item.description
  35. ?.replaceAll("}}", "|}}")
  36. .split("|")
  37. .filter((value) => value.includes("=?"))
  38. .map((item) => {
  39. const [k, v] = item.split("=");
  40. const value: IParam = {
  41. key: k,
  42. label: k,
  43. value: v,
  44. type: "number",
  45. initValue: 1,
  46. step: v === "?++" ? 1 : v === "?+" ? 0 : -1,
  47. };
  48. return value;
  49. });
  50. const constant = item.description
  51. ?.replaceAll("}}", "|}}")
  52. .split("|")
  53. .filter((value) => value.includes("=%"))
  54. .map((item) => {
  55. const [k, v] = item.split("=");
  56. const paramKey = v.split("@");
  57. const value: IParam = {
  58. key: v,
  59. label: paramKey[0],
  60. value: "",
  61. type:
  62. paramKey.length > 1 && paramKey[1]
  63. ? (paramKey[1] as TParamType)
  64. : "string",
  65. initValue: 0,
  66. step: 0,
  67. };
  68. return value;
  69. });
  70. let output: IParam[] = [];
  71. if (num) {
  72. output = [...output, ...num];
  73. }
  74. if (constant) {
  75. output = [...output, ...constant];
  76. }
  77. return {
  78. taskTitle: item.title,
  79. taskId: item.id,
  80. param: output,
  81. };
  82. });
  83. setProp(newProp);
  84. }, [workflow]);
  85. const change = (
  86. tIndex: number,
  87. pIndex: number,
  88. value: string,
  89. initValue: number,
  90. step: number
  91. ) => {
  92. const newData = prop?.map((item, tId) => {
  93. return {
  94. taskTitle: item.taskTitle,
  95. taskId: item.taskId,
  96. param: item.param?.map((param, pId) => {
  97. if (tIndex === tId && pIndex === pId) {
  98. return { ...param, value: value, initValue: initValue, step: step };
  99. } else {
  100. return param;
  101. }
  102. }),
  103. };
  104. });
  105. setProp(newData);
  106. console.debug("newData", newData);
  107. onChange && onChange(newData);
  108. };
  109. const Value = (item: IParam, taskId: number, paramId: number) => {
  110. let channelType: string | undefined;
  111. if (item.key.includes("@channel")) {
  112. const [_, channel] = item.key.split("@");
  113. if (channel.includes(":")) {
  114. channelType = channel.split(":")[1].replaceAll("%", "");
  115. }
  116. }
  117. return item.type === "number" ? (
  118. <InputNumber
  119. defaultValue={item.initValue}
  120. value={item.initValue}
  121. onChange={(e) => {
  122. if (e) {
  123. change(taskId, paramId, item.value, e, item.step);
  124. }
  125. }}
  126. />
  127. ) : item.type === "string" ? (
  128. <Input
  129. defaultValue={item.value}
  130. value={item.value}
  131. onChange={(e) => {
  132. if (e) {
  133. change(taskId, paramId, e.target.value, item.initValue, item.step);
  134. }
  135. }}
  136. />
  137. ) : (
  138. <ChannelSelectWithToken
  139. channelsId={channelsId}
  140. type={channelType}
  141. onChange={(e) => {
  142. console.debug("channel select onChange", e);
  143. change(taskId, paramId, e ?? "", item.initValue, item.step);
  144. }}
  145. />
  146. );
  147. };
  148. const Step = (item: IParam, taskId: number, paramId: number) => {
  149. return item.type === "string" ? (
  150. <>{"无"}</>
  151. ) : item.value === "?" ? (
  152. <>{"无"}</>
  153. ) : (
  154. <InputNumber
  155. defaultValue={item.step}
  156. readOnly={item.value === "?++"}
  157. onChange={(e) => {
  158. if (e) {
  159. change(taskId, paramId, item.value, item.initValue, e);
  160. }
  161. }}
  162. />
  163. );
  164. };
  165. return (
  166. <>
  167. {prop?.map((item, taskId) => {
  168. return (
  169. <div key={taskId}>
  170. <Divider>{item.taskTitle}</Divider>
  171. <table>
  172. <thead>
  173. <tr>
  174. <td>变量名</td>
  175. <td>值</td>
  176. <td>递增步长</td>
  177. </tr>
  178. </thead>
  179. <tbody>
  180. {item.param?.map((item, paramId) => {
  181. return (
  182. <tr key={paramId}>
  183. <td key={1}>{item.label}</td>
  184. <td key={2}>{Value(item, taskId, paramId)}</td>
  185. <td key={3}>{Step(item, taskId, paramId)}</td>
  186. </tr>
  187. );
  188. })}
  189. </tbody>
  190. </table>
  191. </div>
  192. );
  193. })}
  194. </>
  195. );
  196. };
  197. export default TaskBuilderProp;