Table.js 16 KB

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