Browse Source

[ADD] odoo container creation support

Gogs 7 years ago
parent
commit
b602296384

+ 19 - 7
src/actions/index.js

@@ -1,4 +1,5 @@
 import axios from 'axios'
+import { isArray } from 'lodash'
 import { API_URL } from '../constants/ResourceNames'
 import { 
     REQUEST_START,
@@ -53,17 +54,28 @@ export const get = resource => async dispatch => {
  * 
  * @param {*} resource 
  */
-export const post = resources => async dispatch => {
-    for (let r of resources) {
-        dispatch({
-            type: REQUEST_START
-        })
+export const post = (resources, data) => async dispatch => {
+    dispatch({
+        type: REQUEST_START
+    })
 
+    data = data || {}
+
+    if (isArray(resources)) {
+        for (let r of resources) {
+            try {
+                const response = await axios.post(`${API_URL}${r}`, data)
+                dispatch(ok(response.data))
+            } catch (error) {
+                dispatch(ko(r, error))
+            }
+        }
+    } else {
         try {
-            const response = await axios.post(`${API_URL}${r}`)
+            const response = await axios.post(`${API_URL}${resources}`, data)
             dispatch(ok(response.data))
         } catch (error) {
-            dispatch(ko(r, error))
+            dispatch(ko(resources, error))
         }
     }
 }

+ 9 - 1
src/components/common/Base.js

@@ -33,6 +33,8 @@ class Base extends Component {
     render() {
         const { classes, app, onHideNotification } = this.props
 
+        console.log(app)
+
         return (
             <div className={classes.root}>
                 <Helmet>
@@ -53,7 +55,7 @@ class Base extends Component {
                 <Snackbar 
                     open={app.notification.isOpen} 
                     autoHideDuration={2000} 
-                    onClose={(e) => onHideNotification(e)} 
+                    onClose={onHideNotification} 
                     message={app.notification.message} 
                 />
                 <Spinner 
@@ -87,6 +89,12 @@ const mapDispatchToProps = (dispatch, props) => ({
      */
     onHideNotification() {
         dispatch(notify(null))
+    },
+    /**
+     * 
+     */
+    onHideDialog() {
+        console.log('hide dialog')
     }
 })
 

+ 140 - 39
src/components/pages/TasksList.js

@@ -3,7 +3,13 @@ import { connect } from 'react-redux'
 import { withStyles } from 'material-ui/styles'
 import Button from 'material-ui/Button'
 import Base from '../common/Base'
-import DataTable from '../common/DataTable'
+import Paper from 'material-ui/Paper'
+import Table, { TableHead, TableBody, TableRow, TableCell } from 'material-ui/Table'
+import Dialog, { DialogActions, DialogContent, DialogContentText, DialogTitle } from 'material-ui/Dialog'
+import TextField from 'material-ui/TextField'
+import { isEqual, isEmpty } from 'lodash'
+import { ODOO } from '../../constants/ResourceNames'
+import { post } from '../../actions'
 
 const styles = theme => ({
     gap: {
@@ -12,64 +18,157 @@ const styles = theme => ({
 })
 
 class TasksList extends Component {
+    constructor(props) {
+        super(props)
+
+        this.state = {
+            isDialogOpened: false,
+            isDialogValid: true,
+            name: '',
+            nameConfirmation: ''
+        }
+    }
+
+    /**
+     * 
+     */
+    handleOpenDialog = e => {
+        this.setState({
+            isDialogOpened: true
+        })
+    }
+
+    /**
+     * 
+     */
+    handleCloseDialog = e => {
+        this.setState({
+            isDialogOpened: false,
+            isDialogValid: true,
+            name: '',
+            nameConfirmation: ''
+        })
+    }
+    
+    /**
+    * 
+    */
+    handleChangeName = e => {
+        if (isEqual(e.target.id, 'name')) {
+            this.setState({
+                name: e.target.value
+            }, this.handleStateChange)
+        }
+
+        if (isEqual(e.target.id, 'nameConfirmation')) {
+            this.setState({
+                nameConfirmation: e.target.value
+            }, this.handleStateChange)
+        }
+    }
+
     /**
      * 
-     * @param {*} e 
      */
-    onAction(e) {
-        console.log(e)
+    handleStateChange = () => {
+        if (isEqual(this.state.name, this.state.nameConfirmation)) {
+            this.setState({
+                isDialogValid: true
+            })
+        } else {
+            this.setState({
+                isDialogValid: false
+            })
+        }
     }
 
     /**
      * 
-     * @param {*} e 
-     * @param {*} ids 
      */
-    onSelect(e, ids) {
+    handleAcceptDialog = e => {
+        const { name, nameConfirmation } = this.state
+        
+        if (isEmpty(name) || isEmpty(nameConfirmation)) {
+            return;
+        }
+
+        if (isEqual(name, nameConfirmation)) {
+            this.props.createOdoo(name)
 
+            this.setState({
+                isDialogOpened: false,
+                name: '',
+                nameConfirmation: ''
+            })
+
+        }
     }
 
     /**
      * 
      */
     render() {
-        const columns = [
-            {
-                title: 'Nombre',
-                key: 'title'
-            },
-            {
-                title: 'Última Ejecución',
-                key: 'last_execution'
-            }
-        ]
-
-        const { tasks } = this.props
+        const { isDialogOpened, isDialogValid } = this.state
 
         return (
             <Base title={this.props.title}>
-                <Button variant='raised' color='primary' onClick={e => this.onAction(e)}>Ejecutar</Button>
-                <DataTable
-                    columns={columns}
-                    rows={tasks}
-                    onSelect={(e, ids) => this.onSelect(e, ids)}
-                />
+                <Paper>
+                    <Table>
+                        <TableHead>
+                            <TableRow>
+                                <TableCell>Nombre</TableCell>
+                                <TableCell>Última ejecución</TableCell>
+                                <TableCell>Usuario</TableCell>
+                                <TableCell />
+                            </TableRow>
+                        </TableHead>
+                        <TableBody>
+                            <TableRow>
+                                <TableCell>Crear contenedor Odoo</TableCell>
+                                <TableCell>Nunca</TableCell>
+                                <TableCell>Anónimo</TableCell>
+                                <TableCell>
+                                    <Button variant='raised' color='primary' data-action='create' onClick={this.handleOpenDialog}>Ejecutar</Button>
+                                </TableCell>
+                            </TableRow>
+                        </TableBody>
+                    </Table>
+                </Paper>
+                <Dialog open={isDialogOpened} onClose={this.handleCloseDialog}>
+                    <DialogTitle>Confirmar</DialogTitle>
+                    <DialogContent>
+                        <DialogContentText>Estas solicitando crear un contenedor Odoo. Tenga en cuenta que ésta tarea puede tardar unos instantes dependiendo del tráfico de red y el uso de los recursos del servidor</DialogContentText>
+                        <TextField 
+                            id='name'
+                            margin='dense' 
+                            label='Nombre del sistema'
+                            type='text' 
+                            autoComplete='off' 
+                            autoFocus 
+                            fullWidth
+                            onKeyUp={this.handleChangeName}
+                         />
+                        <TextField
+                            id='nameConfirmation'
+                            margin='dense' 
+                            label='Nombre del sistema'
+                            type='text' 
+                            autoComplete='off' 
+                            fullWidth
+                            error={!isDialogValid}
+                            onKeyUp={this.handleChangeName}
+                         />
+                    </DialogContent>
+                    <DialogActions>
+                        <Button color='primary' onClick={this.handleCloseDialog}>Cancelar</Button>
+                        <Button color='primary' onClick={this.handleAcceptDialog}>Aceptar</Button>
+                    </DialogActions>
+                </Dialog>
             </Base>
         )
     }
 }
 
-/**
- * 
- * @param {*} state 
- * @param {*} props 
- */
-const mapStateToProps = (state, props) => {
-    return {
-        tasks: []
-    }
-}
-
 /**
  * 
  * @param {*} dispatch 
@@ -79,11 +178,13 @@ const mapDispatchToProps = (dispatch, props) => ({
     /**
      * 
      */
-    loadData() {
-
+    createOdoo(name) {
+        dispatch(post(`${ODOO}create/`, {
+            name
+        }))
     }
 })
 
 TasksList = withStyles(styles)(TasksList)
 
-export default connect(mapStateToProps, mapDispatchToProps)(TasksList)
+export default connect(null, mapDispatchToProps)(TasksList)

+ 6 - 1
src/constants/ResourceNames.js

@@ -6,4 +6,9 @@ export const API_URL = 'http://192.168.88.100:8000/api/v1/'
 /** 
  * 
  */
-export const DOCKER = 'docker/'
+export const DOCKER = 'docker/'
+
+/**
+ * 
+ */
+export const ODOO = 'odoo/'

+ 26 - 7
src/reducers/app.js

@@ -1,4 +1,4 @@
-import { isString } from 'lodash'
+import { isEqual, has, isString } from 'lodash'
 import {
     REQUEST_START,
     REQUEST_KO, 
@@ -17,6 +17,10 @@ const initialState = {
     notification: {
         isOpen: false,
         message: null
+    },
+    dialog: {
+        isOpen: false,
+        message: null
     }
 }
 
@@ -26,7 +30,7 @@ const initialState = {
  * @param {*} action 
  */
 export const app = (state = initialState, action) => {
-    if (action.type === SHOW_SPINNER || action.type === REQUEST_START) {
+    if (isEqual(action.type, SHOW_SPINNER) || isEqual(action.type, REQUEST_START)) {
         state = {
             ...state,
             spinner: {
@@ -36,7 +40,18 @@ export const app = (state = initialState, action) => {
         }
     }
 
-    if (action.type === HIDE_SPINNER || action.type === REQUEST_OK) {
+    if (isEqual(action.type, HIDE_SPINNER) || isEqual(action.type, REQUEST_OK)) {
+        if (has(action.payload, 'action')) {
+            if (isEqual(action.payload.action.type, 'redirect')) {
+                const params = {
+                    ip: action.payload.action.ip,
+                    port: action.payload.action.port
+                }
+
+                window.open(`${window.location.protocol}//${params.ip}:${params.port}`, '_blank')
+            }
+        }   
+        
         state = {
             ...state,
             spinner: {
@@ -46,17 +61,21 @@ export const app = (state = initialState, action) => {
         }
     }
 
-    if (action.type === SHOW_NOTIFICATION || action.type === REQUEST_KO) {
+    if (isEqual(action.type, SHOW_NOTIFICATION) || isEqual(action.type, REQUEST_KO)) {
         state = {
             ...state,
+            spinner: {
+                isOpen: false,
+                message: null
+            },
             notification: {
                 isOpen: true,
-                message: isString(action.payload) ? action.payload : null
+                message: isString(action.payload) ? action.payload : 'No se pudo terminar la petición'
             }
         }
     }
 
-    if (action.type === HIDE_NOTIFICATION) {
+    if (isEqual(action.type, HIDE_NOTIFICATION)) {
         state = {
             ...state,
             notification: {
@@ -67,4 +86,4 @@ export const app = (state = initialState, action) => {
     }
 
     return state
-}
+}