Ajout notifications
This commit is contained in:
parent
7d57d51f07
commit
d1f78689b8
|
@ -0,0 +1,11 @@
|
||||||
|
export const ADD_MESSAGE = 'ADD_MESSAGE'
|
||||||
|
|
||||||
|
export function addMessage(type, text) {
|
||||||
|
return { type: ADD_MESSAGE, text, messageType: type };
|
||||||
|
}
|
||||||
|
|
||||||
|
export const REMOVE_OLDEST_MESSAGE = 'REMOVE_OLDEST_MESSAGE'
|
||||||
|
|
||||||
|
export function removeOldestMessage() {
|
||||||
|
return { type: REMOVE_OLDEST_MESSAGE }
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
export function MessageList({ messages }) {
|
||||||
|
if (!Array.isArray(messages)) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="columns" style={{marginTop:"1em"}}>
|
||||||
|
<div className="column is-4 is-offset-4">
|
||||||
|
<div className="messages">
|
||||||
|
{
|
||||||
|
messages.map((m, i) => {
|
||||||
|
return (
|
||||||
|
<div key={`message-${i}`} className={`message is-${m.type}`}>
|
||||||
|
<div className="message-body">
|
||||||
|
{m.text}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
import 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';
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,33 @@
|
||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react'
|
||||||
|
import { MessageList } from '../components/message-list';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { removeOldestMessage } from '../actions/message.actions';
|
||||||
|
|
||||||
export default function Page({ title, children }) {
|
export default function Page({ title, messages, dispatch, children }) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.title = title ? `${title } - PleaseWait` : 'PleaseWait';
|
document.title = title ? `${title } - PleaseWait` : 'PleaseWait';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!Array.isArray(messages) || messages.length === 0) return;
|
||||||
|
|
||||||
|
let timeoutId = setTimeout(() => {
|
||||||
|
dispatch(removeOldestMessage());
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
return () => clearTimeout(timeoutId);
|
||||||
|
}, [messages])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
|
<MessageList messages={messages} />
|
||||||
{ children }
|
{ children }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mapStateToProps(state) {
|
||||||
|
return { messages: state.messages.sortedByTimestamp };
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ConnectedPage = connect(mapStateToProps)(Page);
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { ADD_MESSAGE, REMOVE_OLDEST_MESSAGE } from "../actions/message.actions";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
sortedByTimestamp: []
|
||||||
|
};
|
||||||
|
|
||||||
|
export function messagesReducer(state = initialState, action) {
|
||||||
|
switch(action.type) {
|
||||||
|
case ADD_MESSAGE:
|
||||||
|
return handleAddMessage(state, action);
|
||||||
|
case REMOVE_OLDEST_MESSAGE:
|
||||||
|
return handleRemoveOldestMessage(state, action);
|
||||||
|
};
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleAddMessage(state, action) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
sortedByTimestamp: [
|
||||||
|
{ ts: Date.now(), text: action.text, type: action.messageType },
|
||||||
|
...state.sortedByTimestamp
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleRemoveOldestMessage(state, action) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
sortedByTimestamp: state.sortedByTimestamp.slice(0, -1)
|
||||||
|
}
|
||||||
|
};
|
|
@ -15,7 +15,7 @@ export function sessionReducer(state = initialState, action) {
|
||||||
|
|
||||||
function handleLoginSuccess(state, action) {
|
function handleLoginSuccess(state, action) {
|
||||||
return {
|
return {
|
||||||
...state.user,
|
...state,
|
||||||
isLoggedIn: true,
|
isLoggedIn: true,
|
||||||
user: {
|
user: {
|
||||||
username: action.username,
|
username: action.username,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { call, put } from 'redux-saga/effects';
|
import { call, put } from 'redux-saga/effects';
|
||||||
import { loginFailure, loginSuccess } from '../actions/auth.actions';
|
import { loginFailure, loginSuccess } from '../actions/auth.actions';
|
||||||
|
import { addMessage } from '../actions/message.actions';
|
||||||
|
|
||||||
export function* loginSaga(action) {
|
export function* loginSaga(action) {
|
||||||
let result;
|
let result;
|
||||||
|
@ -7,10 +8,13 @@ export function* loginSaga(action) {
|
||||||
result = yield call(doLogin, action.username, action.password);
|
result = yield call(doLogin, action.username, action.password);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
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."));
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
yield put(addMessage('danger', message));
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,13 @@ 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';
|
||||||
|
|
||||||
const sagaMiddleware = createSagaMiddleware()
|
const sagaMiddleware = createSagaMiddleware()
|
||||||
|
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
session: sessionReducer,
|
session: sessionReducer,
|
||||||
|
messages: messagesReducer,
|
||||||
});
|
});
|
||||||
|
|
||||||
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
|
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
|
||||||
|
|
Loading…
Reference in New Issue