form-dialog.tsx 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /* eslint-disable react-hooks/exhaustive-deps */
  2. import { addOmcDB, apiInterceptors, getSupportDBList, postDbAdd, postDbEdit, postDbTestConnect } from '@/client/api';
  3. import { isFileDb } from '@/pages/construct/database';
  4. import { DBOption, DBType, DbListResponse, PostDbParams } from '@/types/db';
  5. import { useDebounceFn } from 'ahooks';
  6. import { Button, Form, Input, InputNumber, Modal, Select, Spin, Tooltip, message } from 'antd';
  7. import { useEffect, useMemo, useState } from 'react';
  8. import { useTranslation } from 'react-i18next';
  9. type DBItem = DbListResponse[0] & { db_arn?: string };
  10. interface Props {
  11. dbTypeList: DBOption[];
  12. open: boolean;
  13. choiceDBType?: DBType;
  14. editValue?: DBItem;
  15. dbNames: string[];
  16. onSuccess?: () => void;
  17. onClose?: () => void;
  18. }
  19. function FormDialog({ open, choiceDBType, dbTypeList, editValue, dbNames, onClose, onSuccess }: Props) {
  20. const [loading, setLoading] = useState(false);
  21. const { t } = useTranslation();
  22. const [form] = Form.useForm<DBItem>();
  23. const dbType = Form.useWatch('db_type', form);
  24. const [omcDBList, setOmcDBList] = useState([]);
  25. const [omcListLoading, setOmcListLoading] = useState(false);
  26. const fileDb = useMemo(() => isFileDb(dbTypeList, dbType), [dbTypeList, dbType]);
  27. useEffect(() => {
  28. if (choiceDBType) {
  29. form.setFieldValue('db_type', choiceDBType);
  30. }
  31. }, [choiceDBType]);
  32. useEffect(() => {
  33. if (editValue) {
  34. form.setFieldsValue({ ...editValue });
  35. if (editValue.db_type === 'omc') {
  36. form.setFieldValue('db_arn', editValue.db_path);
  37. }
  38. }
  39. }, [editValue]);
  40. useEffect(() => {
  41. if (!open) {
  42. form.resetFields();
  43. }
  44. }, [open]);
  45. const onFinish = async (val: DBItem) => {
  46. const { db_host, db_path, db_port, db_type, ...params } = val;
  47. setLoading(true);
  48. if (db_type === 'omc') {
  49. const item = omcDBList?.find((item: any) => item.arn === val.db_name) as any;
  50. try {
  51. const [err] = await apiInterceptors(
  52. addOmcDB({
  53. db_type: 'omc',
  54. file_path: val.db_arn || '',
  55. comment: val.comment,
  56. db_name: item?.dbName || val.db_name,
  57. }),
  58. );
  59. if (err) {
  60. message.error(err.message);
  61. return;
  62. }
  63. message.success('success');
  64. onSuccess?.();
  65. } catch (e: any) {
  66. message.error(e.message);
  67. } finally {
  68. setLoading(false);
  69. }
  70. }
  71. if (!editValue && dbNames.some(item => item === params.db_name)) {
  72. message.error('The database already exists!');
  73. return;
  74. }
  75. const data: PostDbParams = {
  76. db_host: fileDb ? undefined : db_host,
  77. db_port: fileDb ? undefined : db_port,
  78. db_type: db_type,
  79. file_path: fileDb ? db_path : undefined,
  80. ...params,
  81. };
  82. try {
  83. const [testErr] = await apiInterceptors(postDbTestConnect(data));
  84. if (testErr) return;
  85. const [err] = await apiInterceptors((editValue ? postDbEdit : postDbAdd)(data));
  86. if (err) {
  87. message.error(err.message);
  88. return;
  89. }
  90. message.success('success');
  91. onSuccess?.();
  92. } catch (e: any) {
  93. message.error(e.message);
  94. } finally {
  95. setLoading(false);
  96. }
  97. };
  98. const { run: fetchOmcList } = useDebounceFn(
  99. async (name: string) => {
  100. setOmcListLoading(true);
  101. const [_, data = []] = (await apiInterceptors(getSupportDBList(name))) as any;
  102. setOmcListLoading(false);
  103. setOmcDBList(data.map((item: any) => ({ ...item, label: item.dbName, value: item.arn })));
  104. },
  105. {
  106. wait: 500,
  107. },
  108. );
  109. const lockDBType = useMemo(() => !!editValue || !!choiceDBType, [editValue, choiceDBType]);
  110. return (
  111. <Modal
  112. open={open}
  113. width={800}
  114. title={editValue ? t('Edit') : t('create_database')}
  115. maskClosable={false}
  116. footer={null}
  117. onCancel={onClose}
  118. >
  119. <Form form={form} className='pt-2' labelCol={{ span: 6 }} labelAlign='left' onFinish={onFinish}>
  120. <Form.Item name='db_type' label='DB Type' className='mb-6' rules={[{ required: true }]}>
  121. <Select aria-readonly={lockDBType} disabled={lockDBType} options={dbTypeList} />
  122. </Form.Item>
  123. {form.getFieldValue('db_type') === 'omc' ? (
  124. <Form.Item name='db_name' label='DB Name' className='mb-6' rules={[{ required: true }]}>
  125. <Select
  126. optionRender={(option, { index }) => {
  127. const item = omcDBList[index] as any;
  128. return (
  129. <div key={option.value} className='flex flex-col'>
  130. <span className='text-[18px]'>{item?.dbName}</span>
  131. <span>
  132. <span>env: </span>
  133. <span className='text-gray-500'>{item.env}</span>
  134. </span>
  135. <span>
  136. <span>account: </span>
  137. <span className='text-gray-500'>{item.account}</span>
  138. </span>
  139. <span>
  140. <span>searchName: </span>
  141. <Tooltip title={item.searchName}>
  142. <span className='text-gray-500'>{item.searchName}</span>
  143. </Tooltip>
  144. </span>
  145. </div>
  146. );
  147. }}
  148. notFoundContent={omcListLoading ? <Spin size='small' /> : null}
  149. showSearch
  150. options={omcDBList}
  151. onSearch={fetchOmcList}
  152. onSelect={searchName => {
  153. const item = omcDBList?.find((item: any) => item.value === searchName) as any;
  154. form.setFieldsValue({
  155. db_arn: item?.arn,
  156. });
  157. }}
  158. />
  159. </Form.Item>
  160. ) : (
  161. <Form.Item name='db_name' label='DB Name' className='mb-3' rules={[{ required: true }]}>
  162. <Input readOnly={!!editValue} disabled={!!editValue} />
  163. </Form.Item>
  164. )}
  165. {fileDb === true && (
  166. <Form.Item name='db_path' label='Path' className='mb-6' rules={[{ required: true }]}>
  167. <Input />
  168. </Form.Item>
  169. )}
  170. {fileDb === false && form.getFieldValue('db_type') !== 'omc' && (
  171. <>
  172. <Form.Item name='db_user' label='Username' className='mb-6' rules={[{ required: true }]}>
  173. <Input />
  174. </Form.Item>
  175. <Form.Item name='db_pwd' label='Password' className='mb-6' rules={[{ required: false }]}>
  176. <Input type='password' />
  177. </Form.Item>
  178. <Form.Item name='db_host' label='Host' className='mb-6' rules={[{ required: true }]}>
  179. <Input />
  180. </Form.Item>
  181. <Form.Item name='db_port' label='Port' className='mb-6' rules={[{ required: true }]}>
  182. <InputNumber min={1} step={1} max={65535} />
  183. </Form.Item>
  184. </>
  185. )}
  186. {form.getFieldValue('db_type') === 'omc' && (
  187. <Form.Item name='db_arn' label='Arn' className='mb-6' rules={[{ required: true }]}>
  188. <Input />
  189. </Form.Item>
  190. )}
  191. <Form.Item name='comment' label='Remark' className='mb-6'>
  192. <Input />
  193. </Form.Item>
  194. <Form.Item className='flex flex-row-reverse pt-1 mb-0'>
  195. <Button htmlType='submit' type='primary' size='middle' className='mr-1' loading={loading}>
  196. Save
  197. </Button>
  198. <Button size='middle' onClick={onClose}>
  199. Cancel
  200. </Button>
  201. </Form.Item>
  202. </Form>
  203. </Modal>
  204. );
  205. }
  206. export default FormDialog;