Commit 08b3e90d authored by Alessandro Abluton's avatar Alessandro Abluton 🤖

Add to team, creation in team, editing user's params and delete user from team...

Add to team, creation in team, editing user's params and delete user from team completely working; store now correctly updates on mods to users, everything coherent
parent e7d5c9bb
window.env = {
// MEDIA
// Online Simcaa.it
"PathImages": "http://www.simcaa.it/media/symbols/",
/* "PathImages": "http://www.simcaa.it/media/symbols/",
"WaterImages": "http://www.simcaa.it/media/specialchar/",
"CustomImage": "http://www.simcaa.it/demo/media/custom/",
"ApiImageUpload": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/imageupload",
"ApiSymbolUpload": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/imageuploadtmp",
"MediaImage": "http://www.simcaa.it/demo/media/images/",
"TmpImage": "http://www.simcaa.it/demo/media/tmp/",
*/
// Local
/*
"PathImages": "http://10.0.0.132/media/symbols/",
"WaterImages": "http://10.0.0.132/media/watermark/",
"CustomImage": "http://10.0.0.132/media/custom/",
......@@ -18,10 +18,10 @@ window.env = {
"ApiSymbolUpload": "http://10.0.0.132:8085/graphql/imageuploadtmp",
"MediaImage": "http://10.0.0.132/media/images/",
"TmpImage": "http://10.0.0.132/media/tmp/",
*/
// API SERVER
// Online Simcaa.it
"GraphQLServer": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/query",
/* "GraphQLServer": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/query",
"GraphQLServerNoAuth": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/query/noauth",
"GraphQLLogin": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/login",
"GraphQLCurrentUser": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/me",
......@@ -29,9 +29,9 @@ window.env = {
"RestApiCard": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/card",
"RestApiDuplicateProject": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/duplicateproject",
"RestApiDuplicateChapter": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/duplicatechapter",
*/
// Local
/*
"GraphQLServer": "http://10.0.0.132:8085/graphql/query",
"GraphQLServerNoAuth": "http://10.0.0.132:8085/graphql/query/noauth",
"GraphQLLogin": "http://10.0.0.132:8085/graphql/login",
......@@ -40,7 +40,7 @@ window.env = {
"RestApiCard": "http://10.0.0.132:8085/graphql/card",
"RestApiDuplicateProject": "http://10.0.0.132:8085/graphql/duplicateproject",
"RestApiDuplicateChapter": "http://10.0.0.132:8085/graphql/duplicatechapter",
*/
// CSS - remote
// "SemanticCSS": "http://10.0.0.132/includes/css/semantic.min.css",
// "StyleCSS": "http://10.0.0.132/includes/css/style.css",
......
......@@ -23,7 +23,6 @@ class Admin extends Component{
)
}
componentDidMount(){
this.props.saveTeamsToStore()
this.props.saveRolesToStore()
this.props.saveUserTeamsToStore()
......
import React, { Component } from 'react'
import UsersPagination from './UsersPagination'
class AddUserForm extends Component {
constructor(props) {
super(props)
}
render(){
return (
<UsersPagination/>
)
}
}
export default AddUserForm
import React, { Component, Fragment } from 'react'
import {Button, Form, Message, Accordion, Input, Select, Icon} from 'semantic-ui-react'
class EditUserForm extends Component{
constructor(props){
super(props)
this.state={
roles: [],
modPass: -1
}
}
componentDidMount(){
let tmpRoles = this.props.roles.map((role)=>{
return({
text: role.role_desc,
value: role.id
})
});
this.setState({
roles: tmpRoles
});
}
render(){
const panels = [
{
key: 'password',
title: 'Modifica Password',
content:
[
{
as: Form.Input,
label: 'Password attuale',
type: 'password'
},
{
as: Form.Input,
label: 'Nuova password',
type: 'password'
}
],
},
]
return(
<Form>
<Form.Group widths='equal'>
<Form.Field control={Input} label='Nome' value={this.props.name} onChange={this.props.nameChange()}/>
<Form.Field control={Input} label='Email' value={this.props.email} onChange={this.props.emailChange()}/>
<Form.Field control={Input} label='Username' value={this.props.username} onChange={this.props.usernameChange()}/>
</Form.Group>
<Form.Group widths='equal'>
<Form.Field control={Input} label='Organizzazione' value={this.props.organization} onChange={this.props.orgChange()}/>
<Form.Field control={Input} label='Sito Web' value={this.props.link_web} onChange={this.props.linkWebChange()}/>
<Form.Field control={Select} label='Ruolo' options={this.state.roles} onChange={this.props.roleChange()} defaultValue={this.props.toUser.role_id}/>
</Form.Group>
<Accordion as={Form.Field} >
<Accordion.Title active={this.state.modPass === 0} index={0} onClick={(e, titleProps)=>{titleProps.index === this.state.modPass ? this.setState({modPass: -1}) : this.setState({modPass: 0})}}>
<Icon name='dropdown'/>
Modifica password
</Accordion.Title>
<Accordion.Content active={this.state.modPass === 0}>
<Form.Field control={Input} label='Password attuale' onChange={this.props.oldPassChange()} type='password'/>
<Form.Field control={Input} label='Nuova password' onChange={this.props.newPassChange()} type='password'/>
</Accordion.Content>
</Accordion>
</Form>
)
}
}
export default EditUserForm
......@@ -28,9 +28,9 @@ class AdminMenu extends Component{
<Menu.Item name='goback' onClick={()=>this.props.history.push('/')}>
{t("ADM_MNU_BACK")}
</Menu.Item>
<Menu.Item name='language-switch'>
<LanguageSwitcher type='dropdown' />
</Menu.Item>
<Menu.Item name='logout' onClick={()=>this.Logout()}>
<b>Logout</b>
</Menu.Item>
......
......@@ -57,7 +57,7 @@ class UsersTable extends React.Component {
content= {t("POPUP_DEL")}
/>
<Popup
trigger={<Button circular icon={<Icon name='edit' size='large'/>} onClick={()=>this.mod(item.id)}/>}
trigger={<Button circular icon={<Icon name='edit' size='large'/>} onClick={()=>this.props.openEdit(item)}/>}
content= "Modifica dati"
/>
</Table.Cell>
......
import React, { Component } from 'react'
import { Modal,Button,Message } from 'semantic-ui-react'
import React, { Component,Fragment } from 'react'
import { Modal,Button,Message, Icon, Popup } from 'semantic-ui-react'
import PositiveMessage from '../components/PositiveMessage'
import NegativeMessage from '../components/ErrorMessage'
......@@ -44,7 +44,6 @@ class AddUserModal extends Component {
}
})
.catch((error)=>{
console.log(error);
this.setState({done:false, error:true, loading:false})
})
}
......@@ -59,17 +58,24 @@ class AddUserModal extends Component {
let usrs = this.props.user_teams.filter((el)=>{
return el.team_id !== this.props.curTeam
})
for(let i=0; i<usrs.length; i++){
for(let j=1; j<usrs.length; j++){
if(usrs[i].user_id === usrs[j].user_id){
usrs.splice(j,1)
}
}
}
this.setState({users: usrs})
}
userSelected(id){
console.log(id);
this.setState({userToAdd: id},()=>{this.forceUpdate()})
}
getModalContent(){
if(!this.state.done && !this.state.error){
//user yet to Search
return(
<div>
<Fragment>
<p>Seleziona l'utente da inserire nel team, ti basta cliccare sulla sua riga</p>
<UsersTable
users={this.state.users}
......@@ -83,7 +89,7 @@ class AddUserModal extends Component {
Hai selezionato l'utente con id: {this.state.userToAdd}
</p>
</Message>
</div>
</Fragment>
)
}else if(this.state.done){
//user added to team
......@@ -104,6 +110,8 @@ class AddUserModal extends Component {
<Modal closeIcon="close" open={this.props.openModal} onClose={this.props.closeModal}>
<Modal.Header>
Aggiunta di un utente per il team {this.state.teamName}
<Popup trigger={<Icon name='help' style={{float: 'right'}}/>}
content={"In questa tabella sono mostrati gli utenti del sistema che non appartengono al team "+this.state.teamName+", cliccando sulla riga di un utente questi verrà selezionato, per aggiungerlo in questo team basterà poi cliccare su Aggiungi."}/>
</Modal.Header>
<Modal.Content>
{contentLayout}
......
import React, { Component } from 'react'
import { Modal,Button } from 'semantic-ui-react'
import { Modal,Button, Popup, Icon } from 'semantic-ui-react'
import ErrorMessage from '../components/ErrorMessage'
import PositiveMessage from '../components/PositiveMessage'
import CreateUserForm from '../components/CreateUserForm'
import {apolloFetch} from '../../store/apolloFetchUtils'
import {escapeQuotes} from '../../store/functionUtils'
import {connect} from 'react-redux'
import {saveUserTeams} from '../../store/actions/AdministrationActions'
class CreateUserModal extends Component {
constructor(props){
......@@ -18,6 +22,7 @@ class CreateUserModal extends Component {
newLinkWeb: '',
newOrg: '',
newRole: '',
newPermissions: '',
userCreated: false,
addedToTeam: false,
error: false,
......@@ -43,7 +48,10 @@ class CreateUserModal extends Component {
this.setState({newPassword: e.target.value})
}
selectRole(e,data){
this.setState({newRole: data.value})
let permissions = this.props.roles.filter((role)=>{
if(role.id === data.value) return role
})
this.setState({newRole: data.value, newPermissions: escapeQuotes(permissions[0].role_permissions)})
}
checkFormValues(){
//check on input values??
......@@ -58,7 +66,8 @@ class CreateUserModal extends Component {
user: "${this.state.newUsername}",
organization: "${this.state.newOrg}",
link_web: "${this.state.newLinkWeb}",
role_id: ${this.state.newRole}
role_id: ${this.state.newRole},
user_permissions: "${this.state.newPermissions}"
){
id
}
......@@ -85,6 +94,7 @@ class CreateUserModal extends Component {
if(!data.hasOwnProperty("errors")){
//user added to team
this.setState({error: false, userCreated: true, addedToTeam: true})
this.props.saveUserTeamsToStore()
}else{
//errors returned, user created but not added to any team
this.setState({error: true, userCreated:true, addedToTeam:false})
......@@ -118,7 +128,7 @@ class CreateUserModal extends Component {
//user yet to create
return(
<div>
<CreateUserForm roles = {this.props.roles}
<CreateUserForm
name = {this.state.newName}
newNameChange = {()=>this.newNameChange.bind(this)}
email = {this.state.newEmail}
......@@ -131,6 +141,7 @@ class CreateUserModal extends Component {
newLinkWebChange = {()=>this.newLinkWebChange.bind(this)}
org = {this.state.newOrg}
newOrgChange = {()=>this.newOrgChange.bind(this)}
roles = {this.props.roles}
selectRole = {()=>this.selectRole.bind(this)}
/>
<p>Per continuare, compila tutti i campi segnati con *</p>
......@@ -182,6 +193,8 @@ class CreateUserModal extends Component {
<Modal closeIcon="close" open={this.props.openModal} onClose={this.props.closeModal}>
<Modal.Header>
Creazione di nuovo utente per il team {this.state.teamName}
<Popup trigger={<Icon name='help' style={{float: 'right'}}/>}
content={"Creazione di un nuovo utente, una volta creato verrà immediatamente aggiunto al team "+this.state.teamName}/>
</Modal.Header>
<Modal.Content>
{contentLayout}
......@@ -193,4 +206,9 @@ class CreateUserModal extends Component {
)
}
}
export default CreateUserModal
const mapDispatchToProps = (dispatch) => {
return {
saveUserTeamsToStore: ()=> dispatch(saveUserTeams())
}
}
export default connect(null,mapDispatchToProps)(CreateUserModal)
import React, { Component, Fragment } from 'react'
import { Modal, Button, Icon, Popup } from 'semantic-ui-react'
import PositiveMessage from '../components/PositiveMessage'
import NegativeMessage from '../components/ErrorMessage'
import EditUserForm from '../components/EditUserForm'
import {apolloFetch, apolloFetchNoAuth} from '../../store/apolloFetchUtils'
import {connect} from 'react-redux'
import {saveUserTeams} from '../../store/actions/AdministrationActions'
import { translate, Trans } from 'react-i18next'
class EditUserParamsModal extends Component {
constructor(props){
super(props)
this.state={
error: false,
loading: false,
updated: false,
somethingModded: false,
name: this.props.toUser.name,
email: this.props.toUser.email,
username: this.props.toUser.username,
organization: this.props.toUser.organization,
link_web: this.props.toUser.web_site,
role_id: this.props.toUser.role_id,
old_password: '',
new_password: ''
}
}
nameChange(e){
this.setState({name: e.target.value, somethingModded: true})
}
emailChange(e){
this.setState({email: e.target.value, somethingModded: true})
}
usernameChange(e){
this.setState({username: e.target.value, somethingModded: true})
}
orgChange(e){
this.setState({organization: e.target.value, somethingModded: true})
}
linkWebChange(e){
this.setState({link_web: e.target.value, somethingModded: true})
}
roleChange(e,data){
console.log(e);
console.log(data);
this.setState({role: data.value, somethingModded: true})
}
oldPassChange(e){
this.setState({old_password: e.target.value})
}
newPassChange(e){
this.setState({new_password: e.target.value, somethingModded: true})
}
modUser(){
let query = ``
if(this.state.old_password === '' && this.state.new_password === ''){
//password not modified
query = `
mutation modUser{
updateCaaUser(
id: ${this.props.toUser.user_id},
name: "${this.state.name}",
email: "${this.state.email}",
user: "${this.state.username}",
organization: "${this.state.organization}",
link_web: "${this.state.link_web}",
role_id: ${this.state.role_id}
){
id
}
}
`
}else{
//password to modify!
query = `
mutation modUser{
updateCaaUser(
id: ${this.props.toUser.user_id},
name: "${this.state.name}",
email: "${this.state.email}",
user: "${this.state.username}",
organization: "${this.state.organization}",
link_web: "${this.state.link_web}",
role_id: ${this.state.role_id},
old_password: "${this.state.old_password}",
new_password: "${this.state.new_password}"
){
id
}
}
`
}
this.setState({loading: true})
apolloFetch({query})
.then((data)=>{
if(!data.hasOwnProperty("errors")){
//no errors returned, user updated correctly
this.setState({loading: false, error: false, updated: true})
this.props.saveUserTeamsToStore()
}else{
this.setState({loading: false, error: true, updated: false})
}
})
.catch((error)=>{
this.setState({loading: false, error: true, updated: false})
})
}
render(){
return(
<Modal closeIcon="close" open={this.props.openModal} onClose={this.props.closeModal}>
<Modal.Header>
Modifica parametri di <b>{this.props.toUser.name}</b>
<Popup trigger={<Icon name='help' style={{float: 'right'}}/>}
content="Modifica dei parametri dell'utente, basta digitare il nuovo valore per uno o più parametri e poi cliccare su Modifica. "/>
</Modal.Header>
<Modal.Content>
<EditUserForm
name={this.state.name}
nameChange={()=>this.nameChange.bind(this)}
email={this.state.email}
emailChange={()=>this.emailChange.bind(this)}
username={this.state.username}
usernameChange={()=>this.usernameChange.bind(this)}
organization = {this.state.organization}
orgChange={()=>this.orgChange.bind(this)}
link_web = {this.state.link_web}
linkWebChange={()=>this.linkWebChange.bind(this)}
roles = {this.props.roles}
roleChange={()=>this.roleChange.bind(this)}
oldPassChange={()=>this.oldPassChange.bind(this)}
newPassChange={()=>this.newPassChange.bind(this)}
toUser={this.props.toUser}
/>
<PositiveMessage header="Tutto ok!" message="Utente modificato correttamente :)" hidden={!this.state.updated}/>
<NegativeMessage header="Errore!" message="Non è stato possibile modificare i parametri dell'utente" hidden={!this.state.error}/>
</Modal.Content>
<Modal.Actions>
<Button negative onClick={()=>this.props.closeModal()} loading={this.state.loading}>Chiudi</Button>
<Button positive onClick={()=>this.modUser()} loading={this.state.loading} disabled={!this.state.somethingModded}>Modifica</Button>
</Modal.Actions>
</Modal>
)
}
}
const mapStateToProps = (state)=>{
return{
roles: state.adminReducer.roles,
toUser: state.modalReducer.toUser
}
}
const mapDispatchToProps = (dispatch) => {
return {
saveUserTeamsToStore: ()=> dispatch(saveUserTeams())
}
}
export default connect(mapStateToProps,mapDispatchToProps)(translate('translations')(EditUserParamsModal))
import React, { Component } from 'react'
import { Modal, Button } from 'semantic-ui-react'
import { Modal, Button, Icon, Popup } from 'semantic-ui-react'
import PositiveMessage from '../components/PositiveMessage'
import NegativeMessage from '../components/ErrorMessage'
......@@ -20,9 +20,7 @@ class ManageTeamModal extends Component {
}
}
modUser(id){
console.log(id);
}
componentDidMount(){
this.props.teams.forEach((team)=>{
if(team.id === this.props.toTeam){
......@@ -58,11 +56,12 @@ class ManageTeamModal extends Component {
<Modal closeIcon="close" open={this.props.openModal} onClose={this.props.closeModal}>
<Modal.Header>
Gestione del team <b>{this.state.teamName}</b>
<Popup trigger={<Icon name='help' style={{float: 'right'}}/>}
content={"In questa tabella sono visualizzati gli utenti appartenenti al team "+this.state.teamName+", è possibile tramite gli appositi tasti eliminare un utente dal team oppure modificare i parametri e i permessi di un utente (attenzione, i parametri/permessi dell'utente non sono modificati solamente per questo team!)"}/>
</Modal.Header>
<Modal.Content>
<ManageTeamTable
userTeams = {this.props.user_teams}
modUser={this.modUser.bind(this)}
removeUser={this.removeUser.bind(this)}
/>
<PositiveMessage header="Tutto ok!" message="Utente eliminato correttamente dal team :)" hidden={!this.state.removed}/>
......
......@@ -7,7 +7,7 @@ import ErrorMessage from '../components/ErrorMessage'
import {Loader, Dimmer} from 'semantic-ui-react'
import {connect} from 'react-redux'
import {saveUserTeams} from '../../store/actions/AdministrationActions'
import {saveUserTeams, openModalEditUserParams} from '../../store/actions/AdministrationActions'
class ManageTeamTable extends Component {
constructor(props) {
......@@ -44,8 +44,8 @@ class ManageTeamTable extends Component {
users={this.state.users}
selectable={false}
manageUsers={true}
modUser={this.props.modUser.bind(this)}
removeUser={this.remove.bind(this)}
openEdit = {this.props.openModalEditUserParams.bind(this)}
/>
<ErrorMessage hidden={!this.state.error} header="Errore!" message="Errore nel caricare gli utenti, prova a caricare un'altra pagina."/>
</Fragment>
......@@ -66,7 +66,7 @@ const mapStateToProps = (state)=>{
}
const mapDispatchToProps = (dispatch) => {
return {
saveUserTeamsToStore: ()=> dispatch(saveUserTeams())
openModalEditUserParams: (toUser) => dispatch(openModalEditUserParams(toUser))
}
}
export default connect(mapStateToProps,mapDispatchToProps)(ManageTeamTable)
......@@ -4,9 +4,10 @@ import { translate } from 'react-i18next'
import { connect } from 'react-redux'
import {closeModal} from '../../store/actions/AdministrationActions'
import CreateUserModal from '../containers/CreateUserModal'
import AddUserModal from '../containers/AddUserModal'
import ManageTeamModal from '../containers/ManageTeamModal'
import CreateUserModal from './CreateUserModal'
import AddUserModal from './AddUserModal'
import ManageTeamModal from './ManageTeamModal'
import EditUserParamsModal from './EditUserParamsModal'
class RootModal extends Component{
render(){
......@@ -17,6 +18,8 @@ class RootModal extends Component{
return(<AddUserModal {...this.props}/>)
case "manage_team":
return(<ManageTeamModal {...this.props}/>)
case "edit_user_params":
return(<EditUserParamsModal {...this.props}/>)
default:
return(<div></div>)
}
......
import React, { Component } from 'react'
import {Table, Button, Icon, Input, Modal, Message} from 'semantic-ui-react'
import { translate } from 'react-i18next'
import { withApolloFetch } from '../../withApolloFetch'
import { withRouter } from 'react-router-dom'
class UsrConfig extends Component{
constructor(props){
super(props)
this.handleNameInput = this.handleNameInput.bind(this)
this.handleEmailInput = this.handleEmailInput.bind(this)
this.handleOrgInput = this.handleOrgInput.bind(this)
this.handleWebInput = this.handleWebInput.bind(this)
this.state={
newName: '',
newEmail: '',
newOrganization: '',
newWeb: '',
name: this.props.name,
email: this.props.email,
organization: this.props.organization,
web: this.props.link_web,
interror: false,
loading: false,
missingData: false
}
}
modData(which){
let paramToUpdate = "";
let value = "";
switch(which){
case 0:
paramToUpdate = "name"
value = ((this.state.newName !== '') ? this.state.newName : '-1')
break;
case 1:
paramToUpdate = "email"
value = ((this.state.newEmail !== '') ? this.state.newEmail : '-1')
break;
case 2:
paramToUpdate = "organization"
value = ((this.state.newOrganization !== '') ? this.state.newOrganization : '-1')
break;
case 3:
paramToUpdate = "link_web"
value = ((this.state.newWeb !== '') ? this.state.newWeb : '-1')
break;
default:
break;
}
//faccio query solo se il valore da inserire non è vuoto
if(value !== '-1'){
let query = `
mutation updateUser {
updateCaaUser(id: ${this.props.id},
${paramToUpdate}: "${value}"){
id
}
}
`
this.setState({loading: true})
this.props.apolloFetch({ query })
.then((data) => {
if(data.hasOwnProperty('errors')){
this.setState({interror: true, loading: false})
}else{
switch(which){
case 0:
this.setState({
name: value
})
break;
case 1:
this.setState({
email: value
})
break;
case 2:
this.setState({
organization: value
})
break;
case 3:
this.setState({
web: value
})
break;
default:
break;
}
this.setState({loading: false})
this.props.update();
}
})
.catch((error) => {
this.setState({loading: false, interror: true})
})
}else{
//errore dati mancanti
this.setState({missingData: true});
}
}
handleNameInput(e){
this.setState({
newName: e.target.value
})
}
handleEmailInput(e){
this.setState({
newEmail: e.target.value
})
}
handleOrgInput(e){
this.setState({
newOrganization: e.target.value
})
}
handleWebInput(e){
this.setState({
newWeb: e.target.value
})
}
render(){
const { t } = this.props
return(