DeployCardRender.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. import React, {Component} from 'react';
  2. import {FormattedMessage} from 'react-intl';
  3. import {Input, Radio, Collapse, Button, Icon, Tooltip} from 'antd';
  4. import {idGen} from "../../../../../func";
  5. import {graphqlUrl, manageUsers} from "../../../../../config";
  6. import {
  7. ADD_DEPLOY,
  8. UPDATE_DEPLOY,
  9. UPDATE_PROJECT_DEPLOY_AND_CLOUD,
  10. UPDATE_PROJECT_ONLY_STATUS
  11. } from "../../../../../gql";
  12. import {request} from 'graphql-request'
  13. import {removePrefix, shiftPrefix} from "../../../../../func";
  14. const Panel = Collapse.Panel;
  15. // 如需改变显示,请在此处 value 处更改
  16. // 如需添加中文,请在此处 value 处添加
  17. // eg: 'xxxx': <F.. id='xxx'/>
  18. const valueToKey = {
  19. 'functionName': 'functionName',
  20. 'cosBucketName': 'cosBucketName',
  21. 'cosObjectName': 'cosObjectName',
  22. 'cosBucketRegion': 'cosBucketRegion',
  23. 'serviceName': 'serviceName',
  24. 'subnetId': 'subnetId',
  25. 'vpcId': 'vpcId',
  26. 'region': 'region',
  27. 'description': 'description',
  28. };
  29. const toolTipTitle = {
  30. 'functionName': 'its funcname',
  31. 'cosBucketName': 'its cosBucketName',
  32. 'cosObjectName': 'its cosObjectName',
  33. 'cosBucketRegion': 'its cosBucketRegion',
  34. 'serviceName': 'its serviceName',
  35. 'subnetId': 'its subnetId',
  36. 'vpcId': 'its vpcId',
  37. 'region': 'its region',
  38. 'description': 'its description',
  39. };
  40. const youMustFill = {
  41. 'functionName': true,
  42. 'cosBucketName': true,
  43. 'cosObjectName': true,
  44. 'cosBucketRegion': true,
  45. 'serviceName': true,
  46. 'subnetId': false,
  47. 'vpcId': false,
  48. 'region': true,
  49. 'description': false,
  50. };
  51. class DeployCardRender extends Component {
  52. constructor(props) {
  53. super(props);
  54. if(props.deploy !== '' && props.deploy !== null) {
  55. let {functionName, cosBucketName, cosObjectName, cosBucketRegion, serviceName, vpcId, subnetId, region, description} = props.deploy;
  56. this.state = {
  57. configs: ['description', 'vpcId', 'subnetId'],
  58. description,
  59. showOK: false,
  60. functionName,
  61. region,
  62. cosBucketName,
  63. cosObjectName,
  64. cosBucketRegion,
  65. serviceName,
  66. vpcId,
  67. subnetId
  68. }
  69. } else {
  70. this.state = {
  71. configs: ['description', 'vpcId', 'subnetId'],
  72. description: '',
  73. showOK: false,
  74. functionName: props.defalutName,
  75. region: props.region === '' ? 'ap-beijing' : props.region,
  76. cosBucketName: 'graphqlfc',
  77. cosObjectName: props.defalutName,
  78. cosBucketRegion: props.region === '' ? 'ap-beijing' : props.region,
  79. serviceName: '',
  80. vpcId: '',
  81. subnetId: '',
  82. };
  83. }
  84. }
  85. componentWillReceiveProps(next) {
  86. if (next.deploy !== '' && next.deploy !== null) {
  87. let {functionName, cosBucketName, cosObjectName, cosBucketRegion, serviceName, vpcId, subnetId, region, description} = next.deploy;
  88. this.setState({
  89. description,
  90. functionName,
  91. region: next.region === '' ? region : next.region,
  92. cosBucketName,
  93. cosObjectName,
  94. cosBucketRegion: next.region === '' ? cosBucketRegion : next.region,
  95. serviceName,
  96. vpcId,
  97. subnetId
  98. })
  99. } else {
  100. this.setState({
  101. functionName: next.defalutName,
  102. region: next.region === '' ? 'ap-beijing' : next.region,
  103. cosBucketName: 'graphqlfc',
  104. cosObjectName: next.defalutName,
  105. cosBucketRegion: next.region === '' ? 'ap-beijing' : next.region,
  106. serviceName: '',
  107. vpcId: '',
  108. subnetId: ''
  109. });
  110. }
  111. };
  112. switchConfig = (label) => {
  113. return (e) => {
  114. this.setState({
  115. [label]: e.target.value
  116. })
  117. };
  118. };
  119. ok = (id, userID, projectID, cloudID, deploy) => {
  120. let {description, cosBucketName, subnetId, cosObjectName, region, vpcId, cosBucketRegion, functionName} = this.state;
  121. region = shiftPrefix('ap-', region);
  122. cosBucketRegion = shiftPrefix('ap-', cosBucketRegion);
  123. let varObj = {
  124. id,
  125. cloud_id: cloudID,
  126. user_id: userID,
  127. description,
  128. cosBucketName,
  129. subnetId,
  130. cosObjectName,
  131. region,
  132. vpcId,
  133. cosBucketRegion,
  134. functionName,
  135. memorySize: 512,
  136. timeout: 300,
  137. handler: 'tencent_graphql.Bridge::handler',
  138. serviceName: "",
  139. fc_id: '',
  140. createdAt: new Date().getTime(),
  141. updatedAt: ''
  142. };
  143. if (deploy === '') {
  144. request(graphqlUrl, ADD_DEPLOY, varObj).then(
  145. data => {
  146. if (data.create_deploy !== null) {
  147. this.setState({
  148. showOK: true
  149. });
  150. // 写回 project
  151. request(graphqlUrl, UPDATE_PROJECT_DEPLOY_AND_CLOUD, {
  152. id: projectID,
  153. updatedAt: new Date().getTime(),
  154. deploy_id: id,
  155. cloud_id: cloudID,
  156. projectStatus: 'functioned'
  157. }).then(data => {
  158. if(data.update_project !== null)
  159. this.props.stepByStep(1);
  160. })
  161. }
  162. setTimeout(() => {
  163. this.setState({
  164. showOK: false
  165. })
  166. }, 1500)
  167. }
  168. )
  169. } else {
  170. let {description, cosBucketName, subnetId, cosObjectName, region, vpcId, cosBucketRegion, functionName} = this.state;
  171. region = shiftPrefix('ap-', region);
  172. cosBucketRegion = shiftPrefix('ap-', cosBucketRegion);
  173. let varObj = {
  174. id: deploy.id,
  175. description,
  176. subnetId,
  177. cosBucketName,
  178. cosObjectName,
  179. region,
  180. vpcId,
  181. cosBucketRegion,
  182. functionName,
  183. updatedAt: new Date().getTime()
  184. };
  185. request(graphqlUrl, UPDATE_DEPLOY, varObj).then(
  186. data => {
  187. if (data.update_deploy !== null) {
  188. this.setState({
  189. showOK: true
  190. });
  191. request(graphqlUrl, UPDATE_PROJECT_ONLY_STATUS, {
  192. id: projectID,
  193. updatedAt: new Date().getTime(),
  194. projectStatus: 'updated'
  195. }).then(data => {
  196. if(data.update_project !== null)
  197. this.props.stepByStep(1);
  198. })
  199. }
  200. setTimeout(() => {
  201. this.setState({
  202. showOK: false
  203. })
  204. }, 1500)
  205. }
  206. )
  207. }
  208. };
  209. render() {
  210. const customPanelStyle = {
  211. background: '#f7f7f7',
  212. borderRadius: 4,
  213. marginBottom: 24,
  214. border: 0,
  215. overflow: 'hidden',
  216. };
  217. const ioobotCloudID = ['tencent_CloudID', 'aliyun_CloudID'];
  218. const disable = {
  219. 'subnetId': ioobotCloudID.includes(this.props.cloudID) ? true : '',
  220. 'vpcId': ioobotCloudID.includes(this.props.cloudID) ? true : '',
  221. };
  222. return (
  223. <div>
  224. <div style={{marginBottom: 10}}>
  225. <span className='vice-title'>
  226. {
  227. youMustFill['functionName']?
  228. <span style={{color: 'red', display: 'inline', marginRight: 10}}>*</span>
  229. :
  230. ''
  231. }
  232. <FormattedMessage id={valueToKey['functionName']}/>
  233. &nbsp;
  234. <Tooltip placement="top" title={toolTipTitle['functionName']}>
  235. <Icon type="question-circle"/>
  236. </Tooltip>
  237. </span>
  238. <Input value={this.state.functionName} style={{width: 400}}
  239. onChange={this.switchConfig('functionName')}/>
  240. </div>
  241. <div style={{marginBottom: 10}}>
  242. <span className='vice-title'>
  243. {
  244. youMustFill['region']?
  245. <span style={{color: 'red', display: 'inline', marginRight: 10}}>*</span>
  246. :
  247. ''
  248. }
  249. <FormattedMessage id={valueToKey['region']}/>
  250. &nbsp;
  251. <Tooltip placement="top" title={toolTipTitle['region']}>
  252. <Icon type="question-circle"/>
  253. </Tooltip>
  254. </span>
  255. <Radio.Group onChange={(e) => {
  256. this.props.switchRegion(e);
  257. }} defaultValue={this.state.region} value={removePrefix('ap-', this.state.region)}
  258. buttonStyle="solid">
  259. <Radio.Button value="guangzhou"><FormattedMessage id="Guangzhou"/></Radio.Button>
  260. <Radio.Button value="shanghai"><FormattedMessage id="Shanghai"/></Radio.Button>
  261. <Radio.Button value="beijing"><FormattedMessage id="Beijing"/></Radio.Button>
  262. <Radio.Button value="chengdu"><FormattedMessage id="Chengdu"/></Radio.Button>
  263. </Radio.Group>
  264. </div>
  265. <div style={{marginBottom: 10}}>
  266. <span className='vice-title'>
  267. {
  268. youMustFill['cosBucketRegion']?
  269. <span style={{color: 'red', display: 'inline', marginRight: 10}}>*</span>
  270. :
  271. ''
  272. }
  273. <FormattedMessage id={valueToKey['cosBucketRegion']}/>
  274. &nbsp;
  275. <Tooltip placement="top" title={toolTipTitle['cosBucketRegion']}>
  276. <Icon type="question-circle"/>
  277. </Tooltip>
  278. </span>
  279. <Radio.Group onChange={(e) => {
  280. // 如果不想一变所有都变,就将 onchange 改成
  281. // onChange={this.switchConfig('cosBucketRegion')}
  282. this.props.switchRegion(e);
  283. }} defaultValue={this.state.region}
  284. value={removePrefix('ap-', this.state.cosBucketRegion)} buttonStyle="solid">
  285. <Radio.Button value="guangzhou"><FormattedMessage id="Guangzhou"/></Radio.Button>
  286. <Radio.Button value="shanghai"><FormattedMessage id="Shanghai"/></Radio.Button>
  287. <Radio.Button value="beijing"><FormattedMessage id="Beijing"/></Radio.Button>
  288. <Radio.Button value="chengdu"><FormattedMessage id="Chengdu"/></Radio.Button>
  289. </Radio.Group>
  290. </div>
  291. <div key={'cosBucketName'} style={{marginBottom: 10}}>
  292. <span className='vice-title'>
  293. {
  294. youMustFill['cosBucketName']?
  295. <span style={{color: 'red', display: 'inline', marginRight: 10}}>*</span>
  296. :
  297. ''
  298. }
  299. <FormattedMessage id={valueToKey['cosBucketName']}/>
  300. &nbsp;
  301. <Tooltip placement="top" title={toolTipTitle['cosBucketName']}>
  302. <Icon type="question-circle"/>
  303. </Tooltip>
  304. </span>
  305. <Input value={this.state.cosBucketName} style={{width: 200}}
  306. disabled={disable['cosBucketName'] === true}
  307. onChange={this.switchConfig('cosBucketName')}/>
  308. </div>
  309. <div key={'cosObjectName'} style={{marginBottom: 10}}>
  310. <span className='vice-title'>
  311. {
  312. youMustFill['cosObjectName']?
  313. <span style={{color: 'red', display: 'inline', marginRight: 10}}>*</span>
  314. :
  315. ''
  316. }
  317. <FormattedMessage id={valueToKey['cosObjectName']}/>
  318. &nbsp;
  319. <Tooltip placement="top" title={toolTipTitle['cosObjectName']}>
  320. <Icon type="question-circle"/>
  321. </Tooltip>
  322. </span>
  323. <Input value={this.state.cosBucketName} style={{width: 200}}
  324. disabled={disable['cosObjectName'] === true} addonAfter=".jar"
  325. onChange={this.switchConfig('cosObjectName')}/>
  326. </div>
  327. <Collapse bordered={false}>
  328. <Panel header={<FormattedMessage id="Want more options?"/>} style={customPanelStyle}>
  329. {/*腾讯云为空字符串,不显示,这里未作区分*/}
  330. {/*<div style={{marginBottom: 10}}>*/}
  331. {/*<span className='vice-title'>{valueToKey['serviceName']}*/}
  332. {/*<span> </span>*/}
  333. {/*<Tooltip placement="top" title={toolTipTitle['serviceName']}>*/}
  334. {/*<Icon type="question-circle"/>*/}
  335. {/*</Tooltip>*/}
  336. {/*</span>*/}
  337. {/*<Input value={this.state.serviceName} style={{width: 200}} disabled*/}
  338. {/*onChange={this.switchConfig('serviceName')}/>*/}
  339. {/*</div>*/}
  340. {
  341. this.state.configs.map(config => (
  342. <div key={config} style={{marginBottom: 10}}>
  343. <span className='vice-title'>
  344. {
  345. youMustFill[config]?
  346. <span style={{color: 'red', display: 'inline', marginRight: 10}}>*</span>
  347. :
  348. ''
  349. }
  350. <FormattedMessage id={valueToKey[config]}/>
  351. &nbsp;
  352. <Tooltip placement="top" title={toolTipTitle[config]}>
  353. <Icon type="question-circle"/>
  354. </Tooltip>
  355. </span>
  356. <Input value={this.state[config]} style={{width: 200}}
  357. disabled={disable[config] === true}
  358. onChange={this.switchConfig(config)}/>
  359. </div>
  360. ))
  361. }
  362. </Panel>
  363. </Collapse>
  364. <div>
  365. {
  366. manageUsers.includes(this.props.userID) ?
  367. <div>
  368. <Button onClick={() => {
  369. const id = idGen('deploy');
  370. this.ok(id, this.props.userID, this.props.projectID, this.props.cloudID, this.props.deploy);
  371. }} type='primary'><FormattedMessage id="save"/></Button>
  372. {
  373. this.state.showOK === true ?
  374. <Icon type="check-circle" theme="twoTone" twoToneColor="#52c41a"/>
  375. :
  376. ''
  377. }
  378. </div>
  379. :
  380. this.props.trialcase ?
  381. ''
  382. :
  383. <div>
  384. <Button onClick={() => {
  385. const id = idGen('deploy');
  386. this.ok(id, this.props.userID, this.props.projectID, this.props.cloudID, this.props.deploy);
  387. }} type='primary'><FormattedMessage id="save"/></Button>
  388. {
  389. this.state.showOK === true ?
  390. <Icon type="check-circle" theme="twoTone" twoToneColor="#52c41a"/>
  391. :
  392. ''
  393. }
  394. </div>
  395. }
  396. </div>
  397. </div>
  398. )
  399. }
  400. }
  401. export default DeployCardRender;