Commit eb4da2c3 authored by Lionel Morin's avatar Lionel Morin
Browse files

Merge branch 'serverselection' into 'develop'

Serverselection

See merge request !2
parents c5938e1c 6293918e
This diff is collapsed.
......@@ -3,11 +3,12 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@material-ui/core": "^1.3.1",
"@material-ui/icons": "^1.1.0",
"depcheck": "^0.6.9",
"@material-ui/core": "^3.9.3",
"@material-ui/icons": "^3.0.2",
"depcheck": "^0.7.2",
"history": "^4.7.2",
"install": "^0.11.2",
"keycloak-js": "^4.5.0",
"leaflet": "^1.3.1",
"material-ui-search-bar": "^1.0.0-beta.7",
"qhistory": "^1.0.2",
......@@ -23,13 +24,12 @@
"react-scripts": "^1.1.5",
"react-sparklines": "^1.7.0",
"react-swipeable-views": "^0.12.14",
"recharts": "^1.0.1",
"recharts": "^1.5.0",
"redux": "^4.0.0",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"typeface-roboto": "0.0.54",
"uuid": "^3.3.2",
"keycloak-js": "^4.5.0"
"uuid": "^3.3.2"
},
"scripts": {
"start": "react-scripts start",
......
{
"realm": "zephir",
"auth-server-url": "https://zephir2.ac-test.fr/auth",
"ssl-required": "external",
"resource": "zephir-api",
"public-client": true,
"confidential-port": 0
}
......@@ -14,6 +14,7 @@ import {
NotFoundPage,
HomePage,
ServersPage,
ServerSelectionsPage,
ServerModelsPage,
AppsPage,
UnauthorizedPage,
......@@ -61,6 +62,7 @@ class App extends Component {
<Switch>
<Route exact path="(/|/widgets)" component={HomePage} />
<Route path="/servers" component={ServersPage} />
<Route path="/serverselections" component ={ServerSelectionsPage} />
<Route path="/servermodels" component={ServerModelsPage} />
<Route path="/jobs/:id" component={JobsPage} />
<Route path="/preferences" component={PreferencesPage} />
......
......@@ -7,3 +7,4 @@ export * from './app.actions';
export * from './exec.actions';
export * from './config.actions';
export * from './settings.actions';
export * from './serverselection.actions';
\ No newline at end of file
......@@ -3,7 +3,8 @@ import { Zephir } from '../services';
export const servermodelActions = {
describe,
list
list,
updateLocalFilter,
};
export const SERVERMODEL_DESCRIBE_REQUEST = 'SERVERMODEL_DESCRIBE_REQUEST';
......@@ -56,3 +57,8 @@ function list() {
function success(servermodels) { return { type: SERVERMODEL_LIST_SUCCESS, servermodels }; }
function failure(error) { return { type: SERVERMODEL_LIST_FAILURE, error }; }
}
export const SERVERMODEL_UPDATE_LOCAL_FILTER = 'SERVERMODEL_UPDATE_LOCAL_FILTER';
function updateLocalFilter(filter) {
return { type: SERVERMODEL_UPDATE_LOCAL_FILTER, filter };
}
\ No newline at end of file
import { Zephir } from '../services/zephir.service';
import { alertActions } from './alert.actions';
export const serverselectionActions = {
list,
describe,
create,
update,
updateLocalFilter,
server_set,
user_add,
user_remove,
user_update,
delete: _delete,
getAll: () => ({type: 'GETALL_NOOP'}),
};
export const SERVERSELECTION_LIST_REQUEST = 'SERVERSELECTION_LIST_REQUEST';
export const SERVERSELECTION_LIST_SUCCESS = 'SERVERSELECTION_LIST_SUCCESS';
export const SERVERSELECTION_LIST_FAILURE = 'SERVERSELECTION_LIST_FAILURE';
function list() {
return dispatch => {
dispatch(request());
return Zephir.v1.serverselection.list()
.then(({response}) => {
dispatch(success(response));
return response;
})
.catch(error => {
dispatch(failure(error));
dispatch(alertActions.error(error.message));
throw error;
});
};
function request() { return { type: SERVERSELECTION_LIST_REQUEST }; }
function success(serverselections) { return { type: SERVERSELECTION_LIST_SUCCESS, serverselections }; }
function failure(error) { return { type: SERVERSELECTION_LIST_FAILURE, error }; }
}
export const SERVERSELECTION_DESCRIBE_REQUEST = 'SERVERSELECTION_DESCRIBE_REQUEST';
export const SERVERSELECTION_DESCRIBE_SUCCESS = 'SERVERSELECTION_DESCRIBE_SUCCESS';
export const SERVERSELECTION_DESCRIBE_FAILURE = 'SERVERSELECTION_DESCRIBE_FAILURE';
function describe(serverselectionid) {
return dispatch => {
const serverselectionId = parseInt(serverselectionid, 10);
dispatch(request(serverselectionId));
return Zephir.v1.serverselection.describe({serverselectionid: serverselectionId})
.then(({response}) => {
dispatch(success(response));
return response;
})
.catch(error => {
dispatch(failure(error));
dispatch(alertActions.error(error.message));
throw error;
});
};
function request(serverselectionid) { return { type: SERVERSELECTION_DESCRIBE_REQUEST, serverselectionId: serverselectionid }; }
function success(serverselection) { return { type: SERVERSELECTION_DESCRIBE_SUCCESS, serverselection }; }
function failure(error) { return { type: SERVERSELECTION_DESCRIBE_FAILURE, error }; }
}
export const SERVERSELECTION_CREATE_REQUEST = 'SERVERSELECTION_CREATE_REQUEST';
export const SERVERSELECTION_CREATE_SUCCESS = 'SERVERSELECTION_CREATE_SUCCESS';
export const SERVERSELECTION_CREATE_FAILURE = 'SERVERSELECTION_CREATE_FAILURE';
function create({ serverselectionname, serverselectiondescription}) {
return dispatch => {
dispatch(request());
return Zephir.v1.serverselection.create({
serverselectionname,
serverselectiondescription
})
.then(({response}) => {
dispatch(success(response));
dispatch(alertActions.success('Votre sélection de serveurs a été créée.'));
return response;
})
.catch(error => {
dispatch(failure(error));
dispatch(alertActions.error(error.message));
throw error;
});
};
function request() { return { type: SERVERSELECTION_CREATE_REQUEST }; }
function success(serverselection) { return { type: SERVERSELECTION_CREATE_SUCCESS, serverselection }; }
function failure(error) { return { type: SERVERSELECTION_CREATE_FAILURE, error }; }
}
export const SERVERSELECTION_UPDATE_REQUEST = 'SERVERSELECTION_UPDATE_REQUEST';
export const SERVERSELECTION_UPDATE_SUCCESS = 'SERVERSELECTION_UPDATE_SUCCESS';
export const SERVERSELECTION_UPDATE_FAILURE = 'SERVERSELECTION_UPDATE_FAILURE';
function update({ serverselectionid, serverselectionname, serverselectiondescription}) {
return dispatch => {
dispatch(request());
return Zephir.v1.serverselection.update({
serverselectionname,
serverselectiondescription,
serverselectionid: serverselectionid,
requete: ''
})
.then(({response}) => {
dispatch(success(response));
dispatch(alertActions.success(`La sélection "${serverselectionname}" a été mise à jour.`));
return response;
})
.catch(error => {
dispatch(failure(error));
dispatch(alertActions.error(error.message));
throw error;
});
};
function request() { return { type: SERVERSELECTION_UPDATE_REQUEST }; }
function success(serverselection) { return { type: SERVERSELECTION_UPDATE_SUCCESS, serverselection }; }
function failure(error) { return { type: SERVERSELECTION_UPDATE_FAILURE, error }; }
}
export const SERVERSELECTION_DELETE_REQUEST = 'SERVERSELECTION_DELETE_REQUEST';
export const SERVERSELECTION_DELETE_SUCCESS = 'SERVERSELECTION_DELETE_SUCCESS';
export const SERVERSELECTION_DELETE_FAILURE = 'SERVERSELECTION_DELETE_FAILURE';
function _delete(serverselectionId, serverName) {
return dispatch => {
dispatch(request(serverselectionId));
return Zephir.v1.serverselection.delete({ serverselectionid: serverselectionId })
.then(({response}) => {
dispatch(success(response));
dispatch(alertActions.success(`La sélection "#${serverselectionId} ${serverName}" a été supprimée.`));
return response;
})
.catch(error => {
dispatch(failure(error));
dispatch(alertActions.error(error.message));
throw error;
});
};
function request(serverselectionId) { return { type: SERVERSELECTION_DELETE_REQUEST, serverselectionId }; }
function success(result) { return { type: SERVERSELECTION_DELETE_SUCCESS, result }; }
function failure(error) { return { type: SERVERSELECTION_DELETE_FAILURE, error }; }
}
export const SERVERSELECTION_SERVER_SET_REQUEST = 'SERVERSELECTION_SERVER_SET_REQUEST';
export const SERVERSELECTION_SERVER_SET_SUCCESS = 'SERVERSELECTION_SERVER_SET_SUCCESS';
export const SERVERSELECTION_SERVER_SET_FAILURE = 'SERVERSELECTION_SERVER_SET_FAILURE';
function server_set({ serverselectionid }, serveridlist) {
return dispatch => {
dispatch(request());
return Zephir.v1.serverselection.server.set({
serverselectionid,
serveridlist,
})
.then(({response}) => {
dispatch(success(response));
dispatch(alertActions.success('La liste des serveurs de la sélection a été mise à jour.'));
return response;
})
.catch(error => {
dispatch(failure(error));
dispatch(alertActions.error(error.message));
throw error;
});
};
function request() { return { type: SERVERSELECTION_SERVER_SET_REQUEST }; }
function success(serverselection) { return { type: SERVERSELECTION_SERVER_SET_SUCCESS, serverselection }; }
function failure(error) { return { type: SERVERSELECTION_SERVER_SET_FAILURE, error }; }
}
export const SERVERSELECTION_USER_ADD_REQUEST = 'SERVERSELECTION_USER_ADD_REQUEST';
export const SERVERSELECTION_USER_ADD_SUCCESS = 'SERVERSELECTION_USER_ADD_SUCCESS';
export const SERVERSELECTION_USER_ADD_FAILURE = 'SERVERSELECTION_USER_ADD_FAILURE';
function user_add(serverselectionid , username, role) {
return dispatch => {
dispatch(request());
return Zephir.v1.serverselection.user.add({
serverselectionid,
username,
role
})
.then(({response}) => {
dispatch(success(response));
dispatch(alertActions.success("L'utilisateur a été ajouté à la sélection de serveur"));
return response;
})
.catch(error => {
dispatch(failure(error));
dispatch(alertActions.error(error.message));
throw error;
});
};
function request() { return { type: SERVERSELECTION_USER_ADD_REQUEST }; }
function success(serverselection) { return { type: SERVERSELECTION_USER_ADD_SUCCESS, serverselection }; }
function failure(error) { return { type: SERVERSELECTION_USER_ADD_FAILURE, error }; }
}
export const SERVERSELECTION_USER_DEL_REQUEST = 'SERVERSELECTION_USER_DEL_REQUEST';
export const SERVERSELECTION_USER_DEL_SUCCESS = 'SERVERSELECTION_USER_DEL_SUCCESS';
export const SERVERSELECTION_USER_DEL_FAILURE = 'SERVERSELECTION_USER_DEL_FAILURE';
function user_remove(serverselectionid , username) {
return dispatch => {
dispatch(request());
return Zephir.v1.serverselection.user.remove({
serverselectionid,
username
})
.then(({response}) => {
dispatch(success(response));
dispatch(alertActions.success("L'utilisateur a été retiré de la sélection de serveurs"));
return response;
})
.catch(error => {
dispatch(failure(error));
dispatch(alertActions.error(error.message));
throw error;
});
};
function request() { return { type: SERVERSELECTION_USER_DEL_REQUEST }; }
function success(serverselection) { return { type: SERVERSELECTION_USER_DEL_SUCCESS, serverselection }; }
function failure(error) { return { type: SERVERSELECTION_USER_DEL_FAILURE, error }; }
}
export const SERVERSELECTION_USER_UPDATE_REQUEST = 'SERVERSELECTION_USER_UPDATE_REQUEST';
export const SERVERSELECTION_USER_UPDATE_SUCCESS = 'SERVERSELECTION_USER_UPDATE_SUCCESS';
export const SERVERSELECTION_USER_UPDATE_FAILURE = 'SERVERSELECTION_USER_UPDATE_FAILURE';
function user_update(serverselectionid , username, role) {
return dispatch => {
dispatch(request());
return Zephir.v1.serverselection.user.update({
serverselectionid,
username,
role
})
.then(({response}) => {
dispatch(success(response));
dispatch(alertActions.success("L'utilisateur a été modifié dans la sélection de serveurs"));
return response;
})
.catch(error => {
dispatch(failure(error));
dispatch(alertActions.error(error.message));
throw error;
});
};
function request() { return { type: SERVERSELECTION_USER_UPDATE_REQUEST }; }
function success(serverselection) { return { type: SERVERSELECTION_USER_UPDATE_SUCCESS, serverselection }; }
function failure(error) { return { type: SERVERSELECTION_USER_UPDATE_FAILURE, error }; }
}
export const SERVERSELECTION_UPDATE_LOCAL_FILTER = 'SERVERSELECTION_UPDATE_LOCAL_FILTER';
function updateLocalFilter(filter) {
return { type: SERVERSELECTION_UPDATE_LOCAL_FILTER, filter };
}
\ No newline at end of file
......@@ -10,13 +10,14 @@ export const SETTINGS_GET_REQUEST = 'SETTINGS_GET_REQUEST';
export const SETTINGS_GET_SUCCESS = 'SETTINGS_GET_SUCCESS';
export const SETTINGS_GET_FAILURE = 'SETTINGS_GET_FAILURE';
export function getSetting(username) {
function getSetting(username) {
console.log(username)
return (dispatch) => {
dispatch(request(username));
return Zephir.v1.identity.settings.get(username)
return Zephir.v1.identity.settings.get({username: username})
.then(({ response }) => {
dispatch(success(response.settings));
dispatch(success(response));
return response;
})
.catch(error => {
......@@ -26,7 +27,7 @@ export function getSetting(username) {
});
};
function request(username) { return { type: SETTINGS_GET_REQUEST, username }; }
function request(username) { return { type: SETTINGS_GET_REQUEST, username: username }; }
function success(settings) { return { type: SETTINGS_GET_SUCCESS, settings }; }
function failure(error, username) { return { type: SETTINGS_GET_FAILURE, error, username }; }
......@@ -36,11 +37,11 @@ export const SETTINGS_SET_REQUEST = 'SETTINGS_SET_REQUEST';
export const SETTINGS_SET_SUCCESS = 'SETTINGS_SET_SUCCESS';
export const SETTINGS_SET_FAILURE = 'SETTINGS_SET_FAILURE';
export function setSetting(settings) {
function setSetting(user, settings) {
return (dispatch) => {
dispatch(request(settings));
return Zephir.v1.identity.settings.set(settings)
dispatch(request({user, ...settings}));
return Zephir.v1.identity.settings.set({username: user.username, ...settings})
.then(({ response }) => {
dispatch(success(response));
dispatch(alertActions.success('Les paramètres ont été mis à jour.'));
......
......@@ -10,13 +10,13 @@ class PeeringConfDetails extends React.Component {
return (
<React.Fragment>
<Typography className={classes.title}
variant="headline"
variant="h5"
>
Informations d&#39;appairage
</Typography>
<Grid container>
<Grid item sm={4}>
<Typography variant="subheading">Configuration du client</Typography>
<Typography variant="subtitle1">Configuration du client</Typography>
</Grid>
<Grid item sm={8} className={classes.codeContainer}>
<pre className={classes.code}>
......@@ -26,7 +26,7 @@ class PeeringConfDetails extends React.Component {
</Grid>
<Grid container>
<Grid item sm={4}>
<Typography variant="subheading">Clé publique</Typography>
<Typography variant="subtitle1">Clé publique</Typography>
</Grid>
<Grid item sm={8} className={classes.codeContainer}>
<pre className={classes.code}>
......@@ -36,7 +36,7 @@ class PeeringConfDetails extends React.Component {
</Grid>
<Grid container>
<Grid item sm={4}>
<Typography variant="subheading">Clé privée</Typography>
<Typography variant="subtitle1">Clé privée</Typography>
</Grid>
<Grid item sm={8} className={classes.codeContainer}>
<pre className={classes.code}>
......
......@@ -6,7 +6,7 @@ import { serverActions } from '../../actions';
import { connect } from 'react-redux';
import { Button, Grid, Paper, Typography } from '@material-ui/core';
import {
FileDownload as FileDownloadIcon
SaveAlt as FileDownloadIcon
} from '@material-ui/icons';
import { Loader } from '../../components';
import { PeeringConfDetails } from './PeeringConfDetails';
......
......@@ -51,7 +51,7 @@ class ActionApp extends React.Component {
<Paper className={classes.history}>
<Grid container>
<Grid item sm={9} xs={6}>
<Typography variant="headline">Historique des opérations</Typography>
<Typography variant="h5">Historique des opérations</Typography>
</Grid>
<Grid item sm={3} xs={6} className={classes.alignRight}>
<Button onClick={this.onRefreshClick}>
......
......@@ -60,14 +60,21 @@ export function withForm(validators = {}) {
}
handleChange(evt) {
const { name, value } = evt.target;
const errorMessage = this.validate(name, value, false);
if (errorMessage) {
this.setFieldError(name, errorMessage);
} else {
this.unsetFieldError(name);
const { name, value, type } = evt.target;
if (type === "checkbox"){
console.log(value)
let valcheck = value === 'true' ? false : true
console.log(valcheck)
this.setFieldValue(name, valcheck);
}else {
const errorMessage = this.validate(name, value, false);
if (errorMessage) {
this.setFieldError(name, errorMessage);
} else {
this.unsetFieldError(name);
}
this.setFieldValue(name, value);
}
this.setFieldValue(name, value);
}
handleSubmit(evt) {
......
......@@ -70,7 +70,7 @@ class Navbar extends React.Component {
: <Toolbar className={classes.toolbar}>
{_navLeft}
{navLeft}
<Typography className={classes.title} variant="title" color="inherit" noWrap>
<Typography className={classes.title} variant="h6" color="inherit" noWrap>
{title}
</Typography>
<div className={classes.navRight}>
......
......@@ -54,7 +54,7 @@ class ServerModelSelector extends React.Component {
return servermodels.map(servermodel => (
<MenuItem key={`servermodel-${servermodel.model.servermodelid}`}
value={servermodel.model.servermodelid}>
{servermodel.model.servermodelname} - {groupName}
{servermodel.model.servermodelname} {servermodel.model.subreleasename} - {groupName}
</MenuItem>
));
}
......
import React from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { withStyles } from '@material-ui/core/styles';
import { selectAllServers, selectServerSelectionById } from '../selectors';
import Infinite from 'react-infinite';
import { ServersListItem, } from '../pages/ServersPage';
import {
Grid,
Typography,
List,
} from '@material-ui/core';
class ServerPicker extends React.Component {
constructor(props) {
super(props);
let list_server = selectAllServers(this.props.servers).map(server => server.serverid)
let list_ss = (this.props.serverselection && this.props.serverselection.serverselectionserversid) || []
let difference = list_server.filter(x => !list_ss.includes(x))
this.state = {
boxOne: difference,
boxTwo: list_ss
};
this.handleEvent = this.handleEvent.bind(this);
}
handleEvent(itemId) {
const isInBoxOne = this.state.boxOne.includes(itemId);
// Heres the magic, if the item is in the first Box, filter it out,
// and put into the second, otherwise the other way around..
this.setState({
boxOne: isInBoxOne
? this.state.boxOne.filter(i => i !== itemId)
: [ ...this.state.boxOne, itemId ],
boxTwo: isInBoxOne
? [ ...this.state.boxTwo, itemId ]
: this.state.boxTwo.filter(i => i !== itemId)
}, this.handleList);
}
handleList(){
this.props.handleSrvList(this.state.boxTwo)
}
render() {
// eslint-disable-next-line
const { classes, servers, lastRefresh, serverselection, ...otherProps } = this.props;
const srv = selectAllServers(servers)
return (
<React.Fragment>
<Grid item xs={12} sm={6}>
<Typography variant="subtitle1">Serveurs Disponibles</Typography>
<Infinite
containerHeight={400}
elementHeight={64}>
<ItemList dense={true} handleEvent={this.handleEvent} items={this.state.boxOne} allItems={srv} />
</Infinite>
</Grid>
<Grid item xs={12} sm={6}>
<Typography variant="subtitle1">Serveurs de la sélection</Typography>
<Infinite
containerHeight={400}
elementHeight={64}>
<ItemList dense={true} handleEvent={this.handleEvent} items={this.state.boxTwo} allItems={srv} />
</Infinite>
</Grid>
</React.Fragment>
);
}
}
class ItemList extends React.Component{
render() {
let itemArr = this.props.allItems;
let myItems = this.props.items;
let handleEvent = this.props.handleEvent;
let listItems = itemArr.map((server) => {
if (!myItems.includes(server.serverid)) return null;
return <ServersListItem
key={server.serverid}
server={server}
onClick={() => handleEvent(server.serverid)}
/>
});
return (
<List dense={true} handleEvent={this.handleEvent}>