Compare commits

..

4 Commits

Author SHA1 Message Date
wpetit 7666509ea8 Merge git://192.168.0.112 2020-02-19 13:22:26 +01:00
Gael Peltey 7e99995c98 ajout fixtures 2020-02-19 12:57:53 +01:00
Gael Peltey dc741916c4 Merge branch 'master' of https://forge.cadoles.com/wpetit/react-logo 2020-02-19 11:53:35 +01:00
Gael Peltey a10297e22a List projet + list request 2020-02-19 11:53:32 +01:00
18 changed files with 614 additions and 13 deletions

View File

@ -3,6 +3,7 @@
namespace App\DataFixtures; namespace App\DataFixtures;
use App\Entity\Project; use App\Entity\Project;
use App\Entity\Request;
use App\Entity\User; use App\Entity\User;
use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface; use Doctrine\Common\DataFixtures\DependentFixtureInterface;
@ -14,15 +15,77 @@ class ProjectFixtures extends Fixture implements DependentFixtureInterface
public function load(ObjectManager $manager) public function load(ObjectManager $manager)
{ {
$dev1 = $manager //NEW PROJECT
$user = $manager
->getRepository(User::class) ->getRepository(User::class)
->findOneByUsername('dev1') ->findOneByUsername('dev1')
; ;
$project1 = new Project(); $project = new Project();
$project1->setName("Test"); $request = $manager
$project1->addUser($dev1); ->getRepository(Request::class)
$manager->persist($project1); ->findOneByTitle('Demande num 1')
;
$project->addRequest($request);
$request = $manager
->getRepository(Request::class)
->findOneByTitle('Demande num 2')
;
$project->addRequest($request);
$request = $manager
->getRepository(Request::class)
->findOneByTitle('Demande num 3')
;
$project->addRequest($request);
$project->setName("Projet 1");
$project->addUser($user);
$manager->persist($project);
//NEW PROJECT
$user = $manager
->getRepository(User::class)
->findOneByUsername('client1')
;
$project = new Project();
$request = $manager
->getRepository(Request::class)
->findOneByTitle('Demande num 4')
;
$project->addRequest($request);
$request = $manager
->getRepository(Request::class)
->findOneByTitle('Demande num 5')
;
$project->addRequest($request);
$project->setName("Projet 2");
$project->addUser($user);
$manager->persist($project);
//NEW PROJECT
$user = $manager
->getRepository(User::class)
->findOneByUsername('client1')
;
$project = new Project();
$project->setName("Projet 3");
$project->addUser($user);
$manager->persist($project);
//NEW PROJECT
$user = $manager
->getRepository(User::class)
->findOneByUsername('client2')
;
$project = new Project();
$project->setName("Projet 4");
$project->addUser($user);
$manager->persist($project);
$manager->flush(); $manager->flush();
@ -32,6 +95,7 @@ class ProjectFixtures extends Fixture implements DependentFixtureInterface
{ {
return [ return [
UserFixtures::class, UserFixtures::class,
RequestFixtures::class
]; ];
} }

View File

@ -0,0 +1,121 @@
<?php
namespace App\DataFixtures;
use App\Entity\Request;
use App\Entity\RequestStatus;
use App\Entity\User;
use DateTime;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
class RequestFixtures extends Fixture implements DependentFixtureInterface
{
public function load(ObjectManager $manager)
{
//NEW REQUEST
$user = $manager
->getRepository(User::class)
->findOneByUsername('client1')
;
$status = $manager
->getRepository(RequestStatus::class)
->findOneBySlug('en-attente')
;
$request = new Request();
$request->setTitle("Demande num 1");
$request->setAuthor($user);
$request->setCreatedAt(new DateTime());
$request->setStatus($status);
$manager->persist($request);
//NEW REQUEST
$user = $manager
->getRepository(User::class)
->findOneByUsername('client1')
;
$status = $manager
->getRepository(RequestStatus::class)
->findOneBySlug('pris-en-compte')
;
$request = new Request();
$request->setTitle("Demande num 2");
$request->setAuthor($user);
$request->setCreatedAt(new DateTime());
$request->setStatus($status);
$manager->persist($request);
//NEW REQUEST
$user = $manager
->getRepository(User::class)
->findOneByUsername('client1')
;
$status = $manager
->getRepository(RequestStatus::class)
->findOneBySlug('en-cours-de-traitement')
;
$request = new Request();
$request->setTitle("Demande num 3");
$request->setAuthor($user);
$request->setCreatedAt(new DateTime());
$request->setStatus($status);
$manager->persist($request);
//NEW REQUEST
$user = $manager
->getRepository(User::class)
->findOneByUsername('client2')
;
$status = $manager
->getRepository(RequestStatus::class)
->findOneBySlug('traite')
;
$request = new Request();
$request->setTitle("Demande num 4");
$request->setAuthor($user);
$request->setCreatedAt(new DateTime());
$request->setStatus($status);
$manager->persist($request);
//NEW REQUEST
$user = $manager
->getRepository(User::class)
->findOneByUsername('client2')
;
$status = $manager
->getRepository(RequestStatus::class)
->findOneBySlug('clos')
;
$request = new Request();
$request->setTitle("Demande num 5");
$request->setAuthor($user);
$request->setCreatedAt(new DateTime());
$request->setStatus($status);
$manager->persist($request);
$manager->flush();
}
public function getDependencies()
{
return [
RequestStatusFixtures::class,
UserFixtures::class,
];
}
}

View File

@ -11,16 +11,32 @@ class RequestStatusFixtures extends Fixture
public function load(ObjectManager $manager) public function load(ObjectManager $manager)
{ {
$statuses = [ $statuses = [
'En attente', [
'Pris en compte', 'label' => 'En attente',
'En cours de traitement', 'slug' => 'en-attente'
'Traité', ],
'Clos', [
'label' => 'Pris en compte',
'slug' => 'pris-en-compte'
],
[
'label' => 'En cours de traitement',
'slug' => 'en-cours-de-traitement'
],
[
'label' => 'Traité',
'slug' => 'traite'
],
[
'label' => 'Clos',
'slug' => 'clos'
],
]; ];
foreach($statuses as $statusLabel) { foreach($statuses as $s) {
$status = new RequestStatus(); $status = new RequestStatus();
$status->setLabel($statusLabel); $status->setLabel($s['label']);
$status->setSlug($s['slug']);
$manager->persist($status); $manager->persist($status);
} }

View File

@ -23,6 +23,11 @@ class RequestStatus
*/ */
private $label; private $label;
/**
* @ORM\Column(type="string", length=64)
*/
private $slug;
/** /**
* @ORM\OneToMany(targetEntity="App\Entity\Request", mappedBy="status") * @ORM\OneToMany(targetEntity="App\Entity\Request", mappedBy="status")
*/ */
@ -50,6 +55,18 @@ class RequestStatus
return $this; return $this;
} }
public function getSlug(): ?string
{
return $this->slug;
}
public function setSlug(string $slug): self
{
$this->slug = $slug;
return $this;
}
/** /**
* @return Collection|Request[] * @return Collection|Request[]
*/ */

View File

@ -0,0 +1,27 @@
export const PROJECT_USER_LIST = 'PROJECT_USER_LIST';
export const PROJECT_USER_LIST_SUCCESS = 'PROJECT_USER_LIST_SUCCESS';
export const PROJECT_USER_LIST_FAILURE = 'PROJECT_USER_LIST_FAILURE';
export function projectUserListRequest() {
return { type: PROJECT_USER_LIST}
}
export function projectUserListSuccess(projects) {
return { type: PROJECT_USER_LIST_SUCCESS, projects }
}
export function projectUserListFailure(error) {
return { type: PROJECT_USER_LIST_FAILURE, error }
}
export const PROJECT_LIST = 'PROJECT_LIST';
export const PROJECT_LIST_SUCCESS = 'PROJECT_LIST_SUCCESS';
export const PROJECT_LIST_FAILURE = 'PROJECT_LIST_FAILURE';
export function projectList() {
return { type: PROJECT_LIST}
}
export function projectListSuccess(projects) {
return { type: PROJECT_LIST_SUCCESS, projects }
}
export function projectListFailure(error) {
return { type: PROJECT_LIST_FAILURE, error }
}

View File

@ -4,6 +4,8 @@ import { HashRouter } from 'react-router-dom' // ou BrowserRouter
import { Route, Switch, Redirect } from 'react-router' import { Route, Switch, Redirect } from 'react-router'
import HomePage from './pages/home'; import HomePage from './pages/home';
import { ConnectedLoginPage as LoginPage } from './pages/login'; import { ConnectedLoginPage as LoginPage } from './pages/login';
import DashBoardClient from './pages/DashBoardClient';
import DashBoardDev from './pages/DashBoardDev';
class App extends Component { class App extends Component {
render () { render () {
@ -13,6 +15,8 @@ class App extends Component {
<Switch> <Switch>
<Route path='/login' exact component={LoginPage} /> <Route path='/login' exact component={LoginPage} />
<Route path='/home' exact component={HomePage} /> <Route path='/home' exact component={HomePage} />
<Route path='/dashboard-client' exact component={DashBoardClient} />
<Route path='/dashboard-dev' exact component={DashBoardDev} />
<Route component={() => <Redirect to="/home" />} /> <Route component={() => <Redirect to="/home" />} />
</Switch> </Switch>
</HashRouter> </HashRouter>

View File

@ -0,0 +1,12 @@
import React from 'react'
import ProjectTile from './ProjectTile'
export default ({ projects, withRequest }) => (
<div className="tile is-parent is-vertical">
{
projects.map(project => (
<ProjectTile key={project.id} project={project} withRequest={withRequest} />
))
}
</div>
)

View File

@ -0,0 +1,11 @@
import React from 'react'
import RequestList from './RequestList'
export default ({ project, withRequest }) => (
<article className="tile is-child notification is-primary">
<p className="title">{project.name}</p>
{
withRequest && <RequestList requests={project.requests || []} />
}
</article>
)

View File

@ -0,0 +1,12 @@
import React from 'react'
import RequestTile from './RequestTile'
export default ({ requests }) => (
<div className="tile is-parent is-vertical">
{
requests.map(request => (
<RequestTile key={request.id} request={request} />
))
}
</div>
)

View File

@ -0,0 +1,19 @@
.request-status-en-attente {
background-color: orange !important;
}
.request-status-pris-en-compte {
background-color: palevioletred !important;
}
.request-status-en-cours-de-traitement {
background-color: greenyellow !important;
}
.request-status-traite {
background-color: green !important;
}
.request-status-clos {
background-color: black !important;
}

View File

@ -0,0 +1,14 @@
import React from 'react'
import styles from './RequestTile.css'
import { Link } from 'react-router-dom'
export default ({ request }) => (
<Link to={`dashboard-client/detail-demande/${request.id}`}>
<article className={`tile is-child notification request-status-${request.status.slug}`}>
<p className="title">{request.title}</p>
<div className="content">
<span>{request.author}</span> || <span>{request.createdAt}</span>
</div>
</article>
</Link>
)

View File

@ -0,0 +1,97 @@
import React, { useEffect } from 'react'
import { connect } from 'react-redux'
import Page from './page';
import ProjectList from '../components/ProjectList';
import { projectUserListRequest } from '../actions/project';
const DashBoardClient = ({ projects = [], ...props }) => {
useEffect(() => {
props.dispatch(projectUserListRequest())
}, [])
projects = [
{
id: 1,
name: 'mon premier projet',
requests: [
{
id: 1,
title: 'Demande num 1',
author: 'Gael Peltey',
status: {
id: 1,
slug: 'en-attente'
},
createdAt: 'le 20 juillet 2019'
},
{
id: 2,
title: 'Demande num 2',
author: 'Jean Guy',
status: {
id: 2,
slug: 'pris-en-compte'
},
createdAt: 'le 20 juillet 2020'
},
{
id: 3,
title: 'Demande num 3',
author: 'Gael Peltey',
status: {
id: 3,
slug: 'en-cours-de-traitement'
},
createdAt: 'le 20 juillet 2021'
}
]
},
{
id: 2,
name: 'mon deuxième projet',
},
{
id: 3,
name: 'mon troisième projet',
requests: [
{
id: 4,
title: 'Demande num 4',
author: 'David Pujadas',
status: {
id: 4,
slug: 'traite'
},
createdAt: 'le 20 juillet 2022'
},
{
id: 5,
title: 'Demande num 5',
author: 'Jean Mi',
status: {
id: 5,
slug: 'clos'
},
createdAt: 'le 20 juillet 2023'
}
]
},
]
return (
<Page title="dashBoard client">
<div className="notification">
<h1>Mon dashboard</h1>
</div>
<ProjectList projects={projects} withRequest />
</Page>
);
}
const mapStateToProps = ({ project }) => ({
projects: project.items,
})
export default connect(mapStateToProps)(DashBoardClient)

View File

@ -0,0 +1,97 @@
import React, { useEffect } from 'react'
import { connect } from 'react-redux'
import Page from './page';
import ProjectList from '../components/ProjectList';
import { projectList } from '../actions/project';
const DashBoardDev = ({ projects = [], ...props }) => {
useEffect(() => {
props.dispatch(projectList())
}, [])
projects = [
{
id: 1,
name: 'mon premier projet',
requests: [
{
id: 1,
title: 'Demande num 1',
author: 'Gael Peltey',
status: {
id: 1,
slug: 'en-attente'
},
createdAt: 'le 20 juillet 2019'
},
{
id: 2,
title: 'Demande num 2',
author: 'Jean Guy',
status: {
id: 2,
slug: 'pris-en-compte'
},
createdAt: 'le 20 juillet 2020'
},
{
id: 3,
title: 'Demande num 3',
author: 'Gael Peltey',
status: {
id: 3,
slug: 'en-cours-de-traitement'
},
createdAt: 'le 20 juillet 2021'
}
]
},
{
id: 2,
name: 'mon deuxième projet',
},
{
id: 3,
name: 'mon troisième projet',
requests: [
{
id: 4,
title: 'Demande num 4',
author: 'David Pujadas',
status: {
id: 4,
slug: 'traite'
},
createdAt: 'le 20 juillet 2022'
},
{
id: 5,
title: 'Demande num 5',
author: 'Jean Mi',
status: {
id: 5,
slug: 'clos'
},
createdAt: 'le 20 juillet 2023'
}
]
},
]
return (
<Page title="dashBoard dev">
<div className="notification">
<h1>Developpeur Dashboard</h1>
</div>
<ProjectList projects={projects} />
</Page>
);
}
const mapStateToProps = ({ project }) => ({
projects: project.items,
})
export default connect(mapStateToProps)(DashBoardDev)

View File

@ -19,7 +19,7 @@ export default function Page({ title, messages, dispatch, children }) {
}, [messages]) }, [messages])
return ( return (
<div className="container-fluid"> <div className="container">
<MessageList messages={messages} /> <MessageList messages={messages} />
{ children } { children }
</div> </div>

View File

@ -0,0 +1,31 @@
import {
PROJECT_USER_LIST_SUCCESS,
PROJECT_USER_LIST_FAILURE
} from '../actions/project'
const initialState = {
items: []
}
export default (state = initialState, action) => {
console.log(`Action: ${JSON.stringify(action)}`)
switch (action.type) {
case PROJECT_USER_LIST_SUCCESS:
return {
...state,
items: action.projects
}
case PROJECT_USER_LIST_FAILURE:
return {
...state,
items: [],
error: action.error
}
}
return state
}

View File

@ -0,0 +1,53 @@
import { call, put } from 'redux-saga/effects';
import { projectUserListFailure, projectUserListSuccess, projectListFailure, projectListSuccess } from '../actions/project';
export function* projectUserListSaga() {
let result
try {
result = yield call(projectUserList);
} catch(err) {
yield put(projectUserListFailure(err));
return
}
if ('error' in result) {
yield put(projectUserListFailure(result.error));
return
}
yield put(projectUserListSuccess(result.data));
}
const projectUserList = () => {
return fetch('http://localhost:8001/api/v1/me', {
method: 'GET',
mode: 'cors',
credentials: 'include'
}).then(res => res.json())
}
export function* projectListSaga() {
let result
try {
result = yield call(projectList);
} catch(err) {
yield put(projectListFailure(err));
return
}
if ('error' in result) {
yield put(projectListFailure(result.error));
return
}
yield put(projectListSuccess(result.data));
}
const projectList = () => {
return fetch('http://localhost:8001/api/v1/projects', {
method: 'GET',
mode: 'cors',
credentials: 'include'
}).then(res => res.json())
}

View File

@ -1,9 +1,13 @@
import { all, takeLatest } from 'redux-saga/effects'; import { all, takeLatest } from 'redux-saga/effects';
import { LOGIN_REQUEST } from '../actions/auth.actions'; import { LOGIN_REQUEST } from '../actions/auth.actions';
import { loginSaga} from './auth.sagas'; import { loginSaga} from './auth.sagas';
import { PROJECT_USER_LIST, PROJECT_LIST } from '../actions/project';
import { projectUserListSaga, projectListSaga } from './project';
export default function* rootSaga() { export default function* rootSaga() {
yield all([ yield all([
takeLatest(LOGIN_REQUEST, loginSaga), takeLatest(LOGIN_REQUEST, loginSaga),
takeLatest(PROJECT_USER_LIST, projectUserListSaga),
takeLatest(PROJECT_LIST, projectListSaga),
]); ]);
} }

View File

@ -3,12 +3,14 @@ import createSagaMiddleware from 'redux-saga'
import rootSaga from '../sagas/root' import rootSaga from '../sagas/root'
import { sessionReducer } from '../reducers/session.reducers'; import { sessionReducer } from '../reducers/session.reducers';
import { messagesReducer } from '../reducers/messages.reducers'; import { messagesReducer } from '../reducers/messages.reducers';
import project from '../reducers/project'
const sagaMiddleware = createSagaMiddleware() const sagaMiddleware = createSagaMiddleware()
const rootReducer = combineReducers({ const rootReducer = combineReducers({
session: sessionReducer, session: sessionReducer,
messages: messagesReducer, messages: messagesReducer,
project
}); });
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;