Instrument.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. import gql from 'graphql-tag'
  2. import { Query, Mutation } from 'react-apollo'
  3. import { adopt } from 'react-adopt'
  4. import { InterfaceFormFields } from './Interface'
  5. import InstrumentCommand, {
  6. InstrumentCommandFormFields,
  7. InstrumentCommandFields
  8. } from './InstrumentCommand'
  9. import File, { FileFormFields, FileFields } from './File'
  10. import Gallery from './Gallery'
  11. import { INTERFACES_FULL } from './InterfaceList'
  12. const CREATE_INSTRUMENT = gql`
  13. mutation CREATE_INSTRUMENT(
  14. $id: ID
  15. $name: String!
  16. $manufacturer: String!
  17. $description: String
  18. $picture: ID
  19. $interfaces: [String]!
  20. $documents: [FileUpload]!
  21. $commands: [InstrumentCommandInput]!
  22. ) {
  23. createInstrument(
  24. id: $id
  25. name: $name
  26. manufacturer: $manufacturer
  27. description: $description
  28. picture: $picture
  29. interfaces: $interfaces
  30. documents: $documents
  31. commands: $commands
  32. ) {
  33. id
  34. }
  35. }
  36. `
  37. const INSTRUMENT_QUERY = gql`
  38. query INSTRUMENT_QUERY($id: ID!) {
  39. instrument(id: $id) {
  40. id
  41. name
  42. manufacturer
  43. description
  44. picture
  45. documents {
  46. id
  47. path
  48. name
  49. description
  50. filename
  51. mimetype
  52. size
  53. }
  54. interfaces
  55. commands {
  56. id
  57. tag
  58. name
  59. description
  60. readString
  61. writeString
  62. }
  63. parameters {
  64. id
  65. tag
  66. name
  67. description
  68. type
  69. values
  70. }
  71. }
  72. }
  73. `
  74. const INSTRUMENTS_QUERY = gql`
  75. query INSTRUMENTS_QUERY {
  76. instruments {
  77. id
  78. name
  79. manufacturer
  80. description
  81. picture
  82. }
  83. }
  84. `
  85. const InstrumentFields = {
  86. id: null,
  87. name: '',
  88. manufacturer: '',
  89. description: '',
  90. picture: '',
  91. documents: [],
  92. interfaces: [],
  93. commands: [],
  94. parameters: []
  95. }
  96. class InstrumentForm extends React.Component {
  97. state = {
  98. ...InstrumentFields,
  99. ...this.props.instrument
  100. }
  101. toState = event => {
  102. this.setState({ [event.target.name]: event.target.value })
  103. }
  104. toSubState = (name, index, subState) => {
  105. this.setState({
  106. [name]: [
  107. ...this.state[name].slice(0, index),
  108. subState,
  109. ...this.state[name].slice(index + 1)
  110. ]
  111. })
  112. }
  113. render () {
  114. return (
  115. <Mutation
  116. mutation={CREATE_INSTRUMENT}
  117. variables={this.state}
  118. refetchQueries={[{ query: INSTRUMENTS_QUERY }]}
  119. >
  120. {(createInstrument, { data, error, loading }) => (
  121. <form
  122. onSubmit={event => {
  123. event.preventDefault()
  124. createInstrument()
  125. }}
  126. >
  127. <h1>Create new instrument.</h1>
  128. <h2>Instrument data</h2>
  129. <fieldset>
  130. <label htmlFor='name'>
  131. Name
  132. <input
  133. type='text'
  134. name='name'
  135. id='name'
  136. placeholder='Name'
  137. required
  138. value={this.state.name}
  139. onChange={this.toState}
  140. />
  141. </label>
  142. <label htmlFor='manufacturer'>
  143. Manufacturer
  144. <input
  145. type='text'
  146. name='manufacturer'
  147. id='manufacturer'
  148. placeholder='Manufacturer'
  149. required
  150. value={this.state.manufacturer}
  151. onChange={this.toState}
  152. />
  153. </label>
  154. <label htmlFor='description'>
  155. Description
  156. <textarea
  157. name='description'
  158. id='description'
  159. placeholder='Description'
  160. value={this.state.description}
  161. onChange={this.toState}
  162. />
  163. </label>
  164. </fieldset>
  165. <h2>Documents</h2>
  166. {this.state.documents.map((file, index) => (
  167. <FileFormFields
  168. key={index}
  169. state={file}
  170. onChange={subState =>
  171. this.toSubState('documents', index, subState)
  172. }
  173. />
  174. ))}
  175. <button
  176. type='button'
  177. onClick={event => {
  178. this.setState({
  179. documents: [...this.state.documents, FileFields]
  180. })
  181. }}
  182. >
  183. Add document
  184. </button>
  185. <h2>Interfaces</h2>
  186. <InterfaceFormFields
  187. state={this.state.interfaces}
  188. onChange={interfaces => this.setState({ interfaces })}
  189. />
  190. <h2>Commands</h2>
  191. {this.state.commands.map((command, index) => (
  192. <InstrumentCommandFormFields
  193. key={index}
  194. state={command}
  195. onChange={subState =>
  196. this.toSubState('commands', index, subState)
  197. }
  198. />
  199. ))}
  200. <button
  201. type='button'
  202. onClick={event => {
  203. this.setState({
  204. commands: [...this.state.commands, InstrumentCommandFields]
  205. })
  206. }}
  207. >
  208. Add command
  209. </button>
  210. <button type='submit'>Save Instrument</button>
  211. </form>
  212. )}
  213. </Mutation>
  214. )
  215. }
  216. }
  217. const Instrument = props => {
  218. const { instrument } = props
  219. return instrument ? (
  220. <div>
  221. <h1>{instrument.name}</h1>
  222. <h2>{instrument.manufacturer}</h2>
  223. <p>{instrument.description}</p>
  224. <p>{instrument.picture}</p>
  225. <Gallery
  226. title='Documents'
  227. items={instrument.documents.map(document => (
  228. <File data={document} />
  229. ))}
  230. />
  231. <Gallery
  232. title='Interfaces'
  233. items={instrument.interfaces.map(iface => (
  234. <div>{iface}</div>
  235. ))}
  236. />
  237. <Gallery
  238. title='Commands'
  239. items={instrument.commands.map(command => (
  240. <InstrumentCommand command={command} />
  241. ))}
  242. />
  243. </div>
  244. ) : (
  245. <p>Instrument not found.</p>
  246. )
  247. }
  248. export default Instrument
  249. export { InstrumentFields, InstrumentForm }
  250. export { INSTRUMENT_QUERY, INSTRUMENTS_QUERY }