Table.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. import React, {Component} from 'react';
  2. import {Layout, Select, Input, Icon, Button, notification, Spin, Modal} from 'antd';
  3. import {UPDATE_SCHEMA, SHOW_SCHEMA, SHOW_TABLE} from "../../gql";
  4. import gql from "graphql-tag";
  5. import {Mutation, Query} from "react-apollo";
  6. import {getCookie} from "../../cookie";
  7. const Option = Select.Option;
  8. const {Content} = Layout;
  9. const confirm = Modal.confirm;
  10. class Table extends Component {
  11. constructor(props) {
  12. super(props);
  13. this.state = {
  14. currentTable: props.currentTable,
  15. remark: props.remark,
  16. columns: props.columns,
  17. newColName: '',
  18. newColType: 'type',
  19. types: ['ID', 'String', 'Int', 'Float', 'Boolean', 'DateTime'],
  20. descriptions: ['description', 'key', 'non-null', 'non-null-list', 'list'],
  21. characterTips: false
  22. }
  23. }
  24. // 下面的 handlexxxx 全是 state 内部方法,用于操作视图
  25. // cache 仅在提交删除整体使用
  26. handleNameChange = (index) => {
  27. return (e) => {
  28. let columns = this.state.columns;
  29. columns[index].name = e.target.value;
  30. this.setState({
  31. columns
  32. })
  33. };
  34. };
  35. handleNameNew = (e) => {
  36. let r = /^[^\u4e00-\u9fa5]*$/;
  37. if(r.test(e.target.value)){
  38. this.setState({
  39. newColName: e.target.value,
  40. })
  41. } else {
  42. this.setState({
  43. characterTips: true
  44. });
  45. setTimeout(()=>{
  46. this.setState({
  47. characterTips: false
  48. })
  49. }, 2000)
  50. }
  51. };
  52. handleTypeChange = (index) => {
  53. return (value) => {
  54. let columns = this.state.columns;
  55. columns[index].type = value;
  56. this.setState({
  57. columns
  58. });
  59. }
  60. };
  61. handleTypeNew = (value) => {
  62. if (this.state.newColName !== '') {
  63. let columns = this.state.columns;
  64. columns.push({name: this.state.newColName, type: value, description: 'description'});
  65. this.setState({
  66. columns,
  67. newColName: '',
  68. newColType: 'type'
  69. })
  70. } else {
  71. notification['warning']({
  72. message: 'Notification',
  73. description: 'Input a field name first.',
  74. });
  75. }
  76. };
  77. handleDescChange = (index) => {
  78. return (value) => {
  79. let columns = this.state.columns;
  80. columns[index].description = value;
  81. this.setState({
  82. columns
  83. });
  84. };
  85. };
  86. handleColDelete = (index) => {
  87. return () => {
  88. let columns = this.state.columns;
  89. columns.splice(index, 1);
  90. this.setState({
  91. columns
  92. });
  93. }
  94. };
  95. componentWillReceiveProps(next) {
  96. this.setState({
  97. currentTable: next.currentTable,
  98. columns: next.columns,
  99. remark: next.remark
  100. });
  101. };
  102. render() {
  103. // console.log('columns',this.state.columns);
  104. // console.log('this.props',this.props);
  105. let schemaID = this.props.schemaID || this.props.history.location.state.schemaID;
  106. let schemaName = this.props.schemaName || this.props.history.location.state.schemaName;
  107. // console.log('schemaID',schemaID,'schemaName',schemaName);
  108. let userID = this.props.userID || getCookie('user_id');
  109. // console.log('schemaID',schemaID,'userID',userID);
  110. let trialcase = this.props.trialcase;
  111. return (
  112. <div>
  113. <div className="column-menu" onClick={this.props.goBack}>
  114. {/*()=>this.props.history.goBack()*/}
  115. <Icon type="left" style={{color: '#3187FA'}}/> {schemaName}
  116. </div>
  117. <Layout style={{zIndex: '0'}}>
  118. <Content style={{padding: '24px', minHeight: 280, background: '#fff'}}>
  119. <div className="column-content">
  120. <span className='table-title'> Table name</span>
  121. <Input
  122. value={this.state.currentTable}
  123. placeholder="please input table name"
  124. style={{width: 200, margin: '10px 0'}}
  125. onChange={(e) => {
  126. this.setState({currentTable: e.target.value})
  127. }}/>
  128. </div>
  129. <div style={{marginBottom: 20}}>
  130. <span className='table-title'> Table remark</span>
  131. <Input
  132. value={this.state.remark}
  133. placeholder="please input table remark"
  134. style={{width: 250, margin: '10px 0'}}
  135. onChange={(e) => {
  136. this.setState({remark: e.target.value})
  137. }}/>
  138. </div>
  139. <div>
  140. <span className='table-title'> Table fields</span>
  141. <span className='column-title'>name</span>
  142. <span className='column-title'>type</span>
  143. <span className='column-title'>description</span>
  144. {
  145. this.state.columns.map((col, index) =>
  146. <div key={index} style={{marginBottom: 3}}>
  147. <Input
  148. className="column-details"
  149. value={col.name}
  150. onChange={this.handleNameChange(index)}
  151. />
  152. <Select
  153. className="column-details"
  154. defaultValue={col.type}
  155. onChange={this.handleTypeChange(index)}>
  156. {
  157. this.state.types.map((value) =>
  158. <Option key={Math.random() + 'types'}
  159. value={value.toLowerCase()}>{value}</Option>
  160. )
  161. }
  162. </Select>
  163. <Select
  164. className="column-details"
  165. defaultValue={col.description}
  166. onChange={this.handleDescChange(index)}>
  167. {
  168. this.state.descriptions.map((value) =>
  169. <Option key={Math.random() + 'descriptions'}
  170. value={value.toLowerCase()}>{value}</Option>
  171. )
  172. }
  173. </Select>
  174. {
  175. trialcase ?
  176. ''
  177. :
  178. <Icon type="delete" theme="twoTone" style={{cursor: 'pointer'}}
  179. onClick={this.handleColDelete(index)}/>
  180. }
  181. </div>
  182. )
  183. }
  184. <div>
  185. <Input
  186. className="column-details"
  187. placeholder="field name"
  188. onChange={this.handleNameNew}
  189. value={this.state.newColName}
  190. />
  191. <Select
  192. className="column-details"
  193. defaultValue="type"
  194. onChange={this.handleTypeNew}
  195. value={this.state.newColType}>
  196. {
  197. this.state.types.map((value) =>
  198. <Option key={Math.random()} value={value.toLowerCase()}>{value}</Option>
  199. )
  200. }
  201. </Select>
  202. </div>
  203. </div>
  204. {
  205. trialcase ?
  206. ''
  207. :
  208. <div style={{marginTop: 20}}>
  209. <UpdateTableButton
  210. currentTable={this.state.currentTable}
  211. columns={this.state.columns}
  212. remark={this.state.remark}
  213. schemaID={schemaID}
  214. userID={userID}
  215. schemaData={this.props.schemaData}
  216. fetchData={this.props.fetchData}
  217. showTablePagination={this.props.showTablePagination}
  218. page={this.props.page}
  219. pageSize={this.props.pageSize}
  220. history={this.props.history}
  221. schemaName={schemaName}
  222. add={this.props.add}
  223. />
  224. </div>
  225. }
  226. </Content>
  227. </Layout>
  228. </div>
  229. )
  230. }
  231. }
  232. export default Table;
  233. class UpdateTableButton extends Component {
  234. constructor(props) {
  235. super(props);
  236. this.state = {
  237. originTableName: props.currentTable
  238. }
  239. }
  240. showConfirm = (schemaName,schemaID) => {
  241. let _this = this;
  242. if(this.props.add !== 'add') {
  243. this.props.history.push({
  244. pathname: `/graphql-service/my-create/${schemaName}`,
  245. state:{
  246. schemaName,
  247. schemaID
  248. }
  249. });
  250. }else{
  251. confirm({
  252. title: '添加成功',
  253. content: '继续添加数据表?',
  254. onOk() {
  255. console.log('继续添加');
  256. },
  257. onCancel() {
  258. _this.props.history.push({
  259. pathname: `/graphql-service/my-create/${schemaName}`,
  260. state:{
  261. schemaName,
  262. schemaID
  263. }
  264. });
  265. }
  266. });
  267. }
  268. };
  269. render() {
  270. let schemaID = this.props.schemaID;
  271. let schemaName = this.props.schemaName;
  272. let userID = this.props.userID;
  273. let varobj = {
  274. id: schemaID,
  275. updatedAt: new Date().getTime(),
  276. schemaState: 'updated-update-table',
  277. };
  278. return (
  279. <Query query={gql(SHOW_TABLE)} variables={{schema_id: schemaID}}>
  280. {
  281. ({loading, error, data}) => {
  282. if (loading)
  283. return <Spin style={{marginLeft: 30, marginTop: 10}}/>;
  284. if (error)
  285. return 'error';
  286. let schemaData = data;
  287. let referenceID;
  288. if(data.schema_by_id)
  289. referenceID = data.schema_by_id.reference;
  290. return (
  291. <Mutation
  292. mutation={gql(UPDATE_SCHEMA)}
  293. onCompleted={()=>this.showConfirm(schemaName,schemaID)}
  294. refetchQueries={[{query: gql(SHOW_TABLE), variables: {schema_id: schemaID}}]}
  295. >
  296. {(update_schema, {loading, error}) => {
  297. if (loading)
  298. return <Spin style={{marginLeft: 30, marginTop: 10}}/>;
  299. if (error)
  300. return 'error';
  301. // 更新代码
  302. // 先 query 再 mutation,然后替换,做一个判断
  303. let schemaCols;
  304. if (schemaData.schema_by_id === null) schemaCols = [];
  305. else schemaCols = JSON.parse(schemaData.schema_by_id.schemaData);
  306. // 处理一下description的问题
  307. let cols = this.props.columns;
  308. cols.map(obj => {
  309. if (obj.description === 'description')
  310. obj.description = '';
  311. return obj
  312. });
  313. let newTable = {
  314. name: this.props.currentTable,
  315. remark: this.props.remark,
  316. cols
  317. };
  318. const index = this.state.originTableName === '' ? -2 : this.props.schemaData.findIndex(obj => obj.name === this.state.originTableName);
  319. if (index === -2) {
  320. if(referenceID !== '' && schemaCols.length === 0) {
  321. this.props.fetchData(referenceID).then(value => {
  322. schemaCols = JSON.parse(value);
  323. schemaCols.push(newTable);
  324. });
  325. } else {
  326. schemaCols.push(newTable);
  327. }
  328. } else if (index === -1) {
  329. // 先取数据,然后替换,然后填充
  330. this.props.fetchData(referenceID).then(value => {
  331. schemaCols = JSON.parse(value);
  332. const index = schemaCols.findIndex(obj => obj.name === this.state.originTableName);
  333. schemaCols.splice(index, 1, newTable);
  334. });
  335. } else {
  336. schemaCols.splice(index, 1, newTable);
  337. }
  338. return (
  339. <div style={{display: 'inline-block'}}>
  340. <Button type="primary" onClick={() => {
  341. update_schema({
  342. variables: {
  343. ...varobj,
  344. schemaData: JSON.stringify(schemaCols)
  345. }
  346. });
  347. this.props.showTablePagination(this.props.page, this.props.pageSize, schemaCols);
  348. // if(this.props.add !== 'add') {
  349. // this.props.history.push({
  350. // pathname: `/graphql-service/my-create/${this.props.schemaName}`,
  351. // state:{
  352. // schemaName:this.props.schemaName,
  353. // schemaID:this.props.schemaID
  354. // }
  355. // });
  356. // }
  357. }}>
  358. save
  359. </Button>
  360. </div>
  361. )
  362. }}
  363. </Mutation>
  364. )
  365. }
  366. }
  367. </Query>
  368. )
  369. }
  370. }