TaskBuilderProp.tsx 5.6 KB

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