ProjectForm.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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. const { data } = await createProject()
  146. state.id = data.createProject.id
  147. }}
  148. >
  149. <ProjectFields title='Project' state={state} onChange={toState} />
  150. {state.versions.map((version, index) => (
  151. <ProjectVersionFields
  152. title='Project version'
  153. key={index}
  154. state={version}
  155. onChange={(event, state) => updateVersions(event, state, index)}
  156. />
  157. ))}
  158. <button
  159. type='button'
  160. onClick={event => {
  161. setState({
  162. ...state,
  163. versions: [...state.versions, { ...ProjectVersionState }]
  164. })
  165. }}
  166. >
  167. Add project version
  168. </button>
  169. {state.files.map((file, index) => (
  170. <FileFields
  171. title='Files'
  172. key={index}
  173. state={file}
  174. onChange={(event, state) => updateFiles(event, state, index)}
  175. />
  176. ))}
  177. <button
  178. type='button'
  179. onClick={event => {
  180. setState({ ...state, files: [...state.files, { ...FileState }] })
  181. }}
  182. >
  183. Add file
  184. </button>
  185. <button type='submit'>
  186. {state.id && state.id !== '__NEW__' ? 'Save' : 'Add'}
  187. </button>
  188. </form>
  189. )}
  190. </Mutation>
  191. )
  192. }
  193. export default Project
  194. export { ProjectSelector, QUERY_PROJECTS, ProjectFields }