SettingItem.tsx 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. import { useIntl } from "react-intl";
  2. import { useEffect, useState } from "react";
  3. import {
  4. Switch,
  5. Typography,
  6. Radio,
  7. RadioChangeEvent,
  8. Select,
  9. Transfer,
  10. } from "antd";
  11. import {
  12. onChange as onSettingChanged,
  13. settingInfo,
  14. ISettingItem,
  15. } from "../../../reducers/setting";
  16. import { useAppSelector } from "../../../hooks";
  17. import store from "../../../store";
  18. import { ISetting } from "./default";
  19. import { TransferDirection } from "antd/lib/transfer";
  20. const { Text } = Typography;
  21. interface IWidgetSettingItem {
  22. data?: ISetting;
  23. autoSave?: boolean;
  24. onChange?: Function;
  25. }
  26. const SettingItemWidget = ({
  27. data,
  28. onChange,
  29. autoSave = true,
  30. }: IWidgetSettingItem) => {
  31. const intl = useIntl();
  32. const settings: ISettingItem[] | undefined = useAppSelector(settingInfo);
  33. const [value, setValue] = useState(data?.defaultValue);
  34. const [targetKeys, setTargetKeys] = useState<string[]>([]);
  35. useEffect(() => {
  36. if (typeof data?.defaultValue === "object") {
  37. setTargetKeys(data.defaultValue);
  38. }
  39. }, [data?.defaultValue]);
  40. useEffect(() => {
  41. setValue(data?.defaultValue);
  42. }, [data?.defaultValue]);
  43. useEffect(() => {
  44. const currSetting = settings?.find((element) => element.key === data?.key);
  45. if (typeof currSetting !== "undefined") {
  46. setValue(currSetting.value);
  47. }
  48. }, [data?.key, settings]);
  49. let content: JSX.Element = <></>;
  50. if (typeof data === "undefined") {
  51. return content;
  52. } else {
  53. const description: string | undefined = data.description
  54. ? intl.formatMessage({ id: data.description })
  55. : undefined;
  56. switch (typeof data.defaultValue) {
  57. case "number":
  58. break;
  59. case "object":
  60. switch (data.widget) {
  61. case "transfer":
  62. if (typeof data.options !== "undefined") {
  63. content = (
  64. <Transfer
  65. dataSource={data.options.map((item) => {
  66. return {
  67. key: item.value,
  68. title: intl.formatMessage({ id: item.label }),
  69. };
  70. })}
  71. titles={["备选", "我的选择"]}
  72. targetKeys={targetKeys}
  73. onChange={(
  74. newTargetKeys: string[],
  75. direction: TransferDirection,
  76. moveKeys: string[]
  77. ) => {
  78. setTargetKeys(newTargetKeys);
  79. store.dispatch(
  80. onSettingChanged({
  81. key: data.key,
  82. value: newTargetKeys,
  83. })
  84. );
  85. if (typeof onChange !== "undefined") {
  86. onChange(data.key, newTargetKeys);
  87. }
  88. }}
  89. render={(item) => item.title}
  90. oneWay
  91. />
  92. );
  93. }
  94. break;
  95. }
  96. break;
  97. case "string":
  98. switch (data.widget) {
  99. case "radio-button":
  100. if (typeof data.options !== "undefined") {
  101. content = (
  102. <>
  103. <Radio.Group
  104. value={value}
  105. buttonStyle="solid"
  106. onChange={(e: RadioChangeEvent) => {
  107. setValue(e.target.value);
  108. if (autoSave) {
  109. store.dispatch(
  110. onSettingChanged({
  111. key: data.key,
  112. value: e.target.value,
  113. })
  114. );
  115. }
  116. if (typeof onChange !== "undefined") {
  117. onChange(data.key, e.target.value);
  118. }
  119. }}
  120. >
  121. {data.options.map((item, id) => {
  122. return (
  123. <Radio.Button key={id} value={item.value}>
  124. {intl.formatMessage({ id: item.label })}
  125. </Radio.Button>
  126. );
  127. })}
  128. </Radio.Group>
  129. </>
  130. );
  131. }
  132. break;
  133. default:
  134. if (typeof data.options !== "undefined") {
  135. content = (
  136. <div>
  137. <Select
  138. defaultValue={data.defaultValue}
  139. style={{ width: 120 }}
  140. onChange={(value: string) => {
  141. console.log(`selected ${value}`);
  142. if (autoSave) {
  143. store.dispatch(
  144. onSettingChanged({
  145. key: data.key,
  146. value: value,
  147. })
  148. );
  149. }
  150. if (typeof onChange !== "undefined") {
  151. onChange(data.key, value);
  152. }
  153. }}
  154. options={data.options.map((item) => {
  155. return {
  156. value: item.value,
  157. label: intl.formatMessage({ id: item.label }),
  158. };
  159. })}
  160. />
  161. </div>
  162. );
  163. } else {
  164. }
  165. break;
  166. }
  167. break;
  168. case "boolean":
  169. content = (
  170. <div>
  171. <Switch
  172. defaultChecked={value as boolean}
  173. onChange={(checked) => {
  174. console.log("setting changed", data.key, checked);
  175. if (autoSave) {
  176. store.dispatch(
  177. onSettingChanged({ key: data.key, value: checked })
  178. );
  179. }
  180. if (typeof onChange !== "undefined") {
  181. onChange(data.key, checked);
  182. }
  183. }}
  184. />
  185. </div>
  186. );
  187. break;
  188. default:
  189. break;
  190. }
  191. return (
  192. <div style={{ marginBottom: 10 }}>
  193. <div style={{ display: "flex", justifyContent: "space-between" }}>
  194. <Text>{intl.formatMessage({ id: data.label })}</Text>
  195. {content}
  196. </div>
  197. <Text type="secondary">{description}</Text>
  198. </div>
  199. );
  200. }
  201. };
  202. export default SettingItemWidget;