Gogs %!s(int64=7) %!d(string=hai) anos
pai
achega
f965fcce63

+ 1 - 1
src/actions/index.js

@@ -28,7 +28,7 @@ export const spinner = (show, message) => dispatch => {
 export const notify = message => dispatch  => {
     dispatch({
         type: message ? SHOW_NOTIFICATION : HIDE_NOTIFICATION,
-        payload: message
+        payload: { message }
     })
 }
 

+ 2 - 1
src/components/common/Routes.js

@@ -24,7 +24,8 @@ class Routes extends Component {
                                     }
                                 }} 
                             />)
-                        } 
+                        }
+                        exact={route.exact}
                     />
                 )}
                 <Route path='/login' component={Login} />

+ 53 - 7
src/components/common/Topbar.js

@@ -1,4 +1,5 @@
 import React, { Component } from 'react'
+import { connect } from 'react-redux'
 import AppBar from 'material-ui/AppBar'
 import Toolbar from 'material-ui/Toolbar'
 import Typography from 'material-ui/Typography'
@@ -6,6 +7,7 @@ import Avatar from 'material-ui/Avatar'
 import Button from 'material-ui/Button'
 import Menu, { MenuItem } from 'material-ui/Menu'
 import UserIcon from '../icons/UserIcon'
+import { LOGOUT } from '../../constants/ActionTypes'
 import { withStyles } from 'material-ui/styles'
 
 const styles = theme => ({
@@ -29,16 +31,36 @@ class Topbar extends Component {
         super(props)
 
         this.state = {
-            menuOpened: false
+            anchorEl: null
         }
     }
 
+    /**
+     * 
+     */
+    handleOpenMenu = e => {
+        this.setState({
+            anchorEl: e.target
+        })
+    }
+
+    /**
+     * 
+     */
+    handleSesionClose = e => {
+        this.setState({
+            anchorEl: null
+        })
+        this.props.logout()
+    }
+
     /**
      * 
      */
     render() {
         const { classes } = this.props
-        const { menuOpened } = this.state
+        const { anchorEl } = this.state
+        const openMenu = Boolean(anchorEl)
 
         return (
             <AppBar position="absolute" className={classes.root}>
@@ -50,10 +72,19 @@ class Topbar extends Component {
                         <Avatar className={classes.avatar}>
                             <UserIcon />
                         </Avatar>
-                        <Button color="inherit">Anónimo</Button>
-                        <Menu open={menuOpened}>
-                            <MenuItem>Mi Perfil</MenuItem>
-                            <MenuItem>Salir</MenuItem>
+                        <Button color="inherit" onClick={this.handleOpenMenu}>Anónimo</Button>
+                        <Menu 
+                            open={openMenu} 
+                            anchorEl={anchorEl}
+                            anchorOrigin={{
+                                vertical: 'top',
+                                horizontal: 'right',
+                            }}
+                            transformOrigin={{
+                                vertical: 'top',
+                                horizontal: 'right',
+                            }}>
+                            <MenuItem onClick={this.handleSesionClose}>Cerrar sesión</MenuItem>
                         </Menu>
                     </div>
                 </Toolbar>
@@ -62,4 +93,19 @@ class Topbar extends Component {
     }
 }
 
-export default withStyles(styles)(Topbar)
+/**
+ * 
+ * @param {*} dispatch 
+ * @param {*} props 
+ */
+const mapDispatchToProps = (dispatch, props) => ({
+    logout() {
+        dispatch({
+            type: LOGOUT
+        })
+    }
+})
+
+Topbar = withStyles(styles)(Topbar)
+
+export default connect(null, mapDispatchToProps)(Topbar)

+ 33 - 0
src/components/pages/Welcome.js

@@ -0,0 +1,33 @@
+import React, { Component } from 'react'
+import Base from '../common/Base'
+import DockerIcon from '../icons/DockerIcon'
+import Typography from 'material-ui/Typography'
+import { withStyles } from 'material-ui/styles'
+
+const styles = theme => ({
+    root: {
+
+    },
+    icon: {
+        width: '5em',
+        height: '5em'
+    }
+})
+
+class Welcome extends Component {
+    /**
+     * 
+     */
+    render() {
+        const { classes } = this.props
+
+        return (
+            <Base title={this.props.title}>
+                <DockerIcon className={classes.icon} />
+                <Typography align='center' variant='headline' color='primary'>Bienvenido al Sistema de Automatización</Typography>
+            </Base>
+        )
+    }
+}
+
+export default withStyles(styles)(Welcome)

+ 6 - 1
src/constants/ActionTypes.js

@@ -31,4 +31,9 @@ export const SHOW_NOTIFICATION = 'show_notification'
 /**
  * 
  */
-export const HIDE_NOTIFICATION = 'hide_notification'
+export const HIDE_NOTIFICATION = 'hide_notification'
+
+/**
+ * 
+ */
+export const LOGOUT = 'logout'

+ 14 - 2
src/reducers/auth.js

@@ -1,5 +1,5 @@
 import { createReducer } from '../utils/reducer'
-import { REQUEST_OK, REQUEST_KO } from '../constants/ActionTypes'
+import { REQUEST_OK, REQUEST_KO, LOGOUT } from '../constants/ActionTypes'
 import { setToken } from '../utils/auth'
 import { has, isEqual } from 'lodash'
 
@@ -36,12 +36,24 @@ const checkAuthentication = (isAuthenticated, action) => {
     return isAuthenticated
 }
 
+/**
+ * 
+ * @param {*} isAuthenticated 
+ * @param {*} action 
+ */
+const revokeAuthentication = (isAuthenticated, action) => {
+    setToken(null)
+    return false
+}
+
 /**
  * 
  */
 const authenticationCheckReducer = createReducer(initialState, {
     [REQUEST_OK]: checkAuthentication,
-    [REQUEST_KO]: checkAuthentication
+    [REQUEST_KO]: checkAuthentication,
+    [LOGOUT]: revokeAuthentication
+
 })
 
 /**

+ 2 - 1
src/reducers/containers.js

@@ -12,6 +12,7 @@ const initialState = {
  * @param {*} action 
  */
 const setContainers = (containers, action) => {
+    console.log(action)
     // single instance
     if (has(action.payload, 'container')) {
         return map(containers, c => {
@@ -30,7 +31,7 @@ const setContainers = (containers, action) => {
 /**
  * 
  */
-const containersReducer = createReducer([], {
+const containersReducer = createReducer(initialState.containers, {
     [REQUEST_OK]: setContainers
 })
 

+ 2 - 1
src/reducers/notification.js

@@ -1,5 +1,5 @@
 import { createReducer } from '../utils/reducer'
-import { REQUEST_OK, REQUEST_KO, HIDE_NOTIFICATION } from '../constants/ActionTypes'
+import { REQUEST_OK, REQUEST_KO, SHOW_NOTIFICATION, HIDE_NOTIFICATION } from '../constants/ActionTypes'
 import { isEmpty, has, isEqual } from 'lodash'
 
 const initialState = {
@@ -54,6 +54,7 @@ const hideNotification = (state, action) => {
 const notificationReducer = createReducer(initialState, {
     [REQUEST_OK]: showNotification,
     [REQUEST_KO]: showNotification,
+    [SHOW_NOTIFICATION]: showNotification,
     [HIDE_NOTIFICATION]: hideNotification
 })
 

+ 7 - 8
src/routes/index.js

@@ -1,3 +1,4 @@
+import Welcome from '../components/pages/Welcome'
 import Dashboard from '../components/pages/Dashboard'
 import ContainersList from '../components/pages/ContainersList'
 import RequestsList from '../components/pages/RequestsList'
@@ -5,16 +6,14 @@ import TasksList from '../components/pages/TasksList'
 import UsersList from '../components/pages/UsersList'
 import PermissionsList from '../components/pages/PermissionsList'
 import About from '../components/pages/About'
-// import Page404 from '../components/pages/404'
-
-// import DockerIcon from '../components/icons/DockerIcon'
-// import TaskIcon from '../components/icons/TaskIcon'
-// import FactoryIcon from '../components/icons/FactoryIcon'
-// import UserIcon from '../components/icons/UserIcon'
-// import PermissionIcon from '../components/icons/PermissionIcon'
-// import AboutIcon from '../components/icons/AboutIcon'
 
 const routes = [
+    {
+        path: '/',
+        component: Welcome,
+        title: 'Inicio',
+        exact: true
+    },
     {
         path: '/dashboard',
         component: Dashboard,

+ 1 - 1
src/utils/auth.js

@@ -21,7 +21,7 @@ export const getToken = () => {
  * @param {*} token 
  */
 export const setToken = token => {
-    if (!token.startsWith('JWT')) {
+    if (!isEmpty(token) && !token.startsWith('JWT')) {
         token = `JWT ${token}`
     }