diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/sidebarStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/sidebarStyle.js index 93a2ba54da5066ad40bb3ae944f4df0c91ea2c48..a76a44c74c0e502ee2ddd2fe6bbde75b8c712875 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/sidebarStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/sidebarStyle.js @@ -137,6 +137,18 @@ const sidebarStyle = theme => ({ listStyle: "none", position: "unset" }, + bottomlist: { + marginTop: "20px", + paddingLeft: "0", + paddingTop: "0", + paddingBottom: "0", + marginBottom: "0", + listStyle: "none", + position: "fixed", + bottom: "0", + left: "0", + width: drawerWidth + }, item: { position: "relative", display: "block", diff --git a/jams-react-client/src/components/LanguagePicker/LanguagePicker.js b/jams-react-client/src/components/LanguagePicker/LanguagePicker.js index b6555f5b4ea8b37c815481eec762eddfa54e6a9f..176cf5960f37806ba51f032252794156c9e55028 100644 --- a/jams-react-client/src/components/LanguagePicker/LanguagePicker.js +++ b/jams-react-client/src/components/LanguagePicker/LanguagePicker.js @@ -38,7 +38,7 @@ const useStyles = makeStyles((theme) => ({ }, })); -export default function LanguagePicker() { +export default function LanguagePicker(props) { const history = useHistory(); const [language, setLanguage] = React.useState(i18next.language || window.localStorage.i18nextLng || ""); @@ -51,7 +51,7 @@ export default function LanguagePicker() { const handleChange = (value) => { setLanguage(value); changeLanguage(value); - history.push("/"); + history.push(props.navigationTarget); }; return ( diff --git a/jams-react-client/src/components/Sidebar/Sidebar.js b/jams-react-client/src/components/Sidebar/Sidebar.js index 2d7516357210e1fc875ed89523ff58ef2cb2ed08..5f4105a88f122b76154d55165d303df98ca91b7e 100755 --- a/jams-react-client/src/components/Sidebar/Sidebar.js +++ b/jams-react-client/src/components/Sidebar/Sidebar.js @@ -24,8 +24,6 @@ import styles from "assets/jss/material-dashboard-react/components/sidebarStyle. import auth from "auth"; import Snackbar from "@material-ui/core/Snackbar/Snackbar"; -import LanguagePicker from "../LanguagePicker/LanguagePicker"; - import i18next from "i18next"; const useStyles = makeStyles(styles); @@ -123,6 +121,11 @@ export default function Sidebar(props) { </div> ); })} + </List> + ); + + var bottomLinks = ( + <List className={classes.bottomlist}> {open && ( <ListItem @@ -170,11 +173,9 @@ export default function Sidebar(props) { disableTypography={true} /> </ListItem> - <ListItem alignItems="center"> - <LanguagePicker /> - </ListItem> </List> ); + var brand = ( <div className={classes.logo}> <a @@ -212,6 +213,7 @@ export default function Sidebar(props) { <div className={classes.sidebarWrapper}> {props.rtlActive ? <RTLNavbarLinks /> : <AdminNavbarLinks />} {links} + {bottomLinks} </div> {image !== undefined ? ( <div @@ -234,6 +236,7 @@ export default function Sidebar(props) { > {brand} <div className={classes.sidebarWrapper}>{links}</div> + <div className={classes.sidebarWrapper}>{bottomLinks}</div> {image !== undefined ? ( <div className={classes.background} diff --git a/jams-react-client/src/layouts/SignIn.js b/jams-react-client/src/layouts/SignIn.js index 0d4dc03d28fa819f86932f8e69f6252661e4c58e..cc14a3aa087217b6d84d66df466ede1d224eff9b 100644 --- a/jams-react-client/src/layouts/SignIn.js +++ b/jams-react-client/src/layouts/SignIn.js @@ -189,7 +189,7 @@ export default function SignIn(props) { <Copyright /> </Box> <Box mt={8} justifyContent="center"> - <LanguagePicker /> + <LanguagePicker navigationTarget={"/"} /> </Box> </Container> ); diff --git a/jams-react-client/src/layouts/SignUp.js b/jams-react-client/src/layouts/SignUp.js index 455c6d10aadcade8cf0a7b5391b1cd1d7042ee45..aa5aeb346b68a6e0a5d50222d382de3b7eae7953 100644 --- a/jams-react-client/src/layouts/SignUp.js +++ b/jams-react-client/src/layouts/SignUp.js @@ -113,7 +113,7 @@ export default function SignUp(props) { <Copyright /> </Box> <Box mt={8} justifyContent="center" > - <LanguagePicker /> + <LanguagePicker navigationTarget={"/"} /> </Box> </Paper> </Container> diff --git a/jams-react-client/src/locales/en/translation.json b/jams-react-client/src/locales/en/translation.json index 749fa35473d3d4723eeacdad9653a90438d14e0e..d6556b12c4b7b580a413eef78467419ed1d4be71 100644 --- a/jams-react-client/src/locales/en/translation.json +++ b/jams-react-client/src/locales/en/translation.json @@ -170,7 +170,6 @@ "search_groups": "Search groups", "no_groups_found": "No groups Found", "blueprint": "Blueprint", - "admin_password": "Admin Password", "subscription": "Subscription", "an_error_occured_while_getting_license_information": "An error occurred while getting subscription information!", "subscription_code_is_required": "Subscription code is required", @@ -229,5 +228,7 @@ "create_administrator": "Create Administrator", "paste_your_jams_enterprise_subscription_code_received_from_jami": "Paste your JAMS Enterprise subscription code received from the Jami store.", "blueprint_name": "Blueprint name", - "validate": "Validate" + "validate": "Validate", + "change_language": "Change language", + "general": "General" } diff --git a/jams-react-client/src/locales/fr/translation.json b/jams-react-client/src/locales/fr/translation.json index d980c3beebe52a0d05cd4c54efa4053d4be1aff5..60172aee62a853b2b539ae101f1e88afa6e8997f 100644 --- a/jams-react-client/src/locales/fr/translation.json +++ b/jams-react-client/src/locales/fr/translation.json @@ -170,7 +170,6 @@ "search_groups": "Rechercher dans les groupes", "no_groups_found": "Aucun groupe trouvé", "blueprint": "Gabarit", - "admin_password": "Mot de passe administrateur", "subscription": "Souscription", "an_error_occured_while_getting_license_information": "Une erreur est survenue durant la récupération de l'information de souscription !", "subscription_code_is_required": "Veuillez entrer une license.", @@ -229,5 +228,7 @@ "create_administrator": "Créer un Administrateur", "paste_your_jams_enterprise_subscription_code_received_from_jami": "Coller votre code de souscription JAMS Entreprise émis par la boutique Jami. ", "blueprint_name": "Nom du gabarit", - "validate": "Valider" + "validate": "Valider", + "change_language": "Change language", + "general": "General" } diff --git a/jams-react-client/src/views/Settings/UpdatePassword.js b/jams-react-client/src/views/Settings/General.js similarity index 80% rename from jams-react-client/src/views/Settings/UpdatePassword.js rename to jams-react-client/src/views/Settings/General.js index d29fb66b9e5c608fb3bdcde4d5ae79dd595288c2..f5f0c61a3d6e4292b71119cb8b0ee45c0fa201b2 100644 --- a/jams-react-client/src/views/Settings/UpdatePassword.js +++ b/jams-react-client/src/views/Settings/General.js @@ -17,6 +17,12 @@ import IconButton from "@material-ui/core/IconButton"; import VpnKeyIcon from "@material-ui/icons/VpnKey"; import InputAdornment from "@material-ui/core/InputAdornment"; +import GridContainer from "components/Grid/GridContainer.js"; +import Card from "components/Card/Card.js"; +import CardHeader from "components/Card/CardHeader.js"; +import CardIcon from "components/Card/CardIcon.js"; +import CardBody from "components/Card/CardBody.js"; + import axios from "axios"; import configApiCall from "../../api"; import { api_path_put_update_user } from "../../globalUrls"; @@ -25,6 +31,8 @@ import { CopyToClipboard } from "react-copy-to-clipboard"; import i18next from "i18next"; +import LanguagePicker from "../../components/LanguagePicker/LanguagePicker"; + let generator = require("generate-password"); const useStyles = makeStyles((theme) => ({ @@ -42,15 +50,13 @@ const useStyles = makeStyles((theme) => ({ width: "100%", // Fix IE 11 issue. marginTop: theme.spacing(1), }, - submit: { - margin: theme.spacing(3, 0, 2), - }, button: { - margin: theme.spacing(1), + marginTop: theme.spacing(2), + marginRight: theme.spacing(2), }, })); -export default function UpdatePassword(props) { +export default function General(props) { const classes = useStyles(); const history = useHistory(); @@ -111,6 +117,11 @@ export default function UpdatePassword(props) { }; return ( + <GridContainer> + <Grid item xs={12} sm={12} md={6}> + <Card profile> + <CardHeader color="info" stats icon></CardHeader> + <CardBody profile> <Formik initialValues={{ password: "", @@ -129,11 +140,19 @@ export default function UpdatePassword(props) { errors, }) => ( <form onSubmit={handleSubmit} className={classes.form}> - <Typography variant="h5" gutterBottom color="primary"> - {i18next.t("enter_the_following_information_below_to_change_your_admin_password", "Enter the following information below to change your admin password.")} - </Typography> - <Grid container spacing={3}> - <Grid item xs={6}> + <Grid container spacing={2}> + <Grid item lg={6} style={{ display: "flex"}}> + <Typography variant="p" gutterBottom color="primary"> + {i18next.t("change_language", "Change language")} + </Typography> + </Grid> + <Grid item lg={6} ><LanguagePicker navigationTarget={"/admin/settings"} /></Grid> + <Grid item lg={6} > + <Typography variant="p" gutterBottom color="primary"> + {i18next.t("enter_the_following_information_below_to_change_your_admin_password", "Change administrator password")} + </Typography> + </Grid> + <Grid item lg={6} > <FormikField name="password" label={i18next.t("password", "Password")} @@ -161,9 +180,7 @@ export default function UpdatePassword(props) { {touched.password && errors.password ? ( <span>{errors.password}</span> ) : null} - </Grid> - <Grid item xs={6}> <FormikField name="confirmPassword" label={i18next.t("Confirm password", "Confirm password")} @@ -191,12 +208,10 @@ export default function UpdatePassword(props) { {touched.confirmPassword && errors.confirmPassword ? ( <span>{errors.confirmPassword}</span> ) : null} - </Grid> - <Grid item align="left" xs={12} sm={12} md={6}> <Button variant="contained" - color="primary" + color="info" size="large" className={classes.button} startIcon={<RefreshIcon />} @@ -219,7 +234,7 @@ export default function UpdatePassword(props) { > <Button variant="contained" - color="primary" + color="info" size="large" className={classes.button} startIcon={<FileCopyIcon />} @@ -233,21 +248,29 @@ export default function UpdatePassword(props) { {generated ? ( <span style={{ marginLeft: "10px" }}>{i18next.t("generated", "Generated")}</span> ) : null} + + </Grid> + <Grid item lg={6}></Grid> + <Grid item lg={6}> + <Button + type="submit" + variant="contained" + color="primary" + fullWidth + disable={!isValid && !dirty} + className={classes.submit} + > + {i18next.t("change_admin_password", "Change administrator password")} + </Button> </Grid> </Grid> - <Button - type="submit" - fullWidth - variant="contained" - color="primary" - disable={!isValid && !dirty} - className={classes.submit} - > - {i18next.t("change_admin_password", "Change administrator password")} - </Button> </form> )} </Formik> + </CardBody> + </Card> + </Grid> + </GridContainer> ); } diff --git a/jams-react-client/src/views/Settings/Settings.js b/jams-react-client/src/views/Settings/Settings.js index dd362dec83430a47b41018a4060b11c14ac86648..0736d9e4246f227d38fa5994f9468cf3a12ccf38 100644 --- a/jams-react-client/src/views/Settings/Settings.js +++ b/jams-react-client/src/views/Settings/Settings.js @@ -2,9 +2,7 @@ import React from "react"; // @material-ui/core components import { makeStyles } from "@material-ui/core/styles"; // core components -import IdentityManagement from "components/IdentityManagement/IdentityManagement.js"; -import ServerParameters from "components/ServerParameters/ServerParameters.js"; -import UpdatePassword from "./UpdatePassword"; +import General from "./General"; import Subscription from "./Subscription"; import PropTypes from "prop-types"; @@ -107,12 +105,12 @@ export default function Settings(props) { onChange={handleChange} aria-label="simple tabs example" > - <Tab label={i18next.t("admin_password", "Admin Password")} {...a11yProps(0)} /> + <Tab label={i18next.t("general", "General")} {...a11yProps(0)} /> <Tab label={i18next.t("subscription", "Subscription")} {...a11yProps(1)} /> </Tabs> </AppBar> <TabPanel value={value} index={0}> - <UpdatePassword + <General username="admin" setError={setError} setErrorMessage={setErrorMessage} diff --git a/jams-react-client/src/views/Settings/Subscription.js b/jams-react-client/src/views/Settings/Subscription.js index fc428884de0948ff14e796d5d05bcd4bfa959662..5a039fa03307a60295b72aac46894cfdc08108f0 100644 --- a/jams-react-client/src/views/Settings/Subscription.js +++ b/jams-react-client/src/views/Settings/Subscription.js @@ -8,6 +8,12 @@ import Grid from '@material-ui/core/Grid'; import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; +import GridContainer from "components/Grid/GridContainer.js"; +import Card from "components/Card/Card.js"; +import CardHeader from "components/Card/CardHeader.js"; +import CardIcon from "components/Card/CardIcon.js"; +import CardBody from "components/Card/CardBody.js"; + import axios from 'axios'; import configApiCall from '../../api' import { api_path_post_configuration_register_license } from '../../globalUrls' @@ -90,10 +96,17 @@ export default function Subscription(props) { if(!activated){ return ( + <GridContainer> + <Grid item xs={12} sm={12} md={6}> + <Card profile> + <CardHeader color="info" stats icon></CardHeader> + <CardBody profile> <form className={classes.form} noValidate onSubmit={formik.handleSubmit}> - <Typography variant="h5" gutterBottom color="primary">{i18next.t("paste_your_jams_enterprise_subscription_code_received_from_jami", "Paste your JAMS Enterprise subscription code received from the Jami store.")}</Typography> <Grid container spacing={3}> - <Grid item xs={12}> + <Grid item lg={6}> + <Typography variant="p" gutterBottom color="primary">{i18next.t("paste_your_jams_enterprise_subscription_code_received_from_jami", "Paste your JAMS Enterprise subscription code received from the Jami store.")}</Typography> + </Grid> + <Grid item lg={6}> <TextField variant="outlined" margin="normal" @@ -107,20 +120,22 @@ export default function Subscription(props) { {...formik.getFieldProps('subscriptionCode')} /> {formik.touched.subscriptionCode && formik.errors.subscriptionCode ? (<span>{formik.errors.subscriptionCode}</span>) : null} + <Button + type="submit" + fullWidth + variant="contained" + color="primary" + className={classes.submit} + > + {i18next.t("register", "Register")} + </Button> </Grid> - </Grid> - - <Button - type="submit" - fullWidth - variant="contained" - color="primary" - className={classes.submit} - > - {i18next.t("register", "Register")} - </Button> - + </Grid> </form> + </CardBody> + </Card> + </Grid> + </GridContainer> ); }else{ return( diff --git a/jams-react-client/src/views/UserProfile/DisplayUserProfile.js b/jams-react-client/src/views/UserProfile/DisplayUserProfile.js index 24298103ba42a127d68be10bdf08a8bd768bf3d9..956721895b3440c580700872ee7340f64ca31c8c 100644 --- a/jams-react-client/src/views/UserProfile/DisplayUserProfile.js +++ b/jams-react-client/src/views/UserProfile/DisplayUserProfile.js @@ -167,7 +167,6 @@ export default function DisplayUserProfile(props) { const [changePasswordOpen, setChangePasswordOpen] = React.useState(false); const [loading, setLoading] = React.useState(false); const [progress, setProgress] = React.useState(0); - const [groups, setGroups] = React.useState([]); const [zeroGroup, setZeroGroup] = React.useState(false); @@ -385,13 +384,6 @@ export default function DisplayUserProfile(props) { return ( - <div> - <div className={classes.loading}> - {loading && ( - <LinearProgress variant="determinate" value={progress} /> - )} - </div> - <div> <Dialog open={open} @@ -422,8 +414,12 @@ export default function DisplayUserProfile(props) { setChangePasswordOpen={setChangePasswordOpen} handleClosechangePassword={handleClosechangePassword} /> - {!loading && ( - <GridContainer> + <div className={classes.loading}> + {loading && ( + <LinearProgress variant="determinate" value={progress} /> + )} + </div> + {!loading && (<GridContainer> <Grid item xs={12} sm={12} md={8}> <Card profile> <CardBody profile> @@ -604,6 +600,5 @@ export default function DisplayUserProfile(props) { </GridContainer> )} </div> - </div> ); } diff --git a/jams-react-client/src/views/UserProfile/EditCreateUserProfile.js b/jams-react-client/src/views/UserProfile/EditCreateUserProfile.js index bbc98da3a4e70629864a847cb1b24e843baf7a16..2c75416228785006a851923f0e2bc4adc72ae1c6 100644 --- a/jams-react-client/src/views/UserProfile/EditCreateUserProfile.js +++ b/jams-react-client/src/views/UserProfile/EditCreateUserProfile.js @@ -74,6 +74,8 @@ import FormikField from "components/FormikField/FormikField"; import { Formik } from "formik"; import * as Yup from "yup"; +import LinearProgress from "@material-ui/core/LinearProgress"; + import i18next from "i18next"; let generator = require("generate-password"); @@ -227,8 +229,9 @@ export default function EditCreateUserProfile(props) { const [copied, setCopied] = React.useState(false); const [generated, setGenerated] = React.useState(true); const [userExists, setUserExists] = React.useState(false); - const [userName, setUserName] = React.useState(""); + const [loading, setLoading] = React.useState(false); + const [progress, setProgress] = React.useState(0); const [profilePicture, setProfilePicture] = React.useState(""); const [profilePicturePreview, setProfilePicturePreview] = React.useState( @@ -271,6 +274,16 @@ export default function EditCreateUserProfile(props) { }; React.useEffect(() => { + setLoading(true); + const timer = setInterval(() => { + setProgress((oldProgress) => { + if (oldProgress === 100) { + return 0; + } + const diff = Math.random() * 10; + return Math.min(oldProgress + diff, 100); + }); + }, 500); if (!createUser) { setUserName(props.username); axios( @@ -302,11 +315,15 @@ export default function EditCreateUserProfile(props) { initialValues.phoneNumber = user.phoneNumber; initialValues.phoneNumberExtension = user.phoneNumberExtension; initialValues.mobileNumber = user.mobileNumber; + setLoading(false); }) .catch((error) => { console.log("Error fetching user : " + props.username + " " + error); }); } + return () => { + clearInterval(timer); + }; }, []); const resizeFile = (file, outputFormat) => @@ -550,7 +567,12 @@ export default function EditCreateUserProfile(props) { </Button> </DialogActions> </Dialog> - <GridContainer> + <div className={classes.loading}> + {loading && ( + <LinearProgress variant="determinate" value={progress} /> + )} + </div> + {!loading && (<GridContainer> <GridItem xs={12} sm={12} md={8}> <Formik initialValues={initialValues} @@ -884,6 +906,7 @@ export default function EditCreateUserProfile(props) { </Formik> </GridItem> </GridContainer> + )} </div> ); }