ESlint: application générale des règles
This commit is contained in:
parent
21fe79684d
commit
e5c5d9c8d2
@ -1,20 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace App\Controller;
|
|
||||||
|
|
||||||
use App\Http\DataResponse;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
|
|
||||||
class RequestController
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/api/v1/request", name="api_v1_list_requests")
|
|
||||||
*/
|
|
||||||
public function listRequests()
|
|
||||||
{
|
|
||||||
return new DataResponse([
|
|
||||||
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,31 +1,47 @@
|
|||||||
export const LOGIN_REQUEST = 'LOGIN_REQUEST'
|
export const LOGIN_REQUEST = 'LOGIN_REQUEST';
|
||||||
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
|
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
|
||||||
export const LOGIN_FAILURE = 'LOGIN_FAILURE';
|
export const LOGIN_FAILURE = 'LOGIN_FAILURE';
|
||||||
|
|
||||||
export function login(username, password) {
|
export function login(username, password) {
|
||||||
return { type: LOGIN_REQUEST, username, password }
|
return { type: LOGIN_REQUEST, username, password };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loginFailure(username, error) {
|
export function loginFailure(username, error) {
|
||||||
return { type: LOGIN_FAILURE, username, error }
|
return { type: LOGIN_FAILURE, username, error };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loginSuccess(username) {
|
export function loginSuccess(username) {
|
||||||
return { type: LOGIN_SUCCESS, username }
|
return { type: LOGIN_SUCCESS, username };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LOGOUT_REQUEST = 'LOGOUT_REQUEST'
|
export const LOGOUT_REQUEST = 'LOGOUT_REQUEST';
|
||||||
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS';
|
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS';
|
||||||
export const LOGOUT_FAILURE = 'LOGOUT_FAILURE';
|
export const LOGOUT_FAILURE = 'LOGOUT_FAILURE';
|
||||||
|
|
||||||
export function logout() {
|
export function logout() {
|
||||||
return { type: LOGOUT_REQUEST }
|
return { type: LOGOUT_REQUEST };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function logoutFailure(error) {
|
export function logoutFailure(error) {
|
||||||
return { type: LOGOUT_FAILURE, error }
|
return { type: LOGOUT_FAILURE, error };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function logoutSuccess() {
|
export function logoutSuccess() {
|
||||||
return { type: LOGOUT_SUCCESS }
|
return { type: LOGOUT_SUCCESS };
|
||||||
|
}
|
||||||
|
|
||||||
|
export const REFRESH_USER_SESSION_REQUEST = 'REFRESH_USER_SESSION_REQUEST';
|
||||||
|
export const REFRESH_USER_SESSION_SUCCESS = 'REFRESH_USER_SESSION_SUCCESS';
|
||||||
|
export const REFRESH_USER_SESSION_FAILURE = 'REFRESH_USER_SESSION_FAILURE';
|
||||||
|
|
||||||
|
export function refreshUserSession() {
|
||||||
|
return { type: REFRESH_USER_SESSION_REQUEST };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function refreshUserSessionSuccess(user) {
|
||||||
|
return { type: REFRESH_USER_SESSION_SUCCESS, user };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function refreshUserSessionFailure(error) {
|
||||||
|
return { type: REFRESH_USER_SESSION_FAILURE, error };
|
||||||
}
|
}
|
@ -1,11 +1,11 @@
|
|||||||
export const ADD_MESSAGE = 'ADD_MESSAGE'
|
export const ADD_MESSAGE = 'ADD_MESSAGE';
|
||||||
|
|
||||||
export function addMessage(type, text) {
|
export function addMessage(type, text) {
|
||||||
return { type: ADD_MESSAGE, text, messageType: type };
|
return { type: ADD_MESSAGE, text, messageType: type };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const REMOVE_OLDEST_MESSAGE = 'REMOVE_OLDEST_MESSAGE'
|
export const REMOVE_OLDEST_MESSAGE = 'REMOVE_OLDEST_MESSAGE';
|
||||||
|
|
||||||
export function removeOldestMessage() {
|
export function removeOldestMessage() {
|
||||||
return { type: REMOVE_OLDEST_MESSAGE }
|
return { type: REMOVE_OLDEST_MESSAGE };
|
||||||
}
|
}
|
@ -3,13 +3,13 @@ export const PROJECT_USER_LIST_SUCCESS = 'PROJECT_USER_LIST_SUCCESS';
|
|||||||
export const PROJECT_USER_LIST_FAILURE = 'PROJECT_USER_LIST_FAILURE';
|
export const PROJECT_USER_LIST_FAILURE = 'PROJECT_USER_LIST_FAILURE';
|
||||||
|
|
||||||
export function projectUserListRequest() {
|
export function projectUserListRequest() {
|
||||||
return { type: PROJECT_USER_LIST}
|
return { type: PROJECT_USER_LIST};
|
||||||
}
|
}
|
||||||
export function projectUserListSuccess(projects) {
|
export function projectUserListSuccess(projects) {
|
||||||
return { type: PROJECT_USER_LIST_SUCCESS, projects }
|
return { type: PROJECT_USER_LIST_SUCCESS, projects };
|
||||||
}
|
}
|
||||||
export function projectUserListFailure(error) {
|
export function projectUserListFailure(error) {
|
||||||
return { type: PROJECT_USER_LIST_FAILURE, error }
|
return { type: PROJECT_USER_LIST_FAILURE, error };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PROJECT_LIST = 'PROJECT_LIST';
|
export const PROJECT_LIST = 'PROJECT_LIST';
|
||||||
@ -17,11 +17,11 @@ export const PROJECT_LIST_SUCCESS = 'PROJECT_LIST_SUCCESS';
|
|||||||
export const PROJECT_LIST_FAILURE = 'PROJECT_LIST_FAILURE';
|
export const PROJECT_LIST_FAILURE = 'PROJECT_LIST_FAILURE';
|
||||||
|
|
||||||
export function projectList() {
|
export function projectList() {
|
||||||
return { type: PROJECT_LIST}
|
return { type: PROJECT_LIST};
|
||||||
}
|
}
|
||||||
export function projectListSuccess(projects) {
|
export function projectListSuccess(projects) {
|
||||||
return { type: PROJECT_LIST_SUCCESS, projects }
|
return { type: PROJECT_LIST_SUCCESS, projects };
|
||||||
}
|
}
|
||||||
export function projectListFailure(error) {
|
export function projectListFailure(error) {
|
||||||
return { type: PROJECT_LIST_FAILURE, error }
|
return { type: PROJECT_LIST_FAILURE, error };
|
||||||
}
|
}
|
@ -3,13 +3,13 @@ export const CREATE_USER_SUCCESS = 'CREATE_USER_SUCCESS';
|
|||||||
export const CREATE_USER_FAILURE = 'CREATE_USER_FAILURE';
|
export const CREATE_USER_FAILURE = 'CREATE_USER_FAILURE';
|
||||||
|
|
||||||
export function createUser(username, password) {
|
export function createUser(username, password) {
|
||||||
return { type: CREATE_USER_REQUEST, username, password}
|
return { type: CREATE_USER_REQUEST, username, password};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createUserSuccess(user) {
|
export function createUserSuccess(user) {
|
||||||
return { type: CREATE_USER_SUCCESS, user }
|
return { type: CREATE_USER_SUCCESS, user };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createUserFailure(error) {
|
export function createUserFailure(error) {
|
||||||
return { type: CREATE_USER_FAILURE, error }
|
return { type: CREATE_USER_FAILURE, error };
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
import { Component, Fragment } from 'react'
|
import { Component, Fragment } from 'react';
|
||||||
import { hot } from 'react-hot-loader'
|
import { hot } from 'react-hot-loader';
|
||||||
import { HashRouter } from 'react-router-dom' // ou BrowserRouter
|
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 { ConnectedHomePage as HomePage } from './pages/home';
|
||||||
import { ConnectedLoginPage as LoginPage } from './pages/login';
|
import { ConnectedLoginPage as LoginPage } from './pages/login';
|
||||||
import DashBoardClient from './pages/DashBoardClient';
|
import DashBoardClient from './pages/DashBoardClient';
|
||||||
import DashBoardDev from './pages/DashBoardDev';
|
import DashBoardDev from './pages/DashBoardDev';
|
||||||
@ -11,24 +11,23 @@ import { connect } from 'react-redux';
|
|||||||
import { history } from './util/history';
|
import { history } from './util/history';
|
||||||
|
|
||||||
export class App extends Component {
|
export class App extends Component {
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<HashRouter history={history}>
|
<HashRouter history={history}>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path='/login' exact component={LoginPage} />
|
<Route path='/login' exact component={LoginPage} />
|
||||||
<Route path='/logout' exact component={LogoutPage} />
|
<Route path='/logout' exact component={LogoutPage} />
|
||||||
<Route path='/home' exact component={HomePage} />
|
<Route path='/home' exact component={HomePage} />
|
||||||
<Route path='/dashboard-client' exact component={DashBoardClient} />
|
<Route path='/dashboard-client' exact component={DashBoardClient} />
|
||||||
<Route path='/dashboard-dev' exact component={DashBoardDev} />
|
<Route path='/dashboard-dev' exact component={DashBoardDev} />
|
||||||
<Route component={() => <Redirect to="/home" />} />
|
<Route component={() => <Redirect to="/home" />} />
|
||||||
</Switch>
|
</Switch>
|
||||||
</HashRouter>
|
</HashRouter>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ConnectedApp = connect()(App);
|
export const ConnectedApp = connect()(App);
|
||||||
export const HotApp = hot(module)(ConnectedApp);
|
export const HotApp = hot(module)(ConnectedApp);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react';
|
||||||
import ProjectTile from './ProjectTile'
|
import ProjectTile from './ProjectTile';
|
||||||
|
|
||||||
export default ({ projects, withRequest }) => (
|
export default ({ projects, withRequest }) => (
|
||||||
<div className="tile is-parent is-vertical">
|
<div className="tile is-parent is-vertical">
|
||||||
@ -9,4 +9,4 @@ export default ({ projects, withRequest }) => (
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import React from 'react'
|
import React from 'react';
|
||||||
import RequestList from './RequestList'
|
import RequestList from './RequestList';
|
||||||
|
|
||||||
export default ({ project, withRequest }) => (
|
export default ({ project, withRequest }) => (
|
||||||
<article className="tile is-child notification is-primary">
|
<article className="tile is-child notification is-primary">
|
||||||
<p className="title">{project.name}</p>
|
<p className="title">{project.name}</p>
|
||||||
{
|
{
|
||||||
withRequest && <RequestList requests={project.requests || []} />
|
withRequest && <RequestList requests={project.requests || []} />
|
||||||
}
|
}
|
||||||
</article>
|
</article>
|
||||||
)
|
);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react';
|
||||||
import RequestTile from './RequestTile'
|
import RequestTile from './RequestTile';
|
||||||
|
|
||||||
export default ({ requests }) => (
|
export default ({ requests }) => (
|
||||||
<div className="tile is-parent is-vertical">
|
<div className="tile is-parent is-vertical">
|
||||||
@ -9,4 +9,4 @@ export default ({ requests }) => (
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react';
|
||||||
import styles from './RequestTile.css'
|
import styles from './RequestTile.css';
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
export default ({ request }) => (
|
export default ({ request }) => (
|
||||||
<Link to={`dashboard-client/detail-demande/${request.id}`}>
|
<Link to={`dashboard-client/detail-demande/${request.id}`}>
|
||||||
@ -11,4 +11,4 @@ export default ({ request }) => (
|
|||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
</Link>
|
</Link>
|
||||||
)
|
);
|
||||||
|
@ -3,74 +3,74 @@ import { WithForm } from './WithForm';
|
|||||||
|
|
||||||
export function UserForm({ form, onSubmit }) {
|
export function UserForm({ form, onSubmit }) {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (form.valid && form.submitted) onSubmit(form.data);
|
if (form.valid && form.submitted) onSubmit(form.data);
|
||||||
}, [form.valid, form.submitted]);
|
}, [form.valid, form.submitted]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="form" onSubmit={form.onSubmit}>
|
<form className="form" onSubmit={form.onSubmit}>
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<label className="label" htmlFor="username">Nom d'utilisateur</label>
|
<label className="label" htmlFor="username">Nom d'utilisateur</label>
|
||||||
<div className="control">
|
<div className="control">
|
||||||
<input className={`input ${form.hasError('username') ? 'is-danger' : ''}`} type="text"
|
<input className={`input ${form.hasError('username') ? 'is-danger' : ''}`} type="text"
|
||||||
name="username" value={form.field('username', '')}
|
name="username" value={form.field('username', '')}
|
||||||
onChange={form.onChange('username')} />
|
onChange={form.onChange('username')} />
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
form.hasError('username') ?
|
form.hasError('username') ?
|
||||||
<p className="help is-danger">{form.error('username')}</p>
|
<p className="help is-danger">{form.error('username')}</p>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<label className="label" htmlFor="password">Mot de passe</label>
|
<label className="label" htmlFor="password">Mot de passe</label>
|
||||||
<div className="control">
|
<div className="control">
|
||||||
<input className={`input ${form.hasError('password') ? 'is-danger' : ''}`}
|
<input className={`input ${form.hasError('password') ? 'is-danger' : ''}`}
|
||||||
type="password" name="password"
|
type="password" name="password"
|
||||||
autoComplete='new-password'
|
autoComplete='new-password'
|
||||||
value={form.field('password', '')}
|
value={form.field('password', '')}
|
||||||
onChange={form.onChange('password')} />
|
onChange={form.onChange('password')} />
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
form.hasError('password') ?
|
form.hasError('password') ?
|
||||||
<p className="help is-danger">{form.error('password')}</p>
|
<p className="help is-danger">{form.error('password')}</p>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<label className="label" htmlFor="passwordVerification">Mot de passe (vérification)</label>
|
<label className="label" htmlFor="passwordVerification">Mot de passe (vérification)</label>
|
||||||
<div className="control">
|
<div className="control">
|
||||||
<input className={`input ${form.hasError('passwordVerification') ? 'is-danger' : ''}`}
|
<input className={`input ${form.hasError('passwordVerification') ? 'is-danger' : ''}`}
|
||||||
type="password" name="passwordVerification"
|
type="password" name="passwordVerification"
|
||||||
autoComplete='new-password'
|
autoComplete='new-password'
|
||||||
value={form.field('passwordVerification', '')}
|
value={form.field('passwordVerification', '')}
|
||||||
onChange={form.onChange('passwordVerification')} />
|
onChange={form.onChange('passwordVerification')} />
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
form.hasError('passwordVerification') ?
|
form.hasError('passwordVerification') ?
|
||||||
<p className="help is-danger">{form.error('passwordVerification')}</p>
|
<p className="help is-danger">{form.error('passwordVerification')}</p>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" disabled={!form.valid} className="button">Envoyer</button>
|
<button type="submit" disabled={!form.valid} className="button">Envoyer</button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
const validators = {
|
const validators = {
|
||||||
username: (value, formData) => {
|
username: (value, formData) => {
|
||||||
if (!value) return { hasError: true, message: 'Le nom d\'utilisateur ne peut être vide !' }
|
if (!value) return { hasError: true, message: 'Le nom d\'utilisateur ne peut être vide !' };
|
||||||
return { hasError: false, message: '' };
|
return { hasError: false, message: '' };
|
||||||
},
|
},
|
||||||
password: (value, formData) => {
|
password: (value, formData) => {
|
||||||
if (!value) return { hasError: true, message: 'Le mot de passe ne peut pas être vide !' }
|
if (!value) return { hasError: true, message: 'Le mot de passe ne peut pas être vide !' };
|
||||||
if (value !== formData.passwordVerification) return { hasError: true, message: 'Vos deux mots de passe sont différents !' }
|
if (value !== formData.passwordVerification) return { hasError: true, message: 'Vos deux mots de passe sont différents !' };
|
||||||
return { hasError: false, message: '' };
|
return { hasError: false, message: '' };
|
||||||
},
|
},
|
||||||
passwordVerification: (value, formData) => {
|
passwordVerification: (value, formData) => {
|
||||||
if (value !== formData.password) return { hasError: true, message: 'Vos deux mots de passe sont différents !' }
|
if (value !== formData.password) return { hasError: true, message: 'Vos deux mots de passe sont différents !' };
|
||||||
return { hasError: false, message: '' };
|
return { hasError: false, message: '' };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ExtendedUserForm = WithForm(validators)(UserForm);
|
export const ExtendedUserForm = WithForm(validators)(UserForm);
|
||||||
|
@ -23,7 +23,7 @@ describe('<UserForm />', () => {
|
|||||||
password: 'test',
|
password: 'test',
|
||||||
passwordVerification: 'test'
|
passwordVerification: 'test'
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('username validation', () => {
|
describe('username validation', () => {
|
||||||
|
@ -16,15 +16,15 @@ export function WithForm(validators) {
|
|||||||
setFormErrors(formErrors => {
|
setFormErrors(formErrors => {
|
||||||
return { ...formErrors, [name]: { hasError: false, message: '' } };
|
return { ...formErrors, [name]: { hasError: false, message: '' } };
|
||||||
});
|
});
|
||||||
return
|
return;
|
||||||
};
|
}
|
||||||
|
|
||||||
const value = formData[name];
|
const value = formData[name];
|
||||||
const result = validators[name](value, formData);
|
const result = validators[name](value, formData);
|
||||||
setFormErrors(formErrors => {
|
setFormErrors(formErrors => {
|
||||||
return { ...formErrors, [name]: result };
|
return { ...formErrors, [name]: result };
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Object.keys(formData).forEach(validateField);
|
Object.keys(formData).forEach(validateField);
|
||||||
@ -78,7 +78,7 @@ export function WithForm(validators) {
|
|||||||
|
|
||||||
return <Component form={form} {...props} />;
|
return <Component form={form} {...props} />;
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect(mapStateToProps)(MyComponent)
|
// connect(mapStateToProps)(MyComponent)
|
@ -2,20 +2,20 @@ export function MessageList({ messages }) {
|
|||||||
if (!Array.isArray(messages)) return null;
|
if (!Array.isArray(messages)) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="columns" style={{marginTop:"1em"}}>
|
<div className="columns" style={{marginTop:'1em'}}>
|
||||||
<div className="column is-4 is-offset-4">
|
<div className="column is-4 is-offset-4">
|
||||||
<div className="messages">
|
<div className="messages">
|
||||||
{
|
{
|
||||||
messages.map((m, i) => {
|
messages.map((m, i) => {
|
||||||
return (
|
return (
|
||||||
<div key={`message-${i}`} className={`message is-${m.type}`}>
|
<div key={`message-${i}`} className={`message is-${m.type}`}>
|
||||||
<div className="message-body">
|
<div className="message-body">
|
||||||
{m.text}
|
{m.text}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
export class APIError extends Error {
|
export class APIError extends Error {
|
||||||
constructor(endpoint, code, message, data) {
|
constructor(endpoint, code, message, data) {
|
||||||
super(`APIError: ${message}`);
|
super(`APIError: ${message}`);
|
||||||
this.endpoint = endpoint;
|
this.endpoint = endpoint;
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
Error.captureStackTrace(this, APIError);
|
Error.captureStackTrace(this, APIError);
|
||||||
}
|
}
|
||||||
|
|
||||||
getEndpoint() {
|
getEndpoint() {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export class UnauthorizedError extends Error {
|
export class UnauthorizedError extends Error {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("Unauthorized");
|
super('Unauthorized');
|
||||||
Error.captureStackTrace(this, UnauthorizedError);
|
Error.captureStackTrace(this, UnauthorizedError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom';
|
||||||
import { HotApp as App } from './app'
|
import { HotApp as App } from './app';
|
||||||
import { configureStore } from './store/store'
|
import { configureStore } from './store/store';
|
||||||
import { Provider } from 'react-redux'
|
import { Provider } from 'react-redux';
|
||||||
import 'bulma/css/bulma.min.css';
|
import 'bulma/css/bulma.min.css';
|
||||||
|
|
||||||
const store = configureStore()
|
const store = configureStore();
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<App />
|
<App />
|
||||||
</Provider>,
|
</Provider>,
|
||||||
document.getElementById('app')
|
document.getElementById('app')
|
||||||
)
|
);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react';
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux';
|
||||||
import Page from './page';
|
import Page from './page';
|
||||||
import ProjectList from '../components/ProjectList';
|
import ProjectList from '../components/ProjectList';
|
||||||
import { projectUserListRequest } from '../actions/project';
|
import { projectUserListRequest } from '../actions/project';
|
||||||
@ -7,8 +7,8 @@ import { projectUserListRequest } from '../actions/project';
|
|||||||
const DashBoardClient = ({ projects = [], ...props }) => {
|
const DashBoardClient = ({ projects = [], ...props }) => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
props.dispatch(projectUserListRequest())
|
props.dispatch(projectUserListRequest());
|
||||||
}, [])
|
}, []);
|
||||||
projects = [
|
projects = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
@ -78,7 +78,7 @@ const DashBoardClient = ({ projects = [], ...props }) => {
|
|||||||
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
]
|
];
|
||||||
return (
|
return (
|
||||||
<Page title="dashBoard client">
|
<Page title="dashBoard client">
|
||||||
<div className="notification">
|
<div className="notification">
|
||||||
@ -87,11 +87,11 @@ const DashBoardClient = ({ projects = [], ...props }) => {
|
|||||||
<ProjectList projects={projects} withRequest />
|
<ProjectList projects={projects} withRequest />
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
const mapStateToProps = ({ project }) => ({
|
const mapStateToProps = ({ project }) => ({
|
||||||
projects: project.items,
|
projects: project.items,
|
||||||
})
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(DashBoardClient)
|
export default connect(mapStateToProps)(DashBoardClient);
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react';
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux';
|
||||||
import Page from './page';
|
import Page from './page';
|
||||||
import ProjectList from '../components/ProjectList';
|
import ProjectList from '../components/ProjectList';
|
||||||
import { projectList } from '../actions/project';
|
import { projectList } from '../actions/project';
|
||||||
@ -7,8 +7,8 @@ import { projectList } from '../actions/project';
|
|||||||
const DashBoardDev = ({ projects = [], ...props }) => {
|
const DashBoardDev = ({ projects = [], ...props }) => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
props.dispatch(projectList())
|
props.dispatch(projectList());
|
||||||
}, [])
|
}, []);
|
||||||
projects = [
|
projects = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
@ -78,7 +78,7 @@ const DashBoardDev = ({ projects = [], ...props }) => {
|
|||||||
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
]
|
];
|
||||||
return (
|
return (
|
||||||
<Page title="dashBoard dev">
|
<Page title="dashBoard dev">
|
||||||
<div className="notification">
|
<div className="notification">
|
||||||
@ -87,11 +87,11 @@ const DashBoardDev = ({ projects = [], ...props }) => {
|
|||||||
<ProjectList projects={projects} />
|
<ProjectList projects={projects} />
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
const mapStateToProps = ({ project }) => ({
|
const mapStateToProps = ({ project }) => ({
|
||||||
projects: project.items,
|
projects: project.items,
|
||||||
})
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(DashBoardDev)
|
export default connect(mapStateToProps)(DashBoardDev);
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react'
|
import React from 'react';
|
||||||
import Page from './page';
|
import Page from './page';
|
||||||
import { ExtendedUserForm as UserForm } from '../components/UserForm';
|
import { ExtendedUserForm as UserForm } from '../components/UserForm';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
@ -6,45 +6,45 @@ import { createUser } from '../actions/user.actions';
|
|||||||
|
|
||||||
export class HomePage extends React.PureComponent {
|
export class HomePage extends React.PureComponent {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
const { createUserFormError } = this.props;
|
const { createUserFormError } = this.props;
|
||||||
|
|
||||||
const onUserFormSubmit = ({ username, password }) => {
|
const onUserFormSubmit = ({ username, password }) => {
|
||||||
this.props.dispatch(createUser(username, password));
|
this.props.dispatch(createUser(username, password));
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page title="home">
|
<Page title="home">
|
||||||
<div className="section">
|
<div className="section">
|
||||||
<h1 className="title">Bienvenue sur PleaseWait !</h1>
|
<h1 className="title">Bienvenue sur PleaseWait !</h1>
|
||||||
<h2 className="subtitle">Le gestionnaire de ticket simplifié.</h2>
|
<h2 className="subtitle">Le gestionnaire de ticket simplifié.</h2>
|
||||||
<a href="#/logout">Se déconnecter</a>
|
<a href="#/logout">Se déconnecter</a>
|
||||||
<UserForm onSubmit={onUserFormSubmit} errors={createUserFormError} />
|
<UserForm onSubmit={onUserFormSubmit} errors={createUserFormError} />
|
||||||
</div>
|
</div>
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function transformErrorCode(code) {
|
function transformErrorCode(code) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case 0:
|
case 0:
|
||||||
return {
|
return {
|
||||||
username: {
|
username: {
|
||||||
hasError: true,
|
hasError: true,
|
||||||
message: "Le nom d'utilisateur ne peut pas être vide. (API)"
|
message: 'Le nom d\'utilisateur ne peut pas être vide. (API)'
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps({ users }) {
|
function mapStateToProps({ users }) {
|
||||||
return {
|
return {
|
||||||
createUserFormError: transformErrorCode(users.createUserForm.errorCode),
|
createUserFormError: transformErrorCode(users.createUserForm.errorCode),
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ConnectedHomePage = connect(mapStateToProps)(HomePage)
|
export const ConnectedHomePage = connect(mapStateToProps)(HomePage);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from 'react';
|
||||||
import { ConnectedPage as Page } from './page';
|
import { ConnectedPage as Page } from './page';
|
||||||
import { login } from '../actions/auth.actions';
|
import { login } from '../actions/auth.actions';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
@ -13,10 +13,10 @@ export function LoginPage({ dispatch, isLoggedIn, history }) {
|
|||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
const { username, password } = formData;
|
const { username, password } = formData;
|
||||||
dispatch(login(username, password));
|
dispatch(login(username, password));
|
||||||
}
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isLoggedIn) history.push('/home');
|
if (isLoggedIn) history.push('/home');
|
||||||
}, [isLoggedIn]);
|
}, [isLoggedIn]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react';
|
||||||
import { logout } from '../actions/auth.actions';
|
import { logout } from '../actions/auth.actions';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { ConnectedPage as Page } from './page';
|
import { ConnectedPage as Page } from './page';
|
||||||
@ -16,7 +16,7 @@ export function LogoutPage({ dispatch }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Page>
|
</Page>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ConnectedLogoutPage = connect()(LogoutPage);
|
export const ConnectedLogoutPage = connect()(LogoutPage);
|
@ -1,33 +1,33 @@
|
|||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react';
|
||||||
import { MessageList } from '../components/message-list';
|
import { MessageList } from '../components/message-list';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { removeOldestMessage } from '../actions/message.actions';
|
import { removeOldestMessage } from '../actions/message.actions';
|
||||||
|
|
||||||
export default function Page({ title, messages, dispatch, children }) {
|
export default function Page({ title, messages, dispatch, children }) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.title = title ? `${title } - PleaseWait` : 'PleaseWait';
|
document.title = title ? `${title } - PleaseWait` : 'PleaseWait';
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!Array.isArray(messages) || messages.length === 0) return;
|
if (!Array.isArray(messages) || messages.length === 0) return;
|
||||||
|
|
||||||
let timeoutId = setTimeout(() => {
|
let timeoutId = setTimeout(() => {
|
||||||
dispatch(removeOldestMessage());
|
dispatch(removeOldestMessage());
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
return () => clearTimeout(timeoutId);
|
return () => clearTimeout(timeoutId);
|
||||||
}, [messages])
|
}, [messages]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<MessageList messages={messages} />
|
<MessageList messages={messages} />
|
||||||
{ children }
|
{ children }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return { messages: state.messages.sortedByTimestamp };
|
return { messages: state.messages.sortedByTimestamp };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ConnectedPage = connect(mapStateToProps)(Page);
|
export const ConnectedPage = connect(mapStateToProps)(Page);
|
@ -1,4 +1,4 @@
|
|||||||
import { ADD_MESSAGE, REMOVE_OLDEST_MESSAGE } from "../actions/message.actions";
|
import { ADD_MESSAGE, REMOVE_OLDEST_MESSAGE } from '../actions/message.actions';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
sortedByTimestamp: []
|
sortedByTimestamp: []
|
||||||
@ -6,11 +6,11 @@ const initialState = {
|
|||||||
|
|
||||||
export function messagesReducer(state = initialState, action) {
|
export function messagesReducer(state = initialState, action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case ADD_MESSAGE:
|
case ADD_MESSAGE:
|
||||||
return handleAddMessage(state, action);
|
return handleAddMessage(state, action);
|
||||||
case REMOVE_OLDEST_MESSAGE:
|
case REMOVE_OLDEST_MESSAGE:
|
||||||
return handleRemoveOldestMessage(state, action);
|
return handleRemoveOldestMessage(state, action);
|
||||||
};
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,12 +21,12 @@ function handleAddMessage(state, action) {
|
|||||||
{ ts: Date.now(), text: action.text, type: action.messageType },
|
{ ts: Date.now(), text: action.text, type: action.messageType },
|
||||||
...state.sortedByTimestamp
|
...state.sortedByTimestamp
|
||||||
]
|
]
|
||||||
}
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
function handleRemoveOldestMessage(state, action) {
|
function handleRemoveOldestMessage(state, action) {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
sortedByTimestamp: state.sortedByTimestamp.slice(0, -1)
|
sortedByTimestamp: state.sortedByTimestamp.slice(0, -1)
|
||||||
}
|
};
|
||||||
};
|
}
|
@ -1,15 +1,15 @@
|
|||||||
import {
|
import {
|
||||||
PROJECT_USER_LIST_SUCCESS,
|
PROJECT_USER_LIST_SUCCESS,
|
||||||
PROJECT_USER_LIST_FAILURE
|
PROJECT_USER_LIST_FAILURE
|
||||||
} from '../actions/project'
|
} from '../actions/project';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
items: []
|
items: []
|
||||||
}
|
};
|
||||||
|
|
||||||
export default (state = initialState, action) => {
|
export default (state = initialState, action) => {
|
||||||
|
|
||||||
console.log(`Action: ${JSON.stringify(action)}`)
|
console.log(`Action: ${JSON.stringify(action)}`);
|
||||||
|
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
|
||||||
@ -17,15 +17,15 @@ export default (state = initialState, action) => {
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
items: action.projects
|
items: action.projects
|
||||||
}
|
};
|
||||||
case PROJECT_USER_LIST_FAILURE:
|
case PROJECT_USER_LIST_FAILURE:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
items: [],
|
items: [],
|
||||||
error: action.error
|
error: action.error
|
||||||
}
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
return state
|
return state;
|
||||||
|
|
||||||
}
|
};
|
@ -1,4 +1,4 @@
|
|||||||
import { LOGIN_SUCCESS, LOGOUT_SUCCESS } from "../actions/auth.actions";
|
import { LOGIN_SUCCESS, LOGOUT_SUCCESS } from '../actions/auth.actions';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
isLoggedIn: false,
|
isLoggedIn: false,
|
||||||
@ -7,11 +7,11 @@ const initialState = {
|
|||||||
|
|
||||||
export function sessionReducer(state = initialState, action) {
|
export function sessionReducer(state = initialState, action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case LOGIN_SUCCESS:
|
case LOGIN_SUCCESS:
|
||||||
return handleLoginSuccess(state, action);
|
return handleLoginSuccess(state, action);
|
||||||
case LOGOUT_SUCCESS:
|
case LOGOUT_SUCCESS:
|
||||||
return handleLogoutSuccess(state, action);
|
return handleLogoutSuccess(state, action);
|
||||||
};
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,13 +22,13 @@ function handleLoginSuccess(state, action) {
|
|||||||
user: {
|
user: {
|
||||||
username: action.username,
|
username: action.username,
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
function handleLogoutSuccess(state, action) {
|
function handleLogoutSuccess(state, action) {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
isLoggedIn: false,
|
isLoggedIn: false,
|
||||||
user: null,
|
user: null,
|
||||||
}
|
};
|
||||||
};
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { CREATE_USER_FAILURE } from "../actions/user.actions";
|
import { CREATE_USER_FAILURE } from '../actions/user.actions';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
byId: {},
|
byId: {},
|
||||||
@ -7,9 +7,9 @@ const initialState = {
|
|||||||
|
|
||||||
export function usersReducer(state = initialState, action) {
|
export function usersReducer(state = initialState, action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case CREATE_USER_FAILURE:
|
case CREATE_USER_FAILURE:
|
||||||
return handleCreateUserFailure(state, action);
|
return handleCreateUserFailure(state, action);
|
||||||
};
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,20 +11,20 @@ export function* loginSaga(action) {
|
|||||||
result = yield call(client.login, action.username, action.password);
|
result = yield call(client.login, action.username, action.password);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
if (err instanceof UnauthorizedError) {
|
if (err instanceof UnauthorizedError) {
|
||||||
yield put(addMessage('warning', "Identifiants invalides."));
|
yield put(addMessage('warning', 'Identifiants invalides.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield put(loginFailure(action.username, err));
|
yield put(loginFailure(action.username, err));
|
||||||
yield put(addMessage('danger', "Une erreur inconnue bloque le fonctionnement normal de l'application. Veuillez réessayer plus tard."));
|
yield put(addMessage('danger', 'Une erreur inconnue bloque le fonctionnement normal de l\'application. Veuillez réessayer plus tard.'));
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('error' in result) {
|
if ('error' in result) {
|
||||||
yield put(loginFailure(action.username, result.error));
|
yield put(loginFailure(action.username, result.error));
|
||||||
const message = result.error.message ? result.error.message : result.error.toString();
|
const message = result.error.message ? result.error.message : result.error.toString();
|
||||||
yield put(addMessage('danger', message));
|
yield put(addMessage('danger', message));
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield put(loginSuccess(action.username));
|
yield put(loginSuccess(action.username));
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { history } from "../../util/history";
|
import { history } from '../../util/history';
|
||||||
import { addMessage } from '../../actions/message.actions';
|
import { addMessage } from '../../actions/message.actions';
|
||||||
import { put } from 'redux-saga/effects';
|
import { put } from 'redux-saga/effects';
|
||||||
|
|
||||||
export function* logoutRedirectSaga() {
|
export function* logoutRedirectSaga() {
|
||||||
yield put(addMessage("success", "Vous êtes déconnecté."));
|
yield put(addMessage('success', 'Vous êtes déconnecté.'));
|
||||||
history.push('/login');
|
history.push('/login');
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { APIClient } from "../../services/api-client.service";
|
import { APIClient } from '../../services/api-client.service';
|
||||||
import { logoutFailure, logoutSuccess } from "../../actions/auth.actions";
|
import { logoutFailure, logoutSuccess } from '../../actions/auth.actions';
|
||||||
import { addMessage } from "../../actions/message.actions";
|
import { addMessage } from '../../actions/message.actions';
|
||||||
import { call, put } from 'redux-saga/effects';
|
import { call, put } from 'redux-saga/effects';
|
||||||
|
|
||||||
export function* logoutSaga() {
|
export function* logoutSaga() {
|
||||||
@ -10,7 +10,7 @@ export function* logoutSaga() {
|
|||||||
result = yield call(client.logout);
|
result = yield call(client.logout);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
yield put(logoutFailure(err));
|
yield put(logoutFailure(err));
|
||||||
yield put(addMessage('danger', "Une erreur inconnue bloque le fonctionnement normal de l'application. Veuillez réessayer plus tard."));
|
yield put(addMessage('danger', 'Une erreur inconnue bloque le fonctionnement normal de l\'application. Veuillez réessayer plus tard.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ export function* logoutSaga() {
|
|||||||
yield put(logoutFailure(result.error));
|
yield put(logoutFailure(result.error));
|
||||||
const message = result.error.message ? result.error.message : result.error.toString();
|
const message = result.error.message ? result.error.message : result.error.toString();
|
||||||
yield put(addMessage('danger', message));
|
yield put(addMessage('danger', message));
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield put(logoutSuccess());
|
yield put(logoutSuccess());
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import { LOGIN_REQUEST, LOGOUT_REQUEST, LOGOUT_SUCCESS } from "../../actions/auth.actions";
|
import { LOGIN_REQUEST, LOGOUT_REQUEST, LOGOUT_SUCCESS } from '../../actions/auth.actions';
|
||||||
import { loginSaga } from "./login.saga";
|
import { loginSaga } from './login.saga';
|
||||||
import { logoutSaga } from "./logout.saga";
|
import { logoutSaga } from './logout.saga';
|
||||||
import { logoutRedirectSaga } from "./logout-redirect.saga";
|
import { logoutRedirectSaga } from './logout-redirect.saga';
|
||||||
import { all, takeLatest } from 'redux-saga/effects';
|
import { all, takeLatest } from 'redux-saga/effects';
|
||||||
|
|
||||||
export function * rootSaga() {
|
export function * rootSaga() {
|
||||||
yield all([
|
yield all([
|
||||||
takeLatest(LOGIN_REQUEST, loginSaga),
|
takeLatest(LOGIN_REQUEST, loginSaga),
|
||||||
takeLatest(LOGOUT_REQUEST, logoutSaga),
|
takeLatest(LOGOUT_REQUEST, logoutSaga),
|
||||||
// Redirect after logout success
|
// Redirect after logout success
|
||||||
takeLatest(LOGOUT_SUCCESS, logoutRedirectSaga),
|
takeLatest(LOGOUT_SUCCESS, logoutRedirectSaga),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { failureActionSaga } from "./failure.saga";
|
import { failureActionSaga } from './failure.saga';
|
||||||
import { takeLatest, all } from "redux-saga/effects";
|
import { takeLatest, all } from 'redux-saga/effects';
|
||||||
|
|
||||||
export function * rootSaga(action) {
|
export function * rootSaga(action) {
|
||||||
yield all([
|
yield all([
|
||||||
takeLatest(action => /_FAILURE$/g.test(action.type), failureActionSaga),
|
takeLatest(action => /_FAILURE$/g.test(action.type), failureActionSaga),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { all } from 'redux-saga/effects';
|
import { all } from 'redux-saga/effects';
|
||||||
import { checkSessionSaga } from './session.saga';
|
import { refreshSessionSaga } from './session.saga';
|
||||||
|
|
||||||
export function* rootSaga() {
|
export function* rootSaga() {
|
||||||
yield all([
|
yield all([
|
||||||
checkSessionSaga(),
|
refreshSessionSaga(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
import { APIClient } from '../../services/api-client.service';
|
import { APIClient } from '../../services/api-client.service';
|
||||||
import { call } from 'redux-saga/effects';
|
import { call, put } from 'redux-saga/effects';
|
||||||
|
import { refreshUserSessionFailure, refreshUserSessionSuccess } from '../../actions/auth.actions';
|
||||||
|
|
||||||
export function* checkSessionSaga() {
|
export function* refreshSessionSaga() {
|
||||||
const client = new APIClient();
|
const client = new APIClient();
|
||||||
try {
|
let user;
|
||||||
yield call(client.retrieveSessionUser);
|
try {
|
||||||
} catch(err) {
|
user = yield call(client.retrieveSessionUser);
|
||||||
console.error(err);
|
} catch(err) {
|
||||||
}
|
yield put(refreshUserSessionFailure(err));
|
||||||
|
}
|
||||||
|
yield put(refreshUserSessionSuccess(user));
|
||||||
}
|
}
|
||||||
|
@ -2,17 +2,17 @@ import { call, put } from 'redux-saga/effects';
|
|||||||
import { projectUserListFailure, projectUserListSuccess, projectListFailure, projectListSuccess } from '../actions/project';
|
import { projectUserListFailure, projectUserListSuccess, projectListFailure, projectListSuccess } from '../actions/project';
|
||||||
|
|
||||||
export function* projectUserListSaga() {
|
export function* projectUserListSaga() {
|
||||||
let result
|
let result;
|
||||||
try {
|
try {
|
||||||
result = yield call(projectUserList);
|
result = yield call(projectUserList);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
yield put(projectUserListFailure(err));
|
yield put(projectUserListFailure(err));
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('error' in result) {
|
if ('error' in result) {
|
||||||
yield put(projectUserListFailure(result.error));
|
yield put(projectUserListFailure(result.error));
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield put(projectUserListSuccess(result.data));
|
yield put(projectUserListSuccess(result.data));
|
||||||
@ -23,22 +23,22 @@ const projectUserList = () => {
|
|||||||
method: 'GET',
|
method: 'GET',
|
||||||
mode: 'cors',
|
mode: 'cors',
|
||||||
credentials: 'include'
|
credentials: 'include'
|
||||||
}).then(res => res.json())
|
}).then(res => res.json());
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
export function* projectListSaga() {
|
export function* projectListSaga() {
|
||||||
let result
|
let result;
|
||||||
try {
|
try {
|
||||||
result = yield call(projectList);
|
result = yield call(projectList);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
yield put(projectListFailure(err));
|
yield put(projectListFailure(err));
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('error' in result) {
|
if ('error' in result) {
|
||||||
yield put(projectListFailure(result.error));
|
yield put(projectListFailure(result.error));
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield put(projectListSuccess(result.data));
|
yield put(projectListSuccess(result.data));
|
||||||
@ -49,5 +49,5 @@ const projectList = () => {
|
|||||||
method: 'GET',
|
method: 'GET',
|
||||||
mode: 'cors',
|
mode: 'cors',
|
||||||
credentials: 'include'
|
credentials: 'include'
|
||||||
}).then(res => res.json())
|
}).then(res => res.json());
|
||||||
}
|
};
|
@ -5,10 +5,10 @@ import { rootSaga as initRootSaga } from './init/root.saga';
|
|||||||
import { rootSaga as userRootSaga } from './user/root.saga';
|
import { rootSaga as userRootSaga } from './user/root.saga';
|
||||||
|
|
||||||
export default function* rootSaga() {
|
export default function* rootSaga() {
|
||||||
yield all([
|
yield all([
|
||||||
initRootSaga(),
|
initRootSaga(),
|
||||||
authRootSaga(),
|
authRootSaga(),
|
||||||
failureRootSaga(),
|
failureRootSaga(),
|
||||||
userRootSaga()
|
userRootSaga()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import { CREATE_USER_REQUEST } from '../../actions/user.actions';
|
|||||||
import { createUserSaga } from './user.saga';
|
import { createUserSaga } from './user.saga';
|
||||||
|
|
||||||
export function* rootSaga() {
|
export function* rootSaga() {
|
||||||
yield all([
|
yield all([
|
||||||
takeLatest(CREATE_USER_REQUEST, createUserSaga),
|
takeLatest(CREATE_USER_REQUEST, createUserSaga),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ export function* createUserSaga({username, password}) {
|
|||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
yield put(createUserFailure(err));
|
yield put(createUserFailure(err));
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield put(createUserSuccess(user));
|
yield put(createUserSuccess(user));
|
||||||
|
@ -5,82 +5,82 @@ export const UnauthorizedStatusCode = 401;
|
|||||||
|
|
||||||
export class APIClient {
|
export class APIClient {
|
||||||
constructor(baseURL = 'http://localhost:8001/api/v1') {
|
constructor(baseURL = 'http://localhost:8001/api/v1') {
|
||||||
this.baseURL = baseURL;
|
this.baseURL = baseURL;
|
||||||
this.login = this.login.bind(this);
|
this.login = this.login.bind(this);
|
||||||
this.logout = this.logout.bind(this);
|
this.logout = this.logout.bind(this);
|
||||||
this.retrieveSessionUser = this.retrieveSessionUser.bind(this);
|
this.retrieveSessionUser = this.retrieveSessionUser.bind(this);
|
||||||
this.listUsers = this.listUsers.bind(this);
|
this.listUsers = this.listUsers.bind(this);
|
||||||
this.listRequests = this.listRequests.bind(this);
|
this.listRequests = this.listRequests.bind(this);
|
||||||
this.createUser = this.createUser.bind(this);
|
this.createUser = this.createUser.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
login(username, password) {
|
login(username, password) {
|
||||||
return this._callAPI('/login', { username, password }, 'POST')
|
return this._callAPI('/login', { username, password }, 'POST')
|
||||||
.then(result => result.data);
|
.then(result => result.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
logout() {
|
logout() {
|
||||||
return this._callAPI('/logout')
|
return this._callAPI('/logout');
|
||||||
}
|
}
|
||||||
|
|
||||||
retrieveSessionUser() {
|
retrieveSessionUser() {
|
||||||
return this._callAPI('/me')
|
return this._callAPI('/me')
|
||||||
.then(result => result.data);
|
.then(result => result.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
listUsers() {
|
listUsers() {
|
||||||
return this._callAPI('/users')
|
return this._callAPI('/users');
|
||||||
}
|
}
|
||||||
|
|
||||||
listRequests() {
|
listRequests() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createRequest(request) {
|
createRequest(request) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createUser(username, password) {
|
createUser(username, password) {
|
||||||
return this._callAPI('/users', { username, password }, 'POST')
|
return this._callAPI('/users', { username, password }, 'POST')
|
||||||
.then(this._withAPIErrorMiddleware('create_user'))
|
.then(this._withAPIErrorMiddleware('create_user'))
|
||||||
.then(result => result.data);
|
.then(result => result.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateRequestStatus(reqID, newStatus) {
|
updateRequestStatus(reqID, newStatus) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_callAPI(path, body, method='GET') {
|
_callAPI(path, body, method='GET') {
|
||||||
return fetch(this.baseURL + path, {
|
return fetch(this.baseURL + path, {
|
||||||
method,
|
method,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
mode: 'cors',
|
mode: 'cors',
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
})
|
})
|
||||||
.then(this._withUnauthorizedErrorMiddleware())
|
.then(this._withUnauthorizedErrorMiddleware())
|
||||||
.then(res => res.json())
|
.then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
_withUnauthorizedErrorMiddleware() {
|
_withUnauthorizedErrorMiddleware() {
|
||||||
return res => {
|
return res => {
|
||||||
if (res.status === UnauthorizedStatusCode) {
|
if (res.status === UnauthorizedStatusCode) {
|
||||||
throw new UnauthorizedError();
|
throw new UnauthorizedError();
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_withAPIErrorMiddleware(endpoint) {
|
_withAPIErrorMiddleware(endpoint) {
|
||||||
return result => {
|
return result => {
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
const { code, message, data } = result.error;
|
const { code, message, data } = result.error;
|
||||||
throw new APIError(endpoint, code, message, data);
|
throw new APIError(endpoint, code, message, data);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import { createStore, applyMiddleware, combineReducers, compose } from 'redux'
|
import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
|
||||||
import createSagaMiddleware from 'redux-saga'
|
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'
|
import project from '../reducers/project';
|
||||||
import { usersReducer } from '../reducers/users.reducers';
|
import { usersReducer } from '../reducers/users.reducers';
|
||||||
|
|
||||||
const sagaMiddleware = createSagaMiddleware()
|
const sagaMiddleware = createSagaMiddleware();
|
||||||
|
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
session: sessionReducer,
|
session: sessionReducer,
|
||||||
messages: messagesReducer,
|
messages: messagesReducer,
|
||||||
project,
|
project,
|
||||||
users: usersReducer,
|
users: usersReducer,
|
||||||
});
|
});
|
||||||
|
|
||||||
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
|
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
|
||||||
@ -24,7 +24,7 @@ export function configureStore(initialState = {}) {
|
|||||||
composeEnhancers(
|
composeEnhancers(
|
||||||
applyMiddleware(sagaMiddleware)
|
applyMiddleware(sagaMiddleware)
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
sagaMiddleware.run(rootSaga);
|
sagaMiddleware.run(rootSaga);
|
||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user