├── project-board-react ├── src │ ├── App.css │ ├── actions │ │ ├── types.js │ │ └── projectTaskActions.js │ ├── App.test.js │ ├── reducers │ │ ├── index.js │ │ ├── errorsReducer.js │ │ └── projectTaskReducer.js │ ├── index.css │ ├── index.js │ ├── components │ │ ├── Navbar.js │ │ ├── ProjectTask │ │ │ ├── ProjectTaskItem.js │ │ │ ├── AddProjectTask.js │ │ │ └── UpdateProjectTask.js │ │ └── ProjectBoard.js │ ├── store.js │ ├── App.js │ └── serviceWorker.js ├── public │ ├── favicon.ico │ ├── manifest.json │ └── index.html ├── .gitignore ├── package.json └── README.md ├── projectboard ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── io │ │ │ └── agileintelligence │ │ │ └── projectboard │ │ │ ├── ProjectboardApplication.java │ │ │ ├── repository │ │ │ └── ProjectTaskRepository.java │ │ │ ├── service │ │ │ └── ProjectTaskService.java │ │ │ ├── domain │ │ │ └── ProjectTask.java │ │ │ └── web │ │ │ └── ProjectTaskController.java │ └── test │ │ └── java │ │ └── io │ │ └── agileintelligence │ │ └── projectboard │ │ └── ProjectboardApplicationTests.java ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.properties │ │ └── maven-wrapper.jar ├── .gitignore ├── pom.xml ├── mvnw.cmd └── mvnw ├── .idea ├── modules.xml ├── misc.xml ├── ProjectBoardCourse.iml ├── inspectionProfiles │ └── Project_Default.xml ├── libraries │ └── antlr_2_7_7.xml └── workspace.xml └── design ├── ProjectTaskForm.html └── ProjectBoard.html /project-board-react/src/App.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /projectboard/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /project-board-react/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgileIntYoutube/FullStackProjectSpringReactRedux/HEAD/project-board-react/public/favicon.ico -------------------------------------------------------------------------------- /projectboard/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /projectboard/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgileIntYoutube/FullStackProjectSpringReactRedux/HEAD/projectboard/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /project-board-react/src/actions/types.js: -------------------------------------------------------------------------------- 1 | export const GET_ERRORS = "GET_ERRORS"; 2 | export const GET_PROJECT_TASKS = "GET_PROJECT_TASKS"; 3 | export const GET_PROJECT_TASK = "GET_PROJECT_TASK"; 4 | export const DELETE_PROJECT_TASK = "DELETE_PROJECT_TASK"; 5 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /project-board-react/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /project-board-react/src/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from "redux"; 2 | import errorsReducer from "./errorsReducer"; 3 | import projectTaskReducer from "./projectTaskReducer"; 4 | 5 | export default combineReducers({ 6 | // 7 | errors: errorsReducer, 8 | project_task: projectTaskReducer 9 | }); 10 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /project-board-react/src/reducers/errorsReducer.js: -------------------------------------------------------------------------------- 1 | import { GET_ERRORS } from "../actions/types"; 2 | 3 | const initialState = {}; 4 | 5 | export default function(state = initialState, action) { 6 | switch (action.type) { 7 | case GET_ERRORS: 8 | return action.payload; 9 | 10 | default: 11 | return state; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /projectboard/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ -------------------------------------------------------------------------------- /project-board-react/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /project-board-react/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /project-board-react/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 5 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /projectboard/src/main/java/io/agileintelligence/projectboard/ProjectboardApplication.java: -------------------------------------------------------------------------------- 1 | package io.agileintelligence.projectboard; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ProjectboardApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ProjectboardApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /projectboard/src/main/java/io/agileintelligence/projectboard/repository/ProjectTaskRepository.java: -------------------------------------------------------------------------------- 1 | package io.agileintelligence.projectboard.repository; 2 | 3 | import io.agileintelligence.projectboard.domain.ProjectTask; 4 | import org.springframework.data.repository.CrudRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | @Repository 8 | public interface ProjectTaskRepository extends CrudRepository { 9 | 10 | ProjectTask getById(Long id); 11 | } 12 | -------------------------------------------------------------------------------- /projectboard/src/test/java/io/agileintelligence/projectboard/ProjectboardApplicationTests.java: -------------------------------------------------------------------------------- 1 | package io.agileintelligence.projectboard; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class ProjectboardApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /project-board-react/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | 9 | // If you want your app to work offline and load faster, you can change 10 | // unregister() to register() below. Note this comes with some pitfalls. 11 | // Learn more about service workers: http://bit.ly/CRA-PWA 12 | serviceWorker.unregister(); 13 | -------------------------------------------------------------------------------- /.idea/ProjectBoardCourse.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /project-board-react/src/components/Navbar.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function Navbar() { 4 | return ( 5 | 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /project-board-react/src/store.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware, compose } from "redux"; 2 | import thunk from "redux-thunk"; 3 | import rootReducer from "./reducers"; 4 | 5 | const initialState = {}; 6 | const middleware = [thunk]; 7 | 8 | const ReactReduxDevTools = 9 | window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(); 10 | let store; 11 | 12 | if (window.navigator.userAgent.includes("Chrome") && ReactReduxDevTools) { 13 | store = createStore( 14 | rootReducer, 15 | initialState, 16 | compose( 17 | applyMiddleware(...middleware), 18 | ReactReduxDevTools 19 | ) 20 | ); 21 | } else { 22 | store = createStore( 23 | rootReducer, 24 | initialState, 25 | compose(applyMiddleware(...middleware)) 26 | ); 27 | } 28 | 29 | export default store; 30 | -------------------------------------------------------------------------------- /project-board-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "project-board-react", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "axios": "^0.18.0", 7 | "bootstrap": "^4.1.3", 8 | "classnames": "^2.2.6", 9 | "react": "^16.5.2", 10 | "react-dom": "^16.5.2", 11 | "react-redux": "^5.1.0", 12 | "react-router-dom": "^4.3.1", 13 | "react-scripts": "2.0.5", 14 | "redux": "^4.0.1", 15 | "redux-thunk": "^2.3.0" 16 | }, 17 | "scripts": { 18 | "start": "react-scripts start", 19 | "build": "react-scripts build", 20 | "test": "react-scripts test", 21 | "eject": "react-scripts eject" 22 | }, 23 | "eslintConfig": { 24 | "extends": "react-app" 25 | }, 26 | "browserslist": [ 27 | ">0.2%", 28 | "not dead", 29 | "not ie <= 11", 30 | "not op_mini all" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /project-board-react/src/reducers/projectTaskReducer.js: -------------------------------------------------------------------------------- 1 | import { 2 | GET_PROJECT_TASKS, 3 | DELETE_PROJECT_TASK, 4 | GET_PROJECT_TASK 5 | } from "../actions/types"; 6 | 7 | const initialState = { 8 | project_tasks: [], 9 | project_task: {} 10 | }; 11 | 12 | export default function(state = initialState, action) { 13 | switch (action.type) { 14 | case GET_PROJECT_TASKS: 15 | return { 16 | ...state, 17 | project_tasks: action.payload 18 | }; 19 | 20 | case GET_PROJECT_TASK: 21 | return { 22 | ...state, 23 | project_task: action.payload 24 | }; 25 | 26 | case DELETE_PROJECT_TASK: 27 | return { 28 | ...state, 29 | project_tasks: state.project_tasks.filter( 30 | project_task => project_task.id !== action.payload 31 | ) 32 | }; 33 | default: 34 | return state; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /project-board-react/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import "./App.css"; 3 | import "bootstrap/dist/css/bootstrap.min.css"; 4 | import Navbar from "./components/Navbar"; 5 | import ProjectBoard from "./components/ProjectBoard"; 6 | import { BrowserRouter as Router, Route } from "react-router-dom"; 7 | import AddProjectTask from "./components/ProjectTask/AddProjectTask"; 8 | import { Provider } from "react-redux"; 9 | import store from "./store"; 10 | import UpdateProjectTask from "./components/ProjectTask/UpdateProjectTask"; 11 | 12 | class App extends Component { 13 | render() { 14 | return ( 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 27 |
28 |
29 |
30 | ); 31 | } 32 | } 33 | 34 | export default App; 35 | -------------------------------------------------------------------------------- /projectboard/src/main/java/io/agileintelligence/projectboard/service/ProjectTaskService.java: -------------------------------------------------------------------------------- 1 | package io.agileintelligence.projectboard.service; 2 | 3 | import io.agileintelligence.projectboard.domain.ProjectTask; 4 | import io.agileintelligence.projectboard.repository.ProjectTaskRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | @Service 9 | public class ProjectTaskService { 10 | 11 | @Autowired 12 | private ProjectTaskRepository projectTaskRepository; 13 | 14 | public ProjectTask saveOrUpdateProjectTask(ProjectTask projectTask){ 15 | 16 | if(projectTask.getStatus()==null || projectTask.getStatus()==""){ 17 | projectTask.setStatus("TO_DO"); 18 | } 19 | 20 | return projectTaskRepository.save(projectTask); 21 | } 22 | 23 | 24 | public Iterable findAll(){ 25 | return projectTaskRepository.findAll(); 26 | } 27 | 28 | public ProjectTask findById(Long id){ 29 | return projectTaskRepository.getById(id); 30 | } 31 | 32 | public void delete(Long id){ 33 | ProjectTask projectTask = findById(id); 34 | projectTaskRepository.delete(projectTask); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /.idea/libraries/antlr_2_7_7.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /projectboard/src/main/java/io/agileintelligence/projectboard/domain/ProjectTask.java: -------------------------------------------------------------------------------- 1 | package io.agileintelligence.projectboard.domain; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | import javax.validation.constraints.NotBlank; 8 | 9 | @Entity 10 | public class ProjectTask { 11 | 12 | @Id 13 | @GeneratedValue(strategy = GenerationType.IDENTITY) 14 | private Long id; 15 | 16 | @NotBlank(message = "Summary cannot be blank") 17 | private String summary; 18 | private String acceptanceCriteria; 19 | private String status; 20 | 21 | public ProjectTask() { 22 | } 23 | 24 | 25 | public Long getId() { 26 | return id; 27 | } 28 | 29 | public void setId(Long id) { 30 | this.id = id; 31 | } 32 | 33 | public String getSummary() { 34 | return summary; 35 | } 36 | 37 | public void setSummary(String summary) { 38 | this.summary = summary; 39 | } 40 | 41 | public String getAcceptanceCriteria() { 42 | return acceptanceCriteria; 43 | } 44 | 45 | public void setAcceptanceCriteria(String acceptanceCriteria) { 46 | this.acceptanceCriteria = acceptanceCriteria; 47 | } 48 | 49 | public String getStatus() { 50 | return status; 51 | } 52 | 53 | public void setStatus(String status) { 54 | this.status = status; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /project-board-react/src/components/ProjectTask/ProjectTaskItem.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { Link } from "react-router-dom"; 3 | import PropTypes from "prop-types"; 4 | import { connect } from "react-redux"; 5 | import { deleteProjectTask } from "../../actions/projectTaskActions"; 6 | 7 | class ProjectTaskItem extends Component { 8 | onDeleteClick(pt_id) { 9 | this.props.deleteProjectTask(pt_id); 10 | } 11 | 12 | render() { 13 | const { project_task } = this.props; 14 | return ( 15 |
16 |
ID: {project_task.id}
17 |
18 |
{project_task.summary}
19 |

20 | {project_task.acceptanceCriteria} 21 |

22 | 26 | View / Update 27 | 28 | 29 | 35 |
36 |
37 | ); 38 | } 39 | } 40 | 41 | ProjectTaskItem.propTypes = { 42 | deleteProjectTask: PropTypes.func.isRequired 43 | }; 44 | 45 | export default connect( 46 | null, 47 | { deleteProjectTask } 48 | )(ProjectTaskItem); 49 | -------------------------------------------------------------------------------- /project-board-react/src/actions/projectTaskActions.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { 3 | GET_ERRORS, 4 | GET_PROJECT_TASKS, 5 | DELETE_PROJECT_TASK, 6 | GET_PROJECT_TASK 7 | } from "./types"; 8 | 9 | export const addProjectTask = (project_task, history) => async dispatch => { 10 | try { 11 | await axios.post("http://localhost:8080/api/board", project_task); 12 | history.push("/"); 13 | dispatch({ 14 | type: GET_ERRORS, 15 | payload: {} 16 | }); 17 | } catch (error) { 18 | dispatch({ 19 | type: GET_ERRORS, 20 | payload: error.response.data 21 | }); 22 | } 23 | }; 24 | 25 | export const getBacklog = () => async dispatch => { 26 | const res = await axios.get("http://localhost:8080/api/board/all"); 27 | dispatch({ 28 | type: GET_PROJECT_TASKS, 29 | payload: res.data 30 | }); 31 | }; 32 | 33 | export const deleteProjectTask = pt_id => async dispatch => { 34 | if ( 35 | window.confirm( 36 | `You are deleting project task ${pt_id}, this action cannot be undone` 37 | ) 38 | ) { 39 | await axios.delete(`http://localhost:8080/api/board/${pt_id}`); 40 | dispatch({ 41 | type: DELETE_PROJECT_TASK, 42 | payload: pt_id 43 | }); 44 | } 45 | }; 46 | 47 | export const getProjectTask = (pt_id, history) => async dispatch => { 48 | try { 49 | const res = await axios.get(`http://localhost:8080/api/board/${pt_id}`); 50 | dispatch({ 51 | type: GET_PROJECT_TASK, 52 | payload: res.data 53 | }); 54 | } catch (error) { 55 | history.push("/"); 56 | } 57 | }; 58 | -------------------------------------------------------------------------------- /project-board-react/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 23 | 25 | PROJECT BOARD!!! App 26 | 27 | 28 | 29 | 32 |
33 | 34 |
35 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /projectboard/src/main/java/io/agileintelligence/projectboard/web/ProjectTaskController.java: -------------------------------------------------------------------------------- 1 | package io.agileintelligence.projectboard.web; 2 | 3 | 4 | import io.agileintelligence.projectboard.domain.ProjectTask; 5 | import io.agileintelligence.projectboard.service.ProjectTaskService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.validation.BindingResult; 10 | import org.springframework.validation.FieldError; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | import javax.validation.Valid; 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | 17 | @RestController 18 | @RequestMapping("/api/board") 19 | @CrossOrigin 20 | public class ProjectTaskController { 21 | 22 | @Autowired 23 | private ProjectTaskService projectTaskService; 24 | 25 | @PostMapping("") 26 | public ResponseEntity addPTToBoard(@Valid @RequestBody ProjectTask projectTask, BindingResult result){ 27 | 28 | if(result.hasErrors()){ 29 | Map errorMap = new HashMap<>(); 30 | 31 | for(FieldError error: result.getFieldErrors()){ 32 | errorMap.put(error.getField(), error.getDefaultMessage()); 33 | } 34 | return new ResponseEntity>(errorMap, HttpStatus.BAD_REQUEST); 35 | } 36 | 37 | ProjectTask newPT = projectTaskService.saveOrUpdateProjectTask(projectTask); 38 | 39 | return new ResponseEntity(newPT, HttpStatus.CREATED); 40 | } 41 | 42 | @GetMapping("/all") 43 | public Iterable getAllPTs(){ 44 | return projectTaskService.findAll(); 45 | } 46 | 47 | @GetMapping("/{pt_id}") 48 | public ResponseEntity getPTById(@PathVariable Long pt_id){ 49 | ProjectTask projectTask = projectTaskService.findById(pt_id); 50 | return new ResponseEntity(projectTask, HttpStatus.OK); 51 | } 52 | 53 | @DeleteMapping("/{pt_id}") 54 | public ResponseEntity deleteProjectTask(@PathVariable Long pt_id){ 55 | projectTaskService.delete(pt_id); 56 | 57 | return new ResponseEntity("Project Task deleted", HttpStatus.OK); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /projectboard/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | io.agileintelligence 7 | projectboard 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | projectboard 12 | project board 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.0.6.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-data-jpa 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-web 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-devtools 40 | runtime 41 | 42 | 43 | com.h2database 44 | h2 45 | runtime 46 | 47 | 48 | mysql 49 | mysql-connector-java 50 | runtime 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-starter-test 55 | test 56 | 57 | 58 | 59 | 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-maven-plugin 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /project-board-react/src/components/ProjectBoard.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { Link } from "react-router-dom"; 3 | import ProjectTaskItem from "./ProjectTask/ProjectTaskItem"; 4 | import { connect } from "react-redux"; 5 | import PropTypes from "prop-types"; 6 | import { getBacklog } from "../actions/projectTaskActions"; 7 | 8 | class ProjectBoard extends Component { 9 | componentDidMount() { 10 | this.props.getBacklog(); 11 | } 12 | render() { 13 | const { project_tasks } = this.props.project_tasks; 14 | 15 | let BoardContent; 16 | let todoItems = []; 17 | let inProgressItems = []; 18 | let doneItems = []; 19 | 20 | const BoardAlgorithm = project_tasks => { 21 | if (project_tasks.length < 1) { 22 | return ( 23 |
24 | No Project Tasks on this board 25 |
26 | ); 27 | } else { 28 | const tasks = project_tasks.map(project_task => ( 29 | 30 | )); 31 | 32 | for (let i = 0; i < tasks.length; i++) { 33 | if (tasks[i].props.project_task.status === "TO_DO") { 34 | todoItems.push(tasks[i]); 35 | } 36 | 37 | if (tasks[i].props.project_task.status === "IN_PROGRESS") { 38 | inProgressItems.push(tasks[i]); 39 | } 40 | 41 | if (tasks[i].props.project_task.status === "DONE") { 42 | doneItems.push(tasks[i]); 43 | } 44 | } 45 | 46 | return ( 47 | 48 |
49 |
50 |
51 |
52 |
53 |

TO DO

54 |
55 |
56 | 57 | {todoItems} 58 |
59 |
60 |
61 |
62 |

In Progress

63 |
64 |
65 | 66 | {inProgressItems} 67 |
68 |
69 |
70 |
71 |

Done

72 |
73 |
74 | 75 | {doneItems} 76 |
77 |
78 |
79 |
80 | ); 81 | } 82 | }; 83 | 84 | BoardContent = BoardAlgorithm(project_tasks); 85 | 86 | return ( 87 |
88 | 89 | Create Project Task 90 | 91 |
92 |
93 | {BoardContent} 94 |
95 | ); 96 | } 97 | } 98 | 99 | ProjectBoard.propTypes = { 100 | getBacklog: PropTypes.func.isRequired, 101 | project_tasks: PropTypes.object.isRequired 102 | }; 103 | 104 | const mapStateToProps = state => ({ 105 | project_tasks: state.project_task 106 | }); 107 | 108 | export default connect( 109 | mapStateToProps, 110 | { getBacklog } 111 | )(ProjectBoard); 112 | -------------------------------------------------------------------------------- /design/ProjectTaskForm.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 12 | 13 | 14 | 15 | 16 | 17 | 19 | 20 | Project Task Tool 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 40 | 41 | 42 | 43 | 44 |
45 |
46 |
47 |
48 | 49 | Back to Board 50 | 51 |

Add /Update Project Task

52 |
53 |
54 | 55 |
56 |
57 | 58 |
59 |
60 | 66 |
67 | 68 |
69 |
70 |
71 |
72 |
73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 84 | 86 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /project-board-react/src/components/ProjectTask/AddProjectTask.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { Link } from "react-router-dom"; 3 | import PropTypes from "prop-types"; 4 | import { connect } from "react-redux"; 5 | import { addProjectTask } from "../../actions/projectTaskActions"; 6 | import classnames from "classnames"; 7 | 8 | class AddProjectTask extends Component { 9 | constructor() { 10 | super(); 11 | this.state = { 12 | summary: "", 13 | acceptanceCriteria: "", 14 | status: "", 15 | errors: {} 16 | }; 17 | this.onChange = this.onChange.bind(this); 18 | this.onSubmit = this.onSubmit.bind(this); 19 | } 20 | componentWillReceiveProps(nextProps) { 21 | if (nextProps.errors) { 22 | this.setState({ errors: nextProps.errors }); 23 | } 24 | } 25 | 26 | onChange(e) { 27 | this.setState({ [e.target.name]: e.target.value }); 28 | } 29 | 30 | onSubmit(e) { 31 | e.preventDefault(); 32 | const newProjectTask = { 33 | summary: this.state.summary, 34 | acceptanceCriteria: this.state.acceptanceCriteria, 35 | status: this.state.status 36 | }; 37 | // console.log(newProjectTask); 38 | this.props.addProjectTask(newProjectTask, this.props.history); 39 | } 40 | 41 | render() { 42 | const { errors } = this.state; 43 | return ( 44 |
45 |
46 |
47 |
48 | 49 | Back to Board 50 | 51 |

52 | Add /Update Project Task 53 |

54 |
55 |
56 | 66 | {errors.summary && ( 67 |
{errors.summary}
68 | )} 69 |
70 |
71 |