project redux store
This commit is contained in:
		
							parent
							
								
									a8e36a4f06
								
							
						
					
					
						commit
						a30747c608
					
				
							
								
								
									
										68
									
								
								src/actions/projectActions.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/actions/projectActions.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | |||||||
|  | import { PROJECT_PROGRESS, GET_PROJECT, GET_PROJECTS, PROJECT_TYPE } from './types'; | ||||||
|  | 
 | ||||||
|  | import axios from 'axios'; | ||||||
|  | import { workspaceName } from './workspaceActions'; | ||||||
|  | import { returnErrors, returnSuccess } from './messageActions'; | ||||||
|  | 
 | ||||||
|  | export const setType = (type) => (dispatch) => { | ||||||
|  |   dispatch({ | ||||||
|  |     type: PROJECT_TYPE, | ||||||
|  |     payload: type | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export const getProject = (type, id) => (dispatch) => { | ||||||
|  |   dispatch({type: PROJECT_PROGRESS}); | ||||||
|  |   dispatch(setType(type)); | ||||||
|  |   axios.get(`${process.env.REACT_APP_BLOCKLY_API}/${type}/${id}`) | ||||||
|  |     .then(res => { | ||||||
|  |       var data = type === 'share' ? 'content' : type; | ||||||
|  |       var project = res.data[data]; | ||||||
|  |       if(project){ | ||||||
|  |         dispatch({ | ||||||
|  |           type: GET_PROJECT, | ||||||
|  |           payload: project | ||||||
|  |         }); | ||||||
|  |         dispatch({type: PROJECT_PROGRESS}); | ||||||
|  |         dispatch(returnSuccess(res.data.message, res.status, 'GET_PROJECT_SUCCESS')); | ||||||
|  |       } | ||||||
|  |       else{ | ||||||
|  |         dispatch({type: PROJECT_PROGRESS}); | ||||||
|  |         dispatch(returnErrors(res.data.message, res.status, 'PROJECT_EMPTY')); | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  |     .catch(err => { | ||||||
|  |       if(err.response){ | ||||||
|  |         dispatch(returnErrors(err.response.data.message, err.response.status, 'GET_PROJECT_FAIL')); | ||||||
|  |       } | ||||||
|  |       dispatch({type: PROJECT_PROGRESS}); | ||||||
|  |     }); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export const getProjects = (type) => (dispatch) => { | ||||||
|  |   dispatch({type: PROJECT_PROGRESS}); | ||||||
|  |   axios.get(`${process.env.REACT_APP_BLOCKLY_API}/${type}`) | ||||||
|  |     .then(res => { | ||||||
|  |       var data = type === 'project' ? 'projects' : 'galleries'; | ||||||
|  |       var projects = res.data[data]; | ||||||
|  |       dispatch({ | ||||||
|  |         type: GET_PROJECTS, | ||||||
|  |         payload: projects | ||||||
|  |       }); | ||||||
|  |       dispatch({type: PROJECT_PROGRESS}); | ||||||
|  |       dispatch(returnSuccess(res.data.message, res.status)); | ||||||
|  |     }) | ||||||
|  |     .catch(err => { | ||||||
|  |       if(err.response){ | ||||||
|  |         dispatch(returnErrors(err.response.data.message, err.response.status, 'GET_PROJECTS_FAIL')); | ||||||
|  |       } | ||||||
|  |       dispatch({type: PROJECT_PROGRESS}); | ||||||
|  |     }); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export const resetProject = () => (dispatch) => { | ||||||
|  |   dispatch({ | ||||||
|  |     type: GET_PROJECTS, | ||||||
|  |     payload: [] | ||||||
|  |   }); | ||||||
|  | }; | ||||||
| @ -37,3 +37,10 @@ export const VISIT = 'VISIT'; | |||||||
| export const GET_ERRORS = 'GET_ERRORS'; | export const GET_ERRORS = 'GET_ERRORS'; | ||||||
| export const GET_SUCCESS = 'GET_SUCCESS'; | export const GET_SUCCESS = 'GET_SUCCESS'; | ||||||
| export const CLEAR_MESSAGES = 'CLEAR_MESSAGES'; | export const CLEAR_MESSAGES = 'CLEAR_MESSAGES'; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // projects: share, gallery, project
 | ||||||
|  | export const PROJECT_PROGRESS = 'PROJECT_PROGRESS'; | ||||||
|  | export const GET_PROJECT = 'GET_PROJECT'; | ||||||
|  | export const GET_PROJECTS = 'GET_PROJECTS'; | ||||||
|  | export const PROJECT_TYPE = 'PROJECT_TYPE'; | ||||||
|  | |||||||
| @ -53,7 +53,7 @@ class Navbar extends Component { | |||||||
|       <div> |       <div> | ||||||
|         <AppBar |         <AppBar | ||||||
|           position="relative" |           position="relative" | ||||||
|           style={{ height: '50px', marginBottom: this.props.isLoading ? '0px' : '30px', boxShadow: this.props.isLoading ? 'none' : '0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)' }} |           style={{ height: '50px', marginBottom: this.props.tutorialIsLoading || this.props.projectIsLoading ? '0px' : '30px', boxShadow: this.props.tutorialIsLoading || this.props.projectIsLoading ? 'none' : '0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)' }} | ||||||
|           classes={{ root: this.props.classes.appBarColor }} |           classes={{ root: this.props.classes.appBarColor }} | ||||||
|         > |         > | ||||||
|           <Toolbar style={{ height: '50px', minHeight: '50px', padding: 0, color: 'white' }}> |           <Toolbar style={{ height: '50px', minHeight: '50px', padding: 0, color: 'white' }}> | ||||||
| @ -122,7 +122,7 @@ class Navbar extends Component { | |||||||
|             ))} |             ))} | ||||||
|           </List> */} |           </List> */} | ||||||
|         </Drawer> |         </Drawer> | ||||||
|         {this.props.isLoading ? |         {this.props.tutorialIsLoading || this.props.projectIsLoading ? | ||||||
|           <LinearProgress style={{marginBottom: '30px', boxShadow: '0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)'}}/> |           <LinearProgress style={{marginBottom: '30px', boxShadow: '0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)'}}/> | ||||||
|         : null} |         : null} | ||||||
|       </div> |       </div> | ||||||
| @ -131,11 +131,13 @@ class Navbar extends Component { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Navbar.propTypes = { | Navbar.propTypes = { | ||||||
|   isLoading: PropTypes.bool.isRequired |   tutorialIsLoading: PropTypes.bool.isRequired, | ||||||
|  |   projectIsLoading: PropTypes.bool.isRequired | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = state => ({ | ||||||
|   isLoading: state.tutorial.progress, |   tutorialIsLoading: state.tutorial.progress, | ||||||
|  |   projectIsLoading: state.project.progress | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, null)(withStyles(styles, { withTheme: true })(withRouter(Navbar))); | export default connect(mapStateToProps, null)(withStyles(styles, { withTheme: true })(withRouter(Navbar))); | ||||||
|  | |||||||
| @ -2,6 +2,8 @@ import React, { Component } from 'react'; | |||||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||||
| import { connect } from 'react-redux'; | import { connect } from 'react-redux'; | ||||||
| import { workspaceName } from '../../actions/workspaceActions'; | import { workspaceName } from '../../actions/workspaceActions'; | ||||||
|  | import { getProject, resetProject } from '../../actions/projectActions'; | ||||||
|  | import { clearMessages } from '../../actions/messageActions'; | ||||||
| 
 | 
 | ||||||
| import axios from 'axios'; | import axios from 'axios'; | ||||||
| import { createNameId } from 'mnemonic-id'; | import { createNameId } from 'mnemonic-id'; | ||||||
| @ -15,69 +17,77 @@ import CircularProgress from '@material-ui/core/CircularProgress'; | |||||||
| 
 | 
 | ||||||
| class Project extends Component { | class Project extends Component { | ||||||
| 
 | 
 | ||||||
|   state = { |  | ||||||
|     project: {}, |  | ||||||
|     progress: false, |  | ||||||
|     type: '' |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   componentDidMount() { |   componentDidMount() { | ||||||
|     this.getProject(); |     this.getProject(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   componentDidUpdate(props) { |   componentDidUpdate(props) { | ||||||
|     if(props.location.path !== this.props.location.path){ |     if(props.location.path !== this.props.location.path || | ||||||
|  |        props.match.params[`${this.props.type}Id`] !== this.props.match.params[`${this.props.type}Id`]){ | ||||||
|  |       if(this.props.message.msg){ | ||||||
|  |         this.props.clearMessages(); | ||||||
|  |       } | ||||||
|       this.getProject(); |       this.getProject(); | ||||||
|     } |     } | ||||||
|  |     if(this.props.message !== props.message){ | ||||||
|  |       if(this.props.message.id === 'PROJECT_EMPTY' || this.props.message.id === 'GET_PROJECT_FAIL'){ | ||||||
|  |         this.props.workspaceName(createNameId()); | ||||||
|  |         this.props.history.push('/'); | ||||||
|  |       } | ||||||
|  |       if(this.props.message.id === 'GET_PROJECT_SUCCESS'){ | ||||||
|  |         this.props.workspaceName(this.props.project.title); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   componentWillUnmount() { | ||||||
|  |     this.props.resetProject(); | ||||||
|  |     this.props.workspaceName(null); | ||||||
|  |     if(this.props.message.msg){ | ||||||
|  |       this.props.clearMessages(); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   getProject = () => { |   getProject = () => { | ||||||
|     var param = this.props.match.params.shareId ? 'share' : this.props.match.params.galleryId ? 'gallery' : 'project'; |     var param = this.props.match.params.shareId ? 'share' : this.props.match.params.galleryId ? 'gallery' : 'project'; | ||||||
|     this.setState({ type: param, progress: true }); |  | ||||||
|     var id = this.props.match.params[`${param}Id`]; |     var id = this.props.match.params[`${param}Id`]; | ||||||
|     axios.get(`${process.env.REACT_APP_BLOCKLY_API}/${param}/${id}`) |     this.props.getProject(param, id); | ||||||
|       .then(res => { |  | ||||||
|         var data = param === 'share' ? 'content' : param; |  | ||||||
|         if(res.data[data]){ |  | ||||||
|           this.props.workspaceName(res.data[data].title); |  | ||||||
|           this.setState({ project: res.data[data], progress: false }); |  | ||||||
|         } |  | ||||||
|         else { |  | ||||||
|           this.props.workspaceName(createNameId()); |  | ||||||
|           this.setState({ progress: false }); |  | ||||||
|           this.props.history.push('/'); |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|       .catch(err => { |  | ||||||
|         // TODO:
 |  | ||||||
|         this.setState({ progress: false, snackbar: true, key: Date.now(), message: `Fehler beim Aufrufen des angeforderten Programms. Versuche es noch einmal.`, type: 'error' }); |  | ||||||
|         this.props.workspaceName(createNameId()); |  | ||||||
|         this.props.history.push('/'); |  | ||||||
|         window.scrollTo(0, 0); |  | ||||||
|       }); |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     var data = this.state.type === 'project' ? 'Projekte' : 'Galerie'; |     var data = this.props.type === 'project' ? 'Projekte' : 'Galerie'; | ||||||
|     return ( |     return ( | ||||||
|       this.state.progress ? |       this.props.progress ? | ||||||
|         <Backdrop open invisible> |         <Backdrop open invisible> | ||||||
|           <CircularProgress color="primary" /> |           <CircularProgress color="primary" /> | ||||||
|         </Backdrop> |         </Backdrop> | ||||||
|       : |       : this.props.project ? | ||||||
|         <div> |         <div> | ||||||
|           {this.state.type !== 'share' ? |           {this.props.type !== 'share' ? | ||||||
|             <Breadcrumbs content={[{ link: `/${this.state.type}`, title: data },{ link: this.props.location.path, title: this.state.project.title }]} /> |             <Breadcrumbs content={[{ link: `/${this.props.type}`, title: data },{ link: this.props.location.path, title: this.props.project.title }]} /> | ||||||
|           : null} |           : null} | ||||||
|           <Home project={this.state.project.xml}/> |           <Home project={this.props.project.xml}/> | ||||||
|         </div> |         </div> : null | ||||||
|     ); |     ); | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Project.propTypes = { | Project.propTypes = { | ||||||
|   workspaceName: PropTypes.func.isRequired |   workspaceName: PropTypes.func.isRequired, | ||||||
|  |   getProject: PropTypes.func.isRequired, | ||||||
|  |   resetProject: PropTypes.func.isRequired, | ||||||
|  |   clearMessages: PropTypes.func.isRequired, | ||||||
|  |   project: PropTypes.object.isRequired, | ||||||
|  |   type: PropTypes.string.isRequired, | ||||||
|  |   message: PropTypes.object.isRequired, | ||||||
|  |   progress: PropTypes.bool.isRequired | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | const mapStateToProps = state => ({ | ||||||
|  |   project: state.project.projects[0], | ||||||
|  |   progress: state.project.progress, | ||||||
|  |   type: state.project.type, | ||||||
|  |   message: state.message | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| export default connect(null, { workspaceName })(Project); | export default connect(mapStateToProps, { workspaceName, getProject, resetProject, clearMessages })(Project); | ||||||
|  | |||||||
| @ -1,4 +1,7 @@ | |||||||
| import React, { Component } from 'react'; | import React, { Component } from 'react'; | ||||||
|  | import PropTypes from 'prop-types'; | ||||||
|  | import { connect } from 'react-redux'; | ||||||
|  | import { getProjects, resetProject } from '../../actions/projectActions'; | ||||||
| 
 | 
 | ||||||
| import axios from 'axios'; | import axios from 'axios'; | ||||||
| import { Link } from 'react-router-dom'; | import { Link } from 'react-router-dom'; | ||||||
| @ -14,32 +17,21 @@ import Typography from '@material-ui/core/Typography'; | |||||||
| 
 | 
 | ||||||
| class ProjectHome extends Component { | class ProjectHome extends Component { | ||||||
| 
 | 
 | ||||||
|   state = { |  | ||||||
|     projects: [] |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   componentDidMount() { |   componentDidMount() { | ||||||
|     this.getProjects(); |     this.props.getProjects(this.props.match.path.replace('/','')); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   componentDidUpdate(props) { |   componentDidUpdate(props) { | ||||||
|     if(props.match.path !== this.props.match.path){ |     if(props.match.path !== this.props.match.path){ | ||||||
|       this.setState({projects: []}); |       this.props.getProjects(this.props.match.path.replace('/','')); | ||||||
|       this.getProjects(); |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   getProjects = () => { |   componentWillUnmount() { | ||||||
|     var data = this.props.match.path === '/project' ? 'projects' : 'galleries'; |     this.props.resetProject(); | ||||||
|     axios.get(`${process.env.REACT_APP_BLOCKLY_API}${this.props.match.path}`) |  | ||||||
|       .then(res => { |  | ||||||
|         this.setState({ projects: res.data[data] }); |  | ||||||
|       }) |  | ||||||
|       .catch(err => { |  | ||||||
|         // TODO:
 |  | ||||||
|       }); |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|   render() { |   render() { | ||||||
|     var data = this.props.match.path === '/project' ? 'Projekte' : 'Galerie'; |     var data = this.props.match.path === '/project' ? 'Projekte' : 'Galerie'; | ||||||
|     return ( |     return ( | ||||||
| @ -47,8 +39,9 @@ class ProjectHome extends Component { | |||||||
|         <Breadcrumbs content={[{ link: this.props.match.path, title: data }]} /> |         <Breadcrumbs content={[{ link: this.props.match.path, title: data }]} /> | ||||||
| 
 | 
 | ||||||
|         <h1>{data}</h1> |         <h1>{data}</h1> | ||||||
|  |         {this.props.progress ? null : | ||||||
|         <Grid container spacing={2}> |         <Grid container spacing={2}> | ||||||
|           {this.state.projects.map((project, i) => { |           {this.props.projects.map((project, i) => { | ||||||
|             return ( |             return ( | ||||||
|               <Grid item xs={12} sm={6} md={4} xl={3} key={i}> |               <Grid item xs={12} sm={6} md={4} xl={3} key={i}> | ||||||
|                 <Link to={`/${data === 'Projekte' ? 'project' : 'gallery'}/${project._id}`} style={{ textDecoration: 'none', color: 'inherit' }}> |                 <Link to={`/${data === 'Projekte' ? 'project' : 'gallery'}/${project._id}`} style={{ textDecoration: 'none', color: 'inherit' }}> | ||||||
| @ -66,10 +59,23 @@ class ProjectHome extends Component { | |||||||
|               </Grid> |               </Grid> | ||||||
|             ) |             ) | ||||||
|           })} |           })} | ||||||
|         </Grid> |         </Grid>} | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default ProjectHome; | ProjectHome.propTypes = { | ||||||
|  |   getProjects: PropTypes.func.isRequired, | ||||||
|  |   resetProject: PropTypes.func.isRequired, | ||||||
|  |   projects: PropTypes.array.isRequired, | ||||||
|  |   progress: PropTypes.bool.isRequired | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const mapStateToProps = state => ({ | ||||||
|  |   projects: state.project.projects, | ||||||
|  |   progress: state.project.progress | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export default connect(mapStateToProps, { getProjects, resetProject })(ProjectHome); | ||||||
|  | |||||||
| @ -3,12 +3,14 @@ import workspaceReducer from './workspaceReducer'; | |||||||
| import tutorialReducer from './tutorialReducer'; | import tutorialReducer from './tutorialReducer'; | ||||||
| import tutorialBuilderReducer from './tutorialBuilderReducer'; | import tutorialBuilderReducer from './tutorialBuilderReducer'; | ||||||
| import generalReducer from './generalReducer'; | import generalReducer from './generalReducer'; | ||||||
|  | import projectReducer from './projectReducer'; | ||||||
| import messageReducer from './messageReducer'; | import messageReducer from './messageReducer'; | ||||||
| 
 | 
 | ||||||
| export default combineReducers({ | export default combineReducers({ | ||||||
|   workspace: workspaceReducer, |   workspace: workspaceReducer, | ||||||
|   tutorial: tutorialReducer, |   tutorial: tutorialReducer, | ||||||
|   builder: tutorialBuilderReducer, |   builder: tutorialBuilderReducer, | ||||||
|  |   project: projectReducer, | ||||||
|   general: generalReducer, |   general: generalReducer, | ||||||
|   message: messageReducer |   message: messageReducer | ||||||
| }); | }); | ||||||
|  | |||||||
							
								
								
									
										34
									
								
								src/reducers/projectReducer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/reducers/projectReducer.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | import { PROJECT_PROGRESS, GET_PROJECT, GET_PROJECTS, PROJECT_TYPE } from '../actions/types'; | ||||||
|  | 
 | ||||||
|  | const initialState = { | ||||||
|  |   projects: [], | ||||||
|  |   type: '', | ||||||
|  |   progress: false | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default function (state = initialState, action) { | ||||||
|  |   switch (action.type) { | ||||||
|  |     case PROJECT_PROGRESS: | ||||||
|  |       return { | ||||||
|  |         ...state, | ||||||
|  |         progress: !state.progress | ||||||
|  |       } | ||||||
|  |     case GET_PROJECTS: | ||||||
|  |       return { | ||||||
|  |         ...state, | ||||||
|  |         projects: action.payload | ||||||
|  |       }; | ||||||
|  |     case GET_PROJECT: | ||||||
|  |       return { | ||||||
|  |         ...state, | ||||||
|  |         projects: [action.payload] | ||||||
|  |       } | ||||||
|  |     case PROJECT_TYPE: | ||||||
|  |       return { | ||||||
|  |         ...state, | ||||||
|  |         type: action.payload | ||||||
|  |       } | ||||||
|  |     default: | ||||||
|  |       return state; | ||||||
|  |   } | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user