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_SUCCESS = 'GET_SUCCESS'; | ||||
| 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> | ||||
|         <AppBar | ||||
|           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 }} | ||||
|         > | ||||
|           <Toolbar style={{ height: '50px', minHeight: '50px', padding: 0, color: 'white' }}> | ||||
| @ -102,7 +102,7 @@ class Navbar extends Component { | ||||
|             {[{ text: 'Tutorials', icon: faChalkboardTeacher, link: "/tutorial" }, | ||||
|               { text: 'Tutorial-Builder', icon: faTools, link: "/tutorial/builder" }, | ||||
|               { text: 'Galerie', icon: faLightbulb, link: "/gallery" }, | ||||
|               { text: 'Projekte', icon: faLayerGroup, link: "/project" },  | ||||
|               { text: 'Projekte', icon: faLayerGroup, link: "/project" }, | ||||
|               { text: 'Einstellungen', icon: faCog, link: "/settings" }].map((item, index) => ( | ||||
|               <Link to={item.link} key={index} style={{ textDecoration: 'none', color: 'inherit' }}> | ||||
|                 <ListItem button onClick={this.toggleDrawer}> | ||||
| @ -122,7 +122,7 @@ class Navbar extends Component { | ||||
|             ))} | ||||
|           </List> */} | ||||
|         </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)'}}/> | ||||
|         : null} | ||||
|       </div> | ||||
| @ -131,11 +131,13 @@ class Navbar extends Component { | ||||
| } | ||||
| 
 | ||||
| Navbar.propTypes = { | ||||
|   isLoading: PropTypes.bool.isRequired | ||||
|   tutorialIsLoading: PropTypes.bool.isRequired, | ||||
|   projectIsLoading: PropTypes.bool.isRequired | ||||
| }; | ||||
| 
 | ||||
| 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))); | ||||
|  | ||||
| @ -2,6 +2,8 @@ import React, { Component } from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import { connect } from 'react-redux'; | ||||
| import { workspaceName } from '../../actions/workspaceActions'; | ||||
| import { getProject, resetProject } from '../../actions/projectActions'; | ||||
| import { clearMessages } from '../../actions/messageActions'; | ||||
| 
 | ||||
| import axios from 'axios'; | ||||
| import { createNameId } from 'mnemonic-id'; | ||||
| @ -15,69 +17,77 @@ import CircularProgress from '@material-ui/core/CircularProgress'; | ||||
| 
 | ||||
| class Project extends Component { | ||||
| 
 | ||||
|   state = { | ||||
|     project: {}, | ||||
|     progress: false, | ||||
|     type: '' | ||||
|   } | ||||
| 
 | ||||
|   componentDidMount() { | ||||
|     this.getProject(); | ||||
|   } | ||||
| 
 | ||||
|   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(); | ||||
|     } | ||||
|     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 = () => { | ||||
|     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`]; | ||||
|     axios.get(`${process.env.REACT_APP_BLOCKLY_API}/${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); | ||||
|       }); | ||||
|     this.props.getProject(param, id); | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|     var data = this.state.type === 'project' ? 'Projekte' : 'Galerie'; | ||||
|     var data = this.props.type === 'project' ? 'Projekte' : 'Galerie'; | ||||
|     return ( | ||||
|       this.state.progress ? | ||||
|       this.props.progress ? | ||||
|         <Backdrop open invisible> | ||||
|           <CircularProgress color="primary" /> | ||||
|         </Backdrop> | ||||
|       : | ||||
|       : this.props.project ? | ||||
|         <div> | ||||
|           {this.state.type !== 'share' ? | ||||
|             <Breadcrumbs content={[{ link: `/${this.state.type}`, title: data },{ link: this.props.location.path, title: this.state.project.title }]} /> | ||||
|           {this.props.type !== 'share' ? | ||||
|             <Breadcrumbs content={[{ link: `/${this.props.type}`, title: data },{ link: this.props.location.path, title: this.props.project.title }]} /> | ||||
|           : null} | ||||
|           <Home project={this.state.project.xml}/> | ||||
|         </div> | ||||
|           <Home project={this.props.project.xml}/> | ||||
|         </div> : null | ||||
|     ); | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| 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 PropTypes from 'prop-types'; | ||||
| import { connect } from 'react-redux'; | ||||
| import { getProjects, resetProject } from '../../actions/projectActions'; | ||||
| 
 | ||||
| import axios from 'axios'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| @ -14,32 +17,21 @@ import Typography from '@material-ui/core/Typography'; | ||||
| 
 | ||||
| class ProjectHome extends Component { | ||||
| 
 | ||||
|   state = { | ||||
|     projects: [] | ||||
|   } | ||||
| 
 | ||||
|   componentDidMount() { | ||||
|     this.getProjects(); | ||||
|     this.props.getProjects(this.props.match.path.replace('/','')); | ||||
|   } | ||||
| 
 | ||||
|   componentDidUpdate(props) { | ||||
|     if(props.match.path !== this.props.match.path){ | ||||
|       this.setState({projects: []}); | ||||
|       this.getProjects(); | ||||
|       this.props.getProjects(this.props.match.path.replace('/','')); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   getProjects = () => { | ||||
|     var data = this.props.match.path === '/project' ? 'projects' : 'galleries'; | ||||
|     axios.get(`${process.env.REACT_APP_BLOCKLY_API}${this.props.match.path}`) | ||||
|       .then(res => { | ||||
|         this.setState({ projects: res.data[data] }); | ||||
|       }) | ||||
|       .catch(err => { | ||||
|         // TODO:
 | ||||
|       }); | ||||
|   componentWillUnmount() { | ||||
|     this.props.resetProject(); | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|   render() { | ||||
|     var data = this.props.match.path === '/project' ? 'Projekte' : 'Galerie'; | ||||
|     return ( | ||||
| @ -47,8 +39,9 @@ class ProjectHome extends Component { | ||||
|         <Breadcrumbs content={[{ link: this.props.match.path, title: data }]} /> | ||||
| 
 | ||||
|         <h1>{data}</h1> | ||||
|         {this.props.progress ? null : | ||||
|         <Grid container spacing={2}> | ||||
|           {this.state.projects.map((project, i) => { | ||||
|           {this.props.projects.map((project, i) => { | ||||
|             return ( | ||||
|               <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' }}> | ||||
| @ -66,10 +59,23 @@ class ProjectHome extends Component { | ||||
|               </Grid> | ||||
|             ) | ||||
|           })} | ||||
|         </Grid> | ||||
|         </Grid>} | ||||
|       </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 tutorialBuilderReducer from './tutorialBuilderReducer'; | ||||
| import generalReducer from './generalReducer'; | ||||
| import projectReducer from './projectReducer'; | ||||
| import messageReducer from './messageReducer'; | ||||
| 
 | ||||
| export default combineReducers({ | ||||
|   workspace: workspaceReducer, | ||||
|   tutorial: tutorialReducer, | ||||
|   builder: tutorialBuilderReducer, | ||||
|   project: projectReducer, | ||||
|   general: generalReducer, | ||||
|   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