Parcourir la source

[ADD] copy modules task

Gogs il y a 7 ans
Parent
commit
01ee88c584

+ 2 - 2
src/actions/index.js

@@ -87,9 +87,9 @@ export const get = resource => async (dispatch, getState) => {
 
     try {
         const response = await http.get(`${resource}`)
-        dispatch({ type: 'REQUEST_OK', payload: response.data })
+        return dispatch({ type: 'REQUEST_OK', payload: response.data })
     } catch (error) {
-        dispatch({ type: 'REQUEST_KO', payload: error.response.status })
+        return dispatch({ type: 'REQUEST_KO', payload: error.response.status })
     }
 }
 

+ 201 - 73
src/components/pages/TasksList.js

@@ -5,14 +5,17 @@ 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 { InputLabel } from 'material-ui/Input'
+import { FormControl } from 'material-ui/Form'
+import Select from 'material-ui/Select'
 import MenuItem from 'material-ui/Menu/MenuItem'
 import Typography from 'material-ui/Typography'
 import List, { ListItem, ListItemText, ListItemSecondaryAction } from 'material-ui/List'
 import IconButton from 'material-ui/IconButton'
 import AddIcon from '../icons/AddIcon'
 import RemoveIcon from '../icons/RemoveIcon'
-import { isEqual, isEmpty } from 'lodash'
-import { ODOO, REQUEST } from '../../constants/ResourceNames'
+import { isEqual, isEmpty, union, difference, defer } from 'lodash'
+import { ODOO, DOCKER, REQUEST, GIT } from '../../constants/ResourceNames'
 import { post, get } from '../../actions'
 import { connect } from 'react-redux'
 import { withStyles } from 'material-ui/styles'
@@ -29,6 +32,10 @@ const styles = theme => ({
         height: '100%',
         padding: 15,
         flexGrow: 1
+    },
+    transferModules: {
+        height: 300,
+        overflowY: 'auto'
     }
 })
 
@@ -40,7 +47,11 @@ class TasksList extends Component {
             showDialog: null,
             isDialogValid: true,
             name: '',
-            nameConfirmation: ''
+            nameConfirmation: '',
+            odoos: [],
+            modules: [],
+            selectedOdoo: '',
+            modulesToInstall: []
         }
     }
 
@@ -55,17 +66,40 @@ class TasksList extends Component {
      * 
      */
     handleShowDialog = (taskName, e) => {
+        if (taskName === 'create-odoo') {
+            this.showDialog(taskName)
+        }
+
+        if (taskName === 'show-modules') {
+            Promise.all([
+                this.props.loadContainers(),
+                this.props.loadRepositories()
+            ]).then(data => {   
+                this.setState({
+                    odoos: data[0].payload.containers,
+                    modules: data[1].payload.repositories
+                }, () => this.showDialog(taskName))
+            })
+        }
+    }
+
+    /**
+     * 
+     */
+    showDialog = dialog => {
         this.setState({
-            showDialog: taskName
-        })
+            showDialog: dialog
+        })    
     }
 
     /**
      * 
      */
     handleCloseDialog = taskName => {
-        this.setState({
-            showDialog: null
+        defer(() => {
+            this.setState({
+                showDialog: null
+            })
         })
     }
 
@@ -73,17 +107,19 @@ class TasksList extends Component {
      * 
      */
     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)
-        }
+        defer(() => {
+            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)
+            }
+        })
     }
 
     /**
@@ -100,28 +136,86 @@ class TasksList extends Component {
             })
         }
     }
+    
+    /**
+     * 
+     */
+    handleChangeOdooSystem = e => {
+        defer(() => {
+            this.setState({
+                [e.target.name]: e.target.value
+            })
+        })
+    }
 
     /**
      * 
      */
     handleAcceptDialog = e => {
-        const { name, nameConfirmation } = this.state
-        
-        if (isEmpty(name) || isEmpty(nameConfirmation)) {
-            return
+        // handling odoo creating
+        if (this.state.showDialog === 'create-odoo') {
+            const { name, nameConfirmation } = this.state
+            
+            if (isEmpty(name) || isEmpty(nameConfirmation)) {
+                return
+            }
+    
+            if (isEqual(name, nameConfirmation)) {
+                this.props.createOdoo(name)
+    
+                this.setState({
+                    showDialog: null,
+                    name: '',
+                    nameConfirmation: ''
+                })
+            }
         }
 
-        if (isEqual(name, nameConfirmation)) {
-            this.props.createOdoo(name)
+        // handling copying modules
+        if (this.state.showDialog === 'show-modules') {
+            const { selectedOdoo, modulesToInstall } = this.state
+
+            if (isEmpty(selectedOdoo) || isEmpty(modulesToInstall)) {
+                return
+            }
 
             this.setState({
-                isDialogOpened: false,
-                name: '',
-                nameConfirmation: ''
-            })
+                showDialog: null,
+                selectedOdoo: '',
+                modulesToInstall: []
+            }, () => this.props.installModules(selectedOdoo, modulesToInstall))
         }
     }
 
+    /**
+     * 
+     */
+    handleAddModule = (index, e) => {
+        defer(() => {
+            const item = this.state.modules[index]
+        
+            this.setState({
+                modules: difference(this.state.modules, [item]),
+                modulesToInstall: union(this.state.modulesToInstall, [item])
+            })
+        })
+            
+    }
+    
+    /**
+     * 
+     */
+    handleRemoveModule = (index, e) => {
+        defer(() => {
+            const item = this.state.modulesToInstall[index]
+    
+            this.setState({
+                modules: union(this.state.modules, [item]),
+                modulesToInstall: difference(this.state.modulesToInstall, [item])
+            })
+        })
+    }
+
     /**
      * 
      */
@@ -161,6 +255,7 @@ class TasksList extends Component {
                         </TableBody>
                     </Table>
                 </Paper>
+
                 {/* Dialog for create odoo container */}
                 <Dialog open={showDialog === 'create-odoo'} onClose={this.handleCloseDialog}>
                     <DialogTitle>Confirmar</DialogTitle>
@@ -188,69 +283,70 @@ class TasksList extends Component {
                          />
                     </DialogContent>
                     <DialogActions>
-                        <Button color='primary'>Cancelar</Button>
+                        <Button color='primary' onClick={this.handleCloseDialog}>Cancelar</Button>
                         <Button color='primary' onClick={this.handleAcceptDialog}>Aceptar</Button>
                     </DialogActions>
                 </Dialog>
+
                 {/* Dialog for copy odoo modules */}
                 <Dialog open={showDialog === 'show-modules'} onClose={this.handleCloseDialog} fullScreen={true}>
                     <DialogTitle>Seleccionar modulos</DialogTitle>
                     <DialogContent>
                         <DialogContentText>Seleccione los módulos que desea copiar/actualizar en un sistema desplegado.</DialogContentText>
-                        <TextField label='Nombre del Sistema' fullWidth={true} margin='normal'>
-                            <MenuItem value='sistema1'>Sistema 1</MenuItem>
-                            <MenuItem value='sistema2'>Sistema 2</MenuItem>
-                            <MenuItem value='sistema3'>Sistema 3</MenuItem>
-                        </TextField>
+                        <FormControl margin='normal' fullWidth={true}>
+                            <InputLabel>Nombre del Sistema</InputLabel>
+                            <Select 
+                                value={this.state.selectedOdoo}
+                                onChange={this.handleChangeOdooSystem}
+                                inputProps={{
+                                    name: 'selectedOdoo'
+                                }}>
+                                {this.state.odoos.map(o =>
+                                    <MenuItem key={o.id} value={o.name}>{o.name}</MenuItem>
+                                )}
+                            </Select>
+                        </FormControl>
                         <div className={classes.transfer}>
                             <div className={classes.transferPanels}>
                                 <Typography variant='title'>Módulos disponibles</Typography>
                                 <TextField type='search' placeholder='Buscar' fullWidth={true} margin='normal' />
-                                <List>
-                                    <ListItem>
-                                        <ListItemText primary='Módulo 1' />
-                                        <ListItemSecondaryAction>
-                                            <IconButton>
-                                                <AddIcon />
-                                            </IconButton>
-                                        </ListItemSecondaryAction>
-                                    </ListItem>
-                                    <ListItem>
-                                        <ListItemText primary='Módulo 2' />
-                                        <ListItemSecondaryAction>
-                                            <IconButton>
-                                                <AddIcon />
-                                            </IconButton>
-                                        </ListItemSecondaryAction>
-                                    </ListItem>
-                                    <ListItem>
-                                        <ListItemText primary='Módulo 3' />
-                                        <ListItemSecondaryAction>
-                                            <IconButton>
-                                                <AddIcon />
-                                            </IconButton>
-                                        </ListItemSecondaryAction>
-                                    </ListItem>
-                                </List>
+                                <div className={classes.transferModules}>
+                                    <List>
+                                        {this.state.modules.map((repo, index) =>
+                                            <ListItem key={index}>
+                                                <ListItemText primary={repo} />
+                                                <ListItemSecondaryAction onClick={e => this.handleAddModule(index, e)}>
+                                                    <IconButton>
+                                                        <AddIcon />
+                                                    </IconButton>
+                                                </ListItemSecondaryAction>
+                                            </ListItem>
+                                        )}
+                                    </List>
+                                </div>
                             </div>
                             <div className={classes.transferPanels}>
-                                <Typography variant='title'>Módulos a instalar</Typography>
-                                <List>
-                                    <ListItem>
-                                        <ListItemText primary='Módulo 4' />
-                                        <ListItemSecondaryAction>
-                                            <IconButton>
-                                                <RemoveIcon />
-                                            </IconButton>
-                                        </ListItemSecondaryAction>
-                                    </ListItem>
-                                </List>
+                                <Typography variant='title'>Módulos a copiar/actualizar</Typography>
+                                <div className={classes.transferModules}>
+                                    <List>
+                                        {this.state.modulesToInstall.map((toInstall, index) => 
+                                            <ListItem key={index}>
+                                                <ListItemText primary={toInstall} />
+                                                <ListItemSecondaryAction onClick={e => this.handleRemoveModule(index, e)}>
+                                                    <IconButton>
+                                                        <RemoveIcon />
+                                                    </IconButton>
+                                                </ListItemSecondaryAction>
+                                            </ListItem>
+                                        )}
+                                    </List>
+                                </div>
                             </div>
                         </div>
                     </DialogContent>
                     <DialogActions>
                         <Button color='primary' onClick={this.handleCloseDialog}>Cancelar</Button>
-                        <Button color='primary'>Aceptar</Button>
+                        <Button color='primary' onClick={this.handleAcceptDialog}>Aceptar</Button>
                     </DialogActions>
                 </Dialog>
             </Base>
@@ -258,6 +354,18 @@ class TasksList extends Component {
     }
 }
 
+/**
+ * 
+ * @param {*} state 
+ * @param {*} props 
+ */
+const mapStateToProps = (state, props) => {
+    return {
+        containers: state.containers,
+        repositories: state.repositories
+    }
+}
+
 /**
  * 
  * @param {*} dispatch 
@@ -270,14 +378,34 @@ const mapDispatchToProps = (dispatch, props) => ({
     loadData() {
         dispatch(get(`${REQUEST}?last`))
     },
+    /**
+     * 
+     */
+    loadRepositories() {
+        return dispatch(get(`${GIT}repositories/`))
+    },
+    /**
+     * 
+     */
+    loadContainers() {
+        return dispatch(get(`${DOCKER}container/all/`))
+    },
     /**
      * 
      */
     createOdoo(name) {
         dispatch(post(`${ODOO}create/`, { name }))
+    },
+    /**
+     * 
+     * @param {*} name 
+     * @param {*} modules 
+     */
+    installModules(system, modules) {
+        dispatch(post(`${ODOO}install_modules/`, {system, modules}))
     }
 })
 
 TasksList = withStyles(styles)(TasksList)
 
-export default connect(null, mapDispatchToProps)(TasksList)
+export default connect(mapStateToProps, mapDispatchToProps)(TasksList)

+ 5 - 0
src/constants/ResourceNames.js

@@ -20,6 +20,11 @@ export const DOCKER = 'docker/'
  */
 export const REQUEST = 'request/'
 
+/**
+ * 
+ */
+export const GIT = 'git/'
+
 /**
  * 
  */

+ 2 - 0
src/reducers/index.js

@@ -10,6 +10,7 @@ import { notification } from './notification'
 import { containers } from './containers'
 import { task } from './task'
 import { requests } from './requests'
+import { repositories } from './repositories'
 
 const history = createBrowserHistory()
 
@@ -20,6 +21,7 @@ const rootReducer = combineReducers({
     containers,
     task,
     requests,
+    repositories,
     router: routerReducer
 })
 

+ 33 - 0
src/reducers/repositories.js

@@ -0,0 +1,33 @@
+import { createReducer } from '../utils/reducer'
+import { has } from 'lodash'
+
+const initialState = {
+    repositories: []
+}
+
+/**
+ * 
+ */
+const setRepositories = (repositories, action) => {
+    if (has(action.payload, 'repositories')) {
+        return action.payload.repositories
+    }
+
+    return repositories
+}
+
+/**
+ * 
+ */
+const repositoriesReducer = createReducer([], {
+    'REQUEST_OK': setRepositories
+})
+
+/**
+ * 
+ * @param {*} state 
+ * @param {*} action 
+ */
+export const repositories = (state = initialState, action) => {
+    return repositoriesReducer(state.repositories, action)
+}