Răsfoiți Sursa

plan to push information from child to parent.

Tomi Cvetic 5 ani în urmă
părinte
comite
60aec133de

+ 18 - 0
frontend/components/Error.js

@@ -0,0 +1,18 @@
+const Errors = React.createContext([])
+
+const Error = props => (
+  <li>{props.error.message}</li>
+)
+
+const ErrorList = props => {
+  const errors = React.useContext(Errors)
+
+  return (
+    <ul>
+      {errors.filter(error => !error.waived).map(error => <Error error={error} />)}
+    </ul>
+  )
+}
+
+export default ErrorList
+export { ErrorList }

+ 25 - 10
frontend/components/FileUpload.js

@@ -1,15 +1,30 @@
+import { useState } from 'react'
 import { endpoint } from '../config'
 
-const FileFields = props => (
-  <fieldset>
-    <label htmlFor='file'>File</label>
-    <input type='file' name='file' id='file' onChange={props.selectFile} />
-    <label htmlFor='name'>File name</label>
-    <input type='text' name='name' id='name' placeholder='File name' value={props.state.name} onChange={props.onChange} />
-    <label htmlFor='description'>File description</label>
-    <textarea name='description' id='description' placeholder='File description' value={props.state.description} onChange={props.onChange} />
-  </fieldset>
-)
+const FileFields = props => {
+  const [state, setState] = useState({ ...FileState })
+
+  const updateState = async event => {
+    const { name, type, value, files } = event.target
+    await setState({
+      ...state,
+      [name]: type === 'file' ? files[0] : value
+    })
+    console.log(state)
+    props.onChange(event, state)
+  }
+
+  return (
+    < fieldset >
+      <label htmlFor='file'>File</label>
+      <input type='file' name='file' id='file' onChange={updateState} />
+      < label htmlFor='name'>File name</label>
+      <input type='text' name='name' id='name' placeholder='File name' value={state.name} onChange={updateState} />
+      <label htmlFor='description'>File description</label>
+      <textarea name='description' id='description' placeholder='File description' value={state.description} onChange={updateState} />
+    </fieldset >
+  )
+}
 
 const FileState = {
   file: null,

+ 75 - 47
frontend/components/ProjectForm.js

@@ -1,3 +1,4 @@
+import { useState } from 'react'
 import styled from 'styled-components'
 import gql from 'graphql-tag'
 import { Mutation, Query } from 'react-apollo'
@@ -46,7 +47,7 @@ const ProjectSelector = props => (
       if (!data || !data.projects.length) return (<p>No project found.</p>)
       if (!props.value) props.onChange({ target: { name: 'project', value: data.projects[0].id } })
       const selector = (
-        <select {...props}>
+        <select value={12} {...props}>
           {data.projects.map(project =>
             <option key={project.id} value={project.id}>{project.name}</option>
           )}
@@ -57,58 +58,85 @@ const ProjectSelector = props => (
   </Query >
 )
 
-const ProjectFields = props => (
-  <fieldset>
-    {props.title && <legend>{props.title}</legend>}
-    <label htmlFor='name'>Project name</label>
-    <input type='text' name='name' id='name' placeholder='Project name' value={props.state.name} onChange={props.onChange} />
-    <label htmlFor='abbreviation'>Project abbreviation</label>
-    <input type='text' name='abbreviation' id='abbreviation' placeholder='Project abbreviation' value={props.state.abbreviation} onChange={props.onChange} />
-    <label htmlFor='description'>Project description</label>
-    <textarea name='description' id='description' placeholder='Project description' value={props.state.description} onChange={props.onChange} />
-  </fieldset>
-)
+const ProjectState = {
+  id: null,
+  name: '',
+  abbreviation: '',
+  description: '',
+  files: [],
+  versions: []
+}
+
+const ProjectFields = props => {
+  const [state, setState] = useState({ ...ProjectState })
 
-class Project extends React.Component {
-  state = {
-    id: null,
-    name: '',
-    abbreviation: '',
-    description: '',
-    files: [],
-    versions: [],
-    ...this.props.project
+  const updateState = event => {
+    setState({
+      ...state,
+      [event.target.name]: event.target.value
+    })
+    props.onChange(event, state)
   }
 
-  toState = event => {
-    this.setState({ [event.target.name]: event.target.value })
+  return (
+    <fieldset >
+      {props.title && <legend>{props.title}</legend>}
+      <label htmlFor='name' > Project name</label>
+      <input type='text' name='name' id='name' placeholder='Project name' value={state.name} onChange={updateState} />
+      <label htmlFor='abbreviation'>Project abbreviation</label>
+      <input type='text' name='abbreviation' id='abbreviation' placeholder='Project abbreviation' value={state.abbreviation} onChange={updateState} />
+      <label htmlFor='description'>Project description</label>
+      <textarea name='description' id='description' placeholder='Project description' value={state.description} onChange={updateState} />
+    </fieldset >
+  )
+}
+
+const Project = props => {
+  const [state, setState] = useState({
+    ...ProjectState,
+    ...props.project
+  })
+
+  const toState = (event, newState) => {
+    setState({ ...newState })
   }
 
-  render() {
-    return (
-      <Mutation mutation={CREATE_PROJECT} variables={this.state} refetchQueries={[{ query: QUERY_PROJECTS }]}>
-        {(createProject, { data, error, loading }) => (
-          <form onSubmit={async event => {
-            event.preventDefault()
-            const { data } = await createProject()
-            this.state.id = data.createProject.id
-          }}>
-            <ProjectFields title="Project" state={this.state} onChange={this.toState} />
-            {this.state.versions.map(version =>
-              <ProjectVersionFields title="Project version" state={version} onChange={this.toState} />
-            )}
-            <button onClick={event => this.state.versions.push(ProjectVersionState)}>Add project version</button>
-            {this.state.files.map(file =>
-              <FileFields state={file} onChange={this.toState} />
-            )}
-            <button onClick={event => this.state.files.push(FileState)}>Add file</button>
-            <button type='submit'>{this.state.id && this.state.id !== "__NEW__" ? "Save" : "Add"}</button>
-          </form>
-        )}
-      </Mutation>
-    )
+  const updateVersions = (event, newState, index) => {
+    const versions = [...state.versions]
+    versions[index] = newState
+    setState({ ...state, versions })
   }
+
+  const updateFiles = (event, newState, index) => {
+    const files = [...state.files]
+    files[index] = newState
+    setState({ ...state, files })
+  }
+
+  return (
+    <Mutation mutation={CREATE_PROJECT} variables={state} refetchQueries={[{ query: QUERY_PROJECTS }]}>
+      {(createProject, { data, error, loading }) => (
+        <form onSubmit={async event => {
+          event.preventDefault()
+          console.log('form submitted.')
+          const { data } = await createProject()
+          state.id = data.createProject.id
+        }}>
+          <ProjectFields title='Project' state={state} onChange={toState} />
+          {state.versions.map((version, index) =>
+            <ProjectVersionFields title='Project version' key={index} state={version} onChange={(event, state) => updateVersions(event, state, index)} />
+          )}
+          <button type='button' onClick={event => { setState({ ...state, versions: [...state.versions, { ...ProjectVersionState }] }) }}>Add project version</button>
+          {state.files.map((file, index) =>
+            <FileFields title='Files' key={index} state={file} onChange={(event, state) => updateFiles(event, state, index)} />
+          )}
+          <button type='button' onClick={event => { setState({ ...state, files: [...state.files, { ...FileState }] }) }}>Add file</button>
+          <button type='submit'>{state.id && state.id !== '__NEW__' ? 'Save' : 'Add'}</button>
+        </form>
+      )}
+    </Mutation>
+  )
 }
 
 export default Project
-export { ProjectSelector, QUERY_PROJECTS, ProjectFields }
+export { ProjectSelector, QUERY_PROJECTS, ProjectFields }

+ 6 - 7
frontend/components/ProjectVersionForm.js

@@ -41,7 +41,11 @@ class ProjectVersionForm extends React.Component {
     this.setState({ [event.target.name]: event.target.value })
   }
 
-  addComment = event => {
+  addChange = event => {
+    event.preventDefault()
+    const newChanges = this.state.changes
+    newChanges.push(this.state.change)
+    this.setState({ changes: newChanges, change: '' })
   }
 
   render() {
@@ -53,12 +57,7 @@ class ProjectVersionForm extends React.Component {
             const { data } = await createProjectVersion()
             this.state.id = data.createProjectVersion.id
           }}>
-            <ProjectVersionFields title="Project Version" state={this.state} addChange={event => {
-              event.preventDefault()
-              const newChanges = this.state.changes
-              newChanges.push(this.state.change)
-              this.setState({ changes: newChanges, change: '' })
-            }} onChange={this.toState} />
+            <ProjectVersionFields title="Project Version" state={this.state} addChange={this.addChange} onChange={this.toState} />
             {this.state.changes.map((change, index) => <p key={index}>{change}</p>)}
             {this.props.project || <ProjectSelector name='project' id='project' value={this.state.project} onChange={this.toState} />}
             <button type='submit'>Save</button>