ProjectForm.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. import gql from 'graphql-tag'
  2. import { Mutation, Query } from 'react-apollo'
  3. import { ProjectVersionFields, ProjectVersionState } from './ProjectVersionForm'
  4. const CREATE_PROJECT = gql`
  5. mutation CREATE_PROJECT(
  6. $name: String!
  7. $abbreviation: String!
  8. $description: String
  9. ) {
  10. createProject(
  11. name: $name
  12. abbreviation: $abbreviation
  13. description: $description
  14. ) {
  15. id
  16. }
  17. }
  18. `
  19. const QUERY_PROJECTS = gql`
  20. query QUERY_PROJECTS {
  21. projects {
  22. id
  23. name
  24. abbreviation
  25. description
  26. files {
  27. id
  28. path
  29. name
  30. description
  31. filename
  32. mimetype
  33. size
  34. }
  35. versions {
  36. id
  37. name
  38. changes
  39. date
  40. }
  41. }
  42. }
  43. `
  44. const ProjectSelector = props => (
  45. <Query query={QUERY_PROJECTS}>
  46. {({ data, loading, error }) => {
  47. if (error) return <p>Error loading project: ${error.message}</p>
  48. if (loading) return <p>Loading data...</p>
  49. if (!data || !data.projects.length) return <p>No project found.</p>
  50. if (!props.value) {
  51. props.onChange({
  52. target: { name: 'project', value: data.projects[0].id }
  53. })
  54. }
  55. const selector = (
  56. <select value={12} {...props}>
  57. {data.projects.map(project => (
  58. <option key={project.id} value={project.id}>
  59. {project.name}
  60. </option>
  61. ))}
  62. </select>
  63. )
  64. return selector
  65. }}
  66. </Query>
  67. )
  68. const ProjectState = {
  69. id: null,
  70. name: '',
  71. abbreviation: '',
  72. description: '',
  73. files: [],
  74. versions: []
  75. }
  76. const ProjectFields = props => {
  77. const [state, setState] = React.useState({ ...ProjectState })
  78. const updateState = event => {
  79. setState({
  80. ...state,
  81. [event.target.name]: event.target.value
  82. })
  83. props.onChange(event, state)
  84. }
  85. return (
  86. <fieldset>
  87. {props.title && <legend>{props.title}</legend>}
  88. <label htmlFor='name'> Project name</label>
  89. <input
  90. type='text'
  91. name='name'
  92. id='name'
  93. placeholder='Project name'
  94. value={state.name}
  95. onChange={updateState}
  96. />
  97. <label htmlFor='abbreviation'>Project abbreviation</label>
  98. <input
  99. type='text'
  100. name='abbreviation'
  101. id='abbreviation'
  102. placeholder='Project abbreviation'
  103. value={state.abbreviation}
  104. onChange={updateState}
  105. />
  106. <label htmlFor='description'>Project description</label>
  107. <textarea
  108. name='description'
  109. id='description'
  110. placeholder='Project description'
  111. value={state.description}
  112. onChange={updateState}
  113. />
  114. </fieldset>
  115. )
  116. }
  117. const Project = props => {
  118. const [state, setState] = React.useState({
  119. ...ProjectState,
  120. ...props.project
  121. })
  122. const toState = (event, newState) => {
  123. setState({ ...newState })
  124. }
  125. const updateVersions = (event, newState, index) => {
  126. const versions = [...state.versions]
  127. versions[index] = newState
  128. setState({ ...state, versions })
  129. }
  130. const updateFiles = (event, newState, index) => {
  131. const files = [...state.files]
  132. files[index] = newState
  133. setState({ ...state, files })
  134. }
  135. return (
  136. <Mutation
  137. mutation={CREATE_PROJECT}
  138. variables={state}
  139. refetchQueries={[{ query: QUERY_PROJECTS }]}
  140. >
  141. {(createProject, { data, error, loading }) => (
  142. <form
  143. onSubmit={async event => {
  144. event.preventDefault()
  145. console.log('form submitted.')
  146. const { data } = await createProject()
  147. state.id = data.createProject.id
  148. }}
  149. >
  150. <ProjectFields title='Project' state={state} onChange={toState} />
  151. {state.versions.map((version, index) => (
  152. <ProjectVersionFields
  153. title='Project version'
  154. key={index}
  155. state={version}
  156. onChange={(event, state) => updateVersions(event, state, index)}
  157. />
  158. ))}
  159. <button
  160. type='button'
  161. onClick={event => {
  162. setState({
  163. ...state,
  164. versions: [...state.versions, { ...ProjectVersionState }]
  165. })
  166. }}
  167. >
  168. Add project version
  169. </button>
  170. {state.files.map((file, index) => (
  171. <FileFields
  172. title='Files'
  173. key={index}
  174. state={file}
  175. onChange={(event, state) => updateFiles(event, state, index)}
  176. />
  177. ))}
  178. <button
  179. type='button'
  180. onClick={event => {
  181. setState({ ...state, files: [...state.files, { ...FileState }] })
  182. }}
  183. >
  184. Add file
  185. </button>
  186. <button type='submit'>
  187. {state.id && state.id !== '__NEW__' ? 'Save' : 'Add'}
  188. </button>
  189. </form>
  190. )}
  191. </Mutation>
  192. )
  193. }
  194. export default Project
  195. export { ProjectSelector, QUERY_PROJECTS, ProjectFields }