diff --git a/jams-react-client/.babelrc b/jams-react-client/.babelrc index ad0bfb7186fe3e4bca88368a762cfbdbe75aa33e..d483719e6ccb0341b959370b8b8b5fefa5ac1c0c 100644 --- a/jams-react-client/.babelrc +++ b/jams-react-client/.babelrc @@ -4,9 +4,12 @@ "transform-class-properties", "transform-react-jsx", "transform-object-rest-spread", - ["module-resolver", { - "root": ["./src"] - }], - ["import-rename", {"^(.*)\\.jsx$": "$1"}] - ] - } + [ + "module-resolver", + { + "root": ["./src"] + } + ], + ["import-rename", { "^(.*)\\.jsx$": "$1" }] + ] +} diff --git a/jams-react-client/.eslintrc.js b/jams-react-client/.eslintrc.js index 3b1e841596698dd7448beb7ebccf6060cd6b5edb..e254df4e39c6f254a7cf35a90fb4e4293f857d31 100644 --- a/jams-react-client/.eslintrc.js +++ b/jams-react-client/.eslintrc.js @@ -3,19 +3,19 @@ module.exports = { env: { es6: true, node: true, - browser: true + browser: true, }, parserOptions: { ecmaVersion: 6, sourceType: "module", ecmaFeatures: { - jsx: true - } + jsx: true, + }, }, plugins: ["react"], extends: [ "eslint:recommended", "plugin:react/recommended", - "plugin:prettier/recommended" - ] + "plugin:prettier/recommended", + ], }; diff --git a/jams-react-client/README.md b/jams-react-client/README.md index bc9d6dc0c73c004f2e94886a9006e8b70fa2a5ad..2e55daa92e6d16e6e765b329bcd152cbb7de4c77 100644 --- a/jams-react-client/README.md +++ b/jams-react-client/README.md @@ -1,3 +1,3 @@ # Jams Jami Client -Jams client for managing user's devices build with React using https://github.com/creativetimofficial/material-dashboard-react#demo \ No newline at end of file +Jams client for managing user's devices build with React using https://github.com/creativetimofficial/material-dashboard-react#demo diff --git a/jams-react-client/bower.json b/jams-react-client/bower.json index 45376a728251e4f42c2f089f48aa7d788247da34..d7dab4007be946eb1712197799bdaac3ef433f28 100644 --- a/jams-react-client/bower.json +++ b/jams-react-client/bower.json @@ -1,9 +1,7 @@ { "name": "material-dashboard-react", "homepage": "https://github.com/creativetimofficial/material-dashboard-react", - "authors": [ - "creative-tim" - ], + "authors": ["creative-tim"], "description": "A Badass Material-UI Kit based on Material Design", "main": "public/index.html", "keywords": [ diff --git a/jams-react-client/gulpfile.js b/jams-react-client/gulpfile.js index 8fc0f0298f52730e3905d4ecf8daa24de947cc5d..cbffafbfdcb242debd02a457697e3c7619fc20b3 100644 --- a/jams-react-client/gulpfile.js +++ b/jams-react-client/gulpfile.js @@ -1,7 +1,7 @@ const gulp = require("gulp"); const gap = require("gulp-append-prepend"); -gulp.task("licenses", async function() { +gulp.task("licenses", async function () { // this is to add Creative Tim licenses in the production mode for the minified js gulp .src("build/static/js/*chunk.js", { base: "./" }) diff --git a/jams-react-client/package.json b/jams-react-client/package.json index d3bf2f73793e72e2eff822c4867a581dd96b7bae..e7d90b82dd8b082bfe37773cdf15571640f025aa 100644 --- a/jams-react-client/package.json +++ b/jams-react-client/package.json @@ -48,6 +48,7 @@ "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject", "install:clean": "rm -rf node_modules/ && rm -rf package-lock.json && npm install && npm start", + "format": "prettier --write \"src/**/*\"", "lint:check": "eslint . --ext=js,jsx; exit 0", "lint:fix": "eslint . --ext=js,jsx --fix; exit 0", "build-package-css": "cp src/assets/css/material-dashboard-react.css dist/material-dashboard-react.css", diff --git a/jams-react-client/src/assets/jss/material-dashboard-react.js b/jams-react-client/src/assets/jss/material-dashboard-react.js index d644b4292d671fffbff40f4b2ff87a9c464bb85b..4b55358ea3c54d36992ef043957d7668cb95c6f6 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react.js @@ -21,7 +21,7 @@ // // // Example: input = #999 => output = 153, 153, 153 // // // Example: input = 999 => output = 153, 153, 153 // ############################# -const hexToRgb = input => { +const hexToRgb = (input) => { input = input + ""; input = input.replace("#", ""); let hexRegex = /[0-9A-Fa-f]/g; @@ -54,20 +54,20 @@ const hexToRgb = input => { const drawerWidth = 260; const transition = { - transition: "all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1)" + transition: "all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1)", }; const container = { paddingRight: "15px", paddingLeft: "15px", marginRight: "auto", - marginLeft: "auto" + marginLeft: "auto", }; const defaultFont = { fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif', fontWeight: "300", - lineHeight: "1.5em" + lineHeight: "1.5em", }; const primaryColor = ["#ffffff", "#ab47bc", "#8e24aa", "#af2cc5"]; @@ -88,7 +88,7 @@ const grayColor = [ "#333", "#a9afbb", "#eee", - "#e7e7e7" + "#e7e7e7", ]; const blackColor = "#000"; const whiteColor = "#FFF"; @@ -101,7 +101,7 @@ const boxShadow = { hexToRgb(blackColor) + ", 0.12), 0 8px 10px -5px rgba(" + hexToRgb(blackColor) + - ", 0.2)" + ", 0.2)", }; const primaryBoxShadow = { @@ -110,7 +110,7 @@ const primaryBoxShadow = { hexToRgb(blackColor) + ",.14), 0 7px 10px -5px rgba(" + hexToRgb(primaryColor[0]) + - ",.4)" + ",.4)", }; const infoBoxShadow = { boxShadow: @@ -118,7 +118,7 @@ const infoBoxShadow = { hexToRgb(blackColor) + ",.14), 0 7px 10px -5px rgba(" + hexToRgb(infoColor[0]) + - ",.4)" + ",.4)", }; const successBoxShadow = { boxShadow: @@ -126,7 +126,7 @@ const successBoxShadow = { hexToRgb(blackColor) + ",.14), 0 7px 10px -5px rgba(" + hexToRgb(successColor[0]) + - ",.4)" + ",.4)", }; const warningBoxShadow = { boxShadow: @@ -134,7 +134,7 @@ const warningBoxShadow = { hexToRgb(blackColor) + ",.14), 0 7px 10px -5px rgba(" + hexToRgb(warningColor[0]) + - ",.4)" + ",.4)", }; const dangerBoxShadow = { boxShadow: @@ -142,7 +142,7 @@ const dangerBoxShadow = { hexToRgb(blackColor) + ",.14), 0 7px 10px -5px rgba(" + hexToRgb(dangerColor[0]) + - ",.4)" + ",.4)", }; const roseBoxShadow = { boxShadow: @@ -150,38 +150,38 @@ const roseBoxShadow = { hexToRgb(blackColor) + ",.14), 0 7px 10px -5px rgba(" + hexToRgb(roseColor[0]) + - ",.4)" + ",.4)", }; const warningCardHeader = { background: "linear-gradient(60deg, " + warningColor[1] + ", " + warningColor[2] + ")", - ...warningBoxShadow + ...warningBoxShadow, }; const successCardHeader = { background: "linear-gradient(60deg, " + successColor[1] + ", " + successColor[2] + ")", - ...successBoxShadow + ...successBoxShadow, }; const dangerCardHeader = { background: "linear-gradient(60deg, " + dangerColor[1] + ", " + dangerColor[2] + ")", - ...dangerBoxShadow + ...dangerBoxShadow, }; const infoCardHeader = { background: "linear-gradient(60deg, " + infoColor[1] + ", " + infoColor[2] + ")", - ...infoBoxShadow + ...infoBoxShadow, }; const primaryCardHeader = { background: "linear-gradient(60deg, " + primaryColor[1] + ", " + primaryColor[2] + ")", - ...primaryBoxShadow + ...primaryBoxShadow, }; const roseCardHeader = { background: "linear-gradient(60deg, " + roseColor[1] + ", " + roseColor[2] + ")", - ...roseBoxShadow + ...roseBoxShadow, }; const cardActions = { @@ -189,13 +189,13 @@ const cardActions = { paddingTop: "10px", borderTop: "1px solid " + grayColor[10], height: "auto", - ...defaultFont + ...defaultFont, }; const cardHeader = { margin: "-20px 15px 0", borderRadius: "3px", - padding: "15px" + padding: "15px", }; const card = { @@ -206,7 +206,7 @@ const card = { boxShadow: "0 1px 4px 0 rgba(" + hexToRgb(blackColor) + ", 0.14)", borderRadius: "3px", color: "rgba(" + hexToRgb(blackColor) + ", 0.87)", - background: whiteColor + background: whiteColor, }; const defaultBoxShadow = { @@ -221,7 +221,7 @@ const defaultBoxShadow = { hexToRgb(blackColor) + ", 0.2)", padding: "10px 0", - transition: "all 150ms ease 0s" + transition: "all 150ms ease 0s", }; const title = { @@ -235,8 +235,8 @@ const title = { "& small": { color: grayColor[1], fontWeight: "400", - lineHeight: "1" - } + lineHeight: "1", + }, }; const cardTitle = { @@ -248,18 +248,18 @@ const cardTitle = { ...title, marginTop: ".625rem", marginBottom: "0.75rem", - minHeight: "auto" - } + minHeight: "auto", + }, }; const cardSubtitle = { - marginTop: "-.375rem" + marginTop: "-.375rem", }; const cardLink = { "& + $cardLink": { - marginLeft: "1.25rem" - } + marginLeft: "1.25rem", + }, }; export { @@ -298,5 +298,5 @@ export { title, cardTitle, cardSubtitle, - cardLink + cardLink, }; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/cardImagesStyles.js b/jams-react-client/src/assets/jss/material-dashboard-react/cardImagesStyles.js index 39b34e21e37b31b7ba426f17c9390843b814031f..1461bd566f5fb6fac8cff1e00168921d9d96ae6b 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/cardImagesStyles.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/cardImagesStyles.js @@ -2,12 +2,12 @@ const cardImagesStyles = { cardImgTop: { width: "100%", borderTopLeftRadius: "calc(.25rem - 1px)", - borderTopRightRadius: "calc(.25rem - 1px)" + borderTopRightRadius: "calc(.25rem - 1px)", }, cardImgBottom: { width: "100%", borderBottomRightRadius: "calc(.25rem - 1px)", - borderBottomLeftRadius: "calc(.25rem - 1px)" + borderBottomLeftRadius: "calc(.25rem - 1px)", }, cardImgOverlay: { position: "absolute", @@ -15,12 +15,12 @@ const cardImagesStyles = { right: "0", bottom: "0", left: "0", - padding: "1.25rem" + padding: "1.25rem", }, cardImg: { width: "100%", - borderRadius: "calc(.25rem - 1px)" - } + borderRadius: "calc(.25rem - 1px)", + }, }; export default cardImagesStyles; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/checkboxAdnRadioStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/checkboxAdnRadioStyle.js index 5c5ec510136e53aaa722df7467512138a328fe31..c78ec472344ce03b8a1d63d5f4720e5de3da5b1f 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/checkboxAdnRadioStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/checkboxAdnRadioStyle.js @@ -1,51 +1,51 @@ import { primaryColor, blackColor, - hexToRgb + hexToRgb, } from "assets/jss/material-dashboard-react.js"; const checkboxAdnRadioStyle = { root: { padding: "13px", "&:hover": { - backgroundColor: "unset" - } + backgroundColor: "unset", + }, }, labelRoot: { - marginLeft: "-14px" + marginLeft: "-14px", }, checked: { - color: primaryColor[0] + "!important" + color: primaryColor[0] + "!important", }, checkedIcon: { width: "20px", height: "20px", border: "1px solid rgba(" + hexToRgb(blackColor) + ", .54)", - borderRadius: "3px" + borderRadius: "3px", }, uncheckedIcon: { width: "0px", height: "0px", padding: "10px", border: "1px solid rgba(" + hexToRgb(blackColor) + ", .54)", - borderRadius: "3px" + borderRadius: "3px", }, radio: { - color: primaryColor[0] + "!important" + color: primaryColor[0] + "!important", }, radioChecked: { width: "20px", height: "20px", border: "1px solid " + primaryColor[0], - borderRadius: "50%" + borderRadius: "50%", }, radioUnchecked: { width: "0px", height: "0px", padding: "10px", border: "1px solid rgba(" + hexToRgb(blackColor) + ", .54)", - borderRadius: "50%" - } + borderRadius: "50%", + }, }; export default checkboxAdnRadioStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/buttonStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/buttonStyle.js index 3905a98b3c4d0199b393106225ebfbd7fcb6dc1b..634bcc35c4fb9b0fcdaa19e0c49548d5c9aee12d 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/buttonStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/buttonStyle.js @@ -8,7 +8,7 @@ import { roseColor, whiteColor, blackColor, - hexToRgb + hexToRgb, } from "assets/jss/material-dashboard-react.js"; const buttonStyle = { @@ -53,7 +53,7 @@ const buttonStyle = { hexToRgb(blackColor) + ", 0.12), 0 8px 10px -5px rgba(" + hexToRgb(grayColor[0]) + - ", 0.2)" + ", 0.2)", }, "& .fab,& .fas,& .far,& .fal, &.material-icons": { position: "relative", @@ -63,7 +63,7 @@ const buttonStyle = { marginBottom: "-1em", fontSize: "1.1rem", marginRight: "4px", - verticalAlign: "middle" + verticalAlign: "middle", }, "& svg": { position: "relative", @@ -72,7 +72,7 @@ const buttonStyle = { width: "18px", height: "18px", marginRight: "4px", - verticalAlign: "middle" + verticalAlign: "middle", }, "&$justIcon": { "& .fab,& .fas,& .far,& .fal,& .material-icons": { @@ -84,15 +84,15 @@ const buttonStyle = { top: "0px", height: "100%", lineHeight: "41px", - fontSize: "20px" - } - } + fontSize: "20px", + }, + }, }, white: { "&,&:focus,&:hover": { backgroundColor: whiteColor, - color: grayColor[0] - } + color: grayColor[0], + }, }, rose: { backgroundColor: roseColor[0], @@ -113,8 +113,8 @@ const buttonStyle = { hexToRgb(blackColor) + ", 0.12), 0 8px 10px -5px rgba(" + hexToRgb(roseColor[0]) + - ", 0.2)" - } + ", 0.2)", + }, }, primary: { backgroundColor: primaryColor[0], @@ -135,8 +135,8 @@ const buttonStyle = { hexToRgb(blackColor) + ", 0.12), 0 8px 10px -5px rgba(" + hexToRgb(primaryColor[0]) + - ", 0.2)" - } + ", 0.2)", + }, }, info: { backgroundColor: infoColor[0], @@ -157,8 +157,8 @@ const buttonStyle = { hexToRgb(blackColor) + ", 0.12), 0 8px 10px -5px rgba(" + hexToRgb(infoColor[0]) + - ", 0.2)" - } + ", 0.2)", + }, }, success: { backgroundColor: successColor[0], @@ -179,8 +179,8 @@ const buttonStyle = { hexToRgb(blackColor) + ", 0.12), 0 8px 10px -5px rgba(" + hexToRgb(successColor[0]) + - ", 0.2)" - } + ", 0.2)", + }, }, warning: { backgroundColor: warningColor[0], @@ -201,8 +201,8 @@ const buttonStyle = { hexToRgb(blackColor) + ", 0.12), 0 8px 10px -5px rgba(" + hexToRgb(warningColor[0]) + - ", 0.2)" - } + ", 0.2)", + }, }, danger: { backgroundColor: dangerColor[0], @@ -223,81 +223,81 @@ const buttonStyle = { hexToRgb(blackColor) + ", 0.12), 0 8px 10px -5px rgba(" + hexToRgb(dangerColor[0]) + - ", 0.2)" - } + ", 0.2)", + }, }, simple: { "&,&:focus,&:hover": { color: whiteColor, background: "transparent", - boxShadow: "none" + boxShadow: "none", }, "&$rose": { "&,&:focus,&:hover,&:visited": { - color: roseColor[0] - } + color: roseColor[0], + }, }, "&$primary": { "&,&:focus,&:hover,&:visited": { - color: primaryColor[0] - } + color: primaryColor[0], + }, }, "&$info": { "&,&:focus,&:hover,&:visited": { - color: infoColor[0] - } + color: infoColor[0], + }, }, "&$success": { "&,&:focus,&:hover,&:visited": { - color: successColor[0] - } + color: successColor[0], + }, }, "&$warning": { "&,&:focus,&:hover,&:visited": { - color: warningColor[0] - } + color: warningColor[0], + }, }, "&$danger": { "&,&:focus,&:hover,&:visited": { - color: dangerColor[0] - } - } + color: dangerColor[0], + }, + }, }, transparent: { "&,&:focus,&:hover": { color: "inherit", background: "transparent", - boxShadow: "none" - } + boxShadow: "none", + }, }, disabled: { opacity: "0.65", - pointerEvents: "none" + pointerEvents: "none", }, lg: { padding: "1.125rem 2.25rem", fontSize: "0.875rem", lineHeight: "1.333333", - borderRadius: "0.2rem" + borderRadius: "0.2rem", }, sm: { padding: "0.40625rem 1.25rem", fontSize: "0.6875rem", lineHeight: "1.5", - borderRadius: "0.2rem" + borderRadius: "0.2rem", }, round: { - borderRadius: "30px" + borderRadius: "30px", }, block: { - width: "100% !important" + width: "100% !important", }, link: { "&,&:hover,&:focus": { backgroundColor: "transparent", color: grayColor[0], - boxShadow: "none" - } + boxShadow: "none", + }, }, justIcon: { paddingLeft: "12px", @@ -307,7 +307,7 @@ const buttonStyle = { minWidth: "41px", width: "41px", "& .fab,& .fas,& .far,& .fal,& svg,& .material-icons": { - marginRight: "0px" + marginRight: "0px", }, "&$lg": { height: "57px", @@ -316,12 +316,12 @@ const buttonStyle = { lineHeight: "56px", "& .fab,& .fas,& .far,& .fal,& .material-icons": { fontSize: "32px", - lineHeight: "56px" + lineHeight: "56px", }, "& svg": { width: "32px", - height: "32px" - } + height: "32px", + }, }, "&$sm": { height: "30px", @@ -329,14 +329,14 @@ const buttonStyle = { width: "30px", "& .fab,& .fas,& .far,& .fal,& .material-icons": { fontSize: "17px", - lineHeight: "29px" + lineHeight: "29px", }, "& svg": { width: "17px", - height: "17px" - } - } - } + height: "17px", + }, + }, + }, }; export default buttonStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/cardBodyStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/cardBodyStyle.js index cfc0005a050b3c443704114876b99e7fa6f8a18d..38f4856c2601b8bd366dcfd751ab7de793311545 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/cardBodyStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/cardBodyStyle.js @@ -3,15 +3,15 @@ const cardBodyStyle = { padding: "0.9375rem 20px", flex: "1 1 auto", WebkitBoxFlex: "1", - position: "relative" + position: "relative", }, cardBodyPlain: { paddingLeft: "5px", - paddingRight: "5px" + paddingRight: "5px", }, cardBodyProfile: { - marginTop: "15px" - } + marginTop: "15px", + }, }; export default cardBodyStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/cardFooterStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/cardFooterStyle.js index 94bbf6508582c0a90ef7ecb8c8d8fc296d86ac71..3488ec30288c43e6ebbf34556d14c3134a9e1a19 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/cardFooterStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/cardFooterStyle.js @@ -1,6 +1,6 @@ import { grayColor } from "assets/jss/material-dashboard-react.js"; -const cardFooterStyle = theme => ({ +const cardFooterStyle = (theme) => ({ cardFooter: { padding: "0", paddingTop: "10px", @@ -18,18 +18,18 @@ const cardFooterStyle = theme => ({ display: "flex", flexDirection: "column", "& button": { - width: "100%" + width: "100%", }, }, }, }, cardFooterProfile: { - marginTop: "-15px" + marginTop: "-15px", }, cardFooterPlain: { paddingLeft: "5px", paddingRight: "5px", - backgroundColor: "transparent" + backgroundColor: "transparent", }, cardFooterStats: { borderTop: "1px solid " + grayColor[10], @@ -40,19 +40,19 @@ const cardFooterStyle = theme => ({ marginRight: "3px", marginLeft: "3px", width: "16px", - height: "16px" + height: "16px", }, "& .fab,& .fas,& .far,& .fal,& .material-icons": { fontSize: "16px", position: "relative", top: "4px", marginRight: "3px", - marginLeft: "3px" - } + marginLeft: "3px", + }, }, cardFooterChart: { - borderTop: "1px solid " + grayColor[10] - } + borderTop: "1px solid " + grayColor[10], + }, }); export default cardFooterStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/cardHeaderStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/cardHeaderStyle.js index fe8312cb8567389f888c34e8859fffd3e7638595..7cb8f459a6687f32db2e3d66a941b4c0c8913d20 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/cardHeaderStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/cardHeaderStyle.js @@ -5,7 +5,7 @@ import { infoCardHeader, primaryCardHeader, roseCardHeader, - whiteColor + whiteColor, } from "assets/jss/material-dashboard-react.js"; const cardHeaderStyle = { @@ -19,17 +19,17 @@ const cardHeaderStyle = { margin: "0 15px", padding: "0", position: "relative", - color: whiteColor + color: whiteColor, }, "&:first-child": { - borderRadius: "calc(.25rem - 1px) calc(.25rem - 1px) 0 0" + borderRadius: "calc(.25rem - 1px) calc(.25rem - 1px) 0 0", }, "&$warningCardHeader,&$successCardHeader,&$dangerCardHeader,&$infoCardHeader,&$primaryCardHeader,&$roseCardHeader": { "&:not($cardHeaderIcon)": { borderRadius: "3px", marginTop: "-20px", - padding: "15px" - } + padding: "15px", + }, }, "&$cardHeaderStats svg": { fontSize: "36px", @@ -37,7 +37,7 @@ const cardHeaderStyle = { textAlign: "center", width: "36px", height: "36px", - margin: "10px 10px 4px" + margin: "10px 10px 4px", }, "&$cardHeaderStats i,&$cardHeaderStats .material-icons": { fontSize: "36px", @@ -46,79 +46,79 @@ const cardHeaderStyle = { height: "56px", textAlign: "center", overflow: "unset", - marginBottom: "1px" + marginBottom: "1px", }, "&$cardHeaderStats$cardHeaderIcon": { - textAlign: "right" + textAlign: "right", }, }, cardHeaderPlain: { marginLeft: "0px !important", - marginRight: "0px !important" + marginRight: "0px !important", }, cardHeaderStats: { "& $cardHeaderIcon": { - textAlign: "right" + textAlign: "right", }, "& h1,& h2,& h3,& h4,& h5,& h6": { - margin: "0 !important" - } + margin: "0 !important", + }, }, cardHeaderIcon: { "&$warningCardHeader,&$successCardHeader,&$dangerCardHeader,&$infoCardHeader,&$primaryCardHeader,&$roseCardHeader": { background: "transparent", - boxShadow: "none" + boxShadow: "none", }, "& i,& .material-icons": { width: "33px", height: "33px", textAlign: "center", - lineHeight: "33px" + lineHeight: "33px", }, "& svg": { width: "24px", height: "24px", textAlign: "center", lineHeight: "33px", - margin: "5px 4px 0px" - } + margin: "5px 4px 0px", + }, }, warningCardHeader: { color: whiteColor, "&:not($cardHeaderIcon)": { - ...warningCardHeader - } + ...warningCardHeader, + }, }, successCardHeader: { color: whiteColor, "&:not($cardHeaderIcon)": { - ...successCardHeader - } + ...successCardHeader, + }, }, dangerCardHeader: { color: whiteColor, "&:not($cardHeaderIcon)": { - ...dangerCardHeader - } + ...dangerCardHeader, + }, }, infoCardHeader: { color: whiteColor, "&:not($cardHeaderIcon)": { - ...infoCardHeader - } + ...infoCardHeader, + }, }, primaryCardHeader: { color: whiteColor, "&:not($cardHeaderIcon)": { - ...primaryCardHeader - } + ...primaryCardHeader, + }, }, roseCardHeader: { color: whiteColor, "&:not($cardHeaderIcon)": { - ...roseCardHeader - } - } + ...roseCardHeader, + }, + }, }; export default cardHeaderStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/cardIconStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/cardIconStyle.js index 55715f1e520adcf1fe81064f4c0ec5df468ef647..572ed2cbdc2b3192645f477e20c83f6811d24055 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/cardIconStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/cardIconStyle.js @@ -5,7 +5,7 @@ import { infoCardHeader, primaryCardHeader, roseCardHeader, - grayColor + grayColor, } from "assets/jss/material-dashboard-react.js"; const cardIconStyle = { @@ -16,15 +16,15 @@ const cardIconStyle = { padding: "15px", marginTop: "-20px", marginRight: "15px", - float: "left" - } + float: "left", + }, }, warningCardHeader, successCardHeader, dangerCardHeader, infoCardHeader, primaryCardHeader, - roseCardHeader + roseCardHeader, }; export default cardIconStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/cardStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/cardStyle.js index bbe39ea33d3d26ab72872d1f78cb02afafc18991..aa90d468443c368a16f71882493fac034f11d702 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/cardStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/cardStyle.js @@ -1,7 +1,7 @@ import { blackColor, whiteColor, - hexToRgb + hexToRgb, } from "assets/jss/material-dashboard-react.js"; import { grayColor } from "assets/jss/material-dashboard-react"; @@ -24,33 +24,33 @@ const cardStyle = { "& ul": { "list-style": "none", padding: 0, - "& li" :{ - display: 'flex', - alignItems: 'center', - } + "& li": { + display: "flex", + alignItems: "center", + }, }, "&:hover": { boxShadow: "0 1px 4px 0 rgba(" + hexToRgb(blackColor) + ", 0.54)", }, "& a": { - color: blackColor - } + color: blackColor, + }, }, cardPlain: { background: "transparent", - boxShadow: "none" + boxShadow: "none", }, cardProfile: { marginTop: "50px", textAlign: "left", - height: "calc(100% - 4em)" + height: "calc(100% - 4em)", }, cardChart: { "& p": { marginTop: "0px", - paddingTop: "0px" - } - } + paddingTop: "0px", + }, + }, }; export default cardStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/customTabsStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/customTabsStyle.js index 472ccb1ac95bb8be745e53f5e315cd032146f4bd..c436bf2d92e4c8ff2d3b9057319209f234873d38 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/customTabsStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/customTabsStyle.js @@ -4,21 +4,21 @@ const customTabsStyle = { cardTitle: { float: "left", padding: "10px 10px 10px 0px", - lineHeight: "24px" + lineHeight: "24px", }, cardTitleRTL: { float: "right", - padding: "10px 0px 10px 10px !important" + padding: "10px 0px 10px 10px !important", }, displayNone: { - display: "none !important" + display: "none !important", }, tabsRoot: { minHeight: "unset !important", overflowX: "visible", "& $tabRootButton": { - fontSize: "0.875rem" - } + fontSize: "0.875rem", + }, }, tabRootButton: { minHeight: "unset !important", @@ -34,12 +34,12 @@ const customTabsStyle = { color: whiteColor + " !important", marginLeft: "4px", "&:last-child": { - marginLeft: "0px" - } + marginLeft: "0px", + }, }, tabSelected: { backgroundColor: "rgba(" + hexToRgb(whiteColor) + ", 0.2)", - transition: "0.2s background-color 0.1s" + transition: "0.2s background-color 0.1s", }, tabWrapper: { display: "inline-block", @@ -54,9 +54,9 @@ const customTabsStyle = { marginTop: "1px", "& > svg,& > .material-icons": { verticalAlign: "middle", - margin: "-1px 5px 0 0 !important" - } - } + margin: "-1px 5px 0 0 !important", + }, + }, }; export default customTabsStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/devicesStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/devicesStyle.js index e3505a0626ceffd0b598f8d843ef201fd9c4bfe9..710cc0fb9d8c05bbd0bdd9e65fd7b7bfb42d28b4 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/devicesStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/devicesStyle.js @@ -3,7 +3,7 @@ import { primaryColor, dangerColor, grayColor, - infoColor + infoColor, } from "assets/jss/material-dashboard-react.js"; import tooltipStyle from "assets/jss/material-dashboard-react/tooltipStyle.js"; import checkboxAdnRadioStyle from "assets/jss/material-dashboard-react/checkboxAdnRadioStyle.js"; @@ -12,17 +12,17 @@ const tasksStyle = { ...checkboxAdnRadioStyle, table: { marginBottom: "0", - overflow: "visible" + overflow: "visible", }, tableRow: { position: "relative", - borderBottom: "1px solid " + grayColor[5] + borderBottom: "1px solid " + grayColor[5], }, tableActions: { display: "flex", border: "none", padding: "12px 8px !important", - verticalAlign: "middle" + verticalAlign: "middle", }, tableCell: { ...defaultFont, @@ -30,29 +30,29 @@ const tasksStyle = { border: "none", lineHeight: "1.42857143", fontSize: "14px", - textAlign: "left" + textAlign: "left", }, tableCellRTL: { - textAlign: "right" + textAlign: "right", }, tableActionButton: { width: "27px", height: "27px", - padding: "0" + padding: "0", }, tableActionButtonIcon: { width: "17px", - height: "17px" + height: "17px", }, edit: { backgroundColor: "transparent", color: infoColor[0], - boxShadow: "none" + boxShadow: "none", }, close: { backgroundColor: "transparent", color: dangerColor[0], - boxShadow: "none" - } + boxShadow: "none", + }, }; export default tasksStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/footerStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/footerStyle.js index 9d7aa9aab48adcbc3cfdc432dd8d2e2330ee8746..a0613e45a6d4acfaf10262573eb3bf2d408950bb 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/footerStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/footerStyle.js @@ -2,7 +2,7 @@ import { defaultFont, container, primaryColor, - grayColor + grayColor, } from "assets/jss/material-dashboard-react.js"; const footerStyle = { @@ -16,39 +16,39 @@ const footerStyle = { display: "block", ...defaultFont, fontWeight: "500", - fontSize: "12px" + fontSize: "12px", }, left: { float: "left!important", - display: "block" + display: "block", }, right: { padding: "15px 0", margin: "0", fontSize: "14px", - float: "right!important" + float: "right!important", }, footer: { bottom: "0", borderTop: "1px solid " + grayColor[11], padding: "15px 0", - ...defaultFont + ...defaultFont, }, container, a: { color: primaryColor, textDecoration: "none", - backgroundColor: "transparent" + backgroundColor: "transparent", }, list: { marginBottom: "0", padding: "0", - marginTop: "0" + marginTop: "0", }, inlineBlock: { display: "inline-block", padding: "0px", - width: "auto" - } + width: "auto", + }, }; export default footerStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/headerLinksStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/headerLinksStyle.js index fcd3da4ff89003fab844610e43812be6f7649fb0..818cb007dee624c8ffc771918f17df6d6b5ba249 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/headerLinksStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/headerLinksStyle.js @@ -1,16 +1,16 @@ import { defaultFont, dangerColor, - whiteColor + whiteColor, } from "assets/jss/material-dashboard-react.js"; import dropdownStyle from "assets/jss/material-dashboard-react/dropdownStyle.js"; -const headerLinksStyle = theme => ({ +const headerLinksStyle = (theme) => ({ ...dropdownStyle(theme), search: { "& > div": { - marginTop: "0" + marginTop: "0", }, [theme.breakpoints.down("sm")]: { margin: "10px 15px !important", @@ -21,15 +21,15 @@ const headerLinksStyle = theme => ({ width: "60%", marginTop: "40px", "& input": { - color: whiteColor - } - } + color: whiteColor, + }, + }, }, linkText: { zIndex: "4", ...defaultFont, fontSize: "14px", - margin: "0px" + margin: "0px", }, buttonLink: { [theme.breakpoints.down("sm")]: { @@ -40,7 +40,7 @@ const headerLinksStyle = theme => ({ width: "24px", height: "30px", marginRight: "15px", - marginLeft: "-15px" + marginLeft: "-15px", }, "& .fab,& .fas,& .far,& .fal,& .material-icons": { fontSize: "24px", @@ -48,28 +48,28 @@ const headerLinksStyle = theme => ({ width: "24px", height: "30px", marginRight: "15px", - marginLeft: "-15px" + marginLeft: "-15px", }, "& > span": { justifyContent: "flex-start", - width: "100%" - } - } + width: "100%", + }, + }, }, searchButton: { [theme.breakpoints.down("sm")]: { top: "-50px !important", marginRight: "22px", - float: "right" - } + float: "right", + }, }, margin: { zIndex: "4", - margin: "0" + margin: "0", }, searchIcon: { width: "17px", - zIndex: "4" + zIndex: "4", }, notifications: { zIndex: "4", @@ -87,27 +87,27 @@ const headerLinksStyle = theme => ({ textAlign: "center", lineHeight: "16px", verticalAlign: "middle", - display: "block" + display: "block", }, [theme.breakpoints.down("sm")]: { ...defaultFont, fontSize: "14px", - marginRight: "8px" - } + marginRight: "8px", + }, }, manager: { [theme.breakpoints.down("sm")]: { - width: "100%" + width: "100%", }, - display: "inline-block" + display: "inline-block", }, searchWrapper: { [theme.breakpoints.down("sm")]: { width: "-webkit-fill-available", - margin: "10px 15px 0" + margin: "10px 15px 0", }, - display: "inline-block" - } + display: "inline-block", + }, }); export default headerLinksStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/rtlHeaderLinksStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/rtlHeaderLinksStyle.js index fcd3da4ff89003fab844610e43812be6f7649fb0..818cb007dee624c8ffc771918f17df6d6b5ba249 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/rtlHeaderLinksStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/rtlHeaderLinksStyle.js @@ -1,16 +1,16 @@ import { defaultFont, dangerColor, - whiteColor + whiteColor, } from "assets/jss/material-dashboard-react.js"; import dropdownStyle from "assets/jss/material-dashboard-react/dropdownStyle.js"; -const headerLinksStyle = theme => ({ +const headerLinksStyle = (theme) => ({ ...dropdownStyle(theme), search: { "& > div": { - marginTop: "0" + marginTop: "0", }, [theme.breakpoints.down("sm")]: { margin: "10px 15px !important", @@ -21,15 +21,15 @@ const headerLinksStyle = theme => ({ width: "60%", marginTop: "40px", "& input": { - color: whiteColor - } - } + color: whiteColor, + }, + }, }, linkText: { zIndex: "4", ...defaultFont, fontSize: "14px", - margin: "0px" + margin: "0px", }, buttonLink: { [theme.breakpoints.down("sm")]: { @@ -40,7 +40,7 @@ const headerLinksStyle = theme => ({ width: "24px", height: "30px", marginRight: "15px", - marginLeft: "-15px" + marginLeft: "-15px", }, "& .fab,& .fas,& .far,& .fal,& .material-icons": { fontSize: "24px", @@ -48,28 +48,28 @@ const headerLinksStyle = theme => ({ width: "24px", height: "30px", marginRight: "15px", - marginLeft: "-15px" + marginLeft: "-15px", }, "& > span": { justifyContent: "flex-start", - width: "100%" - } - } + width: "100%", + }, + }, }, searchButton: { [theme.breakpoints.down("sm")]: { top: "-50px !important", marginRight: "22px", - float: "right" - } + float: "right", + }, }, margin: { zIndex: "4", - margin: "0" + margin: "0", }, searchIcon: { width: "17px", - zIndex: "4" + zIndex: "4", }, notifications: { zIndex: "4", @@ -87,27 +87,27 @@ const headerLinksStyle = theme => ({ textAlign: "center", lineHeight: "16px", verticalAlign: "middle", - display: "block" + display: "block", }, [theme.breakpoints.down("sm")]: { ...defaultFont, fontSize: "14px", - marginRight: "8px" - } + marginRight: "8px", + }, }, manager: { [theme.breakpoints.down("sm")]: { - width: "100%" + width: "100%", }, - display: "inline-block" + display: "inline-block", }, searchWrapper: { [theme.breakpoints.down("sm")]: { width: "-webkit-fill-available", - margin: "10px 15px 0" + margin: "10px 15px 0", }, - display: "inline-block" - } + display: "inline-block", + }, }); export default headerLinksStyle; 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 70e8054445e97b0eb00d2d68b6b67eccafd29e83..227b7cfea6f82c4b113771ea32020f67628f0ced 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 @@ -12,10 +12,10 @@ import { whiteColor, grayColor, blackColor, - hexToRgb + hexToRgb, } from "assets/jss/material-dashboard-react.js"; -const sidebarStyle = theme => ({ +const sidebarStyle = (theme) => ({ drawerPaper: { border: "none", position: "fixed", @@ -28,7 +28,7 @@ const sidebarStyle = theme => ({ [theme.breakpoints.up("md")]: { width: drawerWidth, position: "fixed", - height: "100%" + height: "100%", }, [theme.breakpoints.down("sm")]: { width: drawerWidth, @@ -47,18 +47,18 @@ const sidebarStyle = theme => ({ paddingRight: "0px", paddingLeft: "0", transform: `translate3d(${drawerWidth}px, 0, 0)`, - ...transition - } + ...transition, + }, }, drawerPaperRTL: { [theme.breakpoints.up("md")]: { left: "auto !important", - right: "0 !important" + right: "0 !important", }, [theme.breakpoints.down("sm")]: { left: "0 !important", - right: "auto !important" - } + right: "auto !important", + }, }, logo: { position: "relative", @@ -76,29 +76,29 @@ const sidebarStyle = theme => ({ textDecoration: "none", backgroundColor: "transparent", "&,&:hover": { - color: whiteColor - } + color: whiteColor, + }, }, logoLinkRTL: { - textAlign: "right" + textAlign: "right", }, logoImage: { width: "30px", display: "inline-block", maxHeight: "30px", marginLeft: "10px", - marginRight: "15px" + marginRight: "15px", }, img: { width: "100%", verticalAlign: "middle", - border: "0" + border: "0", }, itemLinkSeparator: { "& > hr": { width: "75%", - opacity: "50%" - } + opacity: "50%", + }, }, background: { position: "absolute", @@ -118,8 +118,8 @@ const sidebarStyle = theme => ({ content: '""', display: "block", background: blackColor, - opacity: ".8" - } + opacity: ".8", + }, }, list: { paddingLeft: "0", @@ -127,7 +127,7 @@ const sidebarStyle = theme => ({ paddingBottom: "0", marginBottom: "0", listStyle: "none", - position: "unset" + position: "unset", }, bottomlist: { marginTop: "20px", @@ -139,15 +139,15 @@ const sidebarStyle = theme => ({ position: "fixed", bottom: "0", left: "0", - width: drawerWidth + width: drawerWidth, }, item: { position: "relative", display: "block", textDecoration: "none", "&:hover,&:focus,&:visited,&": { - color: whiteColor - } + color: whiteColor, + }, }, itemLink: { width: "auto", @@ -158,7 +158,7 @@ const sidebarStyle = theme => ({ display: "block", padding: "10px 15px", backgroundColor: "transparent", - ...defaultFont + ...defaultFont, }, itemIcon: { width: "24px", @@ -169,33 +169,33 @@ const sidebarStyle = theme => ({ marginRight: "15px", textAlign: "center", verticalAlign: "middle", - color: "rgba(" + hexToRgb(whiteColor) + ", 0.8)" + color: "rgba(" + hexToRgb(whiteColor) + ", 0.8)", }, itemIconRTL: { marginRight: "3px", marginLeft: "15px", - float: "right" + float: "right", }, itemText: { ...defaultFont, margin: "0", lineHeight: "30px", fontSize: "14px", - color: whiteColor + color: whiteColor, }, itemTextRTL: { - textAlign: "right" + textAlign: "right", }, whiteFont: { - color: whiteColor + color: whiteColor, }, purple: { backgroundColor: primaryColor[0], ...primaryBoxShadow, "&:hover,&:focus": { backgroundColor: primaryColor[0], - ...primaryBoxShadow - } + ...primaryBoxShadow, + }, }, blue: { backgroundColor: infoColor[0], @@ -216,8 +216,8 @@ const sidebarStyle = theme => ({ hexToRgb(blackColor) + ",.12), 0 7px 8px -5px rgba(" + hexToRgb(infoColor[0]) + - ",.2)" - } + ",.2)", + }, }, green: { backgroundColor: successColor[0], @@ -238,8 +238,8 @@ const sidebarStyle = theme => ({ hexToRgb(blackColor) + ",.12), 0 7px 8px -5px rgba(" + hexToRgb(successColor[0]) + - ",.2)" - } + ",.2)", + }, }, orange: { backgroundColor: warningColor[0], @@ -260,8 +260,8 @@ const sidebarStyle = theme => ({ hexToRgb(blackColor) + ",.12), 0 7px 8px -5px rgba(" + hexToRgb(warningColor[0]) + - ",.2)" - } + ",.2)", + }, }, red: { backgroundColor: dangerColor[0], @@ -282,8 +282,8 @@ const sidebarStyle = theme => ({ hexToRgb(blackColor) + ",.12), 0 7px 8px -5px rgba(" + hexToRgb(dangerColor[0]) + - ",.2)" - } + ",.2)", + }, }, sidebarWrapper: { position: "relative", @@ -291,15 +291,15 @@ const sidebarStyle = theme => ({ overflow: "auto", width: "260px", zIndex: "4", - overflowScrolling: "touch" + overflowScrolling: "touch", }, activePro: { [theme.breakpoints.up("md")]: { position: "absolute", width: "100%", - bottom: "13px" - } - } + bottom: "13px", + }, + }, }); export default sidebarStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/snackbarContentStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/snackbarContentStyle.js index d10fbc1e0e90c699fc9d4f67d1d82851f822fff7..82b68b19eadf9fa537675d185f03e05b87838333 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/snackbarContentStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/snackbarContentStyle.js @@ -15,7 +15,7 @@ import { roseColor, primaryColor, warningColor, - hexToRgb + hexToRgb, } from "assets/jss/material-dashboard-react.js"; const snackbarContentStyle = { @@ -39,57 +39,57 @@ const snackbarContentStyle = { hexToRgb(blackColor) + ", 0.12), 0 7px 8px -5px rgba(" + hexToRgb(whiteColor) + - ", 0.2)" + ", 0.2)", }, top20: { - top: "20px" + top: "20px", }, top40: { - top: "40px" + top: "40px", }, info: { backgroundColor: infoColor[3], color: whiteColor, - ...infoBoxShadow + ...infoBoxShadow, }, success: { backgroundColor: successColor[3], color: whiteColor, - ...successBoxShadow + ...successBoxShadow, }, warning: { backgroundColor: warningColor[3], color: whiteColor, - ...warningBoxShadow + ...warningBoxShadow, }, danger: { backgroundColor: dangerColor[3], color: whiteColor, - ...dangerBoxShadow + ...dangerBoxShadow, }, primary: { backgroundColor: primaryColor[3], color: whiteColor, - ...primaryBoxShadow + ...primaryBoxShadow, }, rose: { backgroundColor: roseColor[3], color: whiteColor, - ...roseBoxShadow + ...roseBoxShadow, }, message: { padding: "0", display: "block", - maxWidth: "89%" + maxWidth: "89%", }, close: { width: "11px", - height: "11px" + height: "11px", }, iconButton: { width: "24px", height: "24px", - padding: "0px" + padding: "0px", }, icon: { display: "block", @@ -98,34 +98,34 @@ const snackbarContentStyle = { top: "50%", marginTop: "-15px", width: "30px", - height: "30px" + height: "30px", }, infoIcon: { - color: infoColor[3] + color: infoColor[3], }, successIcon: { - color: successColor[3] + color: successColor[3], }, warningIcon: { - color: warningColor[3] + color: warningColor[3], }, dangerIcon: { - color: dangerColor[3] + color: dangerColor[3], }, primaryIcon: { - color: primaryColor[3] + color: primaryColor[3], }, roseIcon: { - color: roseColor[3] + color: roseColor[3], }, iconMessage: { paddingLeft: "50px", - display: "block" + display: "block", }, actionRTL: { marginLeft: "-8px", - marginRight: "auto" - } + marginRight: "auto", + }, }; export default snackbarContentStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/tableStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/tableStyle.js index 8054225b99e00e163bbfe7a37188fb0788aba509..d9108706a55490bd9887c9407db1a7082646d803 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/tableStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/tableStyle.js @@ -6,30 +6,30 @@ import { infoColor, roseColor, grayColor, - defaultFont + defaultFont, } from "assets/jss/material-dashboard-react.js"; -const tableStyle = theme => ({ +const tableStyle = (theme) => ({ warningTableHeader: { - color: warningColor[0] + color: warningColor[0], }, primaryTableHeader: { - color: primaryColor[0] + color: primaryColor[0], }, dangerTableHeader: { - color: dangerColor[0] + color: dangerColor[0], }, successTableHeader: { - color: successColor[0] + color: successColor[0], }, infoTableHeader: { - color: infoColor[0] + color: infoColor[0], }, roseTableHeader: { - color: roseColor[0] + color: roseColor[0], }, grayTableHeader: { - color: grayColor[0] + color: grayColor[0], }, table: { marginBottom: "0", @@ -37,41 +37,41 @@ const tableStyle = theme => ({ maxWidth: "100%", backgroundColor: "transparent", borderSpacing: "0", - borderCollapse: "collapse" + borderCollapse: "collapse", }, tableHeadCell: { color: "inherit", ...defaultFont, "&, &$tableCell": { - fontSize: "1em" - } + fontSize: "1em", + }, }, tableCell: { ...defaultFont, lineHeight: "1.42857143", padding: "12px 8px", verticalAlign: "middle", - fontSize: "0.8125rem" + fontSize: "0.8125rem", }, tableResponsive: { width: "100%", marginTop: theme.spacing(3), - overflowX: "auto" + overflowX: "auto", }, tableHeadRow: { height: "56px", color: "inherit", display: "table-row", outline: "none", - verticalAlign: "middle" + verticalAlign: "middle", }, tableBodyRow: { height: "48px", color: "inherit", display: "table-row", outline: "none", - verticalAlign: "middle" - } + verticalAlign: "middle", + }, }); export default tableStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/tasksStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/tasksStyle.js index 58a5e9c0200046a0d06e7590bb1eaf5368a0b2e0..886494db39109c70d3e4ad7fbac54445cafb4e1f 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/tasksStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/tasksStyle.js @@ -2,7 +2,7 @@ import { defaultFont, primaryColor, dangerColor, - grayColor + grayColor, } from "assets/jss/material-dashboard-react.js"; import tooltipStyle from "assets/jss/material-dashboard-react/tooltipStyle.js"; import checkboxAdnRadioStyle from "assets/jss/material-dashboard-react/checkboxAdnRadioStyle.js"; @@ -11,17 +11,17 @@ const tasksStyle = { ...checkboxAdnRadioStyle, table: { marginBottom: "0", - overflow: "visible" + overflow: "visible", }, tableRow: { position: "relative", - borderBottom: "1px solid " + grayColor[5] + borderBottom: "1px solid " + grayColor[5], }, tableActions: { display: "flex", border: "none", padding: "12px 8px !important", - verticalAlign: "middle" + verticalAlign: "middle", }, tableCell: { ...defaultFont, @@ -29,29 +29,29 @@ const tasksStyle = { verticalAlign: "middle", border: "none", lineHeight: "1.42857143", - fontSize: "14px" + fontSize: "14px", }, tableCellRTL: { - textAlign: "right" + textAlign: "right", }, tableActionButton: { width: "27px", height: "27px", - padding: "0" + padding: "0", }, tableActionButtonIcon: { width: "17px", - height: "17px" + height: "17px", }, edit: { backgroundColor: "transparent", color: primaryColor[0], - boxShadow: "none" + boxShadow: "none", }, close: { backgroundColor: "transparent", color: dangerColor[0], - boxShadow: "none" - } + boxShadow: "none", + }, }; export default tasksStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/typographyStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/typographyStyle.js index 3894ecafe42d42457a3f80ec68804e28a7cf39bc..8aff98a4ff1d637f687fecd01cff057f7b15a2f3 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/components/typographyStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/typographyStyle.js @@ -5,52 +5,52 @@ import { successColor, warningColor, dangerColor, - grayColor + grayColor, } from "assets/jss/material-dashboard-react.js"; const typographyStyle = { defaultFontStyle: { ...defaultFont, - fontSize: "14px" + fontSize: "14px", }, defaultHeaderMargins: { marginTop: "20px", - marginBottom: "10px" + marginBottom: "10px", }, quote: { padding: "10px 20px", margin: "0 0 20px", fontSize: "17.5px", - borderLeft: "5px solid " + grayColor[10] + borderLeft: "5px solid " + grayColor[10], }, quoteText: { margin: "0 0 10px", - fontStyle: "italic" + fontStyle: "italic", }, quoteAuthor: { display: "block", fontSize: "80%", lineHeight: "1.42857143", - color: grayColor[1] + color: grayColor[1], }, mutedText: { - color: grayColor[1] + color: grayColor[1], }, primaryText: { - color: primaryColor[0] + color: primaryColor[0], }, infoText: { - color: infoColor[0] + color: infoColor[0], }, successText: { - color: successColor[0] + color: successColor[0], }, warningText: { - color: warningColor[0] + color: warningColor[0], }, dangerText: { - color: dangerColor[0] - } + color: dangerColor[0], + }, }; export default typographyStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/dropdownStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/dropdownStyle.js index 7a5b376434652673a2a72923c3274b6c0dd6c5be..6e61466309f09d5cd4b1e7e493393cd2592f3a12 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/dropdownStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/dropdownStyle.js @@ -5,16 +5,16 @@ import { defaultFont, blackColor, grayColor, - hexToRgb + hexToRgb, } from "assets/jss/material-dashboard-react.js"; -const dropdownStyle = theme => ({ +const dropdownStyle = (theme) => ({ buttonLink: { [theme.breakpoints.down("md")]: { display: "flex", marginLeft: "30px", - width: "auto" - } + width: "auto", + }, }, links: { width: "20px", @@ -25,16 +25,16 @@ const dropdownStyle = theme => ({ width: "30px", height: "30px", color: grayColor[9], - marginRight: "15px" - } + marginRight: "15px", + }, }, linkText: { zIndex: "4", ...defaultFont, - fontSize: "14px" + fontSize: "14px", }, popperClose: { - pointerEvents: "none" + pointerEvents: "none", }, popperResponsive: { [theme.breakpoints.down("md")]: { @@ -47,8 +47,8 @@ const dropdownStyle = theme => ({ border: "0", WebkitBoxShadow: "none", boxShadow: "none", - color: "black" - } + color: "black", + }, }, popperNav: { [theme.breakpoints.down("sm")]: { @@ -72,11 +72,11 @@ const dropdownStyle = theme => ({ padding: "10px 15px !important", "&:hover": { backgroundColor: "hsla(0,0%,78%,.2)", - boxShadow: "none" - } - } - } - } + boxShadow: "none", + }, + }, + }, + }, }, dropdown: { borderRadius: "3px", @@ -92,7 +92,7 @@ const dropdownStyle = theme => ({ listStyle: "none", backgroundColor: whiteColor, WebkitBackgroundClip: "padding-box", - backgroundClip: "padding-box" + backgroundClip: "padding-box", }, dropdownItem: { ...defaultFont, @@ -116,9 +116,9 @@ const dropdownStyle = theme => ({ "&:hover": { backgroundColor: primaryColor[0], color: whiteColor, - ...primaryBoxShadow - } - } + ...primaryBoxShadow, + }, + }, }); export default dropdownStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/layouts/adminStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/layouts/adminStyle.js index 77f037fc033da58d15e8284ff4b2cb5acc30368b..224045e988b8c64c828f99ad8e9723e38a8a555e 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/layouts/adminStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/layouts/adminStyle.js @@ -1,18 +1,18 @@ import { drawerWidth, transition, - container + container, } from "assets/jss/material-dashboard-react.js"; -const appStyle = theme => ({ +const appStyle = (theme) => ({ wrapper: { position: "relative", top: "0", - height: "100vh" + height: "100vh", }, mainPanel: { [theme.breakpoints.up("md")]: { - width: `calc(100% - ${drawerWidth}px)` + width: `calc(100% - ${drawerWidth}px)`, }, overflow: "auto", position: "relative", @@ -20,7 +20,7 @@ const appStyle = theme => ({ ...transition, maxHeight: "100%", width: "100%", - overflowScrolling: "touch" + overflowScrolling: "touch", }, content: { marginTop: "0px", @@ -28,13 +28,13 @@ const appStyle = theme => ({ marginTop: "30px", }, padding: "30px 15px", - minHeight: "calc(100vh - 123px)" + minHeight: "calc(100vh - 123px)", }, container, map: { marginTop: "0px", - minHeight: "calc(100vh - 63px)" - } + minHeight: "calc(100vh - 63px)", + }, }); export default appStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/layouts/rtlStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/layouts/rtlStyle.js index 677daa6f8601d4d38730fcd4e75c6c49354bcf55..faa9dcc0555ba458c0d410db44d7d2462f9e0e32 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/layouts/rtlStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/layouts/rtlStyle.js @@ -1,19 +1,19 @@ import { drawerWidth, transition, - container + container, } from "assets/jss/material-dashboard-react.js"; -const appStyle = theme => ({ +const appStyle = (theme) => ({ wrapper: { position: "relative", top: "0", height: "100vh", - direction: "rtl" + direction: "rtl", }, mainPanel: { [theme.breakpoints.up("md")]: { - width: `calc(100% - ${drawerWidth}px)` + width: `calc(100% - ${drawerWidth}px)`, }, overflow: "auto", position: "relative", @@ -21,17 +21,17 @@ const appStyle = theme => ({ ...transition, maxHeight: "100%", width: "100%", - overflowScrolling: "touch" + overflowScrolling: "touch", }, content: { marginTop: "70px", padding: "30px 15px", - minHeight: "calc(100vh - 123px)" + minHeight: "calc(100vh - 123px)", }, container, map: { - marginTop: "70px" - } + marginTop: "70px", + }, }); export default appStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/tooltipStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/tooltipStyle.js index bcbd7a0ba79866efaabdae5b59795a7023fb489b..9d83efb51f94bbafd51b9ba309241da33bfb6ddd 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/tooltipStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/tooltipStyle.js @@ -28,7 +28,7 @@ const tooltipStyle = { wordSpacing: "normal", wordWrap: "normal", whiteSpace: "normal", - lineBreak: "auto" - } + lineBreak: "auto", + }, }; export default tooltipStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/views/dashboardStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/views/dashboardStyle.js index fe6f4e9d0045b5891e6d2f155c2abea6776b84e0..42eb7a013a2bdf566d0235720402e79851176401 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/views/dashboardStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/views/dashboardStyle.js @@ -2,16 +2,16 @@ import { successColor, whiteColor, grayColor, - hexToRgb + hexToRgb, } from "assets/jss/material-dashboard-react.js"; const dashboardStyle = { successText: { - color: successColor[0] + color: successColor[0], }, upArrowCardCategory: { width: "16px", - height: "16px" + height: "16px", }, stats: { color: grayColor[0], @@ -24,15 +24,15 @@ const dashboardStyle = { height: "16px", position: "relative", marginRight: "3px", - marginLeft: "3px" + marginLeft: "3px", }, "& .fab,& .fas,& .far,& .fal,& .material-icons": { top: "4px", fontSize: "16px", position: "relative", marginRight: "3px", - marginLeft: "3px" - } + marginLeft: "3px", + }, }, cardCategory: { color: grayColor[0], @@ -40,14 +40,14 @@ const dashboardStyle = { fontSize: "14px", marginTop: "0", paddingTop: "10px", - marginBottom: "0" + marginBottom: "0", }, cardCategoryWhite: { color: "rgba(" + hexToRgb(whiteColor) + ",.62)", margin: "0", fontSize: "14px", marginTop: "0", - marginBottom: "0" + marginBottom: "0", }, cardTitle: { color: grayColor[2], @@ -60,8 +60,8 @@ const dashboardStyle = { "& small": { color: grayColor[1], fontWeight: "400", - lineHeight: "1" - } + lineHeight: "1", + }, }, cardTitleWhite: { color: whiteColor, @@ -74,9 +74,9 @@ const dashboardStyle = { "& small": { color: grayColor[1], fontWeight: "400", - lineHeight: "1" - } - } + lineHeight: "1", + }, + }, }; export default dashboardStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/views/iconsStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/views/iconsStyle.js index 4043b711980720cab978ef9ebdc8eeef8e4a89a2..51c80a327cf7792f830053e6c370fdfdf9aa229a 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/views/iconsStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/views/iconsStyle.js @@ -2,7 +2,7 @@ import { boxShadow, whiteColor, grayColor, - hexToRgb + hexToRgb, } from "assets/jss/material-dashboard-react.js"; const iconsStyle = { @@ -10,10 +10,10 @@ const iconsStyle = { width: "100%", height: "500px", border: "0", - ...boxShadow + ...boxShadow, }, iframeContainer: { - margin: "0 -20px 0" + margin: "0 -20px 0", }, cardCategoryWhite: { "&,& a,& a:hover,& a:focus": { @@ -21,11 +21,11 @@ const iconsStyle = { margin: "0", fontSize: "14px", marginTop: "0", - marginBottom: "0" + marginBottom: "0", }, "& a,& a:hover,& a:focus": { - color: whiteColor - } + color: whiteColor, + }, }, cardTitleWhite: { color: whiteColor, @@ -38,9 +38,9 @@ const iconsStyle = { "& small": { color: grayColor[1], fontWeight: "400", - lineHeight: "1" - } - } + lineHeight: "1", + }, + }, }; export default iconsStyle; diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/views/rtlStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/views/rtlStyle.js index 22d228a9af0f4ba0ffcda1c7ef8f0ce60e27f139..a0f210971c9d227a3c2bb734251a613d72cc4c32 100644 --- a/jams-react-client/src/assets/jss/material-dashboard-react/views/rtlStyle.js +++ b/jams-react-client/src/assets/jss/material-dashboard-react/views/rtlStyle.js @@ -2,16 +2,16 @@ import { successColor, whiteColor, grayColor, - hexToRgb + hexToRgb, } from "assets/jss/material-dashboard-react.js"; const rtlStyle = { successText: { - color: successColor[0] + color: successColor[0], }, upArrowCardCategory: { width: "16px", - height: "16px" + height: "16px", }, stats: { color: grayColor[0], @@ -24,15 +24,15 @@ const rtlStyle = { height: "16px", position: "relative", marginRight: "3px", - marginLeft: "3px" + marginLeft: "3px", }, "& .fab,& .fas,& .far,& .fal,& .material-icons": { top: "4px", fontSize: "16px", position: "relative", marginRight: "3px", - marginLeft: "3px" - } + marginLeft: "3px", + }, }, cardCategory: { color: grayColor[0], @@ -40,7 +40,7 @@ const rtlStyle = { fontSize: "14px", marginTop: "0", paddingTop: "10px", - marginBottom: "0" + marginBottom: "0", }, cardCategoryWhite: { color: "rgba(" + hexToRgb(whiteColor) + ",.62)", @@ -49,8 +49,8 @@ const rtlStyle = { marginTop: "0", marginBottom: "0", "& a": { - color: whiteColor - } + color: whiteColor, + }, }, cardTitle: { color: grayColor[2], @@ -63,8 +63,8 @@ const rtlStyle = { "& small": { color: grayColor[1], fontWeight: "400", - lineHeight: "1" - } + lineHeight: "1", + }, }, cardTitleWhite: { color: whiteColor, @@ -77,9 +77,9 @@ const rtlStyle = { "& small": { color: grayColor[1], fontWeight: "400", - lineHeight: "1" - } - } + lineHeight: "1", + }, + }, }; export default rtlStyle; diff --git a/jams-react-client/src/components/CaSetup/CaSetup.js b/jams-react-client/src/components/CaSetup/CaSetup.js index d0236c0f56b28f6f3bc1813c18543e47a99b2fa9..37ec76072efb032671ae403612150f39b2012a65 100644 --- a/jams-react-client/src/components/CaSetup/CaSetup.js +++ b/jams-react-client/src/components/CaSetup/CaSetup.js @@ -1,361 +1,419 @@ -import React from 'react'; -import {useHistory} from "react-router-dom"; +import React from "react"; +import { useHistory } from "react-router-dom"; import { Formik, Field } from "formik"; -import * as Yup from 'yup'; -import Button from '@material-ui/core/Button'; -import TextField from '@material-ui/core/TextField'; -import { makeStyles } from '@material-ui/core/styles'; +import * as Yup from "yup"; +import Button from "@material-ui/core/Button"; +import TextField from "@material-ui/core/TextField"; +import { makeStyles } from "@material-ui/core/styles"; import CountrySelect from "components/CountrySelect/CountrySelect.js"; -import auth from '../../auth' -import axios from 'axios'; -import configApiCall from '../../api' -import { api_path_post_install_ca } from '../../globalUrls' +import auth from "../../auth"; +import axios from "axios"; +import configApiCall from "../../api"; +import { api_path_post_install_ca } from "../../globalUrls"; import Select from "@material-ui/core/Select"; import * as tool from "../../tools"; import Input from "@material-ui/core/Input"; import Typography from "@material-ui/core/Typography"; -import i18next from 'i18next'; +import i18next from "i18next"; const useStyles = makeStyles((theme) => ({ - paper: { - marginTop: theme.spacing(8), - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - }, - avatar: { - margin: theme.spacing(1), - backgroundColor: theme.palette.secondary.main, - }, - form: { - width: '100%', // Fix IE 11 issue. - marginTop: theme.spacing(1), - }, - submit: { - margin: theme.spacing(3, 0, 2), - }, + paper: { + marginTop: theme.spacing(8), + display: "flex", + flexDirection: "column", + alignItems: "center", + }, + avatar: { + margin: theme.spacing(1), + backgroundColor: theme.palette.secondary.main, + }, + form: { + width: "100%", // Fix IE 11 issue. + marginTop: theme.spacing(1), + }, + submit: { + margin: theme.spacing(3, 0, 2), + }, })); export default function CaSetup(props) { - const history = useHistory(); - - /** - * Formik Validation Fields - */ - - const initialValuesform1 = {commonname: "", state:"", city:"", organization:"", organizationunit:"", country:""}; - - const initialValuesform2 = {certificatefile: "", privkeyfile:""}; - - const validationSchemaform1 = Yup.object().shape({ - commonname: Yup.string() - .required(i18next.t("common_name_is_required", "Common name is required.")), - state: Yup.string() - .required(i18next.t("state_is_required", "State is required.")), - city: Yup.string() - .required(i18next.t("city_is_required", "City is required.")), - organization: Yup.string() - .required(i18next.t("organization_is_required", "Organization is required.")), - organizationunit: Yup.string() - .required(i18next.t("organization_unit_is_required", "Organization unit is required.")), - country: Yup.string() - .required(i18next.t("country_is_required", "Country is required.")), - }); - - const validationSchemaform2 = Yup.object().shape({ - certificatefile: Yup.mixed() - .required(i18next.t("certificate_file_is_required", "Certificate file is required.")), - privkeyfile: Yup.mixed() - .required(i18next.t("private_key_file_is_required", "Private key file is required.")), - }); - - - const getCertificateOptions = [ - {value: 0, label: i18next.t("create_self_signed_certificate_authority", "Create a self-signed Certificate Authority")}, - {value: 1, label: i18next.t("import_existing_certificate_authority", "Import existing Certificate Authority")}, - ]; - - const validityPeriods = [ - {value: 157784630000, label: i18next.t("5_years", "5 years")}, - {value: 315569260000, label: i18next.t("10_years", "10 years")}, - ]; - - const certificateOptionsItems = tool.buildSelectMenuItems(getCertificateOptions); - const validityPeriodsItems = tool.buildSelectMenuItems(validityPeriods); - const classes = useStyles(); - - const [certificateOpt, setCertificateOpt] = React.useState(getCertificateOptions[0]); - const [validityPeriod, setValidityPeriod] = React.useState(validityPeriods[0]); - - - function handleInstallCA(data) { - if(data.status === 500 || data.status === 512 || data.status === 513) { - props.setError(true) - props.setErrorMessage(i18next.t("unknown_error_occured_while_installing_the_ca", "An unknown error occurred while installing the CA. Please try again.")); - } - else if (data.status === 200){ - auth.uri = '/api/install/auth'; - history.push('/'); - } - + const history = useHistory(); + + /** + * Formik Validation Fields + */ + + const initialValuesform1 = { + commonname: "", + state: "", + city: "", + organization: "", + organizationunit: "", + country: "", + }; + + const initialValuesform2 = { certificatefile: "", privkeyfile: "" }; + + const validationSchemaform1 = Yup.object().shape({ + commonname: Yup.string().required( + i18next.t("common_name_is_required", "Common name is required.") + ), + state: Yup.string().required( + i18next.t("state_is_required", "State is required.") + ), + city: Yup.string().required( + i18next.t("city_is_required", "City is required.") + ), + organization: Yup.string().required( + i18next.t("organization_is_required", "Organization is required.") + ), + organizationunit: Yup.string().required( + i18next.t( + "organization_unit_is_required", + "Organization unit is required." + ) + ), + country: Yup.string().required( + i18next.t("country_is_required", "Country is required.") + ), + }); + + const validationSchemaform2 = Yup.object().shape({ + certificatefile: Yup.mixed().required( + i18next.t("certificate_file_is_required", "Certificate file is required.") + ), + privkeyfile: Yup.mixed().required( + i18next.t("private_key_file_is_required", "Private key file is required.") + ), + }); + + const getCertificateOptions = [ + { + value: 0, + label: i18next.t( + "create_self_signed_certificate_authority", + "Create a self-signed Certificate Authority" + ), + }, + { + value: 1, + label: i18next.t( + "import_existing_certificate_authority", + "Import existing Certificate Authority" + ), + }, + ]; + + const validityPeriods = [ + { value: 157784630000, label: i18next.t("5_years", "5 years") }, + { value: 315569260000, label: i18next.t("10_years", "10 years") }, + ]; + + const certificateOptionsItems = tool.buildSelectMenuItems( + getCertificateOptions + ); + const validityPeriodsItems = tool.buildSelectMenuItems(validityPeriods); + const classes = useStyles(); + + const [certificateOpt, setCertificateOpt] = React.useState( + getCertificateOptions[0] + ); + const [validityPeriod, setValidityPeriod] = React.useState( + validityPeriods[0] + ); + + function handleInstallCA(data) { + if (data.status === 500 || data.status === 512 || data.status === 513) { + props.setError(true); + props.setErrorMessage( + i18next.t( + "unknown_error_occured_while_installing_the_ca", + "An unknown error occurred while installing the CA. Please try again." + ) + ); + } else if (data.status === 200) { + auth.uri = "/api/install/auth"; + history.push("/"); } - - const handleCertifOptionChange = (event) => { - props.setError(false); - setCertificateOpt(getCertificateOptions[event.target.value]); - }; - - const handleValidPeriodChange = (event) => { - props.setError(false); - setValidityPeriod(tool.retrieveArrayElement(event.target.value, validityPeriods)); - }; - - const handleSubmit = (values) => { - let jsonData = {}; - if(certificateOpt.value === 0){ - jsonData = { - 'fields': { - 'commonName': values.commonname, - 'organizationalUnit': values.organizationUnit, - 'organization': values.organization, - 'city': values.city, - 'state': values.state, - 'country': values.country, - 'lifetime': validityPeriod.value - } - } - } - else if(certificateOpt.value === 1){ - jsonData = { - 'caCertificate': values.certificatefile, - 'caKey': values.privkeyfile - } - } - - axios(configApiCall(api_path_post_install_ca, "POST", jsonData, null)).then((response)=>{ - handleInstallCA(response); - }).catch((error)=>{ - props.setError(error); - console.log('Error installing CA Setup: ' + error ); - }) + } + + const handleCertifOptionChange = (event) => { + props.setError(false); + setCertificateOpt(getCertificateOptions[event.target.value]); + }; + + const handleValidPeriodChange = (event) => { + props.setError(false); + setValidityPeriod( + tool.retrieveArrayElement(event.target.value, validityPeriods) + ); + }; + + const handleSubmit = (values) => { + let jsonData = {}; + if (certificateOpt.value === 0) { + jsonData = { + fields: { + commonName: values.commonname, + organizationalUnit: values.organizationUnit, + organization: values.organization, + city: values.city, + state: values.state, + country: values.country, + lifetime: validityPeriod.value, + }, + }; + } else if (certificateOpt.value === 1) { + jsonData = { + caCertificate: values.certificatefile, + caKey: values.privkeyfile, + }; } - if(certificateOpt.value === 0){ - return ( - <Formik - validationSchema={validationSchemaform1} - initialValues={initialValuesform1} - onSubmit={values => { - handleSubmit(values); - }} - > - {(props) => { - const { - values, - touched, - errors, - handleSubmit, - handleChange, - handleBlur, - } = props; - return ( - <form className={classes.form} noValidate onSubmit={handleSubmit}> - <h4> - {i18next.t("ca_setup_header", "Select an option for setting-up the certificate authority that will be used to sign all Jami accounts generated on this JAMS instance.")} - </h4> - <Select - labelId="certificate-option-select-label" - fullWidth - value={certificateOpt.value} - onChange={handleCertifOptionChange} - variant="outlined" - children={certificateOptionsItems} - /> - - <TextField - variant="outlined" - margin="normal" - required - fullWidth - id="commonname" - label={i18next.t("common_name", "Common Name")} - name="commonname" - autoComplete="commonname" - autoFocus - value={values.commonname} - onChange={handleChange} - onBlur={handleBlur} - helperText={(errors.commonname && touched.commonname) && errors.commonname} - /> - - <CountrySelect defaultValue={values.country} {...props}/> - {touched.country && errors.country ? (<span class="spanError">{errors.country}</span>) : null} - - <TextField - variant="outlined" - margin="normal" - required - fullWidth - name="state" - label={i18next.t("state", "State")} - id="state" - autoComplete="state" - value={values.state} - onChange={handleChange} - onBlur={handleBlur} - helperText={(errors.state && touched.state) && errors.state} - /> - - <TextField - variant="outlined" - margin="normal" - required - fullWidth - name="city" - label={i18next.t("cistatety", "City")} - id="city" - autoComplete="city" - value={values.city} - onChange={handleChange} - onBlur={handleBlur} - helperText={(errors.city && touched.city) && errors.city} - /> - - - <TextField - variant="outlined" - margin="normal" - required - fullWidth - name="organization" - label={i18next.t("organization", "Organization")} - id="organization" - autoComplete="organization" - value={values.organization} - onChange={handleChange} - onBlur={handleBlur} - helperText={(errors.organization && touched.organization) && errors.organization} - /> - <TextField - variant="outlined" - margin="normal" - required - fullWidth - name="organizationunit" - label={i18next.t("organization_unit", "Organization Unit")} - id="organizationunit" - autoComplete="organizationunit" - value={values.organizationunit} - onChange={handleChange} - onBlur={handleBlur} - helperText={(errors.organizationunit && touched.organizationunit) && errors.organizationunit} - /> - - <Select - labelId="validity-period-select-label" - margin="normal" - fullWidth - variant="outlined" - value={validityPeriod.value} - onChange={handleValidPeriodChange} - children={validityPeriodsItems} - /> - - <Button - type="submit" - fullWidth - variant="contained" - color="primary" - className={classes.submit} - > - {i18next.t("generate_self_signed_certificate_authority", "Generate Self-Signed Certificate Authority")} - </Button> - - </form> - ); + axios(configApiCall(api_path_post_install_ca, "POST", jsonData, null)) + .then((response) => { + handleInstallCA(response); + }) + .catch((error) => { + props.setError(error); + console.log("Error installing CA Setup: " + error); + }); + }; + if (certificateOpt.value === 0) { + return ( + <Formik + validationSchema={validationSchemaform1} + initialValues={initialValuesform1} + onSubmit={(values) => { + handleSubmit(values); + }} + > + {(props) => { + const { + values, + touched, + errors, + handleSubmit, + handleChange, + handleBlur, + } = props; + return ( + <form className={classes.form} noValidate onSubmit={handleSubmit}> + <h4> + {i18next.t( + "ca_setup_header", + "Select an option for setting-up the certificate authority that will be used to sign all Jami accounts generated on this JAMS instance." + )} + </h4> + <Select + labelId="certificate-option-select-label" + fullWidth + value={certificateOpt.value} + onChange={handleCertifOptionChange} + variant="outlined" + children={certificateOptionsItems} + /> + + <TextField + variant="outlined" + margin="normal" + required + fullWidth + id="commonname" + label={i18next.t("common_name", "Common Name")} + name="commonname" + autoComplete="commonname" + autoFocus + value={values.commonname} + onChange={handleChange} + onBlur={handleBlur} + helperText={ + errors.commonname && touched.commonname && errors.commonname } + /> + + <CountrySelect defaultValue={values.country} {...props} /> + {touched.country && errors.country ? ( + <span class="spanError">{errors.country}</span> + ) : null} + + <TextField + variant="outlined" + margin="normal" + required + fullWidth + name="state" + label={i18next.t("state", "State")} + id="state" + autoComplete="state" + value={values.state} + onChange={handleChange} + onBlur={handleBlur} + helperText={errors.state && touched.state && errors.state} + /> + + <TextField + variant="outlined" + margin="normal" + required + fullWidth + name="city" + label={i18next.t("cistatety", "City")} + id="city" + autoComplete="city" + value={values.city} + onChange={handleChange} + onBlur={handleBlur} + helperText={errors.city && touched.city && errors.city} + /> + + <TextField + variant="outlined" + margin="normal" + required + fullWidth + name="organization" + label={i18next.t("organization", "Organization")} + id="organization" + autoComplete="organization" + value={values.organization} + onChange={handleChange} + onBlur={handleBlur} + helperText={ + errors.organization && + touched.organization && + errors.organization } - </Formik> - ); - } - else if(certificateOpt.value === 1){ - return ( - <Formik - validationSchema={validationSchemaform2} - initialValues={initialValuesform2} - onSubmit={values => { - handleSubmit(values); - }} - >{(props) => { - const { - handleSubmit, - handleChange, - } = props; - return ( - <form className={classes.form} noValidate onSubmit={handleSubmit}> - <h4> - {i18next.t("select_option_setting_up_certificate_authority", "Select an option for setting-up the certificate authority that will be used to sign all Jami accounts generated on this JAMS instance.")} - </h4> - - <Select - labelId="demo-simple-select-label" - fullWidth - value={certificateOpt.value} - onChange={handleCertifOptionChange} - variant="outlined" - children={certificateOptionsItems} - /> - <Typography variant="subtitle1" gutterBottom>CA file (PEM-encoded)</Typography> - <Field name="certificatefile"> - {({field, form}) => ( - <div> - <Input - fullWidth - type="file" - onChange={handleChange} - {...field} - /> - {form.errors.certificatefile && form.touched.certificatefile? <span class="spanError">{form.errors.certificatefile}</span> : null} - </div> - ) - } - </Field> - <Typography variant="subtitle1" gutterBottom>Key File (PEM-encoded)</Typography> - <Field name="privkeyfile"> - {({ - field, - form, - meta, - }) => ( - <div> - <Input - fullWidth - type="file" - {...field} - /> - {meta.touched && meta.error && (<span class="spanError">{meta.error}</span>)} - </div> - ) - } - </Field> - - <Button - type="submit" - fullWidth - variant="contained" - color="primary" - className={classes.submit} - > - {i18next.t("import_certificate_authority", "Import Certificate Authority")} - </Button> - - </form> - ); - }} - </Formik> - ); - } -} \ No newline at end of file + /> + + <TextField + variant="outlined" + margin="normal" + required + fullWidth + name="organizationunit" + label={i18next.t("organization_unit", "Organization Unit")} + id="organizationunit" + autoComplete="organizationunit" + value={values.organizationunit} + onChange={handleChange} + onBlur={handleBlur} + helperText={ + errors.organizationunit && + touched.organizationunit && + errors.organizationunit + } + /> + + <Select + labelId="validity-period-select-label" + margin="normal" + fullWidth + variant="outlined" + value={validityPeriod.value} + onChange={handleValidPeriodChange} + children={validityPeriodsItems} + /> + + <Button + type="submit" + fullWidth + variant="contained" + color="primary" + className={classes.submit} + > + {i18next.t( + "generate_self_signed_certificate_authority", + "Generate Self-Signed Certificate Authority" + )} + </Button> + </form> + ); + }} + </Formik> + ); + } else if (certificateOpt.value === 1) { + return ( + <Formik + validationSchema={validationSchemaform2} + initialValues={initialValuesform2} + onSubmit={(values) => { + handleSubmit(values); + }} + > + {(props) => { + const { handleSubmit, handleChange } = props; + return ( + <form className={classes.form} noValidate onSubmit={handleSubmit}> + <h4> + {i18next.t( + "select_option_setting_up_certificate_authority", + "Select an option for setting-up the certificate authority that will be used to sign all Jami accounts generated on this JAMS instance." + )} + </h4> + + <Select + labelId="demo-simple-select-label" + fullWidth + value={certificateOpt.value} + onChange={handleCertifOptionChange} + variant="outlined" + children={certificateOptionsItems} + /> + <Typography variant="subtitle1" gutterBottom> + CA file (PEM-encoded) + </Typography> + <Field name="certificatefile"> + {({ field, form }) => ( + <div> + <Input + fullWidth + type="file" + onChange={handleChange} + {...field} + /> + {form.errors.certificatefile && + form.touched.certificatefile ? ( + <span class="spanError"> + {form.errors.certificatefile} + </span> + ) : null} + </div> + )} + </Field> + <Typography variant="subtitle1" gutterBottom> + Key File (PEM-encoded) + </Typography> + <Field name="privkeyfile"> + {({ field, form, meta }) => ( + <div> + <Input fullWidth type="file" {...field} /> + {meta.touched && meta.error && ( + <span class="spanError">{meta.error}</span> + )} + </div> + )} + </Field> + + <Button + type="submit" + fullWidth + variant="contained" + color="primary" + className={classes.submit} + > + {i18next.t( + "import_certificate_authority", + "Import Certificate Authority" + )} + </Button> + </form> + ); + }} + </Formik> + ); + } +} diff --git a/jams-react-client/src/components/Card/Card.js b/jams-react-client/src/components/Card/Card.js index 5ab48ffc6822de13a485f782022aa1879b5aaeb1..567dd7b9573bd0ca1529dcbe3887caaa4d748632 100644 --- a/jams-react-client/src/components/Card/Card.js +++ b/jams-react-client/src/components/Card/Card.js @@ -20,7 +20,7 @@ export default function Card(props) { [classes.cardPlain]: plain, [classes.cardProfile]: profile, [classes.cardChart]: chart, - [className]: className !== undefined + [className]: className !== undefined, }); return ( <div className={cardClasses} {...rest}> @@ -34,5 +34,5 @@ Card.propTypes = { plain: PropTypes.bool, profile: PropTypes.bool, chart: PropTypes.bool, - children: PropTypes.node + children: PropTypes.node, }; diff --git a/jams-react-client/src/components/Card/CardAvatar.js b/jams-react-client/src/components/Card/CardAvatar.js index 58e0368de1344fcb5d8fbdca636008c572287983..67e5e11049fe520ccac94a1468c0079dc39e2015 100644 --- a/jams-react-client/src/components/Card/CardAvatar.js +++ b/jams-react-client/src/components/Card/CardAvatar.js @@ -14,14 +14,22 @@ const useStyles = makeStyles(styles); export default function CardAvatar(props) { const classes = useStyles(); - const { children, className, plain, profile, displayProfile, editProfile, ...rest } = props; + const { + children, + className, + plain, + profile, + displayProfile, + editProfile, + ...rest + } = props; const cardAvatarClasses = classNames({ [classes.cardAvatar]: true, [classes.cardAvatarProfile]: profile, [classes.cardAvatarDisplayProfile]: displayProfile, [classes.cardAvatarEditProfile]: editProfile, [classes.cardAvatarPlain]: plain, - [className]: className !== undefined + [className]: className !== undefined, }); return ( <div className={cardAvatarClasses} {...rest}> @@ -36,5 +44,5 @@ CardAvatar.propTypes = { profile: PropTypes.bool, displayProfile: PropTypes.bool, editProfile: PropTypes.bool, - plain: PropTypes.bool + plain: PropTypes.bool, }; diff --git a/jams-react-client/src/components/Card/CardBody.js b/jams-react-client/src/components/Card/CardBody.js index 7d059d08b25d4a286322ec981dd88c828f69ddda..4c65b902c9cae7af0fe75fac78122dcaf07b0e58 100644 --- a/jams-react-client/src/components/Card/CardBody.js +++ b/jams-react-client/src/components/Card/CardBody.js @@ -19,7 +19,7 @@ export default function CardBody(props) { [classes.cardBody]: true, [classes.cardBodyPlain]: plain, [classes.cardBodyProfile]: profile, - [className]: className !== undefined + [className]: className !== undefined, }); return ( <div className={cardBodyClasses} {...rest}> @@ -32,5 +32,5 @@ CardBody.propTypes = { className: PropTypes.string, plain: PropTypes.bool, profile: PropTypes.bool, - children: PropTypes.node + children: PropTypes.node, }; diff --git a/jams-react-client/src/components/Card/CardFooter.js b/jams-react-client/src/components/Card/CardFooter.js index 0a52c976c05b974fd2d755b54a8ca676eff0cacb..9559a388ceadbda7c21331897f90ce2b7196d928 100644 --- a/jams-react-client/src/components/Card/CardFooter.js +++ b/jams-react-client/src/components/Card/CardFooter.js @@ -21,7 +21,7 @@ export default function CardFooter(props) { [classes.cardFooterProfile]: profile, [classes.cardFooterStats]: stats, [classes.cardFooterChart]: chart, - [className]: className !== undefined + [className]: className !== undefined, }); return ( <div className={cardFooterClasses} {...rest}> @@ -36,5 +36,5 @@ CardFooter.propTypes = { profile: PropTypes.bool, stats: PropTypes.bool, chart: PropTypes.bool, - children: PropTypes.node + children: PropTypes.node, }; diff --git a/jams-react-client/src/components/Card/CardHeader.js b/jams-react-client/src/components/Card/CardHeader.js index 2d38da2dad3c0656f38bb9f6cb0e7a0aef466a96..6c15a0a79b4c6bce4c3bbb1e714b4dffb7e6641c 100644 --- a/jams-react-client/src/components/Card/CardHeader.js +++ b/jams-react-client/src/components/Card/CardHeader.js @@ -21,7 +21,7 @@ export default function CardHeader(props) { [classes.cardHeaderPlain]: plain, [classes.cardHeaderStats]: stats, [classes.cardHeaderIcon]: icon, - [className]: className !== undefined + [className]: className !== undefined, }); return ( <div className={cardHeaderClasses} {...rest}> @@ -38,10 +38,10 @@ CardHeader.propTypes = { "danger", "info", "primary", - "rose" + "rose", ]), plain: PropTypes.bool, stats: PropTypes.bool, icon: PropTypes.bool, - children: PropTypes.node + children: PropTypes.node, }; diff --git a/jams-react-client/src/components/Card/CardIcon.js b/jams-react-client/src/components/Card/CardIcon.js index f05a4172d872cd27ae45245568e244fd76da8baa..ba7286191e3996b418cba06e2c90f4f594087f03 100644 --- a/jams-react-client/src/components/Card/CardIcon.js +++ b/jams-react-client/src/components/Card/CardIcon.js @@ -18,7 +18,7 @@ export default function CardIcon(props) { const cardIconClasses = classNames({ [classes.cardIcon]: true, [classes[color + "CardHeader"]]: color, - [className]: className !== undefined + [className]: className !== undefined, }); return ( <div className={cardIconClasses} {...rest}> @@ -35,7 +35,7 @@ CardIcon.propTypes = { "danger", "info", "primary", - "rose" + "rose", ]), - children: PropTypes.node + children: PropTypes.node, }; diff --git a/jams-react-client/src/components/CountrySelect/CountrySelect.js b/jams-react-client/src/components/CountrySelect/CountrySelect.js index b0bef0d50866b6f203cbb21d8e62e4b6a78441a3..9b7a4f46aab118ac57ea9f752bb5affe7d79def0 100644 --- a/jams-react-client/src/components/CountrySelect/CountrySelect.js +++ b/jams-react-client/src/components/CountrySelect/CountrySelect.js @@ -1,320 +1,323 @@ -import React from 'react'; -import TextField from '@material-ui/core/TextField'; -import Autocomplete from '@material-ui/lab/Autocomplete'; -import { makeStyles } from '@material-ui/core/styles'; +import React from "react"; +import TextField from "@material-ui/core/TextField"; +import Autocomplete from "@material-ui/lab/Autocomplete"; +import { makeStyles } from "@material-ui/core/styles"; import i18next from "i18next"; // ISO 3166-1 alpha-2 // âš ï¸ No support for IE 11 function countryToFlag(isoCode) { - return typeof String.fromCodePoint !== 'undefined' - ? isoCode - .toUpperCase() - .replace(/./g, (char) => String.fromCodePoint(char.charCodeAt(0) + 127397)) - : isoCode; + return typeof String.fromCodePoint !== "undefined" + ? isoCode + .toUpperCase() + .replace(/./g, (char) => + String.fromCodePoint(char.charCodeAt(0) + 127397) + ) + : isoCode; } const useStyles = makeStyles({ - option: { - fontSize: 15, - '& > span': { - marginRight: 10, - fontSize: 18, - }, + option: { + fontSize: 15, + "& > span": { + marginRight: 10, + fontSize: 18, }, + }, }); export default function CountrySelect(props) { - const classes = useStyles(); + const classes = useStyles(); - - return ( - <Autocomplete - id="country-select-demo" - name="country" - options={countries} - classes={{ - option: classes.option, - }} - onChange={(e, value) => { - value!=null ? props.setFieldValue("country", value.code): props.setFieldValue("country", ""); - }} - autoHighlight - getOptionLabel={(option) => ( - countryToFlag(option.code) + " "+ option.label - )} - renderOption={(option) => ( - <React.Fragment> - <span>{countryToFlag(option.code)}</span> - {option.label} - </React.Fragment> - )} - renderInput={(params) => ( - <TextField - {...params} - label={i18next.t("choose_a_country", "Choose a country")} - name="country" - variant="outlined" - onBlur={props.handleBlur} - inputProps={{ - ...params.inputProps, - autoComplete: 'country', // disable autocomplete and autofill - }} - /> - )} + return ( + <Autocomplete + id="country-select-demo" + name="country" + options={countries} + classes={{ + option: classes.option, + }} + onChange={(e, value) => { + value != null + ? props.setFieldValue("country", value.code) + : props.setFieldValue("country", ""); + }} + autoHighlight + getOptionLabel={(option) => + countryToFlag(option.code) + " " + option.label + } + renderOption={(option) => ( + <React.Fragment> + <span>{countryToFlag(option.code)}</span> + {option.label} + </React.Fragment> + )} + renderInput={(params) => ( + <TextField + {...params} + label={i18next.t("choose_a_country", "Choose a country")} + name="country" + variant="outlined" + onBlur={props.handleBlur} + inputProps={{ + ...params.inputProps, + autoComplete: "country", // disable autocomplete and autofill + }} /> - ); + )} + /> + ); } // From https://bitbucket.org/atlassian/atlaskit-mk-2/raw/4ad0e56649c3e6c973e226b7efaeb28cb240ccb0/packages/core/select/src/data/countries.js const countries = [ - { code: 'AD', label: 'Andorra' }, - { code: 'AE', label: 'United Arab Emirates' }, - { code: 'AF', label: 'Afghanistan' }, - { code: 'AG', label: 'Antigua and Barbuda' }, - { code: 'AI', label: 'Anguilla' }, - { code: 'AL', label: 'Albania' }, - { code: 'AM', label: 'Armenia' }, - { code: 'AO', label: 'Angola' }, - { code: 'AQ', label: 'Antarctica' }, - { code: 'AR', label: 'Argentina' }, - { code: 'AS', label: 'American Samoa' }, - { code: 'AT', label: 'Austria' }, - { code: 'AU', label: 'Australia', suggested: true }, - { code: 'AW', label: 'Aruba' }, - { code: 'AX', label: 'Alland Islands' }, - { code: 'AZ', label: 'Azerbaijan' }, - { code: 'BA', label: 'Bosnia and Herzegovina' }, - { code: 'BB', label: 'Barbados' }, - { code: 'BD', label: 'Bangladesh' }, - { code: 'BE', label: 'Belgium' }, - { code: 'BF', label: 'Burkina Faso' }, - { code: 'BG', label: 'Bulgaria' }, - { code: 'BH', label: 'Bahrain' }, - { code: 'BI', label: 'Burundi' }, - { code: 'BJ', label: 'Benin' }, - { code: 'BL', label: 'Saint Barthelemy' }, - { code: 'BM', label: 'Bermuda' }, - { code: 'BN', label: 'Brunei Darussalam' }, - { code: 'BO', label: 'Bolivia' }, - { code: 'BR', label: 'Brazil' }, - { code: 'BS', label: 'Bahamas' }, - { code: 'BT', label: 'Bhutan' }, - { code: 'BV', label: 'Bouvet Island' }, - { code: 'BW', label: 'Botswana' }, - { code: 'BY', label: 'Belarus' }, - { code: 'BZ', label: 'Belize' }, - { code: 'CA', label: 'Canada', suggested: true }, - { code: 'CC', label: 'Cocos (Keeling) Islands' }, - { code: 'CD', label: 'Congo, Democratic Republic of the' }, - { code: 'CF', label: 'Central African Republic' }, - { code: 'CG', label: 'Congo, Republic of the' }, - { code: 'CH', label: 'Switzerland' }, - { code: 'CI', label: "Cote d'Ivoire" }, - { code: 'CK', label: 'Cook Islands' }, - { code: 'CL', label: 'Chile' }, - { code: 'CM', label: 'Cameroon' }, - { code: 'CN', label: 'China' }, - { code: 'CO', label: 'Colombia' }, - { code: 'CR', label: 'Costa Rica' }, - { code: 'CU', label: 'Cuba' }, - { code: 'CV', label: 'Cape Verde' }, - { code: 'CW', label: 'Curacao' }, - { code: 'CX', label: 'Christmas Island' }, - { code: 'CY', label: 'Cyprus' }, - { code: 'CZ', label: 'Czech Republic' }, - { code: 'DE', label: 'Germany', suggested: true }, - { code: 'DJ', label: 'Djibouti' }, - { code: 'DK', label: 'Denmark' }, - { code: 'DM', label: 'Dominica' }, - { code: 'DO', label: 'Dominican Republic' }, - { code: 'DZ', label: 'Algeria' }, - { code: 'EC', label: 'Ecuador' }, - { code: 'EE', label: 'Estonia' }, - { code: 'EG', label: 'Egypt' }, - { code: 'EH', label: 'Western Sahara' }, - { code: 'ER', label: 'Eritrea' }, - { code: 'ES', label: 'Spain' }, - { code: 'ET', label: 'Ethiopia' }, - { code: 'FI', label: 'Finland' }, - { code: 'FJ', label: 'Fiji' }, - { code: 'FK', label: 'Falkland Islands (Malvinas)' }, - { code: 'FM', label: 'Micronesia, Federated States of' }, - { code: 'FO', label: 'Faroe Islands' }, - { code: 'FR', label: 'France', suggested: true }, - { code: 'GA', label: 'Gabon' }, - { code: 'GB', label: 'United Kingdom' }, - { code: 'GD', label: 'Grenada' }, - { code: 'GE', label: 'Georgia' }, - { code: 'GF', label: 'French Guiana' }, - { code: 'GG', label: 'Guernsey' }, - { code: 'GH', label: 'Ghana' }, - { code: 'GI', label: 'Gibraltar' }, - { code: 'GL', label: 'Greenland' }, - { code: 'GM', label: 'Gambia' }, - { code: 'GN', label: 'Guinea' }, - { code: 'GP', label: 'Guadeloupe' }, - { code: 'GQ', label: 'Equatorial Guinea' }, - { code: 'GR', label: 'Greece' }, - { code: 'GS', label: 'South Georgia and the South Sandwich Islands' }, - { code: 'GT', label: 'Guatemala' }, - { code: 'GU', label: 'Guam' }, - { code: 'GW', label: 'Guinea-Bissau' }, - { code: 'GY', label: 'Guyana' }, - { code: 'HK', label: 'Hong Kong' }, - { code: 'HM', label: 'Heard Island and McDonald Islands' }, - { code: 'HN', label: 'Honduras' }, - { code: 'HR', label: 'Croatia' }, - { code: 'HT', label: 'Haiti' }, - { code: 'HU', label: 'Hungary' }, - { code: 'ID', label: 'Indonesia' }, - { code: 'IE', label: 'Ireland' }, - { code: 'IL', label: 'Israel' }, - { code: 'IM', label: 'Isle of Man' }, - { code: 'IN', label: 'India' }, - { code: 'IO', label: 'British Indian Ocean Territory' }, - { code: 'IQ', label: 'Iraq' }, - { code: 'IR', label: 'Iran, Islamic Republic of' }, - { code: 'IS', label: 'Iceland' }, - { code: 'IT', label: 'Italy' }, - { code: 'JE', label: 'Jersey' }, - { code: 'JM', label: 'Jamaica' }, - { code: 'JO', label: 'Jordan' }, - { code: 'JP', label: 'Japan', suggested: true }, - { code: 'KE', label: 'Kenya' }, - { code: 'KG', label: 'Kyrgyzstan' }, - { code: 'KH', label: 'Cambodia' }, - { code: 'KI', label: 'Kiribati' }, - { code: 'KM', label: 'Comoros' }, - { code: 'KN', label: 'Saint Kitts and Nevis' }, - { code: 'KP', label: "Korea, Democratic People's Republic of" }, - { code: 'KR', label: 'Korea, Republic of' }, - { code: 'KW', label: 'Kuwait' }, - { code: 'KY', label: 'Cayman Islands' }, - { code: 'KZ', label: 'Kazakhstan' }, - { code: 'LA', label: "Lao People's Democratic Republic" }, - { code: 'LB', label: 'Lebanon' }, - { code: 'LC', label: 'Saint Lucia' }, - { code: 'LI', label: 'Liechtenstein' }, - { code: 'LK', label: 'Sri Lanka' }, - { code: 'LR', label: 'Liberia' }, - { code: 'LS', label: 'Lesotho' }, - { code: 'LT', label: 'Lithuania' }, - { code: 'LU', label: 'Luxembourg' }, - { code: 'LV', label: 'Latvia' }, - { code: 'LY', label: 'Libya' }, - { code: 'MA', label: 'Morocco' }, - { code: 'MC', label: 'Monaco' }, - { code: 'MD', label: 'Moldova, Republic of' }, - { code: 'ME', label: 'Montenegro' }, - { code: 'MF', label: 'Saint Martin (French part)' }, - { code: 'MG', label: 'Madagascar' }, - { code: 'MH', label: 'Marshall Islands' }, - { code: 'MK', label: 'Macedonia, the Former Yugoslav Republic of' }, - { code: 'ML', label: 'Mali' }, - { code: 'MM', label: 'Myanmar' }, - { code: 'MN', label: 'Mongolia' }, - { code: 'MO', label: 'Macao' }, - { code: 'MP', label: 'Northern Mariana Islands' }, - { code: 'MQ', label: 'Martinique' }, - { code: 'MR', label: 'Mauritania' }, - { code: 'MS', label: 'Montserrat' }, - { code: 'MT', label: 'Malta' }, - { code: 'MU', label: 'Mauritius' }, - { code: 'MV', label: 'Maldives' }, - { code: 'MW', label: 'Malawi' }, - { code: 'MX', label: 'Mexico' }, - { code: 'MY', label: 'Malaysia' }, - { code: 'MZ', label: 'Mozambique' }, - { code: 'NA', label: 'Namibia' }, - { code: 'NC', label: 'New Caledonia' }, - { code: 'NE', label: 'Niger' }, - { code: 'NF', label: 'Norfolk Island' }, - { code: 'NG', label: 'Nigeria' }, - { code: 'NI', label: 'Nicaragua' }, - { code: 'NL', label: 'Netherlands' }, - { code: 'NO', label: 'Norway' }, - { code: 'NP', label: 'Nepal' }, - { code: 'NR', label: 'Nauru' }, - { code: 'NU', label: 'Niue' }, - { code: 'NZ', label: 'New Zealand' }, - { code: 'OM', label: 'Oman' }, - { code: 'PA', label: 'Panama' }, - { code: 'PE', label: 'Peru' }, - { code: 'PF', label: 'French Polynesia' }, - { code: 'PG', label: 'Papua New Guinea' }, - { code: 'PH', label: 'Philippines' }, - { code: 'PK', label: 'Pakistan' }, - { code: 'PL', label: 'Poland' }, - { code: 'PM', label: 'Saint Pierre and Miquelon' }, - { code: 'PN', label: 'Pitcairn' }, - { code: 'PR', label: 'Puerto Rico' }, - { code: 'PS', label: 'Palestine, State of' }, - { code: 'PT', label: 'Portugal' }, - { code: 'PW', label: 'Palau' }, - { code: 'PY', label: 'Paraguay' }, - { code: 'QA', label: 'Qatar' }, - { code: 'RE', label: 'Reunion' }, - { code: 'RO', label: 'Romania' }, - { code: 'RS', label: 'Serbia' }, - { code: 'RU', label: 'Russian Federation' }, - { code: 'RW', label: 'Rwanda' }, - { code: 'SA', label: 'Saudi Arabia' }, - { code: 'SB', label: 'Solomon Islands' }, - { code: 'SC', label: 'Seychelles' }, - { code: 'SD', label: 'Sudan' }, - { code: 'SE', label: 'Sweden' }, - { code: 'SG', label: 'Singapore' }, - { code: 'SH', label: 'Saint Helena' }, - { code: 'SI', label: 'Slovenia' }, - { code: 'SJ', label: 'Svalbard and Jan Mayen' }, - { code: 'SK', label: 'Slovakia' }, - { code: 'SL', label: 'Sierra Leone' }, - { code: 'SM', label: 'San Marino' }, - { code: 'SN', label: 'Senegal' }, - { code: 'SO', label: 'Somalia' }, - { code: 'SR', label: 'Suriname' }, - { code: 'SS', label: 'South Sudan' }, - { code: 'ST', label: 'Sao Tome and Principe' }, - { code: 'SV', label: 'El Salvador' }, - { code: 'SX', label: 'Sint Maarten (Dutch part)' }, - { code: 'SY', label: 'Syrian Arab Republic' }, - { code: 'SZ', label: 'Swaziland' }, - { code: 'TC', label: 'Turks and Caicos Islands' }, - { code: 'TD', label: 'Chad' }, - { code: 'TF', label: 'French Southern Territories' }, - { code: 'TG', label: 'Togo' }, - { code: 'TH', label: 'Thailand' }, - { code: 'TJ', label: 'Tajikistan' }, - { code: 'TK', label: 'Tokelau' }, - { code: 'TL', label: 'Timor-Leste' }, - { code: 'TM', label: 'Turkmenistan' }, - { code: 'TN', label: 'Tunisia' }, - { code: 'TO', label: 'Tonga' }, - { code: 'TR', label: 'Turkey' }, - { code: 'TT', label: 'Trinidad and Tobago' }, - { code: 'TV', label: 'Tuvalu' }, - { code: 'TW', label: 'Taiwan, Province of China' }, - { code: 'TZ', label: 'United Republic of Tanzania' }, - { code: 'UA', label: 'Ukraine' }, - { code: 'UG', label: 'Uganda' }, - { code: 'US', label: 'United States', suggested: true }, - { code: 'UY', label: 'Uruguay' }, - { code: 'UZ', label: 'Uzbekistan' }, - { code: 'VA', label: 'Holy See (Vatican City State)' }, - { code: 'VC', label: 'Saint Vincent and the Grenadines' }, - { code: 'VE', label: 'Venezuela' }, - { code: 'VG', label: 'British Virgin Islands' }, - { code: 'VI', label: 'US Virgin Islands' }, - { code: 'VN', label: 'Vietnam' }, - { code: 'VU', label: 'Vanuatu' }, - { code: 'WF', label: 'Wallis and Futuna' }, - { code: 'WS', label: 'Samoa' }, - { code: 'XK', label: 'Kosovo' }, - { code: 'YE', label: 'Yemen' }, - { code: 'YT', label: 'Mayotte' }, - { code: 'ZA', label: 'South Africa' }, - { code: 'ZM', label: 'Zambia' }, - { code: 'ZW', label: 'Zimbabwe' }, -]; \ No newline at end of file + { code: "AD", label: "Andorra" }, + { code: "AE", label: "United Arab Emirates" }, + { code: "AF", label: "Afghanistan" }, + { code: "AG", label: "Antigua and Barbuda" }, + { code: "AI", label: "Anguilla" }, + { code: "AL", label: "Albania" }, + { code: "AM", label: "Armenia" }, + { code: "AO", label: "Angola" }, + { code: "AQ", label: "Antarctica" }, + { code: "AR", label: "Argentina" }, + { code: "AS", label: "American Samoa" }, + { code: "AT", label: "Austria" }, + { code: "AU", label: "Australia", suggested: true }, + { code: "AW", label: "Aruba" }, + { code: "AX", label: "Alland Islands" }, + { code: "AZ", label: "Azerbaijan" }, + { code: "BA", label: "Bosnia and Herzegovina" }, + { code: "BB", label: "Barbados" }, + { code: "BD", label: "Bangladesh" }, + { code: "BE", label: "Belgium" }, + { code: "BF", label: "Burkina Faso" }, + { code: "BG", label: "Bulgaria" }, + { code: "BH", label: "Bahrain" }, + { code: "BI", label: "Burundi" }, + { code: "BJ", label: "Benin" }, + { code: "BL", label: "Saint Barthelemy" }, + { code: "BM", label: "Bermuda" }, + { code: "BN", label: "Brunei Darussalam" }, + { code: "BO", label: "Bolivia" }, + { code: "BR", label: "Brazil" }, + { code: "BS", label: "Bahamas" }, + { code: "BT", label: "Bhutan" }, + { code: "BV", label: "Bouvet Island" }, + { code: "BW", label: "Botswana" }, + { code: "BY", label: "Belarus" }, + { code: "BZ", label: "Belize" }, + { code: "CA", label: "Canada", suggested: true }, + { code: "CC", label: "Cocos (Keeling) Islands" }, + { code: "CD", label: "Congo, Democratic Republic of the" }, + { code: "CF", label: "Central African Republic" }, + { code: "CG", label: "Congo, Republic of the" }, + { code: "CH", label: "Switzerland" }, + { code: "CI", label: "Cote d'Ivoire" }, + { code: "CK", label: "Cook Islands" }, + { code: "CL", label: "Chile" }, + { code: "CM", label: "Cameroon" }, + { code: "CN", label: "China" }, + { code: "CO", label: "Colombia" }, + { code: "CR", label: "Costa Rica" }, + { code: "CU", label: "Cuba" }, + { code: "CV", label: "Cape Verde" }, + { code: "CW", label: "Curacao" }, + { code: "CX", label: "Christmas Island" }, + { code: "CY", label: "Cyprus" }, + { code: "CZ", label: "Czech Republic" }, + { code: "DE", label: "Germany", suggested: true }, + { code: "DJ", label: "Djibouti" }, + { code: "DK", label: "Denmark" }, + { code: "DM", label: "Dominica" }, + { code: "DO", label: "Dominican Republic" }, + { code: "DZ", label: "Algeria" }, + { code: "EC", label: "Ecuador" }, + { code: "EE", label: "Estonia" }, + { code: "EG", label: "Egypt" }, + { code: "EH", label: "Western Sahara" }, + { code: "ER", label: "Eritrea" }, + { code: "ES", label: "Spain" }, + { code: "ET", label: "Ethiopia" }, + { code: "FI", label: "Finland" }, + { code: "FJ", label: "Fiji" }, + { code: "FK", label: "Falkland Islands (Malvinas)" }, + { code: "FM", label: "Micronesia, Federated States of" }, + { code: "FO", label: "Faroe Islands" }, + { code: "FR", label: "France", suggested: true }, + { code: "GA", label: "Gabon" }, + { code: "GB", label: "United Kingdom" }, + { code: "GD", label: "Grenada" }, + { code: "GE", label: "Georgia" }, + { code: "GF", label: "French Guiana" }, + { code: "GG", label: "Guernsey" }, + { code: "GH", label: "Ghana" }, + { code: "GI", label: "Gibraltar" }, + { code: "GL", label: "Greenland" }, + { code: "GM", label: "Gambia" }, + { code: "GN", label: "Guinea" }, + { code: "GP", label: "Guadeloupe" }, + { code: "GQ", label: "Equatorial Guinea" }, + { code: "GR", label: "Greece" }, + { code: "GS", label: "South Georgia and the South Sandwich Islands" }, + { code: "GT", label: "Guatemala" }, + { code: "GU", label: "Guam" }, + { code: "GW", label: "Guinea-Bissau" }, + { code: "GY", label: "Guyana" }, + { code: "HK", label: "Hong Kong" }, + { code: "HM", label: "Heard Island and McDonald Islands" }, + { code: "HN", label: "Honduras" }, + { code: "HR", label: "Croatia" }, + { code: "HT", label: "Haiti" }, + { code: "HU", label: "Hungary" }, + { code: "ID", label: "Indonesia" }, + { code: "IE", label: "Ireland" }, + { code: "IL", label: "Israel" }, + { code: "IM", label: "Isle of Man" }, + { code: "IN", label: "India" }, + { code: "IO", label: "British Indian Ocean Territory" }, + { code: "IQ", label: "Iraq" }, + { code: "IR", label: "Iran, Islamic Republic of" }, + { code: "IS", label: "Iceland" }, + { code: "IT", label: "Italy" }, + { code: "JE", label: "Jersey" }, + { code: "JM", label: "Jamaica" }, + { code: "JO", label: "Jordan" }, + { code: "JP", label: "Japan", suggested: true }, + { code: "KE", label: "Kenya" }, + { code: "KG", label: "Kyrgyzstan" }, + { code: "KH", label: "Cambodia" }, + { code: "KI", label: "Kiribati" }, + { code: "KM", label: "Comoros" }, + { code: "KN", label: "Saint Kitts and Nevis" }, + { code: "KP", label: "Korea, Democratic People's Republic of" }, + { code: "KR", label: "Korea, Republic of" }, + { code: "KW", label: "Kuwait" }, + { code: "KY", label: "Cayman Islands" }, + { code: "KZ", label: "Kazakhstan" }, + { code: "LA", label: "Lao People's Democratic Republic" }, + { code: "LB", label: "Lebanon" }, + { code: "LC", label: "Saint Lucia" }, + { code: "LI", label: "Liechtenstein" }, + { code: "LK", label: "Sri Lanka" }, + { code: "LR", label: "Liberia" }, + { code: "LS", label: "Lesotho" }, + { code: "LT", label: "Lithuania" }, + { code: "LU", label: "Luxembourg" }, + { code: "LV", label: "Latvia" }, + { code: "LY", label: "Libya" }, + { code: "MA", label: "Morocco" }, + { code: "MC", label: "Monaco" }, + { code: "MD", label: "Moldova, Republic of" }, + { code: "ME", label: "Montenegro" }, + { code: "MF", label: "Saint Martin (French part)" }, + { code: "MG", label: "Madagascar" }, + { code: "MH", label: "Marshall Islands" }, + { code: "MK", label: "Macedonia, the Former Yugoslav Republic of" }, + { code: "ML", label: "Mali" }, + { code: "MM", label: "Myanmar" }, + { code: "MN", label: "Mongolia" }, + { code: "MO", label: "Macao" }, + { code: "MP", label: "Northern Mariana Islands" }, + { code: "MQ", label: "Martinique" }, + { code: "MR", label: "Mauritania" }, + { code: "MS", label: "Montserrat" }, + { code: "MT", label: "Malta" }, + { code: "MU", label: "Mauritius" }, + { code: "MV", label: "Maldives" }, + { code: "MW", label: "Malawi" }, + { code: "MX", label: "Mexico" }, + { code: "MY", label: "Malaysia" }, + { code: "MZ", label: "Mozambique" }, + { code: "NA", label: "Namibia" }, + { code: "NC", label: "New Caledonia" }, + { code: "NE", label: "Niger" }, + { code: "NF", label: "Norfolk Island" }, + { code: "NG", label: "Nigeria" }, + { code: "NI", label: "Nicaragua" }, + { code: "NL", label: "Netherlands" }, + { code: "NO", label: "Norway" }, + { code: "NP", label: "Nepal" }, + { code: "NR", label: "Nauru" }, + { code: "NU", label: "Niue" }, + { code: "NZ", label: "New Zealand" }, + { code: "OM", label: "Oman" }, + { code: "PA", label: "Panama" }, + { code: "PE", label: "Peru" }, + { code: "PF", label: "French Polynesia" }, + { code: "PG", label: "Papua New Guinea" }, + { code: "PH", label: "Philippines" }, + { code: "PK", label: "Pakistan" }, + { code: "PL", label: "Poland" }, + { code: "PM", label: "Saint Pierre and Miquelon" }, + { code: "PN", label: "Pitcairn" }, + { code: "PR", label: "Puerto Rico" }, + { code: "PS", label: "Palestine, State of" }, + { code: "PT", label: "Portugal" }, + { code: "PW", label: "Palau" }, + { code: "PY", label: "Paraguay" }, + { code: "QA", label: "Qatar" }, + { code: "RE", label: "Reunion" }, + { code: "RO", label: "Romania" }, + { code: "RS", label: "Serbia" }, + { code: "RU", label: "Russian Federation" }, + { code: "RW", label: "Rwanda" }, + { code: "SA", label: "Saudi Arabia" }, + { code: "SB", label: "Solomon Islands" }, + { code: "SC", label: "Seychelles" }, + { code: "SD", label: "Sudan" }, + { code: "SE", label: "Sweden" }, + { code: "SG", label: "Singapore" }, + { code: "SH", label: "Saint Helena" }, + { code: "SI", label: "Slovenia" }, + { code: "SJ", label: "Svalbard and Jan Mayen" }, + { code: "SK", label: "Slovakia" }, + { code: "SL", label: "Sierra Leone" }, + { code: "SM", label: "San Marino" }, + { code: "SN", label: "Senegal" }, + { code: "SO", label: "Somalia" }, + { code: "SR", label: "Suriname" }, + { code: "SS", label: "South Sudan" }, + { code: "ST", label: "Sao Tome and Principe" }, + { code: "SV", label: "El Salvador" }, + { code: "SX", label: "Sint Maarten (Dutch part)" }, + { code: "SY", label: "Syrian Arab Republic" }, + { code: "SZ", label: "Swaziland" }, + { code: "TC", label: "Turks and Caicos Islands" }, + { code: "TD", label: "Chad" }, + { code: "TF", label: "French Southern Territories" }, + { code: "TG", label: "Togo" }, + { code: "TH", label: "Thailand" }, + { code: "TJ", label: "Tajikistan" }, + { code: "TK", label: "Tokelau" }, + { code: "TL", label: "Timor-Leste" }, + { code: "TM", label: "Turkmenistan" }, + { code: "TN", label: "Tunisia" }, + { code: "TO", label: "Tonga" }, + { code: "TR", label: "Turkey" }, + { code: "TT", label: "Trinidad and Tobago" }, + { code: "TV", label: "Tuvalu" }, + { code: "TW", label: "Taiwan, Province of China" }, + { code: "TZ", label: "United Republic of Tanzania" }, + { code: "UA", label: "Ukraine" }, + { code: "UG", label: "Uganda" }, + { code: "US", label: "United States", suggested: true }, + { code: "UY", label: "Uruguay" }, + { code: "UZ", label: "Uzbekistan" }, + { code: "VA", label: "Holy See (Vatican City State)" }, + { code: "VC", label: "Saint Vincent and the Grenadines" }, + { code: "VE", label: "Venezuela" }, + { code: "VG", label: "British Virgin Islands" }, + { code: "VI", label: "US Virgin Islands" }, + { code: "VN", label: "Vietnam" }, + { code: "VU", label: "Vanuatu" }, + { code: "WF", label: "Wallis and Futuna" }, + { code: "WS", label: "Samoa" }, + { code: "XK", label: "Kosovo" }, + { code: "YE", label: "Yemen" }, + { code: "YT", label: "Mayotte" }, + { code: "ZA", label: "South Africa" }, + { code: "ZM", label: "Zambia" }, + { code: "ZW", label: "Zimbabwe" }, +]; diff --git a/jams-react-client/src/components/CreateAdmin/CreateAdmin.js b/jams-react-client/src/components/CreateAdmin/CreateAdmin.js index dcb8af4d851f0014462d57786bb0bfb27cd86c4f..31951800569099dd4deacfa16e727c8e03e27486 100644 --- a/jams-react-client/src/components/CreateAdmin/CreateAdmin.js +++ b/jams-react-client/src/components/CreateAdmin/CreateAdmin.js @@ -51,15 +51,41 @@ export default function CreateAdmin(props) { }, validationSchema: Yup.object({ username: Yup.string() - .max(60, i18next.t("must_be_60_characters_or_less", "Must be 60 characters or less")) + .max( + 60, + i18next.t( + "must_be_60_characters_or_less", + "Must be 60 characters or less" + ) + ) .required(i18next.t("username_is_required", "Username is required!")), password: Yup.string() - .max(50, i18next.t("must_be_50_characters_or_less", "Must be 50 characters or less")) + .max( + 50, + i18next.t( + "must_be_50_characters_or_less", + "Must be 50 characters or less" + ) + ) .required("Password is required"), confirmPassword: Yup.string() - .oneOf([Yup.ref("password"), null], i18next.t("password_must_match", "Passwords must match")) - .max(50, i18next.t("must_be_50_characters_or_less", "Must be 50 characters or less")) - .required(i18next.t("password_confirmation_required", "Password confirmation is required.")), + .oneOf( + [Yup.ref("password"), null], + i18next.t("password_must_match", "Passwords must match") + ) + .max( + 50, + i18next.t( + "must_be_50_characters_or_less", + "Must be 50 characters or less" + ) + ) + .required( + i18next.t( + "password_confirmation_required", + "Password confirmation is required." + ) + ), }), onSubmit: (values) => { @@ -82,13 +108,13 @@ export default function CreateAdmin(props) { password: values.password, }; axios(configApiCall(api_path_post_install_admin, "PUT", jsonData, null)) - .then((response) => { - createAdminCallBackHandler(response); - }) - .catch((error) => { - props.setErrorMessage(error); - props.setError(true); - }); + .then((response) => { + createAdminCallBackHandler(response); + }) + .catch((error) => { + props.setErrorMessage(error); + props.setError(true); + }); } return ( diff --git a/jams-react-client/src/components/CustomButtons/Button.js b/jams-react-client/src/components/CustomButtons/Button.js index 9cf835f8d705b75d56d3aa99ba814a47a9659b7e..166cb8e85095ac15b05baa782518381f8aa652fd 100644 --- a/jams-react-client/src/components/CustomButtons/Button.js +++ b/jams-react-client/src/components/CustomButtons/Button.js @@ -38,7 +38,7 @@ export default function RegularButton(props) { [classes.block]: block, [classes.link]: link, [classes.justIcon]: justIcon, - [className]: className + [className]: className, }); return ( <Button {...rest} classes={muiClasses} className={btnClasses}> @@ -56,7 +56,7 @@ RegularButton.propTypes = { "danger", "rose", "white", - "transparent" + "transparent", ]), size: PropTypes.oneOf(["sm", "lg"]), simple: PropTypes.bool, @@ -68,5 +68,5 @@ RegularButton.propTypes = { className: PropTypes.string, // use this to pass the classes props from Material-UI muiClasses: PropTypes.object, - children: PropTypes.node + children: PropTypes.node, }; diff --git a/jams-react-client/src/components/CustomInput/CustomInput.js b/jams-react-client/src/components/CustomInput/CustomInput.js index 782d38ad054d54fb3e4ee2ce1da1e2052873264c..59e179573c82b68c8d4ac7d9a40c35d4a8665287 100644 --- a/jams-react-client/src/components/CustomInput/CustomInput.js +++ b/jams-react-client/src/components/CustomInput/CustomInput.js @@ -23,20 +23,20 @@ export default function CustomInput(props) { labelProps, inputProps, error, - success + success, } = props; const labelClasses = classNames({ [" " + classes.labelRootError]: error, - [" " + classes.labelRootSuccess]: success && !error + [" " + classes.labelRootSuccess]: success && !error, }); const underlineClasses = classNames({ [classes.underlineError]: error, [classes.underlineSuccess]: success && !error, - [classes.underline]: true + [classes.underline]: true, }); const marginTop = classNames({ - [classes.marginTop]: labelText === undefined + [classes.marginTop]: labelText === undefined, }); return ( <FormControl @@ -56,7 +56,7 @@ export default function CustomInput(props) { classes={{ root: marginTop, disabled: classes.disabled, - underline: underlineClasses + underline: underlineClasses, }} id={id} {...inputProps} @@ -77,5 +77,5 @@ CustomInput.propTypes = { inputProps: PropTypes.object, formControlProps: PropTypes.object, error: PropTypes.bool, - success: PropTypes.bool + success: PropTypes.bool, }; diff --git a/jams-react-client/src/components/CustomPopupState/CustomPopupState.js b/jams-react-client/src/components/CustomPopupState/CustomPopupState.js index 9e1c44eaccbcf9dc6a9b5add868f2776dfcf79b6..5ee4948b01aed00729d63f6c798279e4589aabdc 100644 --- a/jams-react-client/src/components/CustomPopupState/CustomPopupState.js +++ b/jams-react-client/src/components/CustomPopupState/CustomPopupState.js @@ -1,39 +1,40 @@ -import React from 'react'; -import InfoIcon from '@material-ui/icons/Info'; -import Popover from '@material-ui/core/Popover'; -import PopupState, { bindTrigger, bindPopover } from 'material-ui-popup-state'; -import IconButton from '@material-ui/core/IconButton'; -import Box from '@material-ui/core/Box'; -import Typography from '@material-ui/core/Typography'; - +import React from "react"; +import InfoIcon from "@material-ui/icons/Info"; +import Popover from "@material-ui/core/Popover"; +import PopupState, { bindTrigger, bindPopover } from "material-ui-popup-state"; +import IconButton from "@material-ui/core/IconButton"; +import Box from "@material-ui/core/Box"; +import Typography from "@material-ui/core/Typography"; export default function CustomPopupState(props) { - - return( -<IconButton> - -<PopupState variant="popover" popupId="demo-popup-popover"> - {(popupState) => ( - <div> - <InfoIcon color="disabled" fontSize="small" {...bindTrigger(popupState)} /> - <Popover - {...bindPopover(popupState)} - anchorOrigin={{ - vertical: 'top', - horizontal: 'left', - }} - transformOrigin={{ - vertical: 'bottom', - horizontal: 'left', - }} - > - <Box p={1}> - <Typography>{props.message}</Typography> - </Box> - </Popover> - </div> - )} -</PopupState> -</IconButton> - ); -} \ No newline at end of file + return ( + <IconButton> + <PopupState variant="popover" popupId="demo-popup-popover"> + {(popupState) => ( + <div> + <InfoIcon + color="disabled" + fontSize="small" + {...bindTrigger(popupState)} + /> + <Popover + {...bindPopover(popupState)} + anchorOrigin={{ + vertical: "top", + horizontal: "left", + }} + transformOrigin={{ + vertical: "bottom", + horizontal: "left", + }} + > + <Box p={1}> + <Typography>{props.message}</Typography> + </Box> + </Popover> + </div> + )} + </PopupState> + </IconButton> + ); +} diff --git a/jams-react-client/src/components/CustomTabs/CustomTabs.js b/jams-react-client/src/components/CustomTabs/CustomTabs.js index 1d153fa856296466a1e8892a32df1be6eadfa991..6c151f2a116894b0583d62d6908b3204a986c2fb 100644 --- a/jams-react-client/src/components/CustomTabs/CustomTabs.js +++ b/jams-react-client/src/components/CustomTabs/CustomTabs.js @@ -26,7 +26,7 @@ export default function CustomTabs(props) { const { headerColor, plainTabs, tabs, title, rtlActive } = props; const cardTitle = classNames({ [classes.cardTitle]: true, - [classes.cardTitleRTL]: rtlActive + [classes.cardTitleRTL]: rtlActive, }); return ( <Card plain={plainTabs}> @@ -38,7 +38,7 @@ export default function CustomTabs(props) { classes={{ root: classes.tabsRoot, indicator: classes.displayNone, - scrollButtons: classes.displayNone + scrollButtons: classes.displayNone, }} variant="scrollable" scrollButtons="auto" @@ -47,7 +47,7 @@ export default function CustomTabs(props) { var icon = {}; if (prop.tabIcon) { icon = { - icon: <prop.tabIcon /> + icon: <prop.tabIcon />, }; } return ( @@ -55,7 +55,7 @@ export default function CustomTabs(props) { classes={{ root: classes.tabRootButton, selected: classes.tabSelected, - wrapper: classes.tabWrapper + wrapper: classes.tabWrapper, }} key={key} label={prop.tabName} @@ -84,16 +84,16 @@ CustomTabs.propTypes = { "danger", "info", "primary", - "rose" + "rose", ]), title: PropTypes.string, tabs: PropTypes.arrayOf( PropTypes.shape({ tabName: PropTypes.string.isRequired, tabIcon: PropTypes.object, - tabContent: PropTypes.node.isRequired + tabContent: PropTypes.node.isRequired, }) ), rtlActive: PropTypes.bool, - plainTabs: PropTypes.bool + plainTabs: PropTypes.bool, }; diff --git a/jams-react-client/src/components/CustomizedSteppers/CustomizedSteppers.js b/jams-react-client/src/components/CustomizedSteppers/CustomizedSteppers.js index 71518121ee91ade1419c4c277d77d38e8d67bc84..cf12276be8719757ca7f636c599453e99b94118c 100644 --- a/jams-react-client/src/components/CustomizedSteppers/CustomizedSteppers.js +++ b/jams-react-client/src/components/CustomizedSteppers/CustomizedSteppers.js @@ -1,35 +1,35 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { makeStyles } from '@material-ui/core/styles'; -import clsx from 'clsx'; -import Stepper from '@material-ui/core/Stepper'; -import Step from '@material-ui/core/Step'; -import StepLabel from '@material-ui/core/StepLabel'; -import Check from '@material-ui/icons/Check'; -import SettingsIcon from '@material-ui/icons/Settings'; -import GroupAddIcon from '@material-ui/icons/GroupAdd'; -import VideoLabelIcon from '@material-ui/icons/VideoLabel'; +import React from "react"; +import PropTypes from "prop-types"; +import { makeStyles } from "@material-ui/core/styles"; +import clsx from "clsx"; +import Stepper from "@material-ui/core/Stepper"; +import Step from "@material-ui/core/Step"; +import StepLabel from "@material-ui/core/StepLabel"; +import Check from "@material-ui/icons/Check"; +import SettingsIcon from "@material-ui/icons/Settings"; +import GroupAddIcon from "@material-ui/icons/GroupAdd"; +import VideoLabelIcon from "@material-ui/icons/VideoLabel"; -import i18next from 'i18next'; +import i18next from "i18next"; const useQontoStepIconStyles = makeStyles({ root: { - color: '#eaeaf0', - display: 'flex', + color: "#eaeaf0", + display: "flex", height: 22, - alignItems: 'center', + alignItems: "center", }, active: { - color: '#784af4', + color: "#784af4", }, circle: { width: 8, height: 8, - borderRadius: '50%', - backgroundColor: 'currentColor', + borderRadius: "50%", + backgroundColor: "currentColor", }, completed: { - color: '#784af4', + color: "#784af4", zIndex: 1, fontSize: 18, }, @@ -45,7 +45,11 @@ function QontoStepIcon(props) { [classes.active]: active, })} > - {completed ? <Check className={classes.completed} /> : <div className={classes.circle} />} + {completed ? ( + <Check className={classes.completed} /> + ) : ( + <div className={classes.circle} /> + )} </div> ); } @@ -63,24 +67,24 @@ QontoStepIcon.propTypes = { const useColorlibStepIconStyles = makeStyles({ root: { - backgroundColor: '#ccc', + backgroundColor: "#ccc", zIndex: 1, - color: '#fff', + color: "#fff", width: 50, height: 50, - display: 'flex', - borderRadius: '50%', - justifyContent: 'center', - alignItems: 'center', + display: "flex", + borderRadius: "50%", + justifyContent: "center", + alignItems: "center", }, active: { backgroundImage: - 'linear-gradient( 136deg, rgb(242,113,33) 0%, rgb(233,64,87) 50%, rgb(138,35,135) 100%)', - boxShadow: '0 4px 10px 0 rgba(0,0,0,.25)', + "linear-gradient( 136deg, rgb(242,113,33) 0%, rgb(233,64,87) 50%, rgb(138,35,135) 100%)", + boxShadow: "0 4px 10px 0 rgba(0,0,0,.25)", }, completed: { backgroundImage: - 'linear-gradient( 136deg, rgb(242,113,33) 0%, rgb(233,64,87) 50%, rgb(138,35,135) 100%)', + "linear-gradient( 136deg, rgb(242,113,33) 0%, rgb(233,64,87) 50%, rgb(138,35,135) 100%)", }, }); @@ -123,7 +127,7 @@ ColorlibStepIcon.propTypes = { const useStyles = makeStyles((theme) => ({ root: { - width: '100%', + width: "100%", }, button: { marginRight: theme.spacing(1), @@ -135,7 +139,12 @@ const useStyles = makeStyles((theme) => ({ })); function getSteps() { - return [i18next.t("create_administrator_user", 'Create Administrator User'), i18next.t("certificate_authority_setup", 'Certificate Authority Setup'), i18next.t("identity_management", 'Identity Management'), i18next.t("server_parameters", 'Server Parameters')]; + return [ + i18next.t("create_administrator_user", "Create Administrator User"), + i18next.t("certificate_authority_setup", "Certificate Authority Setup"), + i18next.t("identity_management", "Identity Management"), + i18next.t("server_parameters", "Server Parameters"), + ]; } export default function CustomizedSteppers(props) { diff --git a/jams-react-client/src/components/Devices/Devices.js b/jams-react-client/src/components/Devices/Devices.js index 9f05363399317e79b188c669897d49e91cc1a654..06793004d3aeb2a343699527b50dc848813577b5 100755 --- a/jams-react-client/src/components/Devices/Devices.js +++ b/jams-react-client/src/components/Devices/Devices.js @@ -1,36 +1,38 @@ -import React, {useEffect} from "react"; +import React, { useEffect } from "react"; import { useHistory } from "react-router-dom"; import classnames from "classnames"; -import {Formik, Field} from "formik"; +import { Formik, Field } from "formik"; // @material-ui/core components import { makeStyles } from "@material-ui/core/styles"; import Tooltip from "@material-ui/core/Tooltip"; import IconButton from "@material-ui/core/IconButton"; import Button from "components/CustomButtons/Button.js"; import Table from "@material-ui/core/Table"; -import TableHead from '@material-ui/core/TableHead'; +import TableHead from "@material-ui/core/TableHead"; import TableRow from "@material-ui/core/TableRow"; import TableBody from "@material-ui/core/TableBody"; import TableCell from "@material-ui/core/TableCell"; -import Dialog from '@material-ui/core/Dialog'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogContent from '@material-ui/core/DialogContent'; -import DialogContentText from '@material-ui/core/DialogContentText'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import TextField from '@material-ui/core/TextField'; +import Dialog from "@material-ui/core/Dialog"; +import DialogActions from "@material-ui/core/DialogActions"; +import DialogContent from "@material-ui/core/DialogContent"; +import DialogContentText from "@material-ui/core/DialogContentText"; +import DialogTitle from "@material-ui/core/DialogTitle"; +import TextField from "@material-ui/core/TextField"; // @material-ui/icons import Edit from "@material-ui/icons/Edit"; import Close from "@material-ui/icons/Close"; // core components import styles from "assets/jss/material-dashboard-react/components/devicesStyle.js"; -import auth from "auth.js" +import auth from "auth.js"; import configApiCall from "api.js"; import { - api_path_delete_admin_device_revoke, api_path_delete_auth_device_revoke, - api_path_get_admin_devices, - api_path_get_auth_devices, api_path_rename_device + api_path_delete_admin_device_revoke, + api_path_delete_auth_device_revoke, + api_path_get_admin_devices, + api_path_get_auth_devices, + api_path_rename_device, } from "../../globalUrls"; import axios from "axios"; @@ -39,278 +41,359 @@ import i18next from "i18next"; const useStyles = makeStyles(styles); export default function Devices(props) { - const classes = useStyles(); - const history = useHistory(); + const classes = useStyles(); + const history = useHistory(); - const [devices, setDevices] = React.useState([]) - const [selectedDevice, setSelectedDevice]= React.useState({}); - const [displayName, setDisplayName] = React.useState("") - const [openEdit, setOpenEdit] = React.useState(false); - const [openRevoke, setOpenRevoke] = React.useState(false); - const userData = { - "username": props.username - }; + const [devices, setDevices] = React.useState([]); + const [selectedDevice, setSelectedDevice] = React.useState({}); + const [displayName, setDisplayName] = React.useState(""); + const [openEdit, setOpenEdit] = React.useState(false); + const [openRevoke, setOpenRevoke] = React.useState(false); + const userData = { + username: props.username, + }; - useEffect(() => { - auth.checkDirectoryType(() => { - if(auth.hasAdminScope()){ - axios(configApiCall(api_path_get_admin_devices, 'GET', userData, null)).then((response)=>{ - if(response.data.length == 0) { - setDevices([]); - }else{ - var resultSet = JSON.parse(response.data.replace(/\s+/g, ' ').trim()); - setDevices(resultSet) - } - }).catch((error) =>{ - console.log(error); - if (error.response.status === 401) { - auth.authenticated = false; - history.push("/signin"); - } - }); + useEffect(() => { + auth.checkDirectoryType(() => { + if (auth.hasAdminScope()) { + axios(configApiCall(api_path_get_admin_devices, "GET", userData, null)) + .then((response) => { + if (response.data.length == 0) { + setDevices([]); + } else { + var resultSet = JSON.parse( + response.data.replace(/\s+/g, " ").trim() + ); + setDevices(resultSet); } - else{ - axios(configApiCall(api_path_get_auth_devices, 'GET', null, null)).then((response)=>{ - if(response.data.length == 0) { - setDevices([]); - }else{ - var resultSet = JSON.parse(response.data.replace(/\s+/g, ' ').trim()); - setDevices(resultSet) - } - }).catch((error) =>{ - if (error.response.status === 401) { - auth.authenticated = false; - history.push("/signin"); - } - }); + }) + .catch((error) => { + console.log(error); + if (error.response.status === 401) { + auth.authenticated = false; + history.push("/signin"); } - }) - }, [selectedDevice]); - - function getDeviceStatus(device) { - if (!(device.revoked)) { - return 'Active'; - } - else { - return 'Revoked'; + }); + } else { + axios(configApiCall(api_path_get_auth_devices, "GET", null, null)) + .then((response) => { + if (response.data.length == 0) { + setDevices([]); + } else { + var resultSet = JSON.parse( + response.data.replace(/\s+/g, " ").trim() + ); + setDevices(resultSet); + } + }) + .catch((error) => { + if (error.response.status === 401) { + auth.authenticated = false; + history.push("/signin"); + } + }); + } + }); + }, [selectedDevice]); - } + function getDeviceStatus(device) { + if (!device.revoked) { + return "Active"; + } else { + return "Revoked"; } + } - function getDeviceId(device) { - return device.deviceId; - } + function getDeviceId(device) { + return device.deviceId; + } - const handleClickEdit = (e, device) => { - e.preventDefault(); - setOpenEdit(true); - setSelectedDevice(device); - } + const handleClickEdit = (e, device) => { + e.preventDefault(); + setOpenEdit(true); + setSelectedDevice(device); + }; - const handleClickRevoke = (e, device) => { - e.preventDefault(); - setOpenRevoke(true); - setSelectedDevice(device); - } + const handleClickRevoke = (e, device) => { + e.preventDefault(); + setOpenRevoke(true); + setSelectedDevice(device); + }; - const handleClose = () => { - setOpenEdit(false); - setOpenRevoke(false); - setSelectedDevice({}); - } - const handleCancel = () => { - setOpenEdit(false); - setOpenRevoke(false); - setSelectedDevice({}); - } + const handleClose = () => { + setOpenEdit(false); + setOpenRevoke(false); + setSelectedDevice({}); + }; + const handleCancel = () => { + setOpenEdit(false); + setOpenRevoke(false); + setSelectedDevice({}); + }; - const handleUpdate = () => { - if(auth.hasAdminScope()){ - const data = { - username: props.username, - deviceId: selectedDevice.deviceId, - deviceName: displayName - } - axios(configApiCall(api_path_delete_admin_device_revoke+"?username="+ data.username+"&deviceId="+data.deviceId+"&deviceName="+data.deviceName, 'PUT', null, null)).then((response)=>{ - setSelectedDevice({}); - setOpenEdit(false); - } - ).catch((error) =>{ - console.log(error); - }); - } - else{ - const data = { - deviceName: displayName - } - axios(configApiCall(api_path_rename_device+"/"+selectedDevice.deviceId+ "?deviceName="+ data.deviceName, 'PUT', null, null)).then((response)=>{ - setSelectedDevice({}); - setOpenEdit(false); - } - ).catch((error) =>{ - console.log(error); - }); - } + const handleUpdate = () => { + if (auth.hasAdminScope()) { + const data = { + username: props.username, + deviceId: selectedDevice.deviceId, + deviceName: displayName, + }; + axios( + configApiCall( + api_path_delete_admin_device_revoke + + "?username=" + + data.username + + "&deviceId=" + + data.deviceId + + "&deviceName=" + + data.deviceName, + "PUT", + null, + null + ) + ) + .then((response) => { + setSelectedDevice({}); + setOpenEdit(false); + }) + .catch((error) => { + console.log(error); + }); + } else { + const data = { + deviceName: displayName, + }; + axios( + configApiCall( + api_path_rename_device + + "/" + + selectedDevice.deviceId + + "?deviceName=" + + data.deviceName, + "PUT", + null, + null + ) + ) + .then((response) => { + setSelectedDevice({}); + setOpenEdit(false); + }) + .catch((error) => { + console.log(error); + }); } + }; - const handleDeviceRevoke = () => { - if(auth.hasAdminScope()){ - const data = { - username: props.username, - deviceId: selectedDevice.deviceId, - } - axios(configApiCall(api_path_delete_admin_device_revoke+"?username="+ data.username+"&deviceId="+data.deviceId, 'DELETE', null, null)).then((response)=>{ - setSelectedDevice({}); - setOpenRevoke(false); - } - ).catch((error) =>{ - console.log(error); - }); - } - else{ - - axios(configApiCall(api_path_delete_auth_device_revoke+"/"+selectedDevice.deviceId, 'DELETE', null, null)).then((response)=>{ - setSelectedDevice({}); - setOpenRevoke(false); - } - ).catch((error) =>{ - console.log(error); - }); - } + const handleDeviceRevoke = () => { + if (auth.hasAdminScope()) { + const data = { + username: props.username, + deviceId: selectedDevice.deviceId, + }; + axios( + configApiCall( + api_path_delete_admin_device_revoke + + "?username=" + + data.username + + "&deviceId=" + + data.deviceId, + "DELETE", + null, + null + ) + ) + .then((response) => { + setSelectedDevice({}); + setOpenRevoke(false); + }) + .catch((error) => { + console.log(error); + }); + } else { + axios( + configApiCall( + api_path_delete_auth_device_revoke + "/" + selectedDevice.deviceId, + "DELETE", + null, + null + ) + ) + .then((response) => { + setSelectedDevice({}); + setOpenRevoke(false); + }) + .catch((error) => { + console.log(error); + }); } + }; - /** - * Formik Validation - */ - const validateDisplayName = displaynamevalue => { - let error; - if (!displaynamevalue) { - error = 'Required'; - } - return error; + /** + * Formik Validation + */ + const validateDisplayName = (displaynamevalue) => { + let error; + if (!displaynamevalue) { + error = "Required"; } + return error; + }; - const tableCellClasses = classnames(classes.tableCell); - return ( - <div> - <Table className={classes.table}> - <TableHead> - <TableRow> - <TableCell>{i18next.t("device_name", "Device Name")}</TableCell> - <TableCell>{i18next.t("device_id", "Device Id")}</TableCell> - <TableCell align="right">{i18next.t("status", "Status")}</TableCell> - <TableCell align="right">{i18next.t("actions", "Actions")}</TableCell> - </TableRow> - </TableHead> - {devices != null && - <TableBody> - {devices.map(device => - <TableRow key={device.displayName} className={classes.tableRow}> - <TableCell className={tableCellClasses}> - {device.displayName} - </TableCell> - <TableCell className={tableCellClasses}>{getDeviceId(device)}</TableCell> - <TableCell align="right" className={tableCellClasses}>{getDeviceStatus(device)}</TableCell> - {!(device.revoked) && - <TableCell align="right" className={classes.tableActions}> - <Tooltip - id="tooltip-top" - title="Edit Device" - placement="top" - classes={{ tooltip: classes.tooltip }} - > - <IconButton - aria-label="Edit" - className={classes.tableActionButton} - onClick={e =>handleClickEdit(e, device)} - > - <Edit - className={ - classes.tableActionButtonIcon + " " + classes.edit - } - /> - </IconButton> - </Tooltip> - <Tooltip - id="tooltip-top-start" - title={i18next.t("revoke_device", "Revoke Device")} - placement="top" - classes={{ tooltip: classes.tooltip }} - > - <IconButton - aria-label="Close" - className={classes.tableActionButton} - onClick={e => handleClickRevoke(e,device)} - > - <Close - className={ - classes.tableActionButtonIcon + " " + classes.close - } - /> - </IconButton> - </Tooltip> - </TableCell> - } - </TableRow> - )} - </TableBody>} - </Table> - <Dialog open={openEdit} onClose={handleClose} aria-labelledby="form-dialog-title"> - <DialogTitle id="form-edit-dialog-title">{i18next.t("update_device_information", "Update Device Information")}</DialogTitle> - <Formik initialValues={{ - displayName: selectedDevice.displayName, - }} + const tableCellClasses = classnames(classes.tableCell); + return ( + <div> + <Table className={classes.table}> + <TableHead> + <TableRow> + <TableCell>{i18next.t("device_name", "Device Name")}</TableCell> + <TableCell>{i18next.t("device_id", "Device Id")}</TableCell> + <TableCell align="right">{i18next.t("status", "Status")}</TableCell> + <TableCell align="right"> + {i18next.t("actions", "Actions")} + </TableCell> + </TableRow> + </TableHead> + {devices != null && ( + <TableBody> + {devices.map((device) => ( + <TableRow key={device.displayName} className={classes.tableRow}> + <TableCell className={tableCellClasses}> + {device.displayName} + </TableCell> + <TableCell className={tableCellClasses}> + {getDeviceId(device)} + </TableCell> + <TableCell align="right" className={tableCellClasses}> + {getDeviceStatus(device)} + </TableCell> + {!device.revoked && ( + <TableCell align="right" className={classes.tableActions}> + <Tooltip + id="tooltip-top" + title="Edit Device" + placement="top" + classes={{ tooltip: classes.tooltip }} + > + <IconButton + aria-label="Edit" + className={classes.tableActionButton} + onClick={(e) => handleClickEdit(e, device)} + > + <Edit + className={ + classes.tableActionButtonIcon + " " + classes.edit + } + /> + </IconButton> + </Tooltip> + <Tooltip + id="tooltip-top-start" + title={i18next.t("revoke_device", "Revoke Device")} + placement="top" + classes={{ tooltip: classes.tooltip }} + > + <IconButton + aria-label="Close" + className={classes.tableActionButton} + onClick={(e) => handleClickRevoke(e, device)} + > + <Close + className={ + classes.tableActionButtonIcon + " " + classes.close + } + /> + </IconButton> + </Tooltip> + </TableCell> + )} + </TableRow> + ))} + </TableBody> + )} + </Table> + <Dialog + open={openEdit} + onClose={handleClose} + aria-labelledby="form-dialog-title" + > + <DialogTitle id="form-edit-dialog-title"> + {i18next.t("update_device_information", "Update Device Information")} + </DialogTitle> + <Formik + initialValues={{ + displayName: selectedDevice.displayName, + }} + > + {({ errors, touched, validateField }) => ( + <form> + <DialogContent> + <Field name="displayName" validate={validateDisplayName}> + {({ field }) => ( + <div> + <TextField + autoFocus + margin="dense" + id="name" + label={i18next.t( + "device_display_name", + "Device Display Name" + )} + fullWidth + onChange={setDisplayName(field.value)} + helperText={ + errors.displayName && + touched.displayName && + errors.displayName + } + {...field} + /> + </div> + )} + </Field> + </DialogContent> + <DialogActions> + <Button onClick={handleCancel} color="primary"> + {i18next.t("cancel", "Cancel")} + </Button> + <Button + onClick={() => + validateField("displayName").then(() => handleUpdate()) + } + color="primary" > - {({ errors, touched, validateField}) => ( - <form> - <DialogContent> - <Field name="displayName" validate={validateDisplayName} > - {({field}) => ( - <div> - <TextField - autoFocus - margin="dense" - id="name" - label={i18next.t("device_display_name", "Device Display Name")} - fullWidth - onChange={setDisplayName(field.value)} - helperText={(errors.displayName && touched.displayName) && errors.displayName} - {...field} - /> - </div> - ) - } - </Field> - </DialogContent> - <DialogActions> - <Button onClick={handleCancel} color="primary"> - {i18next.t("cancel", "Cancel")} - </Button> - <Button onClick={() => validateField('displayName').then(() =>handleUpdate())} color="primary"> - {i18next.t("update", "Update")} - </Button> - </DialogActions> - </form> - )} - </Formik> - </Dialog> - <Dialog open={openRevoke} onClose={handleClose} aria-labelledby="form-dialog-title"> - <DialogTitle id="form-revoke-dialog-title">{i18next.t("revoke_device", "Revoke Device")}</DialogTitle> - <DialogContent> - <DialogContentText> - {i18next.t("are_you_sure_you_want_to_revoke_this_device", "Are you sure you want to revoke this device?")} - </DialogContentText> - </DialogContent> - <DialogActions> - <Button onClick={handleCancel} color="primary"> - {i18next.t("cancel", "Cancel")} - </Button> - <Button onClick={handleDeviceRevoke} color="primary"> - {i18next.t("confirm_revoke", "Confirm Revoke")} - </Button> - </DialogActions> - </Dialog> - </div> - ); + {i18next.t("update", "Update")} + </Button> + </DialogActions> + </form> + )} + </Formik> + </Dialog> + <Dialog + open={openRevoke} + onClose={handleClose} + aria-labelledby="form-dialog-title" + > + <DialogTitle id="form-revoke-dialog-title"> + {i18next.t("revoke_device", "Revoke Device")} + </DialogTitle> + <DialogContent> + <DialogContentText> + {i18next.t( + "are_you_sure_you_want_to_revoke_this_device", + "Are you sure you want to revoke this device?" + )} + </DialogContentText> + </DialogContent> + <DialogActions> + <Button onClick={handleCancel} color="primary"> + {i18next.t("cancel", "Cancel")} + </Button> + <Button onClick={handleDeviceRevoke} color="primary"> + {i18next.t("confirm_revoke", "Confirm Revoke")} + </Button> + </DialogActions> + </Dialog> + </div> + ); } - diff --git a/jams-react-client/src/components/Drawer/Drawer.js b/jams-react-client/src/components/Drawer/Drawer.js index ea35a6dc46f74bb5919be0d6dcf1dc8c5388ddff..f074770660eb0dc60965ff2701145d601bbb58d8 100644 --- a/jams-react-client/src/components/Drawer/Drawer.js +++ b/jams-react-client/src/components/Drawer/Drawer.js @@ -18,13 +18,13 @@ const useStyles = makeStyles((theme) => ({ width: "100%", [theme.breakpoints.up("xl")]: { width: "400px", - } + }, }, fullList: { width: "100%", [theme.breakpoints.up("xl")]: { width: "400px", - } + }, }, search: { width: "100%", @@ -38,54 +38,66 @@ const useStyles = makeStyles((theme) => ({ export default function TemporaryDrawer(props) { const classes = useStyles(); - useEffect(() => { - }, []); - + useEffect(() => {}, []); const listUsers = () => ( <List> - {props.type === "user" ? ( props.targets && props.targets.filter((target) => !props.existingTargets.some(t => target.username == t.username)).map((target) => ( - <ListItem - button - key={target.username} - onClick={() => { - props.addElementToTarget(target); - props.setOpenDrawer(false); - }} - > - <Avatar - style={{ marginRight: "10px" }} - alt={target.username} - src={ - target.profilePicture - ? "data:image/png;base64, " + target.profilePicture - : noProfilePicture - } - /> - <ListItemText - primary={ - target.username === "" - ? target.id - : target.firstName === "" || target.lastName === "" - ? target.username - : target.firstName + " " + target.lastName - } - /> - </ListItem> - ))) : ( props.targets && props.targets.filter((target) => !props.existingTargets.some(t => target.name == t.name)).map((target) => ( - <ListItem - button - key={target.name} - onClick={() => { - props.addElementToTarget(target); - props.setOpenDrawer(false); - }} - > - <ListItemText - primary={target.name} - /> - </ListItem> - )))} + {props.type === "user" + ? props.targets && + props.targets + .filter( + (target) => + !props.existingTargets.some( + (t) => target.username == t.username + ) + ) + .map((target) => ( + <ListItem + button + key={target.username} + onClick={() => { + props.addElementToTarget(target); + props.setOpenDrawer(false); + }} + > + <Avatar + style={{ marginRight: "10px" }} + alt={target.username} + src={ + target.profilePicture + ? "data:image/png;base64, " + target.profilePicture + : noProfilePicture + } + /> + <ListItemText + primary={ + target.username === "" + ? target.id + : target.firstName === "" || target.lastName === "" + ? target.username + : target.firstName + " " + target.lastName + } + /> + </ListItem> + )) + : props.targets && + props.targets + .filter( + (target) => + !props.existingTargets.some((t) => target.name == t.name) + ) + .map((target) => ( + <ListItem + button + key={target.name} + onClick={() => { + props.addElementToTarget(target); + props.setOpenDrawer(false); + }} + > + <ListItemText primary={target.name} /> + </ListItem> + ))} </List> ); @@ -111,7 +123,8 @@ export default function TemporaryDrawer(props) { > <div className={clsx(classes.list, { - [classes.fullList]: props.direction === "top" || props.direction === "bottom", + [classes.fullList]: + props.direction === "top" || props.direction === "bottom", })} role="presentation" > diff --git a/jams-react-client/src/components/FixedPlugin/FixedPlugin.js b/jams-react-client/src/components/FixedPlugin/FixedPlugin.js index 9898441243242ba7cdbfe2dee1d63cbab22bfb1e..dea5626d4f288dca0393c200f8efafd8a534ece9 100644 --- a/jams-react-client/src/components/FixedPlugin/FixedPlugin.js +++ b/jams-react-client/src/components/FixedPlugin/FixedPlugin.js @@ -22,7 +22,7 @@ export default function FixedPlugin(props) { return ( <div className={classnames("fixed-plugin", { - "rtl-fixed-plugin": props.rtlActive + "rtl-fixed-plugin": props.rtlActive, })} > <div id="fixedPluginClasses" className={props.fixedClasses}> @@ -186,5 +186,5 @@ FixedPlugin.propTypes = { fixedClasses: PropTypes.string, bgColor: PropTypes.oneOf(["purple", "blue", "green", "orange", "red"]), handleColorClick: PropTypes.func, - handleImageClick: PropTypes.func + handleImageClick: PropTypes.func, }; diff --git a/jams-react-client/src/components/Footer/Footer.js b/jams-react-client/src/components/Footer/Footer.js index 1387e46b1e350455270384540e2bd0dde64119c4..8dc03ebc7bd761f250a4ad9e6504a278a12ab683 100755 --- a/jams-react-client/src/components/Footer/Footer.js +++ b/jams-react-client/src/components/Footer/Footer.js @@ -8,7 +8,7 @@ import List from "@material-ui/core/List"; // core components import styles from "assets/jss/material-dashboard-react/components/footerStyle.js"; -const pjson = require('../../../package.json'); +const pjson = require("../../../package.json"); const useStyles = makeStyles(styles); @@ -19,8 +19,8 @@ export default function Footer(props) { <div className={classes.container}> <p className={classes.right}> <span> - JAMS Version {pjson.version.slice(0, 3)} - - © {1900 + new Date().getYear()}{" "} + JAMS Version {pjson.version.slice(0, 3)} - ©{" "} + {1900 + new Date().getYear()}{" "} <a href="https://savoirfairelinux.com" target="_blank" diff --git a/jams-react-client/src/components/Grid/GridContainer.js b/jams-react-client/src/components/Grid/GridContainer.js index 635a2a95de738eea239adc6314485a0db78d3a0a..e4f81135c1ee1130832b84f9304b330ad8f5a936 100644 --- a/jams-react-client/src/components/Grid/GridContainer.js +++ b/jams-react-client/src/components/Grid/GridContainer.js @@ -7,8 +7,8 @@ import Grid from "@material-ui/core/Grid"; const styles = { grid: { - // margin: "0 -15px !important", - width: "unset", + // margin: "0 -15px !important", + width: "unset", }, }; diff --git a/jams-react-client/src/components/Grid/GridItem.js b/jams-react-client/src/components/Grid/GridItem.js index f7a82de03791f8c539f29ad38719d568e89283f4..bb74c2a2b61122b001417d5bb1e6093fbc5e6480 100644 --- a/jams-react-client/src/components/Grid/GridItem.js +++ b/jams-react-client/src/components/Grid/GridItem.js @@ -8,7 +8,7 @@ import Grid from "@material-ui/core/Grid"; const styles = { grid: { padding: "0 5px !important", - } + }, }; const useStyles = makeStyles(styles); @@ -24,5 +24,5 @@ export default function GridItem(props) { } GridItem.propTypes = { - children: PropTypes.node + children: PropTypes.node, }; diff --git a/jams-react-client/src/components/IdentityManagement/AdStorageForm.js b/jams-react-client/src/components/IdentityManagement/AdStorageForm.js index 877fd3cd11c46be4819b402ac3a3704d7fca34ad..2880ea1f8748945e23d513cfa5655105fd11cb40 100644 --- a/jams-react-client/src/components/IdentityManagement/AdStorageForm.js +++ b/jams-react-client/src/components/IdentityManagement/AdStorageForm.js @@ -7,14 +7,17 @@ import TextField from "@material-ui/core/TextField"; import Radio from "@material-ui/core/Radio"; import RadioGroup from "@material-ui/core/RadioGroup"; -import i18next from 'i18next'; +import i18next from "i18next"; export default function AdStorageForm(props) { return ( <Grid container spacing={3}> <Grid item xs={12}> <Typography variant="subtitle1" gutterBottom color="primary"> - {i18next.t("active_directory_server_informations", "Active Directory server information")} + {i18next.t( + "active_directory_server_informations", + "Active Directory server information" + )} </Typography> </Grid> <Grid item xs={6}> diff --git a/jams-react-client/src/components/IdentityManagement/IdentityManagement.js b/jams-react-client/src/components/IdentityManagement/IdentityManagement.js index 7145121548d6820882d336e8cd2b141cef8dbe1c..48d54d253d97cd6b96a5926d748ad48dea54029d 100644 --- a/jams-react-client/src/components/IdentityManagement/IdentityManagement.js +++ b/jams-react-client/src/components/IdentityManagement/IdentityManagement.js @@ -20,7 +20,7 @@ import AdStorageForm from "./AdStorageForm"; import auth from "../../auth"; import * as Yup from "yup"; -import i18next from 'i18next'; +import i18next from "i18next"; const useStyles = makeStyles((theme) => ({ paper: { @@ -63,10 +63,18 @@ export default function IdentityManagement(props) { }; const validationSchemaLDAPform = Yup.object().shape({ - servername: Yup.string().required(i18next.t("servername_is_required", "Server name is required.")), - ldapadminusername: Yup.string().required(i18next.t("username_is_required", "Username is required!")), - ldappassword: Yup.string().required(i18next.t("password_is_required", "Password is required!")), - basedn: Yup.string().required(i18next.t("domain_name_is_required", "Domain name is required.")), + servername: Yup.string().required( + i18next.t("servername_is_required", "Server name is required.") + ), + ldapadminusername: Yup.string().required( + i18next.t("username_is_required", "Username is required!") + ), + ldappassword: Yup.string().required( + i18next.t("password_is_required", "Password is required!") + ), + basedn: Yup.string().required( + i18next.t("domain_name_is_required", "Domain name is required.") + ), }); const validationSchemaADform = Yup.object().shape({ @@ -74,11 +82,21 @@ export default function IdentityManagement(props) { .typeError(i18next.t("port_must_be_a_number", "Port must be a number.")) .positive(i18next.t("port_must_be_positive", "Port must be positive.")) .integer(i18next.t("port_must_be_an_integer", "Port must be an integer.")) - .required(i18next.t("port_number_is_required", "Port number is required.")), - host: Yup.string().required(i18next.t("host_is_required", "Host is required.")), - adadminusername: Yup.string().required(i18next.t("username_is_required", "Username is required!")), - domainname: Yup.string().required(i18next.t("domain_name_is_required", "Domain name is required.")), - adpassword: Yup.string().required(i18next.t("password_is_required", "Password is required!")), + .required( + i18next.t("port_number_is_required", "Port number is required.") + ), + host: Yup.string().required( + i18next.t("host_is_required", "Host is required.") + ), + adadminusername: Yup.string().required( + i18next.t("username_is_required", "Username is required!") + ), + domainname: Yup.string().required( + i18next.t("domain_name_is_required", "Domain name is required.") + ), + adpassword: Yup.string().required( + i18next.t("password_is_required", "Password is required!") + ), }); const directoryTypes = [ @@ -221,7 +239,10 @@ export default function IdentityManagement(props) { }) .catch(() => { props.setErrorMessage( - i18next.t("information_appears_incorrect_connection_directory_failed", "The information provided appears to be incorrect, the connection to the directory has failed. Please check the information and credentials provided and try again.") + i18next.t( + "information_appears_incorrect_connection_directory_failed", + "The information provided appears to be incorrect, the connection to the directory has failed. Please check the information and credentials provided and try again." + ) ); props.setError(true); }); @@ -237,7 +258,10 @@ export default function IdentityManagement(props) { }) .catch(() => { props.setErrorMessage( - i18next.t("information_appears_incorrect_connection_directory_failed", "The information provided appears to be incorrect, the connection to the directory has failed. Please check the information and credentials provided and try again.") + i18next.t( + "information_appears_incorrect_connection_directory_failed", + "The information provided appears to be incorrect, the connection to the directory has failed. Please check the information and credentials provided and try again." + ) ); props.setError(true); }); @@ -283,12 +307,15 @@ export default function IdentityManagement(props) { return ( <form className={classes.form} noValidate onSubmit={handleLocalSubmit}> <Typography variant="h5" gutterBottom color="primary"> - {i18next.t("identity_management", "Identity Management")} + {i18next.t("identity_management", "Identity Management")} </Typography> <Grid container spacing={3}> <Grid item xs={12}> <Typography variant="body1" gutterBottom> - {i18next.t("select_type_of_user_directory", "Select the type of user directory to be integrated with JAMS")} + {i18next.t( + "select_type_of_user_directory", + "Select the type of user directory to be integrated with JAMS" + )} </Typography> <Select labelId="demo-simple-select-label" @@ -341,7 +368,10 @@ export default function IdentityManagement(props) { <Grid container spacing={3}> <Grid item xs={12}> <Typography variant="body1" gutterBottom> - {i18next.t("select_type_of_user_directory", "Select the type of user directory to be integrated with JAMS")} + {i18next.t( + "select_type_of_user_directory", + "Select the type of user directory to be integrated with JAMS" + )} </Typography> <Select labelId="demo-simple-select-label" @@ -361,7 +391,10 @@ export default function IdentityManagement(props) { color="primary" className={classes.submit} > - {i18next.t("set_identity_parameters", "Set identity parameters")} + {i18next.t( + "set_identity_parameters", + "Set identity parameters" + )} </Button> </form> ); @@ -394,7 +427,10 @@ export default function IdentityManagement(props) { <Grid container spacing={3}> <Grid item xs={12}> <Typography variant="body1" gutterBottom> - {i18next.t("select_type_of_user_directory", "Select the type of user directory to be integrated with JAMS")} + {i18next.t( + "select_type_of_user_directory", + "Select the type of user directory to be integrated with JAMS" + )} </Typography> <Select labelId="demo-simple-select-label" @@ -414,7 +450,10 @@ export default function IdentityManagement(props) { color="primary" className={classes.submit} > - {i18next.t("set_identity_parameters", "Set identity parameters")} + {i18next.t( + "set_identity_parameters", + "Set identity parameters" + )} </Button> </form> ); diff --git a/jams-react-client/src/components/IdentityManagement/LdapStorageForm.js b/jams-react-client/src/components/IdentityManagement/LdapStorageForm.js index fbf06bb948971cd0f9e808e14e664ed8817f5aad..ab6f51bec40af9540c23e53ebc16784c8aa420af 100644 --- a/jams-react-client/src/components/IdentityManagement/LdapStorageForm.js +++ b/jams-react-client/src/components/IdentityManagement/LdapStorageForm.js @@ -1,106 +1,148 @@ -import React from 'react'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import Typography from '@material-ui/core/Typography'; -import Grid from '@material-ui/core/Grid'; +import React from "react"; +import FormControlLabel from "@material-ui/core/FormControlLabel"; +import Typography from "@material-ui/core/Typography"; +import Grid from "@material-ui/core/Grid"; -import TextField from '@material-ui/core/TextField'; -import Radio from '@material-ui/core/Radio'; -import RadioGroup from '@material-ui/core/RadioGroup'; -import Select from '@material-ui/core/Select'; -import CustomPopupState from '../CustomPopupState/CustomPopupState' +import TextField from "@material-ui/core/TextField"; +import Radio from "@material-ui/core/Radio"; +import RadioGroup from "@material-ui/core/RadioGroup"; +import Select from "@material-ui/core/Select"; +import CustomPopupState from "../CustomPopupState/CustomPopupState"; -import i18next from 'i18next'; +import i18next from "i18next"; export default function LdapStorageForm(props) { + return ( + <Grid container spacing={3}> + <Grid item xs={12}> + <Typography variant="subtitle1" gutterBottom color="primary"> + {i18next.t("ldap_server_information", "LDAP Server informations")} + </Typography> + </Grid> + <Grid item xs={12}> + <TextField + variant="outlined" + margin="normal" + required + fullWidth + id="servername" + label={i18next.t("server_address", "Server address")} + name="servername" + autoComplete="servername" + value={props.values.servername} + onChange={props.handleChange} + onBlur={props.handleBlur} + helperText={ + props.errors.servername && + props.touched.servername && + props.errors.servername + } + /> + </Grid> - return ( - <Grid container spacing={3}> - <Grid item xs={12}> - <Typography variant="subtitle1" gutterBottom color="primary">{i18next.t("ldap_server_information", "LDAP Server informations")}</Typography> - </Grid> - <Grid item xs={12}> - <TextField - variant="outlined" - margin="normal" - required - fullWidth - id="servername" - label={i18next.t("server_address", "Server address")} - name="servername" - autoComplete="servername" - value={props.values.servername} - onChange={props.handleChange} - onBlur={props.handleBlur} - helperText={(props.errors.servername && props.touched.servername) && props.errors.servername} - /> - </Grid> - - <Grid item xs={6}> - <TextField - variant="outlined" - margin="normal" - required - fullWidth - id="adminusername" - label={i18next.t("administrator_username", "Administrator username")} - name="ldapadminusername" - autoComplete="adminusername" - value={props.values.ldapadminusername} - onChange={props.handleChange} - onBlur={props.handleBlur} - helperText={(props.errors.ldapadminusername && props.touched.ldapadminusername) && props.errors.ldapadminusername} - /> - </Grid> - <Grid item xs={6}> - <TextField - variant="outlined" - margin="normal" - required - fullWidth - id="password" - label={i18next.t("password", "Password")} - name="ldappassword" - autoComplete="password" - type="password" - value={props.values.ldappassword} - onChange={props.handleChange} - onBlur={props.handleBlur} - helperText={(props.errors.ldappassword && props.touched.ldappassword) && props.errors.ldappassword} - /> - </Grid> - <Grid item xs={12}> - <TextField - variant="outlined" - id="basedn" - label={i18next.t("base_dn_please_use_ldap_convention", "Base DN (Please use LDAP convention)")} - name="basedn" - autoComplete="basedn" - required - fullWidth - value={props.values.basedn} - onChange={props.handleChange} - onBlur={props.handleBlur} - helperText={(props.errors.basedn && props.touched.basedn) && props.errors.basedn} - /> - </Grid> - <Grid item xs={12}> - <Typography variant="subtitle1" gutterBottom color="primary">Use Start TLS</Typography> - <RadioGroup row aria-label="useStartTLS" name="useStartTLS" value={props.useStartTLS} onChange={props.handleUseStartTLSChange} > - <FormControlLabel value="true" control={<Radio color="primary"/>} label={i18next.t("yes", "Yes")} /> - <FormControlLabel value="false" control={<Radio color="default"/>} label={i18next.t("no", "No")} /> - </RadioGroup> - </Grid> - <Grid item xs={12}> - <Typography variant="subtitle1" gutterBottom color="primary">Filter<CustomPopupState message={i18next.t("field_ldap_structure_contains_username", "This is the field in your LDAP structure which contains the username.")}/></Typography> - <Select - labelId="filter-ldap-select" - fullWidth - value={props.ldapFilter.value} - onChange={props.handleFilterIdChange} - variant="outlined" - children={props.ldapFiltersTypesItems} - /> - </Grid> - </Grid> - ); -} \ No newline at end of file + <Grid item xs={6}> + <TextField + variant="outlined" + margin="normal" + required + fullWidth + id="adminusername" + label={i18next.t("administrator_username", "Administrator username")} + name="ldapadminusername" + autoComplete="adminusername" + value={props.values.ldapadminusername} + onChange={props.handleChange} + onBlur={props.handleBlur} + helperText={ + props.errors.ldapadminusername && + props.touched.ldapadminusername && + props.errors.ldapadminusername + } + /> + </Grid> + <Grid item xs={6}> + <TextField + variant="outlined" + margin="normal" + required + fullWidth + id="password" + label={i18next.t("password", "Password")} + name="ldappassword" + autoComplete="password" + type="password" + value={props.values.ldappassword} + onChange={props.handleChange} + onBlur={props.handleBlur} + helperText={ + props.errors.ldappassword && + props.touched.ldappassword && + props.errors.ldappassword + } + /> + </Grid> + <Grid item xs={12}> + <TextField + variant="outlined" + id="basedn" + label={i18next.t( + "base_dn_please_use_ldap_convention", + "Base DN (Please use LDAP convention)" + )} + name="basedn" + autoComplete="basedn" + required + fullWidth + value={props.values.basedn} + onChange={props.handleChange} + onBlur={props.handleBlur} + helperText={ + props.errors.basedn && props.touched.basedn && props.errors.basedn + } + /> + </Grid> + <Grid item xs={12}> + <Typography variant="subtitle1" gutterBottom color="primary"> + Use Start TLS + </Typography> + <RadioGroup + row + aria-label="useStartTLS" + name="useStartTLS" + value={props.useStartTLS} + onChange={props.handleUseStartTLSChange} + > + <FormControlLabel + value="true" + control={<Radio color="primary" />} + label={i18next.t("yes", "Yes")} + /> + <FormControlLabel + value="false" + control={<Radio color="default" />} + label={i18next.t("no", "No")} + /> + </RadioGroup> + </Grid> + <Grid item xs={12}> + <Typography variant="subtitle1" gutterBottom color="primary"> + Filter + <CustomPopupState + message={i18next.t( + "field_ldap_structure_contains_username", + "This is the field in your LDAP structure which contains the username." + )} + /> + </Typography> + <Select + labelId="filter-ldap-select" + fullWidth + value={props.ldapFilter.value} + onChange={props.handleFilterIdChange} + variant="outlined" + children={props.ldapFiltersTypesItems} + /> + </Grid> + </Grid> + ); +} diff --git a/jams-react-client/src/components/IdentityManagement/LocalStorageForm.js b/jams-react-client/src/components/IdentityManagement/LocalStorageForm.js index c827f3a3392a6d93234b9d3a65dd78349933bf80..1fd17ff00e3f84a48548eafbe4277b541be6d36f 100644 --- a/jams-react-client/src/components/IdentityManagement/LocalStorageForm.js +++ b/jams-react-client/src/components/IdentityManagement/LocalStorageForm.js @@ -1,33 +1,39 @@ -import React from 'react'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import Checkbox from '@material-ui/core/Checkbox'; -import Typography from '@material-ui/core/Typography'; -import Grid from '@material-ui/core/Grid'; -import CustomPopupState from '../CustomPopupState/CustomPopupState' +import React from "react"; +import FormControlLabel from "@material-ui/core/FormControlLabel"; +import Checkbox from "@material-ui/core/Checkbox"; +import Typography from "@material-ui/core/Typography"; +import Grid from "@material-ui/core/Grid"; +import CustomPopupState from "../CustomPopupState/CustomPopupState"; -import i18next from 'i18next'; +import i18next from "i18next"; export default function LocalStorageForm(props) { - - return ( - <Grid container spacing={3}> - <Grid item xs={12}> - <Typography variant="subtitle1" gutterBottom color="primary">{i18next.t("advanced_settings", "Advanced settings")}</Typography> - </Grid> - <Grid item xs={12}> - <FormControlLabel - control={ - <Checkbox - checked={props.nameServerChecked} - onChange={props.handleNameServerChange} - inputProps={{ 'aria-label': 'primary checkbox' }} - color="primary" - /> - } - label={i18next.t("use_public_nameserver", "Use public nameserver")} - /> - <CustomPopupState message={i18next.t("check_box_register_usernames_on_jami_public_nameserver", "Check this box if you want to register your usernames on Jami's public name server.")}/> - </Grid> - </Grid> - ); -} \ No newline at end of file + return ( + <Grid container spacing={3}> + <Grid item xs={12}> + <Typography variant="subtitle1" gutterBottom color="primary"> + {i18next.t("advanced_settings", "Advanced settings")} + </Typography> + </Grid> + <Grid item xs={12}> + <FormControlLabel + control={ + <Checkbox + checked={props.nameServerChecked} + onChange={props.handleNameServerChange} + inputProps={{ "aria-label": "primary checkbox" }} + color="primary" + /> + } + label={i18next.t("use_public_nameserver", "Use public nameserver")} + /> + <CustomPopupState + message={i18next.t( + "check_box_register_usernames_on_jami_public_nameserver", + "Check this box if you want to register your usernames on Jami's public name server." + )} + /> + </Grid> + </Grid> + ); +} diff --git a/jams-react-client/src/components/LanguagePicker/LanguagePicker.js b/jams-react-client/src/components/LanguagePicker/LanguagePicker.js index 107b77c64a28b992b62b6962f02c7296f134445a..a86d5427b6a387adf48591088aa4c9939ecdc6ac 100644 --- a/jams-react-client/src/components/LanguagePicker/LanguagePicker.js +++ b/jams-react-client/src/components/LanguagePicker/LanguagePicker.js @@ -12,44 +12,46 @@ import { useTranslation } from "react-i18next"; export default function LanguagePicker(props) { const history = useHistory(); - const [language, setLanguage] = React.useState(i18next.language || window.localStorage.i18nextLng || "en"); + const [language, setLanguage] = React.useState( + i18next.language || window.localStorage.i18nextLng || "en" + ); const [languages, setLanguages] = React.useState([]); const { i18n } = useTranslation(); const handleChange = (value) => { setLanguage(value); - i18n.changeLanguage(value).then(()=>{ + i18n.changeLanguage(value).then(() => { history.push(props.navigationTarget); - }) + }); }; useEffect(() => { - fetch("/available_languages.json").then(res => res.json()).then((result) => { - const response = result.languages; - let translates_languages = [{ "code": "en", "name": "English"}]; - - response.forEach((lang) => - { - if(result.stats[lang.code]["translated"]["percentage"] > 0.01){ - translates_languages.push(lang); - } - }) + fetch("/available_languages.json") + .then((res) => res.json()) + .then((result) => { + const response = result.languages; + let translates_languages = [{ code: "en", name: "English" }]; - let exists = false; - translates_languages.map((option) => { - if (option.code === language) { - exists = true; - } - }) - if (!exists ) { - setLanguage("en"); - i18n.changeLanguage("en"); - } - setLanguages(translates_languages) - }) + response.forEach((lang) => { + if (result.stats[lang.code]["translated"]["percentage"] > 0.01) { + translates_languages.push(lang); + } + }); - }, [language]) + let exists = false; + translates_languages.map((option) => { + if (option.code === language) { + exists = true; + } + }); + if (!exists) { + setLanguage("en"); + i18n.changeLanguage("en"); + } + setLanguages(translates_languages); + }); + }, [language]); return ( <PopupState variant="popover" popupId="demo-popup-menu"> diff --git a/jams-react-client/src/components/Navbars/AdminNavbarLinks.js b/jams-react-client/src/components/Navbars/AdminNavbarLinks.js index ef329b0af18143a85c12c550083452b3a26b4d30..f3cc665f508c3aac558d025b28a1468d198ded02 100644 --- a/jams-react-client/src/components/Navbars/AdminNavbarLinks.js +++ b/jams-react-client/src/components/Navbars/AdminNavbarLinks.js @@ -24,7 +24,7 @@ export default function AdminNavbarLinks(props) { const classes = useStyles(); const [openProfile, setOpenProfile] = React.useState(null); - const handleClickProfile = event => { + const handleClickProfile = (event) => { if (openProfile && openProfile.contains(event.target)) { setOpenProfile(null); } else { @@ -34,7 +34,7 @@ export default function AdminNavbarLinks(props) { const handleOtherAction = () => { // Do nothing - } + }; return ( <div> @@ -70,7 +70,7 @@ export default function AdminNavbarLinks(props) { id="profile-menu-list-grow" style={{ transformOrigin: - placement === "bottom" ? "center top" : "center bottom" + placement === "bottom" ? "center top" : "center bottom", }} > <Paper> diff --git a/jams-react-client/src/components/Navbars/Navbar.js b/jams-react-client/src/components/Navbars/Navbar.js index fd31db219fdfa9bf1f2bd6fc5e56a375d478858e..7e66562c93b933a9cbc5eee9480afb85517ea7a2 100755 --- a/jams-react-client/src/components/Navbars/Navbar.js +++ b/jams-react-client/src/components/Navbars/Navbar.js @@ -20,14 +20,17 @@ export default function Header(props) { const classes = useStyles(); const { color } = props; const appBarClasses = classNames({ - [" " + classes[color]]: color + [" " + classes[color]]: color, }); return ( <AppBar className={classes.appBar + appBarClasses}> <Toolbar className={classes.container}> <div className={classes.flex}> - <Button color="transparent" href="#" className={classes.title}> - </Button> + <Button + color="transparent" + href="#" + className={classes.title} + ></Button> </div> <Hidden mdUp implementation="css"> <IconButton @@ -47,5 +50,5 @@ Header.propTypes = { color: PropTypes.oneOf(["primary", "info", "success", "warning", "danger"]), rtlActive: PropTypes.bool, handleDrawerToggle: PropTypes.func, - routes: PropTypes.arrayOf(PropTypes.object) + routes: PropTypes.arrayOf(PropTypes.object), }; diff --git a/jams-react-client/src/components/Navbars/RTLNavbarLinks.js b/jams-react-client/src/components/Navbars/RTLNavbarLinks.js index d2eb4274837ad960742e86501e3a84efd2699d97..93b3f5ee4a5394c83f8b0589593ce5574760c546 100644 --- a/jams-react-client/src/components/Navbars/RTLNavbarLinks.js +++ b/jams-react-client/src/components/Navbars/RTLNavbarLinks.js @@ -25,7 +25,7 @@ const useStyles = makeStyles(styles); export default function RTLNavbarLinks() { const classes = useStyles(); const [open, setOpen] = React.useState(null); - const handleToggle = event => { + const handleToggle = (event) => { if (open && open.contains(event.target)) { setOpen(null); } else { @@ -42,13 +42,13 @@ export default function RTLNavbarLinks() { <div className={classes.searchWrapper}> <CustomInput formControlProps={{ - className: classes.margin + " " + classes.search + className: classes.margin + " " + classes.search, }} inputProps={{ placeholder: "جستجو...", inputProps: { - "aria-label": "Search" - } + "aria-label": "Search", + }, }} /> <Button color="white" aria-label="edit" justIcon round> @@ -102,7 +102,7 @@ export default function RTLNavbarLinks() { id="menu-list-grow" style={{ transformOrigin: - placement === "bottom" ? "center top" : "center bottom" + placement === "bottom" ? "center top" : "center bottom", }} > <Paper> diff --git a/jams-react-client/src/components/PasswordDialog/PasswordDialog.js b/jams-react-client/src/components/PasswordDialog/PasswordDialog.js index 1b80b857117a575394422476807fd4dfd8c33863..f3053003cde7e32af1357eab593fd4f90887781c 100644 --- a/jams-react-client/src/components/PasswordDialog/PasswordDialog.js +++ b/jams-react-client/src/components/PasswordDialog/PasswordDialog.js @@ -46,7 +46,7 @@ const styles = (theme) => ({ }, whiteButtonText: { color: "white", - } + }, }); const useStyles = makeStyles(styles); diff --git a/jams-react-client/src/components/ServerParameters/ServerParameters.js b/jams-react-client/src/components/ServerParameters/ServerParameters.js index 16efbb7f5bd2cd091b7ff2c7dbbf6d111484c6a9..4fe0c7afab2dc6b26ea2a0acb93312b5929ad31d 100644 --- a/jams-react-client/src/components/ServerParameters/ServerParameters.js +++ b/jams-react-client/src/components/ServerParameters/ServerParameters.js @@ -18,7 +18,7 @@ import { api_path_post_install_server } from "../../globalUrls"; import auth from "auth"; import * as Yup from "yup"; -import i18next from 'i18next'; +import i18next from "i18next"; const useStyles = makeStyles((theme) => ({ paper: { @@ -44,7 +44,9 @@ export default function ServerParameters(props) { // Formik validation fields const initialValues = { domain: window.location.origin }; const validationSchema = Yup.object().shape({ - domain: Yup.string().required(i18next.t("domain_is_required", "Domain is required.")), + domain: Yup.string().required( + i18next.t("domain_is_required", "Domain is required.") + ), }); const certificateRevocationTypes = [ @@ -107,40 +109,45 @@ export default function ServerParameters(props) { auth.installed = true; auth.authenticated = true; auth.admin = true; - window.localStorage.setItem('scope', 'true'); + window.localStorage.setItem("scope", "true"); auth.checkDirectoryType(() => { history.push("/users"); }); } function handleSubmit(values) { - let jsonData = {}; - let re = new RegExp(/^http[s]?:\/\/\w+(\.\w+)*(:[0-9]+)?\/?(\/[.\w]*)*$/); - let nohttpre = new RegExp(/^\w+(\.\w+)*(:[0-9]+)?\/?(\/[.\w]*)*$/); + let jsonData = {}; + let re = new RegExp(/^http[s]?:\/\/\w+(\.\w+)*(:[0-9]+)?\/?(\/[.\w]*)*$/); + let nohttpre = new RegExp(/^\w+(\.\w+)*(:[0-9]+)?\/?(\/[.\w]*)*$/); - if (values.domain.match(nohttpre)) - values.domain = (window.location.protocol) + "//" + values.domain; + if (values.domain.match(nohttpre)) + values.domain = window.location.protocol + "//" + values.domain; - if (values.domain.match(re)) { - jsonData = { - serverDomain: values.domain, - crlLifetime: certificateRevocation.value, - deviceLifetime: deviceLifetime.value, - userLifetime: userAccountLifetime.value, - sipConfig: sipConfigurationTemplate, - signingAlgorithm: "SHA512WITHRSA", - }; - axios(configApiCall(api_path_post_install_server, "POST", jsonData, null)) - .then((response) => { - callBackServerParameters(); - }) - .catch((error) => { - console.log("Error installing server parameters: " + error); - }); - } else { - props.setError(true); - props.setErrorMessage(i18next.t("please_enter_valid_cors_domain_url", "Please enter a valid CORS domain URL.")); - } + if (values.domain.match(re)) { + jsonData = { + serverDomain: values.domain, + crlLifetime: certificateRevocation.value, + deviceLifetime: deviceLifetime.value, + userLifetime: userAccountLifetime.value, + sipConfig: sipConfigurationTemplate, + signingAlgorithm: "SHA512WITHRSA", + }; + axios(configApiCall(api_path_post_install_server, "POST", jsonData, null)) + .then((response) => { + callBackServerParameters(); + }) + .catch((error) => { + console.log("Error installing server parameters: " + error); + }); + } else { + props.setError(true); + props.setErrorMessage( + i18next.t( + "please_enter_valid_cors_domain_url", + "Please enter a valid CORS domain URL." + ) + ); + } } const handleCertificateRevocationChange = (event) => { @@ -185,17 +192,28 @@ export default function ServerParameters(props) { return ( <form className={classes.form} noValidate onSubmit={handleSubmit}> <Typography variant="h5" gutterBottom color="primary"> - {i18next.t("server_parameters", "Server Parameters")} + {i18next.t("server_parameters", "Server Parameters")} </Typography> <Typography variant="body1" gutterBottom> - {i18next.t("global_parameters_cover_general_configuration_of_servers_engine", "The global parameters cover the general configuration of the server's engine.")} + {i18next.t( + "global_parameters_cover_general_configuration_of_servers_engine", + "The global parameters cover the general configuration of the server's engine." + )} </Typography> <Typography variant="subtitle1" gutterBottom> - {i18next.t("cors_domain_name", "CORS domain name")} - <CustomPopupState message={i18next.t("set_domain_of_web_cleint_server_to_connect_to_hans_admin_dashboard_and_jami_accounts_also_to_set_client_crls_ocsps", "Set the domain of the web client-server to connect to the JAMS admin dashboard and Jami accounts. It is also used to define where the clients should download CRLs and submit OCSP queries. In case you are running a proxied instance (i.e. JAMS behind IIS), please make sure to set this field correctly, otherwise devices will not be able to download CRLs or validate certificates.")} /> + {i18next.t("cors_domain_name", "CORS domain name")} + <CustomPopupState + message={i18next.t( + "set_domain_of_web_cleint_server_to_connect_to_hans_admin_dashboard_and_jami_accounts_also_to_set_client_crls_ocsps", + "Set the domain of the web client-server to connect to the JAMS admin dashboard and Jami accounts. It is also used to define where the clients should download CRLs and submit OCSP queries. In case you are running a proxied instance (i.e. JAMS behind IIS), please make sure to set this field correctly, otherwise devices will not be able to download CRLs or validate certificates." + )} + /> </Typography> <Typography variant="body1" gutterBottom> - {i18next.t("domain_name_of_web_client_server", "The domain name of your web client server.")} + {i18next.t( + "domain_name_of_web_client_server", + "The domain name of your web client server." + )} </Typography> <TextField variant="outlined" @@ -213,8 +231,16 @@ export default function ServerParameters(props) { helperText={errors.domain && touched.domain && errors.domain} /> <Typography variant="subtitle1" gutterBottom> - {i18next.t("certificate_revocation_list_lifetime", "Certificate Revocation List Lifetime")} - <CustomPopupState message={i18next.t("set_liftetime_crl_list_certificates_revoked", "Set the lifetime of the CRL which contains the list of the certificates that have been revoked before their scheduled expiration date.")} /> + {i18next.t( + "certificate_revocation_list_lifetime", + "Certificate Revocation List Lifetime" + )} + <CustomPopupState + message={i18next.t( + "set_liftetime_crl_list_certificates_revoked", + "Set the lifetime of the CRL which contains the list of the certificates that have been revoked before their scheduled expiration date." + )} + /> </Typography> <Select labelId="certificate-revocation-select-label" @@ -249,11 +275,17 @@ export default function ServerParameters(props) { /> {userlifeDisabled ? ( <span class="spanError"> - {i18next.t("account_lifetime_should_be_bigger_to_device_lifetime", "The account lifetime should be longer than the Device lifetime.")} + {i18next.t( + "account_lifetime_should_be_bigger_to_device_lifetime", + "The account lifetime should be longer than the Device lifetime." + )} </span> ) : null} <Typography variant="subtitle1" gutterBottom> - {i18next.t("sip_configuration_template", "SIP Configuration Template")} + {i18next.t( + "sip_configuration_template", + "SIP Configuration Template" + )} </Typography> <Input fullWidth diff --git a/jams-react-client/src/components/Sidebar/Sidebar.js b/jams-react-client/src/components/Sidebar/Sidebar.js index fd15bd6d3a323e312b6d154b8ed1cb253a179d3a..81d244160324def6772c84392781d411c0d1bb77 100755 --- a/jams-react-client/src/components/Sidebar/Sidebar.js +++ b/jams-react-client/src/components/Sidebar/Sidebar.js @@ -56,13 +56,14 @@ export default function Sidebar(props) { var links = ( <List className={classes.list}> - <ListItem - className={classes.itemLink} - >{brand}</ListItem> - <div className={classes.itemLinkSeparator}><hr/></div> + <ListItem className={classes.itemLink}>{brand}</ListItem> + <div className={classes.itemLinkSeparator}> + <hr /> + </div> {routes.map((prop, key) => { - if( prop.admin && !auth.hasAdminScope()) return; - if( !prop.admin && auth.hasAdminScope() && prop.path === "/user/admin") return; + if (prop.admin && !auth.hasAdminScope()) return; + if (!prop.admin && auth.hasAdminScope() && prop.path === "/user/admin") + return; var activePro = " "; var listItemClasses; if (prop.path === "/upgrade-to-pro") { @@ -96,23 +97,28 @@ export default function Sidebar(props) { key={key} > <Link to={`${prop.path}`}> - <ListItem - button - className={classes.itemLink + listItemClasses} - > + <ListItem button className={classes.itemLink + listItemClasses}> {typeof prop.icon === "string" ? ( <Icon - className={classNames(classes.itemIcon, whiteFontClasses, { - [classes.itemIconRTL]: props.rtlActive, - })} + className={classNames( + classes.itemIcon, + whiteFontClasses, + { + [classes.itemIconRTL]: props.rtlActive, + } + )} > {prop.icon} </Icon> ) : ( <prop.icon - className={classNames(classes.itemIcon, whiteFontClasses, { - [classes.itemIconRTL]: props.rtlActive, - })} + className={classNames( + classes.itemIcon, + whiteFontClasses, + { + [classes.itemIconRTL]: props.rtlActive, + } + )} /> )} <ListItemText @@ -133,7 +139,6 @@ export default function Sidebar(props) { var bottomLinks = ( <List className={classes.bottomlist}> - {open && ( <ListItem button diff --git a/jams-react-client/src/components/Snackbar/Snackbar.js b/jams-react-client/src/components/Snackbar/Snackbar.js index 4b4e6ebf703f63eaf4ce42bcc4fbc30ebe58f447..2aca6a5ebaeeaae838caff617134b990e9a164e2 100644 --- a/jams-react-client/src/components/Snackbar/Snackbar.js +++ b/jams-react-client/src/components/Snackbar/Snackbar.js @@ -17,7 +17,7 @@ export default function Snackbar(props) { const { message, color, close, icon, place, open, rtlActive } = props; var action = []; const messageClasses = classNames({ - [classes.iconMessage]: icon !== undefined + [classes.iconMessage]: icon !== undefined, }); if (close !== undefined) { action = [ @@ -29,7 +29,7 @@ export default function Snackbar(props) { onClick={() => props.closeNotification()} > <Close className={classes.close} /> - </IconButton> + </IconButton>, ]; } return ( @@ -41,7 +41,7 @@ export default function Snackbar(props) { ? "left" : place.indexOf("c") !== -1 ? "center" - : "right" + : "right", }} open={open} message={ @@ -55,8 +55,8 @@ export default function Snackbar(props) { classes: { root: classes.root + " " + classes[color], message: classes.message, - action: classNames({ [classes.actionRTL]: rtlActive }) - } + action: classNames({ [classes.actionRTL]: rtlActive }), + }, }} /> ); @@ -70,5 +70,5 @@ Snackbar.propTypes = { place: PropTypes.oneOf(["tl", "tr", "tc", "br", "bl", "bc"]), open: PropTypes.bool, rtlActive: PropTypes.bool, - closeNotification: PropTypes.func + closeNotification: PropTypes.func, }; diff --git a/jams-react-client/src/components/Snackbar/SnackbarContent.js b/jams-react-client/src/components/Snackbar/SnackbarContent.js index f0002739652f530d0cff9db3044c90745e09391e..ebbaa4220d373fc74e3fb422922918c1da372819 100644 --- a/jams-react-client/src/components/Snackbar/SnackbarContent.js +++ b/jams-react-client/src/components/Snackbar/SnackbarContent.js @@ -17,7 +17,7 @@ export default function SnackbarContent(props) { const { message, color, close, icon, rtlActive } = props; var action = []; const messageClasses = classNames({ - [classes.iconMessage]: icon !== undefined + [classes.iconMessage]: icon !== undefined, }); if (close !== undefined) { action = [ @@ -28,7 +28,7 @@ export default function SnackbarContent(props) { color="info" > <Close className={classes.close} /> - </IconButton> + </IconButton>, ]; } return ( @@ -42,7 +42,7 @@ export default function SnackbarContent(props) { classes={{ root: classes.root + " " + classes[color], message: classes.message, - action: classNames({ [classes.actionRTL]: rtlActive }) + action: classNames({ [classes.actionRTL]: rtlActive }), }} action={action} /> @@ -54,5 +54,5 @@ SnackbarContent.propTypes = { color: PropTypes.oneOf(["info", "success", "warning", "danger", "primary"]), close: PropTypes.bool, icon: PropTypes.object, - rtlActive: PropTypes.bool + rtlActive: PropTypes.bool, }; diff --git a/jams-react-client/src/components/Table/Table.js b/jams-react-client/src/components/Table/Table.js index 91ad32dba1870e12ee08ea5adf6a3c0d5e63dd09..80343ba00b80656c67483505a6a7a1cb37063203 100644 --- a/jams-react-client/src/components/Table/Table.js +++ b/jams-react-client/src/components/Table/Table.js @@ -55,7 +55,7 @@ export default function CustomTable(props) { } CustomTable.defaultProps = { - tableHeaderColor: "gray" + tableHeaderColor: "gray", }; CustomTable.propTypes = { @@ -66,8 +66,8 @@ CustomTable.propTypes = { "success", "info", "rose", - "gray" + "gray", ]), tableHead: PropTypes.arrayOf(PropTypes.string), - tableData: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)) + tableData: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)), }; diff --git a/jams-react-client/src/components/Tasks/Tasks.js b/jams-react-client/src/components/Tasks/Tasks.js index 4ab65b2fe6071c3d117e593d00c2256ea09ae591..c9c7a432c93d80d082ffedd4a906b1a9461527fe 100755 --- a/jams-react-client/src/components/Tasks/Tasks.js +++ b/jams-react-client/src/components/Tasks/Tasks.js @@ -22,7 +22,7 @@ const useStyles = makeStyles(styles); export default function Tasks(props) { const classes = useStyles(); const [checked, setChecked] = React.useState([...props.checkedIndexes]); - const handleToggle = value => { + const handleToggle = (value) => { const currentIndex = checked.indexOf(value); const newChecked = [...checked]; if (currentIndex === -1) { @@ -34,12 +34,12 @@ export default function Tasks(props) { }; const { tasksIndexes, tasks, rtlActive } = props; const tableCellClasses = classnames(classes.tableCell, { - [classes.tableCellRTL]: rtlActive + [classes.tableCellRTL]: rtlActive, }); return ( <Table className={classes.table}> <TableBody> - {tasksIndexes.map(value => ( + {tasksIndexes.map((value) => ( <TableRow key={value} className={classes.tableRow}> <TableCell className={tableCellClasses}> <Checkbox @@ -50,7 +50,7 @@ export default function Tasks(props) { icon={<Check className={classes.uncheckedIcon} />} classes={{ checked: classes.checked, - root: classes.root + root: classes.root, }} /> </TableCell> @@ -102,5 +102,5 @@ Tasks.propTypes = { tasksIndexes: PropTypes.arrayOf(PropTypes.number), tasks: PropTypes.arrayOf(PropTypes.node), rtlActive: PropTypes.bool, - checkedIndexes: PropTypes.array + checkedIndexes: PropTypes.array, }; diff --git a/jams-react-client/src/components/Typography/Danger.js b/jams-react-client/src/components/Typography/Danger.js index aba10f5da581139200f110023fb348d0f54f148d..61bb44a9fe6dc8fc799f9a89d447b7482b9f5535 100755 --- a/jams-react-client/src/components/Typography/Danger.js +++ b/jams-react-client/src/components/Typography/Danger.js @@ -18,5 +18,5 @@ export default function Danger(props) { } Danger.propTypes = { - children: PropTypes.node + children: PropTypes.node, }; diff --git a/jams-react-client/src/components/Typography/Info.js b/jams-react-client/src/components/Typography/Info.js index a2deeda817d58686530a8f17b335b5d97e8666c7..633e3f574aff4ac14b8d840546c7d97837e21d7c 100755 --- a/jams-react-client/src/components/Typography/Info.js +++ b/jams-react-client/src/components/Typography/Info.js @@ -18,5 +18,5 @@ export default function Info(props) { } Info.propTypes = { - children: PropTypes.node + children: PropTypes.node, }; diff --git a/jams-react-client/src/components/Typography/Muted.js b/jams-react-client/src/components/Typography/Muted.js index 97a31e454f19b021586b17990a7f82a6db5227e0..e817c8699d12900644b175ad6db097b36e8c6503 100755 --- a/jams-react-client/src/components/Typography/Muted.js +++ b/jams-react-client/src/components/Typography/Muted.js @@ -18,5 +18,5 @@ export default function Muted(props) { } Muted.propTypes = { - children: PropTypes.node + children: PropTypes.node, }; diff --git a/jams-react-client/src/components/Typography/Primary.js b/jams-react-client/src/components/Typography/Primary.js index f0713a000054b6909c7ba41d990371f92da01aa6..cd73db4bdad73869f1150badd5f4002a3de1472b 100755 --- a/jams-react-client/src/components/Typography/Primary.js +++ b/jams-react-client/src/components/Typography/Primary.js @@ -18,5 +18,5 @@ export default function Primary(props) { } Primary.propTypes = { - children: PropTypes.node + children: PropTypes.node, }; diff --git a/jams-react-client/src/components/Typography/Quote.js b/jams-react-client/src/components/Typography/Quote.js index 264266921588d75dd32d2e3ca36413f7655174ab..72acd8ba1498d498c3fb6e073fa8d1dcc72ed2e6 100755 --- a/jams-react-client/src/components/Typography/Quote.js +++ b/jams-react-client/src/components/Typography/Quote.js @@ -20,5 +20,5 @@ export default function Quote(props) { Quote.propTypes = { text: PropTypes.node, - author: PropTypes.node + author: PropTypes.node, }; diff --git a/jams-react-client/src/components/Typography/Success.js b/jams-react-client/src/components/Typography/Success.js index 573b9ea5bd78a14bdcb368d6e5d8faa71fdc117b..959a6b3409ecea91b537d013166dacd0c7a4005c 100755 --- a/jams-react-client/src/components/Typography/Success.js +++ b/jams-react-client/src/components/Typography/Success.js @@ -18,5 +18,5 @@ export default function Success(props) { } Success.propTypes = { - children: PropTypes.node + children: PropTypes.node, }; diff --git a/jams-react-client/src/components/Typography/Warning.js b/jams-react-client/src/components/Typography/Warning.js index 1a85b77f72f84b7040e2de64da62ccf57a5cff20..28e8e1b9bb4de8ee4a4d17d48eb8ba301d5f3603 100755 --- a/jams-react-client/src/components/Typography/Warning.js +++ b/jams-react-client/src/components/Typography/Warning.js @@ -18,5 +18,5 @@ export default function Warning(props) { } Warning.propTypes = { - children: PropTypes.node + children: PropTypes.node, }; diff --git a/jams-react-client/src/configured.route.js b/jams-react-client/src/configured.route.js index 322000890fde8b33d4144e94ac0a49c394cccf87..d56b33dc3b59735a2585999c042f8345c0bfea40 100644 --- a/jams-react-client/src/configured.route.js +++ b/jams-react-client/src/configured.route.js @@ -1,38 +1,34 @@ - -import React from 'react' -import { Route } from 'react-router-dom' -import auth from './auth' +import React from "react"; +import { Route } from "react-router-dom"; +import auth from "./auth"; import SignUp from "layouts/SignUp"; import SignIn from "layouts/SignIn"; export const ConfiguredRoute = ({ component: Component, ...rest }) => { - return ( - <Route {...rest} render={ - - (props) => { - if (auth.hasAdmin()) { - if(auth.isInstalled()){ - return <Component {...props} /> - }else if(!auth.isInstalled() && auth.isAuthenticated()){ - if(auth.uri === '/api/install/ca' || auth.uri === 'start'){ - return <SignUp step={1}/> - } - else if (auth.uri === '/api/install/auth'){ - return <SignUp step={2}/> - } else if (auth.uri === '/api/install/settings'){ - return <SignUp step={3}/> - } else { - console.log('Error no matching path for configuration') - } - - }else { - return <SignIn /> - } - } else { - return <SignUp step={0}/> - } - + return ( + <Route + {...rest} + render={(props) => { + if (auth.hasAdmin()) { + if (auth.isInstalled()) { + return <Component {...props} />; + } else if (!auth.isInstalled() && auth.isAuthenticated()) { + if (auth.uri === "/api/install/ca" || auth.uri === "start") { + return <SignUp step={1} />; + } else if (auth.uri === "/api/install/auth") { + return <SignUp step={2} />; + } else if (auth.uri === "/api/install/settings") { + return <SignUp step={3} />; + } else { + console.log("Error no matching path for configuration"); } - } /> - ) -} \ No newline at end of file + } else { + return <SignIn />; + } + } else { + return <SignUp step={0} />; + } + }} + /> + ); +}; diff --git a/jams-react-client/src/globalUrls.js b/jams-react-client/src/globalUrls.js index 9d7f89c414d1973260595bbf25a7705faf02e06e..aef3865f03f80c9f9f62b6cce4efae86c1d01e52 100644 --- a/jams-react-client/src/globalUrls.js +++ b/jams-react-client/src/globalUrls.js @@ -111,5 +111,5 @@ module.exports = { api_path_get_group_members, api_path_post_group_member, api_path_delete_group_member, - api_path_get_admin_user_groups + api_path_get_admin_user_groups, }; diff --git a/jams-react-client/src/i18n.js b/jams-react-client/src/i18n.js index f5a0df3eceb389378d5d9e502e16d3627e61c7c1..34cce34846890515f7d6c282b35bbc107df9233b 100644 --- a/jams-react-client/src/i18n.js +++ b/jams-react-client/src/i18n.js @@ -1,6 +1,6 @@ import i18next from "i18next"; import LanguageDetector from "i18next-browser-languagedetector"; -import Backend from 'i18next-http-backend'; +import Backend from "i18next-http-backend"; import { initReactI18next } from "react-i18next"; i18next diff --git a/jams-react-client/src/index.js b/jams-react-client/src/index.js index dc95954d0bce87349a29044e9ee21f7510a997e7..8f9b8c4d701f656b458ace9607c99b04fc6ec9b9 100644 --- a/jams-react-client/src/index.js +++ b/jams-react-client/src/index.js @@ -31,7 +31,7 @@ import GroupsRoute from "routes/GroupsRoute.js"; import GroupRoute from "routes/GroupRoute.js"; import BlueprintsRoute from "routes/BlueprintsRoute.js"; import BlueprintRoute from "routes/BlueprintRoute.js"; -import SettingsRoute from "routes/SettingsRoute.js"; +import SettingsRoute from "routes/SettingsRoute.js"; import SignIn from "layouts/SignIn.js"; @@ -54,7 +54,10 @@ auth.checkServerInstalled(() => { <ProtectedRoute path="/groups" component={GroupsRoute} /> <ProtectedRoute path="/group/:groupid" component={GroupRoute} /> <ProtectedRoute path="/blueprints" component={BlueprintsRoute} /> - <ProtectedRoute path="/blueprint/:blueprintname" component={BlueprintRoute} /> + <ProtectedRoute + path="/blueprint/:blueprintname" + component={BlueprintRoute} + /> <ProtectedRoute path="/settings" component={SettingsRoute} /> <Redirect from="/" to="/signin" /> </Switch> diff --git a/jams-react-client/src/layouts/BaseLayout.js b/jams-react-client/src/layouts/BaseLayout.js index 89f336d38785d303888d7e259c7c43092a4c4335..115f551848f8befb61b652544af7129de405766e 100644 --- a/jams-react-client/src/layouts/BaseLayout.js +++ b/jams-react-client/src/layouts/BaseLayout.js @@ -29,13 +29,10 @@ import logo from "assets/img/jams_logo_white_no_gnu_package.svg"; import auth from "auth"; import configApiCall from "api.js"; -import { - api_path_get_start_update -} from "globalUrls"; +import { api_path_get_start_update } from "globalUrls"; import axios from "axios"; - import Dialog from "@material-ui/core/Dialog/Dialog"; import DialogTitle from "@material-ui/core/DialogTitle/DialogTitle"; import DialogContent from "@material-ui/core/DialogContent/DialogContent"; @@ -90,7 +87,7 @@ export default function Admin(props) { icon: Group, component: Groups, layout: "/admin", - admin: true + admin: true, }, { path: "/blueprints", @@ -98,7 +95,7 @@ export default function Admin(props) { icon: AllInbox, component: Blueprints, layout: "/admin", - admin: true + admin: true, }, { path: "/settings", @@ -106,7 +103,7 @@ export default function Admin(props) { icon: SettingsIcon, component: Settings, layout: "/admin", - admin: true + admin: true, }, ]; @@ -124,20 +121,29 @@ export default function Admin(props) { if (auth.hasAdminScope()) { if (auth.isActivated()) { setDialogMessage( - i18next.t("new_version_jams_available", "A new version of JAMS is available. Would you like to update now?") + i18next.t( + "new_version_jams_available", + "A new version of JAMS is available. Would you like to update now?" + ) ); setMessageYes("Update Now"); setMessageNo("Update Later"); } else { setDialogMessage( - i18next.t("running_community_version_jams", "You are currently running the community version of JAMS. Would you like to purchase a JAMS subscription?") + i18next.t( + "running_community_version_jams", + "You are currently running the community version of JAMS. Would you like to purchase a JAMS subscription?" + ) ); setMessageYes("Yes, go to Jami Store"); setMessageNo("No thanks"); } } else { setDialogMessage( - i18next.t("you_are_not_allowed_to_access_this_section", "You are not allowed to access this section. Please contact your administrator to get administrator privileges.") + i18next.t( + "you_are_not_allowed_to_access_this_section", + "You are not allowed to access this section. Please contact your administrator to get administrator privileges." + ) ); } }; @@ -148,7 +154,12 @@ export default function Admin(props) { auth.getUpdates(() => { if (auth.isUpdateAvailable()) { setOpen(true); - setMessage(i18next.t("an_update_is_available_for_jams", "An update is available for JAMS.")); + setMessage( + i18next.t( + "an_update_is_available_for_jams", + "An update is available for JAMS." + ) + ); } }); }); @@ -177,14 +188,24 @@ export default function Admin(props) { const handleUpdate = () => { setQuery(false); if (auth.isActivated()) { - setSnackbarMessage(i18next.t("updating_jams_shutting_down_shortly", "Updating JAMS, shutting down shortly...")); + setSnackbarMessage( + i18next.t( + "updating_jams_shutting_down_shortly", + "Updating JAMS, shutting down shortly..." + ) + ); axios(configApiCall(api_path_get_start_update, "POST", null, null)) .then(() => { handleCancel(); setUpdating(true); }) .catch((error) => { - setSnackbarMessage(i18next.t("error_while_attempting_update_jams", "Error occurred while attempting to update JAMS:") + error); + setSnackbarMessage( + i18next.t( + "error_while_attempting_update_jams", + "Error occurred while attempting to update JAMS:" + ) + error + ); }); } }; @@ -232,14 +253,9 @@ export default function Admin(props) { /> <div className={classes.mainPanel} ref={mainPanel}> - <Navbar - routes={Routes} - handleDrawerToggle={handleDrawerToggle} - /> - <div className={classes.map}> - {props.component} - </div> - <Footer /> + <Navbar routes={Routes} handleDrawerToggle={handleDrawerToggle} /> + <div className={classes.map}>{props.component}</div> + <Footer /> </div> </div> ); diff --git a/jams-react-client/src/layouts/ListLayout.js b/jams-react-client/src/layouts/ListLayout.js index 8183f126caa911c9b5b604b650849df1e43c2020..34f68700805300570ce5170d66a3ca2a6f5498b8 100644 --- a/jams-react-client/src/layouts/ListLayout.js +++ b/jams-react-client/src/layouts/ListLayout.js @@ -11,7 +11,7 @@ import Footer from "components/Footer/Footer.js"; import Sidebar from "components/Sidebar/Sidebar.js"; // @material-ui/icons -import AccountCircleIcon from '@material-ui/icons/AccountCircle'; +import AccountCircleIcon from "@material-ui/icons/AccountCircle"; import Person from "@material-ui/icons/Person"; import Group from "@material-ui/icons/Group"; import AllInbox from "@material-ui/icons/AllInbox"; @@ -30,13 +30,10 @@ import logo from "assets/img/jams_logo_white_no_gnu_package.svg"; import auth from "auth"; import configApiCall from "api.js"; -import { - api_path_get_start_update -} from "globalUrls"; +import { api_path_get_start_update } from "globalUrls"; import axios from "axios"; - import Dialog from "@material-ui/core/Dialog/Dialog"; import DialogTitle from "@material-ui/core/DialogTitle/DialogTitle"; import DialogContent from "@material-ui/core/DialogContent/DialogContent"; @@ -77,7 +74,7 @@ export default function Admin(props) { icon: AccountCircleIcon, component: Users, layout: "/admin", - admin: false + admin: false, }, { path: "/users", @@ -85,7 +82,7 @@ export default function Admin(props) { icon: Person, component: Users, layout: "/admin", - admin: false + admin: false, }, { path: "/groups", @@ -93,7 +90,7 @@ export default function Admin(props) { icon: Group, component: Groups, layout: "/admin", - admin: true + admin: true, }, { path: "/blueprints", @@ -101,7 +98,7 @@ export default function Admin(props) { icon: AllInbox, component: Blueprints, layout: "/admin", - admin: true + admin: true, }, { path: "/settings", @@ -109,7 +106,7 @@ export default function Admin(props) { icon: SettingsIcon, component: Settings, layout: "/admin", - admin: true + admin: true, }, ]; @@ -127,20 +124,29 @@ export default function Admin(props) { if (auth.hasAdminScope()) { if (auth.isActivated()) { setDialogMessage( - i18next.t("new_version_jams_available", "A new version of JAMS is available. Would you like to update now?") + i18next.t( + "new_version_jams_available", + "A new version of JAMS is available. Would you like to update now?" + ) ); setMessageYes("Update Now"); setMessageNo("Update Later"); } else { setDialogMessage( - i18next.t("running_community_version_jams", "You are currently running the community version of JAMS. Would you like to purchase a JAMS subscription?") + i18next.t( + "running_community_version_jams", + "You are currently running the community version of JAMS. Would you like to purchase a JAMS subscription?" + ) ); setMessageYes("Yes, go to Jami Store"); setMessageNo("No thanks"); } } else { setDialogMessage( - i18next.t("you_are_not_allowed_to_access_this_section", "You are not allowed to access this section. Please contact your administrator to get administrator privileges.") + i18next.t( + "you_are_not_allowed_to_access_this_section", + "You are not allowed to access this section. Please contact your administrator to get administrator privileges." + ) ); } }; @@ -151,7 +157,12 @@ export default function Admin(props) { auth.getUpdates(() => { if (auth.isUpdateAvailable()) { setOpen(true); - setMessage(i18next.t("an_update_is_available_for_jams", "An update is available for JAMS.")); + setMessage( + i18next.t( + "an_update_is_available_for_jams", + "An update is available for JAMS." + ) + ); } }); }); @@ -180,14 +191,24 @@ export default function Admin(props) { const handleUpdate = () => { setQuery(false); if (auth.isActivated()) { - setSnackbarMessage(i18next.t("updating_jams_shutting_down_shortly", "Updating JAMS, shutting down shortly...")); + setSnackbarMessage( + i18next.t( + "updating_jams_shutting_down_shortly", + "Updating JAMS, shutting down shortly..." + ) + ); axios(configApiCall(api_path_get_start_update, "POST", null, null)) .then(() => { handleCancel(); setUpdating(true); }) .catch((error) => { - setSnackbarMessage(i18next.t("error_while_attempting_update_jams", "Error occurred while attempting to update JAMS:") + error); + setSnackbarMessage( + i18next.t( + "error_while_attempting_update_jams", + "Error occurred while attempting to update JAMS:" + ) + error + ); }); } }; @@ -235,14 +256,11 @@ export default function Admin(props) { /> <div className={classes.mainPanel} ref={mainPanel}> - <Navbar - routes={Routes} - handleDrawerToggle={handleDrawerToggle} - /> - <div className={classes.content}> - <div className={classes.container}>{props.component}</div> - </div> - <Footer /> + <Navbar routes={Routes} handleDrawerToggle={handleDrawerToggle} /> + <div className={classes.content}> + <div className={classes.container}>{props.component}</div> + </div> + <Footer /> </div> </div> ); diff --git a/jams-react-client/src/layouts/SignIn.js b/jams-react-client/src/layouts/SignIn.js index 5ac22318560c9e4f23aa7705148aa33981545b79..24dcf233bcd494fae9cd76c1cd58bbcf1a40c1e6 100644 --- a/jams-react-client/src/layouts/SignIn.js +++ b/jams-react-client/src/layouts/SignIn.js @@ -74,12 +74,11 @@ export default function SignIn(props) { React.useEffect(() => { if (auth.isAuthenticated() && auth.isInstalled()) { - if(auth.hasAdminScope()) - history.push("/users"); + if (auth.hasAdminScope()) history.push("/users"); else { - if(auth.getUsername() !== null) { + if (auth.getUsername() !== null) { history.push(`/user/${auth.getUsername()}`); - } + } } } }); @@ -94,12 +93,11 @@ export default function SignIn(props) { auth.checkLastKnownStep(() => { auth.checkDirectoryType(() => { if (auth.isServerInstalled()) { - if(auth.hasAdminScope()) - history.push("/users"); + if (auth.hasAdminScope()) history.push("/users"); else { - if(auth.getUsername() !== null) { + if (auth.getUsername() !== null) { history.push(`/user/${auth.getUsername()}`); - } + } } } else { history.push("/"); diff --git a/jams-react-client/src/layouts/SignUp.js b/jams-react-client/src/layouts/SignUp.js index 2a56946e19e04c32e99e1d4699864894715927b5..eafda0e1c0aba0be12068c046a2b644b0f647e07 100644 --- a/jams-react-client/src/layouts/SignUp.js +++ b/jams-react-client/src/layouts/SignUp.js @@ -110,7 +110,7 @@ export default function SignUp(props) { <Box mt={8}> <Copyright /> </Box> - <Box mt={8} justifyContent="center" > + <Box mt={8} justifyContent="center"> <LanguagePicker navigationTarget={"/"} /> </Box> </Paper> diff --git a/jams-react-client/src/protected.route.js b/jams-react-client/src/protected.route.js index 35eeb0eb27e802bdbf6762fa709b4622bdd7d514..bf48b92f49d542d40a39fd37eae19db81137cf42 100644 --- a/jams-react-client/src/protected.route.js +++ b/jams-react-client/src/protected.route.js @@ -1,27 +1,27 @@ -import React from 'react' -import { Route, Redirect } from 'react-router-dom' -import auth from './auth' +import React from "react"; +import { Route, Redirect } from "react-router-dom"; +import auth from "./auth"; export const ProtectedRoute = ({ component: Component, ...rest }) => { - return ( - <Route {...rest} render={ - (props) => { - - if (auth.isAuthenticated() && auth.isInstalled()) { - return <Component {...props} /> - } - else { - return <Redirect to={{ - pathname: "/", - state: { - from: props.location - } - } - - } /> - } - - } - } /> - ) -} + return ( + <Route + {...rest} + render={(props) => { + if (auth.isAuthenticated() && auth.isInstalled()) { + return <Component {...props} />; + } else { + return ( + <Redirect + to={{ + pathname: "/", + state: { + from: props.location, + }, + }} + /> + ); + } + }} + /> + ); +}; diff --git a/jams-react-client/src/routes/BlueprintRoute.js b/jams-react-client/src/routes/BlueprintRoute.js index d9f873043b4cc16fe6faedaa767556c8d6142ef9..69958c571d6e5c0ad02db8d4c15258eb96987db0 100644 --- a/jams-react-client/src/routes/BlueprintRoute.js +++ b/jams-react-client/src/routes/BlueprintRoute.js @@ -3,8 +3,10 @@ import React from "react"; import BaseLayout from "layouts/BaseLayout.js"; import Blueprint from "views/Blueprint/Blueprint"; -export default function BlueprintRoute (props) { - return ( - <BaseLayout component={<Blueprint blueprintName={props.match.params.blueprintname} />} /> - ) -} \ No newline at end of file +export default function BlueprintRoute(props) { + return ( + <BaseLayout + component={<Blueprint blueprintName={props.match.params.blueprintname} />} + /> + ); +} diff --git a/jams-react-client/src/routes/BlueprintsRoute.js b/jams-react-client/src/routes/BlueprintsRoute.js index 35037ee61b7476ead9dd4d1e805768c85f5a99b0..5faa5f57b396fd396a72002d1fb45f928a6c76f2 100644 --- a/jams-react-client/src/routes/BlueprintsRoute.js +++ b/jams-react-client/src/routes/BlueprintsRoute.js @@ -4,8 +4,6 @@ import Blueprints from "views/Blueprints/Blueprints.js"; import ListLayout from "layouts/ListLayout.js"; -export default function BlueprintsRoute () { - return ( - <ListLayout component={<Blueprints />} /> - ) -} \ No newline at end of file +export default function BlueprintsRoute() { + return <ListLayout component={<Blueprints />} />; +} diff --git a/jams-react-client/src/routes/CreateUserRoute.js b/jams-react-client/src/routes/CreateUserRoute.js index 031f871e74efc7b8d963ecab2a1b26c53007d4da..59a8afec6e3a25d796d4f2f9b34ffe48ba7853c9 100644 --- a/jams-react-client/src/routes/CreateUserRoute.js +++ b/jams-react-client/src/routes/CreateUserRoute.js @@ -4,16 +4,14 @@ import EditCreateUserProfile from "views/UserProfile/EditCreateUserProfile.js"; import ListLayout from "layouts/ListLayout.js"; -export default function CreateUserRoute () { - return ( - <ListLayout component={<EditCreateUserProfile createUser={true} />} /> - ) +export default function CreateUserRoute() { + return <ListLayout component={<EditCreateUserProfile createUser={true} />} />; } // <EditCreateUserProfile - // createUser={createUser} - // setCreateUser={setCreateUser} - // setError={props.setError} - // setErrorMessage={props.setErrorMessage} - // setSeverity={props.setSeverity} - // /> \ No newline at end of file +// createUser={createUser} +// setCreateUser={setCreateUser} +// setError={props.setError} +// setErrorMessage={props.setErrorMessage} +// setSeverity={props.setSeverity} +// /> diff --git a/jams-react-client/src/routes/GroupRoute.js b/jams-react-client/src/routes/GroupRoute.js index d33110e1ef064dec3122e017ea14734cc2c75c23..1e3e21f7f11c6dba1f2a5ef3f0215f4655a53288 100644 --- a/jams-react-client/src/routes/GroupRoute.js +++ b/jams-react-client/src/routes/GroupRoute.js @@ -3,8 +3,10 @@ import React from "react"; import ListLayout from "layouts/ListLayout.js"; import EditGroup from "views/Groups/EditGroup.js"; -export default function GroupRoute (props) { - return ( - <ListLayout component={<EditGroup groupid={props.match.params.groupid} />} /> - ) -} \ No newline at end of file +export default function GroupRoute(props) { + return ( + <ListLayout + component={<EditGroup groupid={props.match.params.groupid} />} + /> + ); +} diff --git a/jams-react-client/src/routes/GroupsRoute.js b/jams-react-client/src/routes/GroupsRoute.js index db4bc7133b07d4316194805b972f6993acb899f5..2f016c1916731be6d4c4c474fb8c02540be2f470 100644 --- a/jams-react-client/src/routes/GroupsRoute.js +++ b/jams-react-client/src/routes/GroupsRoute.js @@ -3,8 +3,6 @@ import React from "react"; import ListLayout from "layouts/ListLayout.js"; import Groups from "views/Groups/Groups.js"; -export default function GroupsRoute () { - return ( - <ListLayout component={<Groups />} /> - ) -} \ No newline at end of file +export default function GroupsRoute() { + return <ListLayout component={<Groups />} />; +} diff --git a/jams-react-client/src/routes/SettingsRoute.js b/jams-react-client/src/routes/SettingsRoute.js index c645ee93c07a9c2fdf3a6d3a67cf22cb53a00a74..134e2d8de3182ec93de5800fd2e937e25450203b 100644 --- a/jams-react-client/src/routes/SettingsRoute.js +++ b/jams-react-client/src/routes/SettingsRoute.js @@ -4,8 +4,6 @@ import Settings from "views/Settings/Settings.js"; import BaseLayout from "layouts/BaseLayout.js"; -export default function SettingsRoute (props) { - return ( - <BaseLayout component={<Settings />} /> - ) -} \ No newline at end of file +export default function SettingsRoute(props) { + return <BaseLayout component={<Settings />} />; +} diff --git a/jams-react-client/src/routes/UserRoute.js b/jams-react-client/src/routes/UserRoute.js index 5a765ab7d4bcc5e66d0e549d6f587edbedb40de8..3f3e1ff3c5436399b8af23a5090792febddd8850 100644 --- a/jams-react-client/src/routes/UserRoute.js +++ b/jams-react-client/src/routes/UserRoute.js @@ -4,8 +4,10 @@ import UserProfile from "views/UserProfile/UserProfile.js"; import BaseLayout from "layouts/BaseLayout.js"; -export default function UsersRoute (props) { - return ( - <BaseLayout component={<UserProfile username={props.match.params.username} />} /> - ) -} \ No newline at end of file +export default function UsersRoute(props) { + return ( + <BaseLayout + component={<UserProfile username={props.match.params.username} />} + /> + ); +} diff --git a/jams-react-client/src/routes/UsersRoute.js b/jams-react-client/src/routes/UsersRoute.js index 668f097a4055947aac069c0615474edbecfd9fa4..565e824716ce94b4734c1aaef95a34e17e24921c 100644 --- a/jams-react-client/src/routes/UsersRoute.js +++ b/jams-react-client/src/routes/UsersRoute.js @@ -4,8 +4,6 @@ import Users from "views/Users/Users.js"; import ListLayout from "layouts/ListLayout.js"; -export default function UsersRoute () { - return ( - <ListLayout component={<Users />} /> - ) -} \ No newline at end of file +export default function UsersRoute() { + return <ListLayout component={<Users />} />; +} diff --git a/jams-react-client/src/routes/routes.js b/jams-react-client/src/routes/routes.js index 03eafaedd60d2c74a167390f5a0a26d8394d47c9..71e1bc081efa408ccb31ccbf8f03cb71d46ae108 100644 --- a/jams-react-client/src/routes/routes.js +++ b/jams-react-client/src/routes/routes.js @@ -68,5 +68,4 @@ export default function Routes() { ]; return dashboardRoutes; - -} \ No newline at end of file +} diff --git a/jams-react-client/src/tools.js b/jams-react-client/src/tools.js index 3c6fe215281797df5e9e6385aab7345c79674d6b..ba579019ea1f52c04ab95578e76d57a4d61513f3 100644 --- a/jams-react-client/src/tools.js +++ b/jams-react-client/src/tools.js @@ -1,33 +1,31 @@ -import React from 'react'; -import MenuItem from '@material-ui/core/MenuItem'; +import React from "react"; +import MenuItem from "@material-ui/core/MenuItem"; export function buildSelectMenuItems(elements) { - return elements.map((d) => - <MenuItem value={d.value}>{d.label}</MenuItem> - ) + return elements.map((d) => <MenuItem value={d.value}>{d.label}</MenuItem>); } // read file content export function readSingleFile(evt, fieldContents) { - var f = evt.target.files[0]; - if (f) { - var r = new FileReader(); - r.onload = function (e) { - var contents = e.target.result; - fieldContents=contents; - } - console.log(fieldContents); - r.readAsText(f); - return fieldContents - } + var f = evt.target.files[0]; + if (f) { + var r = new FileReader(); + r.onload = function (e) { + var contents = e.target.result; + fieldContents = contents; + }; + console.log(fieldContents); + r.readAsText(f); + return fieldContents; + } } -export function retrieveArrayElement(value, elements){ - for(let i=0; i < elements.length;i++){ - if(elements[i].value === value){ - return elements[i]; - } +export function retrieveArrayElement(value, elements) { + for (let i = 0; i < elements.length; i++) { + if (elements[i].value === value) { + return elements[i]; } + } } -export default {buildSelectMenuItems, readSingleFile, retrieveArrayElement}; \ No newline at end of file +export default { buildSelectMenuItems, readSingleFile, retrieveArrayElement }; diff --git a/jams-react-client/src/variables/charts.js b/jams-react-client/src/variables/charts.js index 828133ebe35e9222494eb7856d5debe20512d842..59d9d7b7019e902828c478c4185e5ce7fc99e8b4 100755 --- a/jams-react-client/src/variables/charts.js +++ b/jams-react-client/src/variables/charts.js @@ -18,11 +18,11 @@ var delays2 = 80, const dailySalesChart = { data: { labels: ["M", "T", "W", "T", "F", "S", "S"], - series: [[12, 17, 7, 17, 23, 18, 38]] + series: [[12, 17, 7, 17, 23, 18, 38]], }, options: { lineSmooth: Chartist.Interpolation.cardinal({ - tension: 0 + tension: 0, }), low: 0, high: 50, // creative tim: we recommend you to set the high sa the biggest value + something for a better look @@ -30,12 +30,12 @@ const dailySalesChart = { top: 0, right: 0, bottom: 0, - left: 0 - } + left: 0, + }, }, // for animation animation: { - draw: function(data) { + draw: function (data) { if (data.type === "line" || data.type === "area") { data.element.animate({ d: { @@ -47,8 +47,8 @@ const dailySalesChart = { .translate(0, data.chartRect.height()) .stringify(), to: data.path.clone().stringify(), - easing: Chartist.Svg.Easing.easeOutQuint - } + easing: Chartist.Svg.Easing.easeOutQuint, + }, }); } else if (data.type === "point") { data.element.animate({ @@ -57,12 +57,12 @@ const dailySalesChart = { dur: durations, from: 0, to: 1, - easing: "ease" - } + easing: "ease", + }, }); } - } - } + }, + }, }; // ############################## @@ -83,13 +83,13 @@ const emailsSubscriptionChart = { "Sep", "Oct", "Nov", - "Dec" + "Dec", ], - series: [[542, 443, 320, 780, 553, 453, 326, 434, 568, 610, 756, 895]] + series: [[542, 443, 320, 780, 553, 453, 326, 434, 568, 610, 756, 895]], }, options: { axisX: { - showGrid: false + showGrid: false, }, low: 0, high: 1000, @@ -97,8 +97,8 @@ const emailsSubscriptionChart = { top: 0, right: 5, bottom: 0, - left: 0 - } + left: 0, + }, }, responsiveOptions: [ [ @@ -106,15 +106,15 @@ const emailsSubscriptionChart = { { seriesBarDistance: 5, axisX: { - labelInterpolationFnc: function(value) { + labelInterpolationFnc: function (value) { return value[0]; - } - } - } - ] + }, + }, + }, + ], ], animation: { - draw: function(data) { + draw: function (data) { if (data.type === "bar") { data.element.animate({ opacity: { @@ -122,12 +122,12 @@ const emailsSubscriptionChart = { dur: durations2, from: 0, to: 1, - easing: "ease" - } + easing: "ease", + }, }); } - } - } + }, + }, }; // ############################## @@ -137,11 +137,11 @@ const emailsSubscriptionChart = { const completedTasksChart = { data: { labels: ["12am", "3pm", "6pm", "9pm", "12pm", "3am", "6am", "9am"], - series: [[230, 750, 450, 300, 280, 240, 200, 190]] + series: [[230, 750, 450, 300, 280, 240, 200, 190]], }, options: { lineSmooth: Chartist.Interpolation.cardinal({ - tension: 0 + tension: 0, }), low: 0, high: 1000, // creative tim: we recommend you to set the high sa the biggest value + something for a better look @@ -149,11 +149,11 @@ const completedTasksChart = { top: 0, right: 0, bottom: 0, - left: 0 - } + left: 0, + }, }, animation: { - draw: function(data) { + draw: function (data) { if (data.type === "line" || data.type === "area") { data.element.animate({ d: { @@ -165,8 +165,8 @@ const completedTasksChart = { .translate(0, data.chartRect.height()) .stringify(), to: data.path.clone().stringify(), - easing: Chartist.Svg.Easing.easeOutQuint - } + easing: Chartist.Svg.Easing.easeOutQuint, + }, }); } else if (data.type === "point") { data.element.animate({ @@ -175,16 +175,16 @@ const completedTasksChart = { dur: durations, from: 0, to: 1, - easing: "ease" - } + easing: "ease", + }, }); } - } - } + }, + }, }; module.exports = { dailySalesChart, emailsSubscriptionChart, - completedTasksChart + completedTasksChart, }; diff --git a/jams-react-client/src/variables/general.js b/jams-react-client/src/variables/general.js index 1c0b3633ee111d7b09f96344dad2f18653f98c89..f8e665dacff302a6b6f78300cbdf3dcb9ea99404 100755 --- a/jams-react-client/src/variables/general.js +++ b/jams-react-client/src/variables/general.js @@ -6,21 +6,21 @@ var bugs = [ 'Sign contract for "What are conference organizers afraid of?"', "Lines From Great Russian Literature? Or E-mails From My Boss?", "Flooded: One year later, assessing what was lost and what was found when a ravaging rain swept through metro Detroit", - "Create 4 Invisible User Experiences you Never Knew About" + "Create 4 Invisible User Experiences you Never Knew About", ]; var website = [ "Flooded: One year later, assessing what was lost and what was found when a ravaging rain swept through metro Detroit", - 'Sign contract for "What are conference organizers afraid of?"' + 'Sign contract for "What are conference organizers afraid of?"', ]; var server = [ "Lines From Great Russian Literature? Or E-mails From My Boss?", "Flooded: One year later, assessing what was lost and what was found when a ravaging rain swept through metro Detroit", - 'Sign contract for "What are conference organizers afraid of?"' + 'Sign contract for "What are conference organizers afraid of?"', ]; module.exports = { // these 3 are used to create the tasks lists in TasksCard - Dashboard view bugs, website, - server + server, }; diff --git a/jams-react-client/src/views/Blueprint/Blueprint.js b/jams-react-client/src/views/Blueprint/Blueprint.js index 7ea53ff7757ec114216af8a98a01e9ff2c39baaf..29b3d6b84c3dca462f49b847b8e8ca5c80f1085a 100644 --- a/jams-react-client/src/views/Blueprint/Blueprint.js +++ b/jams-react-client/src/views/Blueprint/Blueprint.js @@ -1,18 +1,16 @@ import React from "react"; -import PropTypes from 'prop-types'; -import AppBar from '@material-ui/core/AppBar'; -import Tabs from '@material-ui/core/Tabs'; -import Tab from '@material-ui/core/Tab'; -import Typography from '@material-ui/core/Typography'; -import Box from '@material-ui/core/Box'; +import PropTypes from "prop-types"; +import AppBar from "@material-ui/core/AppBar"; +import Tabs from "@material-ui/core/Tabs"; +import Tab from "@material-ui/core/Tab"; +import Typography from "@material-ui/core/Typography"; +import Box from "@material-ui/core/Box"; -import EditBlueprintPermissions from "./EditBlueprintPermissions" -import EditBlueprintConfiguration from "./EditBlueprintConfiguration" +import EditBlueprintPermissions from "./EditBlueprintPermissions"; +import EditBlueprintConfiguration from "./EditBlueprintConfiguration"; -import { - infoColor -} from "assets/jss/material-dashboard-react.js"; +import { infoColor } from "assets/jss/material-dashboard-react.js"; import i18next from "i18next"; @@ -45,7 +43,7 @@ TabPanel.propTypes = { function a11yProps(index) { return { id: `simple-tab-${index}`, - 'aria-controls': `simple-tabpanel-${index}`, + "aria-controls": `simple-tabpanel-${index}`, }; } @@ -55,7 +53,7 @@ const styles = { margin: "0", fontSize: "14px", marginTop: "0", - marginBottom: "0" + marginBottom: "0", }, cardTitleWhite: { color: "#FFFFFF", @@ -64,12 +62,11 @@ const styles = { fontWeight: "300", fontFamily: "'Roboto', 'Helvetica', 'Arial', sans-serif", marginBottom: "3px", - textDecoration: "none" - } + textDecoration: "none", + }, }; export default function Blueprint(props) { - const [value, setValue] = React.useState(0); const handleChange = (event, newValue) => { @@ -78,16 +75,26 @@ export default function Blueprint(props) { return ( <div> <AppBar position="static" style={{ background: infoColor[0] }}> - <Tabs value={value} onChange={handleChange} aria-label="simple tabs example"> - <Tab label={i18next.t("permissions", "Permissions")} {...a11yProps(0)} /> - <Tab label={i18next.t("configuration", "Configuration")} {...a11yProps(1)} /> + <Tabs + value={value} + onChange={handleChange} + aria-label="simple tabs example" + > + <Tab + label={i18next.t("permissions", "Permissions")} + {...a11yProps(0)} + /> + <Tab + label={i18next.t("configuration", "Configuration")} + {...a11yProps(1)} + /> </Tabs> </AppBar> <TabPanel value={value} index={0}> - <EditBlueprintPermissions blueprintName={props.blueprintName} /> + <EditBlueprintPermissions blueprintName={props.blueprintName} /> </TabPanel> <TabPanel value={value} index={1}> - <EditBlueprintConfiguration blueprintName={props.blueprintName} /> + <EditBlueprintConfiguration blueprintName={props.blueprintName} /> </TabPanel> </div> ); diff --git a/jams-react-client/src/views/Blueprint/EditBlueprintConfiguration.js b/jams-react-client/src/views/Blueprint/EditBlueprintConfiguration.js index 94483f52f88197ea3ab60450e28d925b9d5b4f27..0820df8b904ff40135cf4a3916861a520d64f263 100644 --- a/jams-react-client/src/views/Blueprint/EditBlueprintConfiguration.js +++ b/jams-react-client/src/views/Blueprint/EditBlueprintConfiguration.js @@ -311,13 +311,25 @@ export default function EditBlueprintConfiguration(props) { setOpen(false); setSeverity("success"); setOpen(true); - setMessage(i18next.t("updated_blueprint_configuration_successfully", "Blueprint configuration successfully updated.")); + setMessage( + i18next.t( + "updated_blueprint_configuration_successfully", + "Blueprint configuration successfully updated." + ) + ); }) .catch((error) => { setOpen(false); setSeverity("error"); setOpen(true); - setMessage(i18next.t("error_updating_blueprint_configuration", "Error occurred while updating blueprint configuration.") + error + "!"); + setMessage( + i18next.t( + "error_updating_blueprint_configuration", + "Error occurred while updating blueprint configuration." + ) + + error + + "!" + ); }); }; @@ -387,14 +399,24 @@ export default function EditBlueprintConfiguration(props) { <CardIcon color="info"> <BuildOutlinedIcon /> </CardIcon> - <p className={classes.cardCategory}>{i18next.t("configuration", "Configuration")}</p> + <p className={classes.cardCategory}> + {i18next.t("configuration", "Configuration")} + </p> <h3 className={classes.cardTitle}>{props.blueprintName}</h3> </CardHeader> <CardBody profile> <div className={classes.root}> <Grid container spacing={2}> <Grid item xs={12} sm={12} md={12}> - <FormLabel component="legend">UPnP <CustomPopupState message={i18next.t("upnp_custom_popup", "UPnP allows Jami to automatically open network ports to establish peer-to-peer communications.")} /></FormLabel> + <FormLabel component="legend"> + UPnP{" "} + <CustomPopupState + message={i18next.t( + "upnp_custom_popup", + "UPnP allows Jami to automatically open network ports to establish peer-to-peer communications." + )} + /> + </FormLabel> <FormControlLabel control={ <Switch @@ -417,7 +439,15 @@ export default function EditBlueprintConfiguration(props) { </Grid> <Grid item xs={12} sm={12} md={12}> <FormControl component="fieldset"> - <FormLabel component="legend">TURN <CustomPopupState message={i18next.t("turn_server_configuration_popup", "Configure a TURN server to establish a connection when peer-to-peer communication is not possible")} /></FormLabel> + <FormLabel component="legend"> + TURN{" "} + <CustomPopupState + message={i18next.t( + "turn_server_configuration_popup", + "Configure a TURN server to establish a connection when peer-to-peer communication is not possible" + )} + /> + </FormLabel> <RadioGroup value={selectedTurnOption} aria-label="gender" @@ -427,12 +457,18 @@ export default function EditBlueprintConfiguration(props) { <FormControlLabel value="defaultTurn" control={<StyledRadio />} - label={i18next.t("use_jami_default_turn_configuration", "Use Jami default TURN configuration")} + label={i18next.t( + "use_jami_default_turn_configuration", + "Use Jami default TURN configuration" + )} /> <FormControlLabel value="customTurn" control={<StyledRadio />} - label={i18next.t("use_a_custom_turn_configuration", "Use a custom TURN configuration")} + label={i18next.t( + "use_a_custom_turn_configuration", + "Use a custom TURN configuration" + )} /> <FormGroup row @@ -445,7 +481,10 @@ export default function EditBlueprintConfiguration(props) { > <FormControl className={classes.margin} size="large"> <InputLabel htmlFor="turnServer"> - {i18next.t("turn_server_address", "TURN Server address")} + {i18next.t( + "turn_server_address", + "TURN Server address" + )} </InputLabel> <Input id="turnServer" @@ -477,7 +516,10 @@ export default function EditBlueprintConfiguration(props) { > <FormControl className={classes.margin} size="large"> <InputLabel htmlFor="turnServerUserName"> - {i18next.t("turn_server_username", "TURN server username")} + {i18next.t( + "turn_server_username", + "TURN server username" + )} </InputLabel> <Input id="turnServerUserName" @@ -509,7 +551,10 @@ export default function EditBlueprintConfiguration(props) { > <FormControl className={classes.margin} size="large"> <InputLabel htmlFor="turnServerPassword"> - {i18next.t("turn_server_password", "TURN server password")} + {i18next.t( + "turn_server_password", + "TURN server password" + )} </InputLabel> <Input disabled={!turnEnabled} @@ -548,7 +593,10 @@ export default function EditBlueprintConfiguration(props) { <FormControlLabel value="disabledTurn" control={<StyledRadio />} - label={i18next.t("disable_turn_configuration", "Disable TURN configuration")} + label={i18next.t( + "disable_turn_configuration", + "Disable TURN configuration" + )} /> </RadioGroup> </FormControl> @@ -556,7 +604,15 @@ export default function EditBlueprintConfiguration(props) { <Grid item xs={12} sm={12} md={4}></Grid> <Grid item xs={12} sm={12} md={12}> <FormControl component="fieldset"> - <FormLabel component="legend">DHT Proxy <CustomPopupState message={i18next.t("dht_configuration_popup", "Configure the DHT proxy server used by this account")} /></FormLabel> + <FormLabel component="legend"> + DHT Proxy{" "} + <CustomPopupState + message={i18next.t( + "dht_configuration_popup", + "Configure the DHT proxy server used by this account" + )} + /> + </FormLabel> <RadioGroup value={selectedDHTProxyOption} aria-label="gender" @@ -566,12 +622,18 @@ export default function EditBlueprintConfiguration(props) { <FormControlLabel value="defaultDHTProxy" control={<StyledRadio />} - label={i18next.t("use_jami_default_dht_proxy_configuration", "Use Jami default DHT Proxy configuration")} + label={i18next.t( + "use_jami_default_dht_proxy_configuration", + "Use Jami default DHT Proxy configuration" + )} /> <FormControlLabel value="customDHTProxy" control={<StyledRadio />} - label={i18next.t("use_a_custom_dht_proxy_configuration", "Use a custom DHT Proxy configuration")} + label={i18next.t( + "use_a_custom_dht_proxy_configuration", + "Use a custom DHT Proxy configuration" + )} /> <FormGroup row> <FormControl @@ -585,7 +647,10 @@ export default function EditBlueprintConfiguration(props) { }} > <InputLabel htmlFor="proxyServer"> - {i18next.t("dht_proxy_server_name", "DHT proxy server name")} + {i18next.t( + "dht_proxy_server_name", + "DHT proxy server name" + )} </InputLabel> <Input id="proxyServer" @@ -618,7 +683,10 @@ export default function EditBlueprintConfiguration(props) { }} > <InputLabel htmlFor="dhtProxyListUrl"> - {i18next.t("dht_proxy_list_url", "DHT proxy List URL")} + {i18next.t( + "dht_proxy_list_url", + "DHT proxy List URL" + )} </InputLabel> <Input id="proxyServer" @@ -642,7 +710,10 @@ export default function EditBlueprintConfiguration(props) { <FormControlLabel value="disabledDHTProxy" control={<StyledRadio />} - label={i18next.t("disable_dht_proxy_configuration", "Disable DHT Proxy configuration")} + label={i18next.t( + "disable_dht_proxy_configuration", + "Disable DHT Proxy configuration" + )} /> </RadioGroup> </FormControl> diff --git a/jams-react-client/src/views/Blueprint/EditBlueprintPermissions.js b/jams-react-client/src/views/Blueprint/EditBlueprintPermissions.js index aebb2a16ea30f3c3e5c9fa48a0194c5dd43a3ee2..96c4ba9569c647549e6b6ec18112afaa4abc4cfd 100644 --- a/jams-react-client/src/views/Blueprint/EditBlueprintPermissions.js +++ b/jams-react-client/src/views/Blueprint/EditBlueprintPermissions.js @@ -18,12 +18,12 @@ import FormControlLabel from "@material-ui/core/FormControlLabel"; import FormLabel from "@material-ui/core/FormLabel"; import Button from "components/CustomButtons/Button.js"; -import AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutline'; +import AddCircleOutlineIcon from "@material-ui/icons/AddCircleOutline"; import Avatar from "@material-ui/core/Avatar"; import Table from "@material-ui/core/Table"; -import TableHead from '@material-ui/core/TableHead'; +import TableHead from "@material-ui/core/TableHead"; import TableRow from "@material-ui/core/TableRow"; import TableBody from "@material-ui/core/TableBody"; import TableCell from "@material-ui/core/TableCell"; @@ -38,14 +38,14 @@ import noProfilePicture from "assets/img/faces/no-profile-picture.png"; import axios from "axios"; import configApiCall from "../../api"; -import { +import { api_path_blueprints, api_path_get_user_directory_search, api_path_get_ns_name_from_addr, - api_path_get_user_profile + api_path_get_user_profile, } from "../../globalUrls"; -import TemporaryDrawer from "components/Drawer/Drawer" +import TemporaryDrawer from "components/Drawer/Drawer"; import dashboardStyle from "assets/jss/material-dashboard-react/views/dashboardStyle.js"; @@ -164,13 +164,13 @@ export default function EditBlueprintPermissions(props) { .then((response) => { let profiles = []; const profilesResults = response.data.profiles; - profilesResults.forEach((profile) =>{ - let existingUser = false; - users.forEach((user)=>{ - if(profile.username === user.username) existingUser = true; - }) - if(!existingUser) profiles.push(profile); - }) + profilesResults.forEach((profile) => { + let existingUser = false; + users.forEach((user) => { + if (profile.username === user.username) existingUser = true; + }); + if (!existingUser) profiles.push(profile); + }); setUsers(profiles); }) .catch((error) => { @@ -212,13 +212,21 @@ export default function EditBlueprintPermissions(props) { setAllowLookup(policyData["allowLookup"]); policyData["defaultModerators"].split("/").forEach((id) => { - if(id !== "undefined" && id !== ""){ - axios(configApiCall(api_path_get_ns_name_from_addr + id), null, null).then((usernameResponse) => { + if (id !== "undefined" && id !== "") { + axios( + configApiCall(api_path_get_ns_name_from_addr + id), + null, + null + ).then((usernameResponse) => { let username = usernameResponse.data.name; - axios(configApiCall(api_path_get_user_profile + username), null, null).then((userProfileResponse) => { + axios( + configApiCall(api_path_get_user_profile + username), + null, + null + ).then((userProfileResponse) => { let userProfiles = blueprintModerators; userProfileResponse.data["id"] = id; - userProfiles.push(userProfileResponse.data) + userProfiles.push(userProfileResponse.data); setBlueprintModerators(userProfiles); // This state update is added to refresh the list of moderators setOpenDrawer(true); @@ -226,7 +234,7 @@ export default function EditBlueprintPermissions(props) { }); }); } - }) + }); }) .catch((error) => { console.log( @@ -292,13 +300,25 @@ export default function EditBlueprintPermissions(props) { setOpen(false); setSeverity("success"); setOpen(true); - setMessage(i18next.t("updated_blueprint_permissions_successfully", "Blueprint permissions successfully updated.")); + setMessage( + i18next.t( + "updated_blueprint_permissions_successfully", + "Blueprint permissions successfully updated." + ) + ); }) .catch((error) => { setOpen(false); setSeverity("error"); setOpen(true); - setMessage(i18next.t("error_updating_blueprint_permissions", "Error occurred while updating blueprint permissions.") + error + "!"); + setMessage( + i18next.t( + "error_updating_blueprint_permissions", + "Error occurred while updating blueprint permissions." + ) + + error + + "!" + ); }); }; @@ -307,21 +327,24 @@ export default function EditBlueprintPermissions(props) { }; const addModeratorToBlueprint = (user) => { - handleUpdatePermissions("defaultModerators", defaultModerators + user.id + "/"); - setDefaultModerators(defaultModerators + user.id + "/"); - let newBlueprintModerators = blueprintModerators; - newBlueprintModerators.push(user); - setBlueprintModerators(newBlueprintModerators); - } + handleUpdatePermissions( + "defaultModerators", + defaultModerators + user.id + "/" + ); + setDefaultModerators(defaultModerators + user.id + "/"); + let newBlueprintModerators = blueprintModerators; + newBlueprintModerators.push(user); + setBlueprintModerators(newBlueprintModerators); + }; const removeModeratorFromBlueprint = (user) => { - let newDefaultModerators = defaultModerators.replace( user.id + "/", "") + let newDefaultModerators = defaultModerators.replace(user.id + "/", ""); handleUpdatePermissions("defaultModerators", newDefaultModerators); setDefaultModerators(newDefaultModerators); let newBlueprintModerators = blueprintModerators; newBlueprintModerators.splice(newBlueprintModerators.indexOf(user), 1); setBlueprintModerators(newBlueprintModerators); - } + }; return ( <div> @@ -336,16 +359,19 @@ export default function EditBlueprintPermissions(props) { {message} </Alert> </Snackbar> - <TemporaryDrawer - openDrawer={openDrawer} - setOpenDrawer={setOpenDrawer} - direction="right" - placeholder={i18next.t("add_moderator_to_blueprint", "Add moderator to blueprint ...")} - searchTargets={searchUsers} - targets={users} - existingTargets={blueprintModerators} - addElementToTarget={addModeratorToBlueprint} - type="user" + <TemporaryDrawer + openDrawer={openDrawer} + setOpenDrawer={setOpenDrawer} + direction="right" + placeholder={i18next.t( + "add_moderator_to_blueprint", + "Add moderator to blueprint ..." + )} + searchTargets={searchUsers} + targets={users} + existingTargets={blueprintModerators} + addElementToTarget={addModeratorToBlueprint} + type="user" /> <GridContainer> <GridItem xs={12} sm={12} md={6}> @@ -354,202 +380,285 @@ export default function EditBlueprintPermissions(props) { <CardIcon color="info"> <PriorityHighOutlinedIcon /> </CardIcon> - <p className={classes.cardCategory}>{i18next.t("permissions", "Permissions")}</p> + <p className={classes.cardCategory}> + {i18next.t("permissions", "Permissions")} + </p> <h3 className={classes.cardTitle}>{props.blueprintName}</h3> </CardHeader> <CardBody profile> <div className={classes.root}> <Grid container spacing={5}> <Grid item xs={12} sm={12} md={12}> - <Grid container spacing={2}> - <Grid item xs={12} sm={12} md={12}> - <FormLabel component="legend">Call parameters</FormLabel> - <FormGroup row> - <FormControlLabel - control={ - <Checkbox - checked={videoEnabled} - color="primary" - onChange={(e) => { - setVideoEnabled(e.target.checked); - handleUpdatePermissions( - "videoEnabled", - e.target.checked - ); - }} - name="videoEnabled" + <Grid container spacing={2}> + <Grid item xs={12} sm={12} md={12}> + <FormLabel component="legend"> + Call parameters + </FormLabel> + <FormGroup row> + <FormControlLabel + control={ + <Checkbox + checked={videoEnabled} + color="primary" + onChange={(e) => { + setVideoEnabled(e.target.checked); + handleUpdatePermissions( + "videoEnabled", + e.target.checked + ); + }} + name="videoEnabled" + /> + } + label={i18next.t( + "allow_video_calls", + "Allow video calls" + )} /> - } - label={i18next.t("allow_video_calls", "Allow video calls")} - /> - <CustomPopupState message={i18next.t("allow_incoming_calls_from_unknown_allow_video_calls_info", "If this option is disabled, only audio calls are allowed.")} /> - </FormGroup> - <FormGroup row> - <FormControlLabel - control={ - <Checkbox - checked={publicInCalls} - color="primary" - onChange={(e) => { - setPublicInCalls(e.target.checked); - handleUpdatePermissions( - "publicInCalls", - e.target.checked - ); - }} - name="publicInCalls" + <CustomPopupState + message={i18next.t( + "allow_incoming_calls_from_unknown_allow_video_calls_info", + "If this option is disabled, only audio calls are allowed." + )} /> - } - label={i18next.t("allow_incoming_calls_from_unknown_contacts", "Allow incoming calls from unknown contacts")} - /> - <CustomPopupState message={i18next.t("allow_incoming_calls_from_unknown_contacts_info", "If this option is disabled, only contacts from your list can contact you.")} /> - </FormGroup> - <FormGroup row> - <FormControlLabel - control={ - <Checkbox - checked={autoAnswer} - color="primary" - onChange={(e) => { - setAutoAnswer(e.target.checked); - handleUpdatePermissions( - "autoAnswer", - e.target.checked - ); - }} - name="autoAnswer" + </FormGroup> + <FormGroup row> + <FormControlLabel + control={ + <Checkbox + checked={publicInCalls} + color="primary" + onChange={(e) => { + setPublicInCalls(e.target.checked); + handleUpdatePermissions( + "publicInCalls", + e.target.checked + ); + }} + name="publicInCalls" + /> + } + label={i18next.t( + "allow_incoming_calls_from_unknown_contacts", + "Allow incoming calls from unknown contacts" + )} /> - } - label={i18next.t("auto_answer_calss", "Auto answer calls")} - /> - <CustomPopupState message={i18next.t("auto_answer_calls_info", "If this option is enabled, incoming calls are automatically answered. This option can be useful to monitor your house or a particular room when you are away from home for example.")} /> - </FormGroup> - </Grid> - <Grid item xs={12} sm={12} md={12}> - <FormLabel component="legend">{i18next.t("local_lan","Local LAN")}</FormLabel> - <FormGroup row> - <FormControlLabel - control={ - <Checkbox - checked={peerDiscovery} - color="primary" - onChange={(e) => { - setPeerDiscovery(e.target.checked); - handleUpdatePermissions( - "peerDiscovery", - e.target.checked - ); - }} - name="peerDiscovery" + <CustomPopupState + message={i18next.t( + "allow_incoming_calls_from_unknown_contacts_info", + "If this option is disabled, only contacts from your list can contact you." + )} /> - } - label={i18next.t("allow_use_of_jami_in_local_lan", "Allow discovery of other peers on a local network")} - /> - <CustomPopupState message={i18next.t("local_lan_info", "If this option is enabled, you can communicate with connected contacts on you local lan, even if your lan is disconnected from the Internet.")} /> - </FormGroup> - </Grid> - <Grid item xs={12} sm={12} md={12}> - <FormLabel component="legend">{i18next.t("contact_management", "Contact management")}</FormLabel> - <FormGroup row> - <FormControlLabel - control={ - <Checkbox - checked={allowLookup} - color="primary" - onChange={(e) => { - setAllowLookup(e.target.checked); - handleUpdatePermissions( - "allowLookup", - e.target.checked - ); - }} - name="allowLookup" + </FormGroup> + <FormGroup row> + <FormControlLabel + control={ + <Checkbox + checked={autoAnswer} + color="primary" + onChange={(e) => { + setAutoAnswer(e.target.checked); + handleUpdatePermissions( + "autoAnswer", + e.target.checked + ); + }} + name="autoAnswer" + /> + } + label={i18next.t( + "auto_answer_calss", + "Auto answer calls" + )} /> - } - label={i18next.t("allow_jami_user_to_search_for_other_contacts", "Allow user to add new contacts")} - /> - <CustomPopupState message={i18next.t("lookup_info", "If this option is disabled, user can not search and add new contacts")} /> - </FormGroup> - </Grid> - <Grid item xs={12} sm={12} md={12}> - + <CustomPopupState + message={i18next.t( + "auto_answer_calls_info", + "If this option is enabled, incoming calls are automatically answered. This option can be useful to monitor your house or a particular room when you are away from home for example." + )} + /> + </FormGroup> + </Grid> + <Grid item xs={12} sm={12} md={12}> + <FormLabel component="legend"> + {i18next.t("local_lan", "Local LAN")} + </FormLabel> + <FormGroup row> + <FormControlLabel + control={ + <Checkbox + checked={peerDiscovery} + color="primary" + onChange={(e) => { + setPeerDiscovery(e.target.checked); + handleUpdatePermissions( + "peerDiscovery", + e.target.checked + ); + }} + name="peerDiscovery" + /> + } + label={i18next.t( + "allow_use_of_jami_in_local_lan", + "Allow discovery of other peers on a local network" + )} + /> + <CustomPopupState + message={i18next.t( + "local_lan_info", + "If this option is enabled, you can communicate with connected contacts on you local lan, even if your lan is disconnected from the Internet." + )} + /> + </FormGroup> + </Grid> + <Grid item xs={12} sm={12} md={12}> + <FormLabel component="legend"> + {i18next.t( + "contact_management", + "Contact management" + )} + </FormLabel> + <FormGroup row> + <FormControlLabel + control={ + <Checkbox + checked={allowLookup} + color="primary" + onChange={(e) => { + setAllowLookup(e.target.checked); + handleUpdatePermissions( + "allowLookup", + e.target.checked + ); + }} + name="allowLookup" + /> + } + label={i18next.t( + "allow_jami_user_to_search_for_other_contacts", + "Allow user to add new contacts" + )} + /> + <CustomPopupState + message={i18next.t( + "lookup_info", + "If this option is disabled, user can not search and add new contacts" + )} + /> + </FormGroup> + </Grid> + <Grid item xs={12} sm={12} md={12}></Grid> </Grid> </Grid> </Grid> - </Grid> </div> </CardBody> </Card> </GridItem> <GridItem xs={12} sm={12} md={12}> - <h3>Rendezvous mode</h3> - - <FormGroup row> - <FormControlLabel - control={ - <Switch - checked={rendezVous} - color="primary" - onChange={(e) => { - setRendezVous(e.target.checked); - handleUpdatePermissions( - "rendezVous", - e.target.checked - ); - }} - name="rendezVous" - inputProps={{ "aria-label": "secondary checkbox" }} - /> - } - label={i18next.t("convert_your_account_into_a_rendezvous_point", "Set the account as a Rendezvous point")} - /> - <CustomPopupState message={i18next.t("rendezvous_info", "If this option is enabled, incoming calls are automatically added to a conference room.")}/> - <Button disabled={!rendezVous} color="primary" onClick={() => {setOpenDrawer(true)}}><AddCircleOutlineIcon /> {i18next.t("add_moderator_to", "Add moderator to")} {props.blueprintName}</Button> - <CustomPopupState message={i18next.t("rendezvous_moderators_info", "Moderators can manage the Rendezvous point.")} /> - </FormGroup> - <Table className={classes.table}> - <TableHead> - <TableRow> - <TableCell align="left"></TableCell> - <TableCell align="left">{i18next.t("username", "Username")}</TableCell> - <TableCell align="left">{i18next.t("first_name", "First name")}</TableCell> - <TableCell align="left">{i18next.t("last_name", "Last name")}</TableCell> - <TableCell align="right">{i18next.t("action", "Action")}</TableCell> - </TableRow> - </TableHead> - <TableBody> - {blueprintModerators.map(user => - <TableRow key={user.username} className={classes.tableRow}> - <TableCell className={tableCellClasses}> - <Link to={`/user/${user.username}`}> - <Avatar - style={{ marginRight: "10px" }} - alt={user.username} - src={ - user.profilePicture - ? "data:image/png;base64, " + user.profilePicture - : noProfilePicture - } - /> - </Link> - </TableCell> - <TableCell className={tableCellClasses}> - <Link to={`/user/${user.username}`}>{user.username}</Link> - </TableCell> - <TableCell className={tableCellClasses}> - <Link to={`/user/${user.username}`}>{user.firstName}</Link> - </TableCell> - <TableCell className={tableCellClasses}> - <Link to={`/user/${user.username}`}>{user.lastName}</Link> - </TableCell> - <TableCell align="right" className={classes.tableActions}> - <Button disabled={!rendezVous} color="primary" onClick={() => removeModeratorFromBlueprint(user)}>{i18next.t("remove_moderator", "Remove moderator")}</Button> - </TableCell> - </TableRow> - )} - </TableBody> - </Table> - </GridItem> + <h3>Rendezvous mode</h3> + + <FormGroup row> + <FormControlLabel + control={ + <Switch + checked={rendezVous} + color="primary" + onChange={(e) => { + setRendezVous(e.target.checked); + handleUpdatePermissions("rendezVous", e.target.checked); + }} + name="rendezVous" + inputProps={{ "aria-label": "secondary checkbox" }} + /> + } + label={i18next.t( + "convert_your_account_into_a_rendezvous_point", + "Set the account as a Rendezvous point" + )} + /> + <CustomPopupState + message={i18next.t( + "rendezvous_info", + "If this option is enabled, incoming calls are automatically added to a conference room." + )} + /> + <Button + disabled={!rendezVous} + color="primary" + onClick={() => { + setOpenDrawer(true); + }} + > + <AddCircleOutlineIcon />{" "} + {i18next.t("add_moderator_to", "Add moderator to")}{" "} + {props.blueprintName} + </Button> + <CustomPopupState + message={i18next.t( + "rendezvous_moderators_info", + "Moderators can manage the Rendezvous point." + )} + /> + </FormGroup> + <Table className={classes.table}> + <TableHead> + <TableRow> + <TableCell align="left"></TableCell> + <TableCell align="left"> + {i18next.t("username", "Username")} + </TableCell> + <TableCell align="left"> + {i18next.t("first_name", "First name")} + </TableCell> + <TableCell align="left"> + {i18next.t("last_name", "Last name")} + </TableCell> + <TableCell align="right"> + {i18next.t("action", "Action")} + </TableCell> + </TableRow> + </TableHead> + <TableBody> + {blueprintModerators.map((user) => ( + <TableRow key={user.username} className={classes.tableRow}> + <TableCell className={tableCellClasses}> + <Link to={`/user/${user.username}`}> + <Avatar + style={{ marginRight: "10px" }} + alt={user.username} + src={ + user.profilePicture + ? "data:image/png;base64, " + user.profilePicture + : noProfilePicture + } + /> + </Link> + </TableCell> + <TableCell className={tableCellClasses}> + <Link to={`/user/${user.username}`}>{user.username}</Link> + </TableCell> + <TableCell className={tableCellClasses}> + <Link to={`/user/${user.username}`}>{user.firstName}</Link> + </TableCell> + <TableCell className={tableCellClasses}> + <Link to={`/user/${user.username}`}>{user.lastName}</Link> + </TableCell> + <TableCell align="right" className={classes.tableActions}> + <Button + disabled={!rendezVous} + color="primary" + onClick={() => removeModeratorFromBlueprint(user)} + > + {i18next.t("remove_moderator", "Remove moderator")} + </Button> + </TableCell> + </TableRow> + ))} + </TableBody> + </Table> + </GridItem> </GridContainer> </div> ); diff --git a/jams-react-client/src/views/Blueprints/Blueprints.js b/jams-react-client/src/views/Blueprints/Blueprints.js index dc9ffcd0db56babcbdb5b914a9710a841807e54d..a3a81a956ab0e671f81448261e26a0b46f458041 100644 --- a/jams-react-client/src/views/Blueprints/Blueprints.js +++ b/jams-react-client/src/views/Blueprints/Blueprints.js @@ -18,7 +18,7 @@ import Input from "@material-ui/core/Input"; import InputAdornment from "@material-ui/core/InputAdornment"; import GroupIcon from "@material-ui/icons/Group"; -import PersonIcon from '@material-ui/icons/Person'; +import PersonIcon from "@material-ui/icons/Person"; import Search from "@material-ui/icons/Search"; import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline"; import InfoIcon from "@material-ui/icons/Info"; @@ -81,7 +81,7 @@ const styles = { }, whiteButtonText: { color: "white", - } + }, }; const useStyles = makeStyles(styles); @@ -239,7 +239,6 @@ export default function Blueprints() { history.push("/blueprints"); }; - return ( <div> <Dialog @@ -249,7 +248,7 @@ export default function Blueprints() { aria-describedby="alert-dialog-description" > <DialogTitle id="alert-dialog-title"> - {i18next.t("create_blueprint", "Create blueprint")} + {i18next.t("create_blueprint", "Create blueprint")} </DialogTitle> <DialogContent> <DialogContentText id="alert-dialog-description"> @@ -259,7 +258,7 @@ export default function Blueprints() { error={blueprintNameExits} > <InputLabel htmlFor="blueprintName"> - {i18next.t("blueprint_name", "Blueprint name")} + {i18next.t("blueprint_name", "Blueprint name")} </InputLabel> <Input id="blueprintName" @@ -276,15 +275,29 @@ export default function Blueprints() { /> </FormControl> {disableCreate && blueprintName.length > 0 && ( - <p>{i18next.t("blueprint_name_already_exists", "Blueprint name already exists!")}</p> + <p> + {i18next.t( + "blueprint_name_already_exists", + "Blueprint name already exists!" + )} + </p> )} {disableCreate && blueprintName.length === 0 && ( - <p>{i18next.t("blueprint_name_is_empty", "Blueprint name is empty")}</p> + <p> + {i18next.t( + "blueprint_name_is_empty", + "Blueprint name is empty" + )} + </p> )} </DialogContentText> </DialogContent> <DialogActions> - <Button onClick={handleClose} color="info" className={classes.whiteButtonText}> + <Button + onClick={handleClose} + color="info" + className={classes.whiteButtonText} + > Cancel </Button> <Button @@ -304,23 +317,23 @@ export default function Blueprints() { aria-describedby="alert-dialog-description" > <DialogTitle id="alert-dialog-title"> - {i18next.t("remove_blueprint", "Remove blueprint")} + {i18next.t("remove_blueprint", "Remove blueprint")} </DialogTitle> <DialogContent> <DialogContentText id="alert-dialog-description"> - {i18next.t("are_you_sure_you_want_to_delete", "Are you sure you want to delete")}{" "} + {i18next.t( + "are_you_sure_you_want_to_delete", + "Are you sure you want to delete" + )}{" "} <strong>{removedBlueprint}</strong> ? </DialogContentText> </DialogContent> <DialogActions> - <Button - onClick={() => setOpenRemoveDialog(false)} - color="primary" - > + <Button onClick={() => setOpenRemoveDialog(false)} color="primary"> {i18next.t("cancel", "Cancel")} </Button> <Button onClick={removeBlueprint} color="info" autoFocus> - {i18next.t("remove", "Remove")} + {i18next.t("remove", "Remove")} </Button> </DialogActions> </Dialog> @@ -332,7 +345,8 @@ export default function Blueprints() { href="#contained-buttons" onClick={(e) => setOpen(true)} > - <AddCircleOutlineIcon /> {i18next.t("create_blueprint", "Create blueprint")} + <AddCircleOutlineIcon />{" "} + {i18next.t("create_blueprint", "Create blueprint")} </Button> <div className={classes.searchWrapper}> {!zeroBlueprint && ( @@ -341,9 +355,15 @@ export default function Blueprints() { className: classes.margin + " " + classes.search, }} inputProps={{ - placeholder: i18next.t("search_blueprints_placeholder", "Search blueprints…"), + placeholder: i18next.t( + "search_blueprints_placeholder", + "Search blueprints…" + ), inputProps: { - "aria-label": i18next.t("search_blueprints", "Search blueprints"), + "aria-label": i18next.t( + "search_blueprints", + "Search blueprints" + ), }, onKeyUp: (e) => setSearchValue(e.target.value), }} @@ -360,17 +380,13 @@ export default function Blueprints() { {zeroBlueprint ? ( <div className={classes.blueprintsNotFound}> <InfoIcon /> - <p style={{ marginLeft: "10px" }}>{i18next.t("no_blueprints_found", "No blueprints found")}</p> + <p style={{ marginLeft: "10px" }}> + {i18next.t("no_blueprints_found", "No blueprints found")} + </p> </div> ) : ( blueprints.map((blueprint) => ( - <GridItem - xs={12} - sm={6} - md={3} - lg={2} - xl={2} - key={blueprint.name}> + <GridItem xs={12} sm={6} md={3} lg={2} xl={2} key={blueprint.name}> <Card profile> <Link to={`/blueprint/${blueprint.name}`}> <CardBody profile> @@ -381,18 +397,27 @@ export default function Blueprints() { </h3> <ul> <li> - {JSON.parse(blueprint.policyData).rendezVous == true ? (<p><GroupIcon - fontSize="small" - style={{ marginRight: "10px" }} - />{i18next.t("rendezvous", "Rendezvous")}</p>) : <p><PersonIcon - fontSize="small" - style={{ marginRight: "10px" }} - />{i18next.t("standalone", "Standalone")}</p> - } + {JSON.parse(blueprint.policyData).rendezVous == true ? ( + <p> + <GroupIcon + fontSize="small" + style={{ marginRight: "10px" }} + /> + {i18next.t("rendezvous", "Rendezvous")} + </p> + ) : ( + <p> + <PersonIcon + fontSize="small" + style={{ marginRight: "10px" }} + /> + {i18next.t("standalone", "Standalone")} + </p> + )} </li> </ul> - </CardBody> - </Link> + </CardBody> + </Link> <CardFooter> <IconButton color="secondary" diff --git a/jams-react-client/src/views/Dashboard/Dashboard.js b/jams-react-client/src/views/Dashboard/Dashboard.js index 0678d244957c8b17e6840577ba38c7cecd640dee..d696cc5124ecb3e94bc2152e12c5e46c6ab04415 100755 --- a/jams-react-client/src/views/Dashboard/Dashboard.js +++ b/jams-react-client/src/views/Dashboard/Dashboard.js @@ -34,7 +34,7 @@ import { bugs, website, server } from "variables/general.js"; import { dailySalesChart, emailsSubscriptionChart, - completedTasksChart + completedTasksChart, } from "variables/charts.js"; import styles from "assets/jss/material-dashboard-react/views/dashboardStyle.js"; @@ -62,7 +62,7 @@ export default function Dashboard() { <Danger> <Warning /> </Danger> - <a href="#pablo" onClick={e => e.preventDefault()}> + <a href="#pablo" onClick={(e) => e.preventDefault()}> Get more space </a> </div> @@ -210,7 +210,7 @@ export default function Dashboard() { tasksIndexes={[0, 1, 2, 3]} tasks={bugs} /> - ) + ), }, { tabName: "Website", @@ -221,7 +221,7 @@ export default function Dashboard() { tasksIndexes={[0, 1]} tasks={website} /> - ) + ), }, { tabName: "Server", @@ -232,8 +232,8 @@ export default function Dashboard() { tasksIndexes={[0, 1, 2]} tasks={server} /> - ) - } + ), + }, ]} /> </GridItem> @@ -253,7 +253,7 @@ export default function Dashboard() { ["1", "Dakota Rice", "$36,738", "Niger"], ["2", "Minerva Hooper", "$23,789", "Curaçao"], ["3", "Sage Rodriguez", "$56,142", "Netherlands"], - ["4", "Philip Chaney", "$38,735", "Korea, South"] + ["4", "Philip Chaney", "$38,735", "Korea, South"], ]} /> </CardBody> diff --git a/jams-react-client/src/views/Groups/EditGroup.js b/jams-react-client/src/views/Groups/EditGroup.js index a957259a0f4eaf24ab622949b2de07f0bcbe3b00..540020f2572cd1506216cb910bf1f962ed3839df 100644 --- a/jams-react-client/src/views/Groups/EditGroup.js +++ b/jams-react-client/src/views/Groups/EditGroup.js @@ -6,7 +6,7 @@ import classnames from "classnames"; import { makeStyles } from "@material-ui/core/styles"; // core components -import Grid from '@material-ui/core/Grid'; +import Grid from "@material-ui/core/Grid"; import GridItem from "components/Grid/GridItem.js"; import GridContainer from "components/Grid/GridContainer.js"; import Button from "components/CustomButtons/Button.js"; @@ -14,40 +14,39 @@ 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 FormControl from '@material-ui/core/FormControl'; -import Input from '@material-ui/core/Input'; -import InputAdornment from '@material-ui/core/InputAdornment'; +import FormControl from "@material-ui/core/FormControl"; +import Input from "@material-ui/core/Input"; +import InputAdornment from "@material-ui/core/InputAdornment"; import Table from "@material-ui/core/Table"; -import TableHead from '@material-ui/core/TableHead'; +import TableHead from "@material-ui/core/TableHead"; import TableRow from "@material-ui/core/TableRow"; import TableBody from "@material-ui/core/TableBody"; import TableCell from "@material-ui/core/TableCell"; import InputLabel from "@material-ui/core/InputLabel"; - import Select from "@material-ui/core/Select"; -import AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutline'; -import EditIcon from '@material-ui/icons/Edit'; -import PeopleOutlineIcon from '@material-ui/icons/PeopleOutline'; +import AddCircleOutlineIcon from "@material-ui/icons/AddCircleOutline"; +import EditIcon from "@material-ui/icons/Edit"; +import PeopleOutlineIcon from "@material-ui/icons/PeopleOutline"; -import IconButton from '@material-ui/core/IconButton'; -import SaveIcon from '@material-ui/icons/Save'; +import IconButton from "@material-ui/core/IconButton"; +import SaveIcon from "@material-ui/icons/Save"; -import axios from "axios" -import configApiCall from "../../api" +import axios from "axios"; +import configApiCall from "../../api"; import { - api_path_get_list_group, - api_path_get_group, - api_path_put_update_group, - api_path_get_user_directory_search, - api_path_get_user_profile, - api_path_blueprints, - api_path_get_group_members, - api_path_post_group_member, - api_path_delete_group_member -} from "../../globalUrls" + api_path_get_list_group, + api_path_get_group, + api_path_put_update_group, + api_path_get_user_directory_search, + api_path_get_user_profile, + api_path_blueprints, + api_path_get_group_members, + api_path_post_group_member, + api_path_delete_group_member, +} from "../../globalUrls"; import dashboardStyle from "assets/jss/material-dashboard-react/views/dashboardStyle.js"; import devicesStyle from "assets/jss/material-dashboard-react/components/devicesStyle.js"; @@ -55,7 +54,7 @@ import Avatar from "@material-ui/core/Avatar"; import noProfilePicture from "assets/img/faces/no-profile-picture.png"; -import TemporaryDrawer from "components/Drawer/Drawer" +import TemporaryDrawer from "components/Drawer/Drawer"; import * as tool from "../../tools"; import i18next from "i18next"; @@ -65,402 +64,472 @@ import auth from "auth.js"; import { debounce } from "lodash"; const useStyles = makeStyles((theme) => ({ - ...devicesStyle, - ...dashboardStyle, - root: { - flexGrow: 1 - }, - cardCategoryWhite: { - color: "rgba(255,255,255,.62)", - margin: "0", - fontSize: "14px", - marginTop: "0", - marginBottom: "0" - }, - cardTitleWhite: { - color: "#FFFFFF", - marginTop: "0px", - minHeight: "auto", - fontWeight: "300", - fontFamily: "'Roboto', 'Helvetica', 'Arial', sans-serif", - marginBottom: "3px", - textDecoration: "none" - }, - input: { - display: 'none', - }, - profileAsBackground: { - backgroundSize: "100% 100%", - width: "80px", - height: "80px", - }, - centerIconMiddle: { - position:"relative", - top: "20px", - left: "15px" - }, - dialogPaper: { - minHeight: '60vh', - maxHeight: '60vh', - minWidth: '80vh', - maxWidth: '80vh' - }, - inputBottomMargin: { - marginBottom: "1rem" - } + ...devicesStyle, + ...dashboardStyle, + root: { + flexGrow: 1, + }, + cardCategoryWhite: { + color: "rgba(255,255,255,.62)", + margin: "0", + fontSize: "14px", + marginTop: "0", + marginBottom: "0", + }, + cardTitleWhite: { + color: "#FFFFFF", + marginTop: "0px", + minHeight: "auto", + fontWeight: "300", + fontFamily: "'Roboto', 'Helvetica', 'Arial', sans-serif", + marginBottom: "3px", + textDecoration: "none", + }, + input: { + display: "none", + }, + profileAsBackground: { + backgroundSize: "100% 100%", + width: "80px", + height: "80px", + }, + centerIconMiddle: { + position: "relative", + top: "20px", + left: "15px", + }, + dialogPaper: { + minHeight: "60vh", + maxHeight: "60vh", + minWidth: "80vh", + maxWidth: "80vh", + }, + inputBottomMargin: { + marginBottom: "1rem", + }, })); export default function EditGroup(props) { - const classes = useStyles(); - const history = useHistory(); - - const [name, setName] = React.useState(""); - const [newName, setNewName] = React.useState(""); - const [blueprints, setBlueprints] = React.useState([]); - const [selectedBlueprint, setSelectedBlueprint] = React.useState({ - value: 0, - label: "No blueprint", - }); - const [groupMembers, setGroupMembers] = React.useState([]); - const [openDrawer, setOpenDrawer] = React.useState(false); - const [groupNameExits, setGroupNameExits] = React.useState(false); - const [users, setUsers] = React.useState([]); - - const getUserInfo = username => new Promise((resolve, reject) => { - axios( - configApiCall( - api_path_get_user_profile + username, - "GET", - null, - null - ) - ) - .then((response) => { - resolve(response.data); - }) - .catch((error) => { - reject(error); - }); - }) - - const getGroup = () => { - axios(configApiCall(api_path_get_group + props.groupid, 'GET', null, null)).then((response) => { - let group = response.data; - - axios(configApiCall(api_path_blueprints + "?name=*", "GET", null, null)) - .then((response) => { - setBlueprints(response.data); - let index = 0; - response.data.map((blueprint) => { - if(blueprint.name == group["blueprint"]) - setSelectedBlueprint({ value: index, label: blueprint.name }); - index += 1; - }); - }) - .catch((error) => { - if (error.response.status === 401) { - auth.authenticated = false; - history.push("/signin"); - } - if (error.response.status === 500) { - setBlueprints([]); - } - }); - - axios(configApiCall(api_path_get_group_members + props.groupid, 'GET', null, null)).then((response) => { - let members = response.data; - members.forEach((member) => { - getUserInfo(member.username).then((userInfo) => { - let newGroupMembers = groupMembers; - newGroupMembers.push(userInfo); - setGroupMembers(newGroupMembers); - - //This state update is added to force the groupMembers to displayed on first page loading - setOpenDrawer(true); - setOpenDrawer(false); -  }) - }) - }).catch((error) => { - if (error.response.status === 404) { - setGroupMembers([]); - } - if (error.response.status === 401) { - auth.authenticated = false; - history.push("/signin"); - } - }) - - - setName(group.name); - setNewName(group.name); - - }).catch((error) => { - console.log("Error fetching group members of: " + props.name + " " + error) + const classes = useStyles(); + const history = useHistory(); + + const [name, setName] = React.useState(""); + const [newName, setNewName] = React.useState(""); + const [blueprints, setBlueprints] = React.useState([]); + const [selectedBlueprint, setSelectedBlueprint] = React.useState({ + value: 0, + label: "No blueprint", + }); + const [groupMembers, setGroupMembers] = React.useState([]); + const [openDrawer, setOpenDrawer] = React.useState(false); + const [groupNameExits, setGroupNameExits] = React.useState(false); + const [users, setUsers] = React.useState([]); + + const getUserInfo = (username) => + new Promise((resolve, reject) => { + axios( + configApiCall(api_path_get_user_profile + username, "GET", null, null) + ) + .then((response) => { + resolve(response.data); }) - } - - const getBlueprintsOptions = (inputs) => { - let blueprintsOptions = []; - let index = 0; - if (blueprints.length === 0) - blueprintsOptions.push({ value: index, label: "No blueprint found" }); - else { - blueprints.map((blueprint) => { - blueprintsOptions.push({ value: index, label: blueprint.name }); - index += 1; - }); - } - return blueprintsOptions; - }; - - const blueprintsOptionsItems = tool.buildSelectMenuItems(getBlueprintsOptions(blueprints)); - - React.useEffect(()=>{ - getGroup(); - searchUsers(); - }, []) + .catch((error) => { + reject(error); + }); + }); - const updateGroup = (blueprintValue) => { + const getGroup = () => { + axios(configApiCall(api_path_get_group + props.groupid, "GET", null, null)) + .then((response) => { + let group = response.data; - let data = { - "name": newName, - "blueprint": blueprintValue ? blueprintValue : selectedBlueprint.label - } - - axios(configApiCall(api_path_put_update_group + props.groupid, 'PUT', data, null)).then((response) => { - setName(newName); - }).catch((error) => { - console.log("Error updating group: " + error) - }) - } - - const searchUsers = (value) => { - axios( - configApiCall( - api_path_get_user_directory_search, - "GET", - { queryString: value ? value : "*", page: "1" }, - null - ) - ) + axios(configApiCall(api_path_blueprints + "?name=*", "GET", null, null)) .then((response) => { - let profiles = []; - const profilesResults = response.data.profiles; - profilesResults.forEach((profile) =>{ - let existingUser = false; - users.forEach((user)=>{ - if(profile.username === user.username) existingUser = true; - }) - if(!existingUser) profiles.push(profile); - }) - setUsers(profiles); + setBlueprints(response.data); + let index = 0; + response.data.map((blueprint) => { + if (blueprint.name == group["blueprint"]) + setSelectedBlueprint({ value: index, label: blueprint.name }); + index += 1; + }); }) .catch((error) => { - setUsers([]); if (error.response.status === 401) { auth.authenticated = false; history.push("/signin"); } - }); - }; - - const addUserInGroup = (user) => { - let data = { - "username": user.username - } - axios(configApiCall(api_path_post_group_member + props.groupid, 'POST', data, null)).then((response) => { - let newGroupMembers = groupMembers; - newGroupMembers.push(user); - setGroupMembers(newGroupMembers); - - //This state update is added to force the groupMembers to refreshed displayed - setOpenDrawer(true); - setOpenDrawer(false); - }).catch((error) => { - if (error.response.status === 409) { - alert(`${user.username} is already part of ${name}`); + if (error.response.status === 500) { + setBlueprints([]); } - else - console.log("Error updating group: " + error) - }) - } - - const deleteUserFromGroup = (user) => { - let data = { - "username": user.username - } - axios(configApiCall(api_path_delete_group_member + props.groupid, 'DELETE', data, null)).then((response) => { - let newGroupMembers = groupMembers; - newGroupMembers.splice(newGroupMembers.indexOf(user), 1); - setGroupMembers(newGroupMembers); - - //This state update is added to force the groupMembers to refreshed displayed - setOpenDrawer(true); - setOpenDrawer(false); - }).catch((error) => { - console.log("Error updating group: " + error) - }) - } - - const handleBlueprintsChange = (e) => { - updateGroup(getBlueprintsOptions()[e.target.value].label !== "No blueprint found" ? getBlueprintsOptions()[e.target.value].label : ""); - setSelectedBlueprint(getBlueprintsOptions()[e.target.value]); - } - - const initCheckGroupNameExists = useCallback( - debounce( - (searchGroupNameValue) => - handleCheckGroupNameExists(searchGroupNameValue), - 500 - ), - [] - ); - - - const handleCheckGroupNameExists = (searchGroupNameValue) => { + }); axios( configApiCall( - api_path_get_list_group + "?groupName=" + searchGroupNameValue, + api_path_get_group_members + props.groupid, "GET", null, null ) ) .then((response) => { - setGroupNameExits(false); - response.data.forEach((group) => { - if(searchGroupNameValue === group.name){ - setGroupNameExits(true); - } + let members = response.data; + members.forEach((member) => { + getUserInfo(member.username).then((userInfo) => { + let newGroupMembers = groupMembers; + newGroupMembers.push(userInfo); + setGroupMembers(newGroupMembers); + + //This state update is added to force the groupMembers to displayed on first page loading + setOpenDrawer(true); + setOpenDrawer(false); + }); }); }) .catch((error) => { - setGroupNameExits(false); + if (error.response.status === 404) { + setGroupMembers([]); + } + if (error.response.status === 401) { + auth.authenticated = false; + history.push("/signin"); + } + }); + + setName(group.name); + setNewName(group.name); + }) + .catch((error) => { + console.log( + "Error fetching group members of: " + props.name + " " + error + ); + }); + }; + + const getBlueprintsOptions = (inputs) => { + let blueprintsOptions = []; + let index = 0; + if (blueprints.length === 0) + blueprintsOptions.push({ value: index, label: "No blueprint found" }); + else { + blueprints.map((blueprint) => { + blueprintsOptions.push({ value: index, label: blueprint.name }); + index += 1; + }); + } + return blueprintsOptions; + }; + + const blueprintsOptionsItems = tool.buildSelectMenuItems( + getBlueprintsOptions(blueprints) + ); + + React.useEffect(() => { + getGroup(); + searchUsers(); + }, []); + + const updateGroup = (blueprintValue) => { + let data = { + name: newName, + blueprint: blueprintValue ? blueprintValue : selectedBlueprint.label, + }; + + axios( + configApiCall( + api_path_put_update_group + props.groupid, + "PUT", + data, + null + ) + ) + .then((response) => { + setName(newName); + }) + .catch((error) => { + console.log("Error updating group: " + error); + }); + }; + + const searchUsers = (value) => { + axios( + configApiCall( + api_path_get_user_directory_search, + "GET", + { queryString: value ? value : "*", page: "1" }, + null + ) + ) + .then((response) => { + let profiles = []; + const profilesResults = response.data.profiles; + profilesResults.forEach((profile) => { + let existingUser = false; + users.forEach((user) => { + if (profile.username === user.username) existingUser = true; }); - }; - - const tableCellClasses = classnames(classes.tableCell); - - return( - <div> - <TemporaryDrawer - openDrawer={openDrawer} - setOpenDrawer={setOpenDrawer} - direction="right" - placeholder={i18next.t("add_user_to_group", "Add user to group ...")} - searchTargets={searchUsers} - targets={users} - existingTargets={groupMembers} - addElementToTarget={addUserInGroup} - targetName={name} - type="user" - /> - <GridContainer> - <GridItem xs={12} sm={12} md={6}> - <Card profile> - <CardHeader color="info" stats icon> - <CardIcon color="info"> - <EditIcon /> - </CardIcon> - <p className={classes.cardCategory}>{i18next.t("edit_group", "Edit group")}</p> - <h3 className={classes.cardTitle}>{name}</h3> - </CardHeader> - <CardBody profile> - <div className={classes.root}> - <Grid container spacing={2}> - <Grid item xs={12} sm={12} md={12}> - <FormControl className={classes.margin} size="medium" error={groupNameExits}> - <Input - id="name" - placeholder={name} - startAdornment={ - <InputAdornment position="start"> - <PeopleOutlineIcon /> - </InputAdornment> - } - endAdornment={ - <IconButton color="primary" aria-label="update name" component="span" - onClick={() => { - updateGroup(); - }} - disabled={groupNameExits || name == newName} - > - <SaveIcon /> - </IconButton> - } - onChange={e => { - setNewName(e.target.value); - initCheckGroupNameExists(e.target.value) - }} - /> - </FormControl> - </Grid> - <Grid item xs={12} sm={12} md={12}> - <InputLabel className={classes.inputBottomMargin} htmlFor="blueprint">{i18next.t("select_blueprint", "Select a blueprint")}</InputLabel> - <FormControl className={classes.margin} fullWidth> - <Select - labelId="demo-simple-select-label" - fullWidth - value={selectedBlueprint.value} - onChange={handleBlueprintsChange} - variant="outlined" - children={blueprintsOptionsItems} - disabled={blueprints.length === 0} - /> - </FormControl> - </Grid> - </Grid> - </div> - </CardBody> - </Card> - </GridItem> - <GridItem xs={12} sm={12} md={12}> - <Button color="primary" onClick={() => {setOpenDrawer(true)}}><AddCircleOutlineIcon /> {i18next.t("add_user_to", "Add user to")} {name}</Button> - <Table className={classes.table}> - <TableHead> - <TableRow> - <TableCell align="left"></TableCell> - <TableCell align="left">{i18next.t("username", "Username")}</TableCell> - <TableCell align="left">{i18next.t("first_name", "First name")}</TableCell> - <TableCell align="left">{i18next.t("last_name", "Last name")}</TableCell> - <TableCell align="right">{i18next.t("action", "Action")}</TableCell> - </TableRow> - </TableHead> - <TableBody> - {groupMembers.map(user => - <TableRow key={user.username} className={classes.tableRow}> - <TableCell className={tableCellClasses}> - <Link to={`/user/${user.username}`}> - <Avatar - style={{ marginRight: "10px" }} - alt={user.username} - src={ - user.profilePicture - ? "data:image/png;base64, " + user.profilePicture - : noProfilePicture - } - /> - </Link> - </TableCell> - <TableCell className={tableCellClasses}> - <Link to={`/user/${user.username}`}>{user.username}</Link> - </TableCell> - <TableCell className={tableCellClasses}> - <Link to={`/user/${user.username}`}>{user.firstName}</Link> - </TableCell> - <TableCell className={tableCellClasses}> - <Link to={`/user/${user.username}`}>{user.lastName}</Link> - </TableCell> - <TableCell align="right" className={classes.tableActions}> - <Button color="primary" onClick={() => deleteUserFromGroup(user)}>{i18next.t("remove_user", "Remove user")}</Button> - </TableCell> - </TableRow> - )} - </TableBody> - </Table> - </GridItem> - </GridContainer> - </div> + if (!existingUser) profiles.push(profile); + }); + setUsers(profiles); + }) + .catch((error) => { + setUsers([]); + if (error.response.status === 401) { + auth.authenticated = false; + history.push("/signin"); + } + }); + }; + + const addUserInGroup = (user) => { + let data = { + username: user.username, + }; + axios( + configApiCall( + api_path_post_group_member + props.groupid, + "POST", + data, + null + ) + ) + .then((response) => { + let newGroupMembers = groupMembers; + newGroupMembers.push(user); + setGroupMembers(newGroupMembers); + + //This state update is added to force the groupMembers to refreshed displayed + setOpenDrawer(true); + setOpenDrawer(false); + }) + .catch((error) => { + if (error.response.status === 409) { + alert(`${user.username} is already part of ${name}`); + } else console.log("Error updating group: " + error); + }); + }; + + const deleteUserFromGroup = (user) => { + let data = { + username: user.username, + }; + axios( + configApiCall( + api_path_delete_group_member + props.groupid, + "DELETE", + data, + null + ) + ) + .then((response) => { + let newGroupMembers = groupMembers; + newGroupMembers.splice(newGroupMembers.indexOf(user), 1); + setGroupMembers(newGroupMembers); + + //This state update is added to force the groupMembers to refreshed displayed + setOpenDrawer(true); + setOpenDrawer(false); + }) + .catch((error) => { + console.log("Error updating group: " + error); + }); + }; + + const handleBlueprintsChange = (e) => { + updateGroup( + getBlueprintsOptions()[e.target.value].label !== "No blueprint found" + ? getBlueprintsOptions()[e.target.value].label + : "" ); -} \ No newline at end of file + setSelectedBlueprint(getBlueprintsOptions()[e.target.value]); + }; + + const initCheckGroupNameExists = useCallback( + debounce( + (searchGroupNameValue) => + handleCheckGroupNameExists(searchGroupNameValue), + 500 + ), + [] + ); + + const handleCheckGroupNameExists = (searchGroupNameValue) => { + axios( + configApiCall( + api_path_get_list_group + "?groupName=" + searchGroupNameValue, + "GET", + null, + null + ) + ) + .then((response) => { + setGroupNameExits(false); + response.data.forEach((group) => { + if (searchGroupNameValue === group.name) { + setGroupNameExits(true); + } + }); + }) + .catch((error) => { + setGroupNameExits(false); + }); + }; + + const tableCellClasses = classnames(classes.tableCell); + + return ( + <div> + <TemporaryDrawer + openDrawer={openDrawer} + setOpenDrawer={setOpenDrawer} + direction="right" + placeholder={i18next.t("add_user_to_group", "Add user to group ...")} + searchTargets={searchUsers} + targets={users} + existingTargets={groupMembers} + addElementToTarget={addUserInGroup} + targetName={name} + type="user" + /> + <GridContainer> + <GridItem xs={12} sm={12} md={6}> + <Card profile> + <CardHeader color="info" stats icon> + <CardIcon color="info"> + <EditIcon /> + </CardIcon> + <p className={classes.cardCategory}> + {i18next.t("edit_group", "Edit group")} + </p> + <h3 className={classes.cardTitle}>{name}</h3> + </CardHeader> + <CardBody profile> + <div className={classes.root}> + <Grid container spacing={2}> + <Grid item xs={12} sm={12} md={12}> + <FormControl + className={classes.margin} + size="medium" + error={groupNameExits} + > + <Input + id="name" + placeholder={name} + startAdornment={ + <InputAdornment position="start"> + <PeopleOutlineIcon /> + </InputAdornment> + } + endAdornment={ + <IconButton + color="primary" + aria-label="update name" + component="span" + onClick={() => { + updateGroup(); + }} + disabled={groupNameExits || name == newName} + > + <SaveIcon /> + </IconButton> + } + onChange={(e) => { + setNewName(e.target.value); + initCheckGroupNameExists(e.target.value); + }} + /> + </FormControl> + </Grid> + <Grid item xs={12} sm={12} md={12}> + <InputLabel + className={classes.inputBottomMargin} + htmlFor="blueprint" + > + {i18next.t("select_blueprint", "Select a blueprint")} + </InputLabel> + <FormControl className={classes.margin} fullWidth> + <Select + labelId="demo-simple-select-label" + fullWidth + value={selectedBlueprint.value} + onChange={handleBlueprintsChange} + variant="outlined" + children={blueprintsOptionsItems} + disabled={blueprints.length === 0} + /> + </FormControl> + </Grid> + </Grid> + </div> + </CardBody> + </Card> + </GridItem> + <GridItem xs={12} sm={12} md={12}> + <Button + color="primary" + onClick={() => { + setOpenDrawer(true); + }} + > + <AddCircleOutlineIcon /> {i18next.t("add_user_to", "Add user to")}{" "} + {name} + </Button> + <Table className={classes.table}> + <TableHead> + <TableRow> + <TableCell align="left"></TableCell> + <TableCell align="left"> + {i18next.t("username", "Username")} + </TableCell> + <TableCell align="left"> + {i18next.t("first_name", "First name")} + </TableCell> + <TableCell align="left"> + {i18next.t("last_name", "Last name")} + </TableCell> + <TableCell align="right"> + {i18next.t("action", "Action")} + </TableCell> + </TableRow> + </TableHead> + <TableBody> + {groupMembers.map((user) => ( + <TableRow key={user.username} className={classes.tableRow}> + <TableCell className={tableCellClasses}> + <Link to={`/user/${user.username}`}> + <Avatar + style={{ marginRight: "10px" }} + alt={user.username} + src={ + user.profilePicture + ? "data:image/png;base64, " + user.profilePicture + : noProfilePicture + } + /> + </Link> + </TableCell> + <TableCell className={tableCellClasses}> + <Link to={`/user/${user.username}`}>{user.username}</Link> + </TableCell> + <TableCell className={tableCellClasses}> + <Link to={`/user/${user.username}`}>{user.firstName}</Link> + </TableCell> + <TableCell className={tableCellClasses}> + <Link to={`/user/${user.username}`}>{user.lastName}</Link> + </TableCell> + <TableCell align="right" className={classes.tableActions}> + <Button + color="primary" + onClick={() => deleteUserFromGroup(user)} + > + {i18next.t("remove_user", "Remove user")} + </Button> + </TableCell> + </TableRow> + ))} + </TableBody> + </Table> + </GridItem> + </GridContainer> + </div> + ); +} diff --git a/jams-react-client/src/views/Groups/Groups.js b/jams-react-client/src/views/Groups/Groups.js index 161f44bab8af90e6014096d250656db4e611ecd8..472fd01c69576fcc44985b855536f2696a2c4876 100644 --- a/jams-react-client/src/views/Groups/Groups.js +++ b/jams-react-client/src/views/Groups/Groups.js @@ -32,7 +32,7 @@ import { api_path_get_list_group, api_path_delete_group, api_path_blueprints, - api_path_get_group_members + api_path_get_group_members, } from "globalUrls"; import AddCircleOutlineIcon from "@material-ui/icons/AddCircleOutline"; @@ -89,8 +89,8 @@ const styles = { color: "white", }, inputBottomMargin: { - marginBottom: "1rem" - } + marginBottom: "1rem", + }, }; const useStyles = makeStyles(styles); @@ -111,8 +111,8 @@ export default function Groups() { const [groupNameExits, setGroupNameExits] = React.useState(false); const [removedGroup, setRemovedGroup] = React.useState({ - "id": 0, - "name": "groupeName" + id: 0, + name: "groupeName", }); const [openRemoveDialog, setOpenRemoveDialog] = React.useState(); @@ -160,20 +160,20 @@ export default function Groups() { const getBlueprints = () => { axios(configApiCall(api_path_blueprints + "?name=*", "GET", null, null)) - .then((response) => { - setBlueprints(response.data); - setSelectedBlueprint(getBlueprintsOptions()[0]); - }) - .catch((error) => { - if (error.response.status === 401) { - auth.authenticated = false; - history.push("/signin"); - } - if (error.response.status === 500) { - setBlueprints([]); - } - }); - } + .then((response) => { + setBlueprints(response.data); + setSelectedBlueprint(getBlueprintsOptions()[0]); + }) + .catch((error) => { + if (error.response.status === 401) { + auth.authenticated = false; + history.push("/signin"); + } + if (error.response.status === 500) { + setBlueprints([]); + } + }); + }; useEffect(() => { setLoading(true); @@ -187,25 +187,32 @@ export default function Groups() { }); }, 500); - axios( - configApiCall(api_path_get_list_group, "GET", null, null) - ) + axios(configApiCall(api_path_get_list_group, "GET", null, null)) .then((response) => { let allGroups = response.data; - allGroups.forEach((group)=> { - axios(configApiCall(api_path_get_group_members + group.id, 'GET', null, null)).then((response) => { - group["groupMembersLength"] = response.data.length; - }).catch((error) => { - if (error.response.status === 401) { - auth.authenticated = false; - history.push("/"); - } - if (error.response.status === 404) { - group["groupMembersLength"] = 0; - } - }); - }) + allGroups.forEach((group) => { + axios( + configApiCall( + api_path_get_group_members + group.id, + "GET", + null, + null + ) + ) + .then((response) => { + group["groupMembersLength"] = response.data.length; + }) + .catch((error) => { + if (error.response.status === 401) { + auth.authenticated = false; + history.push("/"); + } + if (error.response.status === 404) { + group["groupMembersLength"] = 0; + } + }); + }); setGroups(allGroups); getBlueprints(); setLoading(false); @@ -215,7 +222,7 @@ export default function Groups() { auth.authenticated = false; history.push("/signin"); } - if (error.response.status === 404){ + if (error.response.status === 404) { getBlueprints(); setZeroGroup(true); } @@ -240,7 +247,7 @@ export default function Groups() { setDisableCreate(false); setGroupNameExits(false); allGroups.forEach((group) => { - if(searchGroupNameValue === group.name){ + if (searchGroupNameValue === group.name) { setDisableCreate(true); setGroupNameExits(true); } @@ -310,12 +317,14 @@ export default function Groups() { return ( <div> <h4> - {i18next.t("you_are_not_allowed_to_access_this_section", "You are not allowed to access this section. Please contact your administrator to get administrator privileges.")} + {i18next.t( + "you_are_not_allowed_to_access_this_section", + "You are not allowed to access this section. Please contact your administrator to get administrator privileges." + )} </h4> </div> ); - } - else { + } else { return ( <div> <Dialog @@ -324,7 +333,9 @@ export default function Groups() { aria-labelledby="alert-dialog-title" aria-describedby="alert-dialog-description" > - <DialogTitle id="alert-dialog-title">{i18next.t("create_group", "Create group")}</DialogTitle> + <DialogTitle id="alert-dialog-title"> + {i18next.t("create_group", "Create group")} + </DialogTitle> <DialogContent> <DialogContentText id="alert-dialog-description"> <Grid container spacing={2}> @@ -334,7 +345,9 @@ export default function Groups() { error={groupNameExits} fullWidth > - <InputLabel htmlFor="groupName">{i18next.t("group_name", "Group name")}</InputLabel> + <InputLabel htmlFor="groupName"> + {i18next.t("group_name", "Group name")} + </InputLabel> <Input id="groupName" placeholder={i18next.t("group_name", "Group name")} @@ -350,14 +363,26 @@ export default function Groups() { /> </FormControl> {disableCreate && groupName.length > 0 && ( - <p>{i18next.t("group_name_already_exists", "Group name already exists!")}</p> + <p> + {i18next.t( + "group_name_already_exists", + "Group name already exists!" + )} + </p> )} {disableCreate && groupName.length === 0 && ( - <p>{i18next.t("group_name_is_empty", "Group name is empty")}</p> + <p> + {i18next.t("group_name_is_empty", "Group name is empty")} + </p> )} </Grid> <Grid item xs={12} sm={12} md={12}> - <InputLabel className={classes.inputBottomMargin} htmlFor="blueprint">{i18next.t("select_blueprint", "Select a blueprint")}</InputLabel> + <InputLabel + className={classes.inputBottomMargin} + htmlFor="blueprint" + > + {i18next.t("select_blueprint", "Select a blueprint")} + </InputLabel> <Select labelId="demo-simple-select-label" fullWidth @@ -372,7 +397,11 @@ export default function Groups() { </DialogContentText> </DialogContent> <DialogActions> - <Button onClick={handleCloseCreate} color="info" className={classes.whiteButtonText}> + <Button + onClick={handleCloseCreate} + color="info" + className={classes.whiteButtonText} + > Cancel </Button> <Button @@ -391,10 +420,16 @@ export default function Groups() { aria-labelledby="alert-dialog-title" aria-describedby="alert-dialog-description" > - <DialogTitle id="alert-dialog-title">{i18next.t("remove_group", "Remove group")}</DialogTitle> + <DialogTitle id="alert-dialog-title"> + {i18next.t("remove_group", "Remove group")} + </DialogTitle> <DialogContent> <DialogContentText id="alert-dialog-description"> - {i18next.t("are_you_sure_you_want_to_delete", "Are you sure you want to delete")} <strong>{removedGroup.name}</strong> ? + {i18next.t( + "are_you_sure_you_want_to_delete", + "Are you sure you want to delete" + )}{" "} + <strong>{removedGroup.name}</strong> ? </DialogContentText> </DialogContent> <DialogActions> @@ -415,7 +450,8 @@ export default function Groups() { href="#contained-buttons" onClick={(e) => setOpenCreate(true)} > - <AddCircleOutlineIcon /> {i18next.t("create_group", "Create group")} + <AddCircleOutlineIcon />{" "} + {i18next.t("create_group", "Create group")} </Button> } <div className={classes.searchWrapper}> @@ -425,7 +461,10 @@ export default function Groups() { className: classes.margin + " " + classes.search, }} inputProps={{ - placeholder: i18next.t("search_groups_placeholder", "Search groups…"), + placeholder: i18next.t( + "search_groups_placeholder", + "Search groups…" + ), inputProps: { "aria-label": i18next.t("search_groups", "Search groups"), }, @@ -435,7 +474,7 @@ export default function Groups() { )} {!zeroGroup && <Search />} <div className={classes.loading}> - {!zeroGroup && loading && ( + {!zeroGroup && loading && ( <LinearProgress variant="determinate" value={progress} /> )} </div> @@ -443,7 +482,10 @@ export default function Groups() { </GridItem> {zeroGroup ? ( <div className={classes.groupsNotFound}> - <InfoIcon /> <p style={{ marginLeft: "10px" }}>{i18next.t("no_groups_found", "No groups Found")}</p> + <InfoIcon />{" "} + <p style={{ marginLeft: "10px" }}> + {i18next.t("no_groups_found", "No groups Found")} + </p> </div> ) : ( groups @@ -457,13 +499,7 @@ export default function Groups() { } }) .map((group) => ( - <GridItem - xs={12} - sm={6} - md={3} - lg={2} - xl={2} - key={group.name}> + <GridItem xs={12} sm={6} md={3} lg={2} xl={2} key={group.name}> <Card profile> <Link to={`/group/${group.id}`}> <CardBody profile> diff --git a/jams-react-client/src/views/Maps/Maps.js b/jams-react-client/src/views/Maps/Maps.js index e33aba9173be460fb6bcdbb30acce5e539653444..e37f3d1c40e25f41a062f66ba966113fa9d2e9a4 100755 --- a/jams-react-client/src/views/Maps/Maps.js +++ b/jams-react-client/src/views/Maps/Maps.js @@ -3,7 +3,7 @@ import { withScriptjs, withGoogleMap, GoogleMap, - Marker + Marker, } from "react-google-maps"; const CustomSkinMap = withScriptjs( @@ -20,8 +20,8 @@ const CustomSkinMap = withScriptjs( stylers: [ { saturation: 43 }, { lightness: -11 }, - { hue: "#0088ff" } - ] + { hue: "#0088ff" }, + ], }, { featureType: "road", @@ -29,51 +29,51 @@ const CustomSkinMap = withScriptjs( stylers: [ { hue: "#ff0000" }, { saturation: -100 }, - { lightness: 99 } - ] + { lightness: 99 }, + ], }, { featureType: "road", elementType: "geometry.stroke", - stylers: [{ color: "#808080" }, { lightness: 54 }] + stylers: [{ color: "#808080" }, { lightness: 54 }], }, { featureType: "landscape.man_made", elementType: "geometry.fill", - stylers: [{ color: "#ece2d9" }] + stylers: [{ color: "#ece2d9" }], }, { featureType: "poi.park", elementType: "geometry.fill", - stylers: [{ color: "#ccdca1" }] + stylers: [{ color: "#ccdca1" }], }, { featureType: "road", elementType: "labels.text.fill", - stylers: [{ color: "#767676" }] + stylers: [{ color: "#767676" }], }, { featureType: "road", elementType: "labels.text.stroke", - stylers: [{ color: "#ffffff" }] + stylers: [{ color: "#ffffff" }], }, { featureType: "poi", stylers: [{ visibility: "off" }] }, { featureType: "landscape.natural", elementType: "geometry.fill", - stylers: [{ visibility: "on" }, { color: "#b8cb93" }] + stylers: [{ visibility: "on" }, { color: "#b8cb93" }], }, { featureType: "poi.park", stylers: [{ visibility: "on" }] }, { featureType: "poi.sports_complex", - stylers: [{ visibility: "on" }] + stylers: [{ visibility: "on" }], }, { featureType: "poi.medical", stylers: [{ visibility: "on" }] }, { featureType: "poi.business", - stylers: [{ visibility: "simplified" }] - } - ] + stylers: [{ visibility: "simplified" }], + }, + ], }} > <Marker position={{ lat: 40.748817, lng: -73.985428 }} /> diff --git a/jams-react-client/src/views/Notifications/Notifications.js b/jams-react-client/src/views/Notifications/Notifications.js index b10db293d5f8368d8f112e7011f1a1ef65fba096..bb8ed8581ef82cfc238631b8a41829faea2a42fa 100755 --- a/jams-react-client/src/views/Notifications/Notifications.js +++ b/jams-react-client/src/views/Notifications/Notifications.js @@ -23,11 +23,11 @@ const styles = { margin: "0", fontSize: "14px", marginTop: "0", - marginBottom: "0" + marginBottom: "0", }, "& a,& a:hover,& a:focus": { - color: "#FFFFFF" - } + color: "#FFFFFF", + }, }, cardTitleWhite: { color: "#FFFFFF", @@ -41,9 +41,9 @@ const styles = { color: "#777", fontSize: "65%", fontWeight: "400", - lineHeight: "1" - } - } + lineHeight: "1", + }, + }, }; const useStyles = makeStyles(styles); @@ -66,12 +66,12 @@ export default function Notifications() { } }; }); - const showNotification = place => { + const showNotification = (place) => { switch (place) { case "tl": if (!tl) { setTL(true); - setTimeout(function() { + setTimeout(function () { setTL(false); }, 6000); } @@ -79,7 +79,7 @@ export default function Notifications() { case "tc": if (!tc) { setTC(true); - setTimeout(function() { + setTimeout(function () { setTC(false); }, 6000); } @@ -87,7 +87,7 @@ export default function Notifications() { case "tr": if (!tr) { setTR(true); - setTimeout(function() { + setTimeout(function () { setTR(false); }, 6000); } @@ -95,7 +95,7 @@ export default function Notifications() { case "bl": if (!bl) { setBL(true); - setTimeout(function() { + setTimeout(function () { setBL(false); }, 6000); } @@ -103,7 +103,7 @@ export default function Notifications() { case "bc": if (!bc) { setBC(true); - setTimeout(function() { + setTimeout(function () { setBC(false); }, 6000); } @@ -111,7 +111,7 @@ export default function Notifications() { case "br": if (!br) { setBR(true); - setTimeout(function() { + setTimeout(function () { setBR(false); }, 6000); } diff --git a/jams-react-client/src/views/RTLPage/RTLPage.js b/jams-react-client/src/views/RTLPage/RTLPage.js index eca4168e6e22d6bcfed84d5f2d7014bb5ee1c9c3..e6d12796368f5f3a82ab9d81493e678565b67112 100644 --- a/jams-react-client/src/views/RTLPage/RTLPage.js +++ b/jams-react-client/src/views/RTLPage/RTLPage.js @@ -36,7 +36,7 @@ import SnackbarContent from "components/Snackbar/SnackbarContent.js"; import { dailySalesChart, emailsSubscriptionChart, - completedTasksChart + completedTasksChart, } from "variables/charts.js"; import styles from "assets/jss/material-dashboard-react/views/rtlStyle.js"; @@ -47,16 +47,16 @@ let bugs = [ "Ø·Ø±Ø§Ø Ú¯Ø±Ø§Ùیک از این متن به عنوان عنصری از ترکیب بندی برای پر کردن؟", " نخست از متن‌های آزمایشی Ùˆ بی‌معنی استÙاده می‌کنند تا صرÙا به مشتری یا صاØب کار خود نشان دهند؟", "همان Øال کار آنها به نوعی وابسته به متن می‌باشد", - " آنها با استÙاده از Ù…Øتویات ساختگی، صÙØÙ‡ گراÙیکی خود را صÙØه‌آرایی می‌کنند" + " آنها با استÙاده از Ù…Øتویات ساختگی، صÙØÙ‡ گراÙیکی خود را صÙØه‌آرایی می‌کنند", ]; let website = [ "بعد از اینکه متن در آن قرار گیرد چگونه به نظر می‌رسد Ùˆ قلم‌ها Ùˆ اندازه‌بندی‌ها چگونه در نظر گرÙته", - "اولیه Ø´Ú©Ù„ ظاهری Ùˆ Ú©Ù„ÛŒ Ø·Ø±Ø Ø³Ùارش گرÙته شده استÙاده Ù…ÛŒ نماید؟" + "اولیه Ø´Ú©Ù„ ظاهری Ùˆ Ú©Ù„ÛŒ Ø·Ø±Ø Ø³Ùارش گرÙته شده استÙاده Ù…ÛŒ نماید؟", ]; let server = [ "گراÙیکی نشانگر چگونگی نوع Ùˆ اندازه Ùونت Ùˆ ظاهر متن باشد. معمولا طراØان گراÙیک برای صÙØه‌آرایی، نخست از متن‌های آزمایشی؟", "از این متن به عنوان عنصری از ترکیب بندی برای پر کردن صÙØÙ‡ Ùˆ ارایه اولیه Ø´Ú©Ù„ ظاهری Ùˆ Ú©Ù„ÛŒ Ø·Ø±Ø Ø³Ùارش گرÙته شده استÙاده Ù…ÛŒ نماید، تا از نظر گراÙیکی نشانگر چگونگی نوع Ùˆ اندازه Ùونت Ùˆ ظاهر متن باشد. معمولا طراØان گراÙیک برای صÙØه‌آرایی، نخست از متن‌های آزمایشی ØŸ", - "از متن‌های آزمایشی Ùˆ بی‌معنی استÙاده می‌کنند تا صرÙا به مشتری یا صاØب کار خود نشان دهند؟" + "از متن‌های آزمایشی Ùˆ بی‌معنی استÙاده می‌کنند تا صرÙا به مشتری یا صاØب کار خود نشان دهند؟", ]; const useStyles = makeStyles(styles); @@ -82,7 +82,7 @@ export default function RTLPage() { <Danger> <Warning /> </Danger> - <a href="#pablo" onClick={e => e.preventDefault()}> + <a href="#pablo" onClick={(e) => e.preventDefault()}> Ùضای بیشتری داشته باشید... </a> </div> @@ -232,7 +232,7 @@ export default function RTLPage() { tasks={bugs} rtlActive /> - ) + ), }, { tabName: "وبسایت", @@ -244,7 +244,7 @@ export default function RTLPage() { tasks={website} rtlActive /> - ) + ), }, { tabName: "سرور", @@ -256,8 +256,8 @@ export default function RTLPage() { tasks={server} rtlActive /> - ) - } + ), + }, ]} /> </GridItem> @@ -277,7 +277,7 @@ export default function RTLPage() { ["1", "اØمد Øسینی ", "$36,738", "مازندران"], ["2", "مینا رضایی ", "$23,789", "گلستان"], ["3", "مبینا اØمدپور ", "$56,142", "تهران"], - ["4", "جلال آقایی ", "$38,735", "شهرکرد"] + ["4", "جلال آقایی ", "$38,735", "شهرکرد"], ]} /> </CardBody> @@ -340,7 +340,7 @@ export default function RTLPage() { <GridItem xs={12} sm={12} md={6}> <Card profile> <CardAvatar profile> - <a href="#pablo" onClick={e => e.preventDefault()}> + <a href="#pablo" onClick={(e) => e.preventDefault()}> <img src={avatar} alt="..." /> </a> </CardAvatar> diff --git a/jams-react-client/src/views/Settings/General.js b/jams-react-client/src/views/Settings/General.js index 3c5fea31b9dc04ba18fadb3adb73863af5edbddd..4e4bfcfcb3928d5d33610d6b8e9ceeedc46ce178 100644 --- a/jams-react-client/src/views/Settings/General.js +++ b/jams-react-client/src/views/Settings/General.js @@ -30,7 +30,7 @@ import i18next from "i18next"; import LanguagePicker from "../../components/LanguagePicker/LanguagePicker"; -const pjson = require('../../../package.json'); +const pjson = require("../../../package.json"); let generator = require("generate-password"); @@ -71,7 +71,12 @@ export default function General(props) { axios(configApiCall(api_path_put_update_user, "PUT", data, null)) .then(() => { props.setSeverity("success"); - props.setErrorMessage(i18next.t("admin_password_updated_successfully", "Administrator password successfully updated.")); + props.setErrorMessage( + i18next.t( + "admin_password_updated_successfully", + "Administrator password successfully updated." + ) + ); props.setError(true); }) .catch((error) => { @@ -100,7 +105,9 @@ export default function General(props) { */ const passwordSchema = Yup.object().shape({ - password: Yup.string().required(i18next.t("password_is_required", "Password is required!")), + password: Yup.string().required( + i18next.t("password_is_required", "Password is required!") + ), passwordConfirmation: Yup.string().oneOf( [Yup.ref("password"), null], i18next.t("password_must_match", "Passwords must match") @@ -116,168 +123,192 @@ export default function General(props) { return ( <GridContainer> - <Grid item xs={12} sm={12} md={6}> - <Card profile> - <CardHeader color="info" stats icon></CardHeader> - <CardBody profile> - <Formik - initialValues={{ - password: "", - confirmPassword: "", - }} - validationSchema={passwordSchema} - onSubmit={changePassword} - > - {({ - isValid, - dirty, - handleSubmit, - values, - setFieldValue, - touched, - errors, - }) => ( - <form onSubmit={handleSubmit} className={classes.form}> - <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", "Enter the following information to change your admin password.")} - </Typography> - </Grid> - <Grid item lg={6} > - <FormikField - name="password" - label={i18next.t("password", "Password")} - placeholder={i18next.t("password", "Password")} - type={passwordVisible ? "text" : "password"} - startAdornment={ - <InputAdornment position="start"> - <VpnKeyIcon /> - </InputAdornment> - } - endAdornment={ - <IconButton - aria-label="toggle password visibility" - onMouseDown={handleMouseDownPassword} - onMouseUp={handleMouseUpPassword} - > - {passwordVisible ? ( - <VisibilityIcon /> - ) : ( - <VisibilityOffIcon /> - )} - </IconButton> - } - handleChange={() => {}} - onKeyUpError={false} - onKeyUpErrorMessage="" - /> - {touched.password && errors.password ? ( - <span>{errors.password}</span> - ) : null} - - <FormikField - name="confirmPassword" - label={i18next.t("Confirm password", "Confirm password")} - placeholder={i18next.t("Confirm password", "Confirm password")} - type={passwordVisible ? "text" : "password"} - startAdornment={ - <InputAdornment position="start"> - <VpnKeyIcon /> - </InputAdornment> - } - endAdornment={ - <IconButton - aria-label="toggle password visibility" - onMouseDown={handleMouseDownPassword} - onMouseUp={handleMouseUpPassword} - > - {passwordVisible ? ( - <VisibilityIcon /> - ) : ( - <VisibilityOffIcon /> - )} - </IconButton> - } - handleChange={() => {}} - onKeyUpError={false} - onKeyUpErrorMessage="" - /> - {touched.confirmPassword && errors.confirmPassword ? ( - <span>{errors.confirmPassword}</span> - ) : null} - - <Button - variant="contained" - color="info" - size="large" - className={classes.button} - startIcon={<RefreshIcon />} - onClick={() => { - const newGeneratedPassword = passwordGenerator(); - setFieldValue("password", newGeneratedPassword, false); - setFieldValue("confirmPassword", newGeneratedPassword, false); - setCopied(false); - setGenerated(true); - }} - > - {i18next.t("generate", "Generate")} - </Button> - <CopyToClipboard - text={values.password} - onCopy={() => { - setCopied(true); - setGenerated(false); - }} - > - <Button - variant="contained" - color="info" - size="large" - className={classes.button} - startIcon={<FileCopyIcon />} - > - {i18next.t("copy_to_clipboard", "Copy to clipboard")} - </Button> - </CopyToClipboard> - {copied ? ( - <span style={{ marginLeft: "10px" }}>{i18next.t("copied", "Copied")}</span> - ) : null} - {generated ? ( - <span style={{ marginLeft: "10px" }}>{i18next.t("generated", "Generated")}</span> - ) : null} + <Grid item xs={12} sm={12} md={6}> + <Card profile> + <CardHeader color="info" stats icon></CardHeader> + <CardBody profile> + <Formik + initialValues={{ + password: "", + confirmPassword: "", + }} + validationSchema={passwordSchema} + onSubmit={changePassword} + > + {({ + isValid, + dirty, + handleSubmit, + values, + setFieldValue, + touched, + errors, + }) => ( + <form onSubmit={handleSubmit} className={classes.form}> + <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", + "Enter the following information to change your admin password." + )} + </Typography> + </Grid> + <Grid item lg={6}> + <FormikField + name="password" + label={i18next.t("password", "Password")} + placeholder={i18next.t("password", "Password")} + type={passwordVisible ? "text" : "password"} + startAdornment={ + <InputAdornment position="start"> + <VpnKeyIcon /> + </InputAdornment> + } + endAdornment={ + <IconButton + aria-label="toggle password visibility" + onMouseDown={handleMouseDownPassword} + onMouseUp={handleMouseUpPassword} + > + {passwordVisible ? ( + <VisibilityIcon /> + ) : ( + <VisibilityOffIcon /> + )} + </IconButton> + } + handleChange={() => {}} + onKeyUpError={false} + onKeyUpErrorMessage="" + /> + {touched.password && errors.password ? ( + <span>{errors.password}</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 item lg={6}> - Version {pjson.version.slice(0, 3)} - </Grid> - </Grid> + <FormikField + name="confirmPassword" + label={i18next.t( + "Confirm password", + "Confirm password" + )} + placeholder={i18next.t( + "Confirm password", + "Confirm password" + )} + type={passwordVisible ? "text" : "password"} + startAdornment={ + <InputAdornment position="start"> + <VpnKeyIcon /> + </InputAdornment> + } + endAdornment={ + <IconButton + aria-label="toggle password visibility" + onMouseDown={handleMouseDownPassword} + onMouseUp={handleMouseUpPassword} + > + {passwordVisible ? ( + <VisibilityIcon /> + ) : ( + <VisibilityOffIcon /> + )} + </IconButton> + } + handleChange={() => {}} + onKeyUpError={false} + onKeyUpErrorMessage="" + /> + {touched.confirmPassword && errors.confirmPassword ? ( + <span>{errors.confirmPassword}</span> + ) : null} - </form> - )} - </Formik> - </CardBody> - </Card> - </Grid> + <Button + variant="contained" + color="info" + size="large" + className={classes.button} + startIcon={<RefreshIcon />} + onClick={() => { + const newGeneratedPassword = passwordGenerator(); + setFieldValue( + "password", + newGeneratedPassword, + false + ); + setFieldValue( + "confirmPassword", + newGeneratedPassword, + false + ); + setCopied(false); + setGenerated(true); + }} + > + {i18next.t("generate", "Generate")} + </Button> + <CopyToClipboard + text={values.password} + onCopy={() => { + setCopied(true); + setGenerated(false); + }} + > + <Button + variant="contained" + color="info" + size="large" + className={classes.button} + startIcon={<FileCopyIcon />} + > + {i18next.t("copy_to_clipboard", "Copy to clipboard")} + </Button> + </CopyToClipboard> + {copied ? ( + <span style={{ marginLeft: "10px" }}> + {i18next.t("copied", "Copied")} + </span> + ) : null} + {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 item lg={6}> + Version {pjson.version.slice(0, 3)} + </Grid> + </Grid> + </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 e8dde97209a969438c7d8c9997e5815253c8059f..7b0852c09763db023e6c8a15fc5e000fdb25b40b 100644 --- a/jams-react-client/src/views/Settings/Settings.js +++ b/jams-react-client/src/views/Settings/Settings.js @@ -74,7 +74,6 @@ const styles = { }; export default function Settings(props) { - const [value, setValue] = React.useState(0); const [error, setError] = React.useState(false); const [severity, setSeverity] = React.useState("error"); @@ -87,7 +86,10 @@ export default function Settings(props) { return ( <div> <h4> - {i18next.t("you_are_not_allowed_to_access_this_section", "You are not allowed to access this section. Please contact your administrator to get administrator privileges.")} + {i18next.t( + "you_are_not_allowed_to_access_this_section", + "You are not allowed to access this section. Please contact your administrator to get administrator privileges." + )} </h4> </div> ); @@ -101,7 +103,10 @@ export default function Settings(props) { aria-label="simple tabs example" > <Tab label={i18next.t("general", "General")} {...a11yProps(0)} /> - <Tab label={i18next.t("subscription", "Subscription")} {...a11yProps(1)} /> + <Tab + label={i18next.t("subscription", "Subscription")} + {...a11yProps(1)} + /> </Tabs> </AppBar> <TabPanel value={value} index={0}> diff --git a/jams-react-client/src/views/Settings/Subscription.js b/jams-react-client/src/views/Settings/Subscription.js index a5ab8a6b8df01c358e0400b1afa341ee6ce3ec99..1dbfa96fdd912e96e051c4cf44d17341ed3363b3 100644 --- a/jams-react-client/src/views/Settings/Subscription.js +++ b/jams-react-client/src/views/Settings/Subscription.js @@ -1,141 +1,200 @@ -import React, {useEffect} from "react"; -import { useFormik } from 'formik'; -import * as Yup from 'yup'; -import Button from '@material-ui/core/Button'; -import TextField from '@material-ui/core/TextField'; -import Grid from '@material-ui/core/Grid'; -import Typography from '@material-ui/core/Typography'; -import { makeStyles } from '@material-ui/core/styles'; +import React, { useEffect } from "react"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import Button from "@material-ui/core/Button"; +import TextField from "@material-ui/core/TextField"; +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 CardBody from "components/Card/CardBody.js"; -import axios from 'axios'; -import configApiCall from '../../api' -import { api_path_post_configuration_register_license } from '../../globalUrls' +import axios from "axios"; +import configApiCall from "../../api"; +import { api_path_post_configuration_register_license } from "../../globalUrls"; import i18next from "i18next"; const useStyles = makeStyles((theme) => ({ - paper: { - marginTop: theme.spacing(8), - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - }, - avatar: { - margin: theme.spacing(1), - backgroundColor: theme.palette.secondary.main, - }, - form: { - width: '100%', // Fix IE 11 issue. - marginTop: theme.spacing(1), - }, - submit: { - margin: theme.spacing(3, 0, 2), - }, + paper: { + marginTop: theme.spacing(8), + display: "flex", + flexDirection: "column", + alignItems: "center", + }, + avatar: { + margin: theme.spacing(1), + backgroundColor: theme.palette.secondary.main, + }, + form: { + width: "100%", // Fix IE 11 issue. + marginTop: theme.spacing(1), + }, + submit: { + margin: theme.spacing(3, 0, 2), + }, })); export default function Subscription(props) { - const classes = useStyles(); - const [activated, setActivated] = React.useState(false); + const classes = useStyles(); + const [activated, setActivated] = React.useState(false); - useEffect(()=>{ - axios(configApiCall(api_path_post_configuration_register_license, "GET", null, null)).then((response)=>{ - if(response.data["activated"] === true) setActivated(true); - }).catch((error)=>{ - if(error.response.status === 500){ - props.setErrorMessage(i18next.t("an_error_occured_while_getting_license_information", "An error occurred while getting subscription information!")); - props.setSeverity("error"); - props.setError(true); - } - }) - }) + useEffect(() => { + axios( + configApiCall( + api_path_post_configuration_register_license, + "GET", + null, + null + ) + ) + .then((response) => { + if (response.data["activated"] === true) setActivated(true); + }) + .catch((error) => { + if (error.response.status === 500) { + props.setErrorMessage( + i18next.t( + "an_error_occured_while_getting_license_information", + "An error occurred while getting subscription information!" + ) + ); + props.setSeverity("error"); + props.setError(true); + } + }); + }); - /** - * Formik Validation Fields - */ - const formik = useFormik({ - initialValues: { - subscriptionCode: '', - }, - validationSchema: Yup.object({ - subscriptionCode: Yup.string().required(i18next.t("subscription_code_is_required", "Subscription code is required.")), - }), + /** + * Formik Validation Fields + */ + const formik = useFormik({ + initialValues: { + subscriptionCode: "", + }, + validationSchema: Yup.object({ + subscriptionCode: Yup.string().required( + i18next.t( + "subscription_code_is_required", + "Subscription code is required." + ) + ), + }), - onSubmit: values => { - handleSubmit(values); - }, - }); + onSubmit: (values) => { + handleSubmit(values); + }, + }); - function handleSubmit(values) { - //e.preventDefault(); - const jsonData = { - "base64License": values.subscriptionCode - } + function handleSubmit(values) { + //e.preventDefault(); + const jsonData = { + base64License: values.subscriptionCode, + }; - axios(configApiCall(api_path_post_configuration_register_license, "POST", jsonData, null)).then(()=>{ - props.setErrorMessage(i18next.t("license_registred_successfully", "Subscription successfully registered.")); - props.setSeverity("success"); - props.setError(true); - }).catch((error)=>{ - if(error.response.status === 500){ - props.setErrorMessage(i18next.t("a_generic_occured_while_trying_to_load_license_or_license_could_not_be_found", "A generic occurred while trying to load your subscription or your subscription could not be found!")); - props.setSeverity("error"); - props.setError(true); - } - }) - } + axios( + configApiCall( + api_path_post_configuration_register_license, + "POST", + jsonData, + null + ) + ) + .then(() => { + props.setErrorMessage( + i18next.t( + "license_registred_successfully", + "Subscription successfully registered." + ) + ); + props.setSeverity("success"); + props.setError(true); + }) + .catch((error) => { + if (error.response.status === 500) { + props.setErrorMessage( + i18next.t( + "a_generic_occured_while_trying_to_load_license_or_license_could_not_be_found", + "A generic occurred while trying to load your subscription or your subscription could not be found!" + ) + ); + props.setSeverity("error"); + props.setError(true); + } + }); + } - if(!activated){ - return ( - <GridContainer> - <Grid item xs={12} sm={12} md={6}> - <Card profile> + 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}> + <form + className={classes.form} + noValidate + onSubmit={formik.handleSubmit} + > <Grid container spacing={3}> - <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" - required - fullWidth - id="subscriptionCode" - label={i18next.t("subscription_code", "Subscription Code")} - name="subscriptionCode" - autoComplete="subscriptionCode" - autoFocus - {...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> - </form> + <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" + required + fullWidth + id="subscriptionCode" + label={i18next.t( + "subscription_code", + "Subscription Code" + )} + name="subscriptionCode" + autoComplete="subscriptionCode" + autoFocus + {...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> + </form> </CardBody> - </Card> - </Grid> - </GridContainer> - ); - }else{ - return( - <div><p>{i18next.t("your_license_is_already_activated", "Your subscription is already activated!")}</p></div> - ); - } - -} \ No newline at end of file + </Card> + </Grid> + </GridContainer> + ); + } else { + return ( + <div> + <p> + {i18next.t( + "your_license_is_already_activated", + "Your subscription is already activated!" + )} + </p> + </div> + ); + } +} diff --git a/jams-react-client/src/views/TableList/TableList.js b/jams-react-client/src/views/TableList/TableList.js index 5182022e0dad33f2dccb6953b8c783176c2e313f..de569d14d2bba26cfd7c9236b6df924d04c665b3 100755 --- a/jams-react-client/src/views/TableList/TableList.js +++ b/jams-react-client/src/views/TableList/TableList.js @@ -16,11 +16,11 @@ const styles = { margin: "0", fontSize: "14px", marginTop: "0", - marginBottom: "0" + marginBottom: "0", }, "& a,& a:hover,& a:focus": { - color: "#FFFFFF" - } + color: "#FFFFFF", + }, }, cardTitleWhite: { color: "#FFFFFF", @@ -34,9 +34,9 @@ const styles = { color: "#777", fontSize: "65%", fontWeight: "400", - lineHeight: "1" - } - } + lineHeight: "1", + }, + }, }; const useStyles = makeStyles(styles); @@ -63,7 +63,7 @@ export default function TableList() { ["Sage Rodriguez", "Netherlands", "Baileux", "$56,142"], ["Philip Chaney", "Korea, South", "Overland Park", "$38,735"], ["Doris Greene", "Malawi", "Feldkirchen in Kärnten", "$63,542"], - ["Mason Porter", "Chile", "Gloucester", "$78,615"] + ["Mason Porter", "Chile", "Gloucester", "$78,615"], ]} /> </CardBody> @@ -92,16 +92,16 @@ export default function TableList() { "Philip Chaney", "$38,735", "Korea, South", - "Overland Park" + "Overland Park", ], [ "5", "Doris Greene", "$63,542", "Malawi", - "Feldkirchen in Kärnten" + "Feldkirchen in Kärnten", ], - ["6", "Mason Porter", "$78,615", "Chile", "Gloucester"] + ["6", "Mason Porter", "$78,615", "Chile", "Gloucester"], ]} /> </CardBody> diff --git a/jams-react-client/src/views/Typography/Typography.js b/jams-react-client/src/views/Typography/Typography.js index 09822a2b8272a4c373ee13bbaa2f6fcb25dad163..98b595b7acfa00fb2433deb9535b15b888f48273 100755 --- a/jams-react-client/src/views/Typography/Typography.js +++ b/jams-react-client/src/views/Typography/Typography.js @@ -17,7 +17,7 @@ const styles = { typo: { paddingLeft: "25%", marginBottom: "40px", - position: "relative" + position: "relative", }, note: { fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif', @@ -30,14 +30,14 @@ const styles = { left: "0", marginLeft: "20px", position: "absolute", - width: "260px" + width: "260px", }, cardCategoryWhite: { color: "rgba(255,255,255,.62)", margin: "0", fontSize: "14px", marginTop: "0", - marginBottom: "0" + marginBottom: "0", }, cardTitleWhite: { color: "#FFFFFF", @@ -46,8 +46,8 @@ const styles = { fontWeight: "300", fontFamily: "'Roboto', 'Helvetica', 'Arial', sans-serif", marginBottom: "3px", - textDecoration: "none" - } + textDecoration: "none", + }, }; const useStyles = makeStyles(styles); diff --git a/jams-react-client/src/views/UpgradeToPro/UpgradeToPro.js b/jams-react-client/src/views/UpgradeToPro/UpgradeToPro.js index fd6d2af022f4c3291df6e0923377045940b5f4bd..1376e00c51d861ace5b97ca4edb7262881eb8c41 100644 --- a/jams-react-client/src/views/UpgradeToPro/UpgradeToPro.js +++ b/jams-react-client/src/views/UpgradeToPro/UpgradeToPro.js @@ -21,11 +21,11 @@ const styles = { margin: "0", fontSize: "14px", marginTop: "0", - marginBottom: "0" + marginBottom: "0", }, "& a,& a:hover,& a:focus": { - color: "#FFFFFF" - } + color: "#FFFFFF", + }, }, cardTitleWhite: { color: "#FFFFFF", @@ -39,15 +39,15 @@ const styles = { color: "#777", fontSize: "65%", fontWeight: "400", - lineHeight: "1" - } + lineHeight: "1", + }, }, tableUpgradeWrapper: { display: "block", width: "100%", overflowX: "auto", WebkitOverflowScrolling: "touch", - MsOverflowStyle: "-ms-autohiding-scrollbar" + MsOverflowStyle: "-ms-autohiding-scrollbar", }, table: { width: "100%", @@ -65,20 +65,20 @@ const styles = { fontWeight: "300", borderTopWidth: "0", borderBottom: "1px solid rgba(0, 0, 0, 0.06)", - textAlign: "inherit" + textAlign: "inherit", }, "& tbody tr td": { padding: "12px 8px", verticalAlign: "middle", - borderTop: "1px solid rgba(0, 0, 0, 0.06)" + borderTop: "1px solid rgba(0, 0, 0, 0.06)", }, "& td, & th": { - display: "table-cell" - } + display: "table-cell", + }, }, center: { - textAlign: "center" - } + textAlign: "center", + }, }; const useStyles = makeStyles(styles); diff --git a/jams-react-client/src/views/UserProfile/DisplayUserProfile.js b/jams-react-client/src/views/UserProfile/DisplayUserProfile.js index 03b3b457d9e527691026495d7c8b23210c07e2d0..2a258d5cd85389ba165b26d891fb0bd12b2c1073 100644 --- a/jams-react-client/src/views/UserProfile/DisplayUserProfile.js +++ b/jams-react-client/src/views/UserProfile/DisplayUserProfile.js @@ -19,10 +19,10 @@ import DialogContentText from "@material-ui/core/DialogContentText"; import DialogTitle from "@material-ui/core/DialogTitle"; import EditIcon from "@material-ui/icons/Edit"; import DeleteIcon from "@material-ui/icons/Delete"; -import AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutline'; +import AddCircleOutlineIcon from "@material-ui/icons/AddCircleOutline"; import Table from "@material-ui/core/Table"; -import TableHead from '@material-ui/core/TableHead'; +import TableHead from "@material-ui/core/TableHead"; import TableRow from "@material-ui/core/TableRow"; import TableBody from "@material-ui/core/TableBody"; import TableCell from "@material-ui/core/TableCell"; @@ -36,7 +36,6 @@ import SmartphoneOutlinedIcon from "@material-ui/icons/SmartphoneOutlined"; import LocalPrintshopOutlinedIcon from "@material-ui/icons/LocalPrintshopOutlined"; import PhoneForwardedOutlinedIcon from "@material-ui/icons/PhoneForwardedOutlined"; - import Avatar from "@material-ui/core/Avatar"; import Chip from "@material-ui/core/Chip"; import CardAvatar from "components/Card/CardAvatar"; @@ -61,7 +60,7 @@ import { api_path_get_group, api_path_post_group_member, api_path_get_admin_user_groups, - api_path_delete_group_member + api_path_delete_group_member, } from "globalUrls"; import dashboardStyle from "assets/jss/material-dashboard-react/views/dashboardStyle.js"; @@ -69,10 +68,9 @@ import dashboardStyle from "assets/jss/material-dashboard-react/views/dashboardS import { hexToRgb, blackColor } from "assets/jss/material-dashboard-react.js"; import axios from "axios"; - import PasswordDialog from "components/PasswordDialog/PasswordDialog"; -import TemporaryDrawer from "components/Drawer/Drawer" +import TemporaryDrawer from "components/Drawer/Drawer"; import i18next from "i18next"; @@ -133,25 +131,25 @@ const styles = (theme) => ({ [theme.breakpoints.down("md")]: { display: "flex", flexDirection: "column", - } + }, }, - footerActionButtons:{ + footerActionButtons: { display: "flex", flexDirection: "row", alignItems: "end", "& button": { - marginRight: "1rem" + marginRight: "1rem", }, [theme.breakpoints.down("md")]: { flexDirection: "column", alignItems: "stretch", "& button": { marginRight: "0", - width: "100%" + width: "100%", }, - } + }, }, - footerActionButtonsRight:{ + footerActionButtonsRight: { display: "flex", justifyContent: "flex-end", alignItems: "end", @@ -161,9 +159,9 @@ const styles = (theme) => ({ alignItems: "stretch", "& button": { marginRight: "0", - width: "100%" + width: "100%", }, - } + }, }, userProfileHeader: { display: "flex", @@ -184,7 +182,7 @@ const styles = (theme) => ({ }, cardAvatarMobile: { [theme.breakpoints.down("md")]: { - textAlign: "center" + textAlign: "center", }, }, loading: { @@ -192,7 +190,7 @@ const styles = (theme) => ({ }, whiteButtonText: { color: "white", - } + }, }); const useStyles = makeStyles(styles); @@ -212,7 +210,7 @@ export default function DisplayUserProfile(props) { const [openDrawer, setOpenDrawer] = React.useState(false); const searchGroups = (value) => { - if(value === "") value = "*"; + if (value === "") value = "*"; axios( configApiCall( api_path_get_list_group + "?groupName=" + value, @@ -224,16 +222,16 @@ export default function DisplayUserProfile(props) { .then((response) => { let availableGroups = []; const groupResults = response.data; - groupResults.forEach((possibleGroup) =>{ - let existingGroup = false; - groups.forEach((actualGroup)=>{ - if(actualGroup === possibleGroup.name) { - existingGroup = true; - return; - } - }) - if(!existingGroup) availableGroups.push(possibleGroup); - }) + groupResults.forEach((possibleGroup) => { + let existingGroup = false; + groups.forEach((actualGroup) => { + if (actualGroup === possibleGroup.name) { + existingGroup = true; + return; + } + }); + if (!existingGroup) availableGroups.push(possibleGroup); + }); setGroups(availableGroups); }) .catch((error) => { @@ -241,21 +239,19 @@ export default function DisplayUserProfile(props) { if (error.response.status === 401) { auth.authenticated = false; history.push("/"); - }else { + } else { setGroups([]); } } else { setGroups([]); } - }); - } + }; const removeUserFromGroup = (group) => { - let data = { - "username": props.username - } + username: props.username, + }; axios( configApiCall( @@ -264,38 +260,36 @@ export default function DisplayUserProfile(props) { data, null ) - ).then((response)=>{ + ) + .then((response) => { let newGroupMemberships = groupMemberships; newGroupMemberships.splice(newGroupMemberships.indexOf(group), 1); setGroupMemberships(newGroupMemberships); - }).catch((error)=>{console.log(error)}) - + }) + .catch((error) => { + console.log(error); + }); }; const addUserToGroup = (group) => { - let data = { - "username": props.username - } + username: props.username, + }; axios( - configApiCall( - api_path_post_group_member + group.id, - "POST", - data, - null - ) - ).then((response)=>{ + configApiCall(api_path_post_group_member + group.id, "POST", data, null) + ) + .then((response) => { let newGroupMemberships = groupMemberships; - newGroupMemberships.push( - { - "groupId": group.id, - "name": group.name - } - ); + newGroupMemberships.push({ + groupId: group.id, + name: group.name, + }); setGroupMemberships(newGroupMemberships); - }).catch((error)=>{console.log(error)}) - + }) + .catch((error) => { + console.log(error); + }); }; useEffect(() => { @@ -330,28 +324,40 @@ export default function DisplayUserProfile(props) { ) .then((response) => { setUser(response.data); - axios(configApiCall(api_path_get_admin_user_groups + props.username, - "GET", - null, - null - )).then((userGroups) => { - let userGroupsData = userGroups.data; - userGroupsData.forEach((group) => { - axios(configApiCall(api_path_get_group + group.groupId, 'GET', null, null)).then((groupInfo) =>{ - group["name"] = groupInfo.data.name; + axios( + configApiCall( + api_path_get_admin_user_groups + props.username, + "GET", + null, + null + ) + ) + .then((userGroups) => { + let userGroupsData = userGroups.data; + userGroupsData.forEach((group) => { + axios( + configApiCall( + api_path_get_group + group.groupId, + "GET", + null, + null + ) + ).then((groupInfo) => { + group["name"] = groupInfo.data.name; + }); }); + setGroupMemberships(userGroupsData); + }) + .catch((error) => { + if (error.response.status === 401) { + auth.authenticated = false; + history.push("/signin"); + } + if (error.response.status === 404) { + setGroupMemberships([]); + } }); - setGroupMemberships(userGroupsData); - }).catch((error) => { - if (error.response.status === 401) { - auth.authenticated = false; - history.push("/signin"); - } - if (error.response.status === 404) { - setGroupMemberships([]); - } - }) - searchGroups("*") + searchGroups("*"); setLoading(false); }) .catch((error) => { @@ -391,27 +397,39 @@ export default function DisplayUserProfile(props) { ) .then((response) => { setUser(response.data); - axios(configApiCall(api_path_get_admin_user_groups + props.username, - "GET", - null, - null - )).then((userGroups) => { - let userGroupsData = userGroups.data; - userGroupsData.forEach((group) => { - axios(configApiCall(api_path_get_group + group.groupId, 'GET', null, null)).then((groupInfo) =>{ - group["name"] = groupInfo.data.name; + axios( + configApiCall( + api_path_get_admin_user_groups + props.username, + "GET", + null, + null + ) + ) + .then((userGroups) => { + let userGroupsData = userGroups.data; + userGroupsData.forEach((group) => { + axios( + configApiCall( + api_path_get_group + group.groupId, + "GET", + null, + null + ) + ).then((groupInfo) => { + group["name"] = groupInfo.data.name; + }); }); + setGroupMemberships(userGroupsData); + }) + .catch((error) => { + if (error.response.status === 401) { + auth.authenticated = false; + history.push("/signin"); + } + if (error.response.status === 404) { + setGroupMemberships([]); + } }); - setGroupMemberships(userGroupsData); - }).catch((error) => { - if (error.response.status === 401) { - auth.authenticated = false; - history.push("/signin"); - } - if (error.response.status === 404) { - setGroupMemberships([]); - } - }) setLoading(false); }) .catch((error) => { @@ -490,16 +508,15 @@ export default function DisplayUserProfile(props) { }; const tableCellClasses = classnames(classes.tableCell); - + const canEdit = () => { - if(auth.isLocalDirectory()) { - if(!auth.hasAdminScope() && auth.getUsername() !== user.username) { - return false + if (auth.isLocalDirectory()) { + if (!auth.hasAdminScope() && auth.getUsername() !== user.username) { + return false; } return true; - } - else return false; - } + } else return false; + }; return ( <div> @@ -514,14 +531,23 @@ export default function DisplayUserProfile(props) { </DialogTitle> <DialogContent> <DialogContentText id="alert-dialog-description"> - {i18next.t("are_you_sure_want_revoke", "Are you sure you want to revoke")} <strong>{revokedUser}</strong> ? + {i18next.t( + "are_you_sure_want_revoke", + "Are you sure you want to revoke" + )}{" "} + <strong>{revokedUser}</strong> ? </DialogContentText> </DialogContent> <DialogActions> <Button onClick={handleClose} color="primary"> {i18next.t("cancel", "Cancel")} </Button> - <Button onClick={revokeUser} color="info" className={classes.whiteButtonText} autoFocus> + <Button + onClick={revokeUser} + color="info" + className={classes.whiteButtonText} + autoFocus + > {i18next.t("revoke", "Revoke")} </Button> </DialogActions> @@ -533,206 +559,231 @@ export default function DisplayUserProfile(props) { handleClosechangePassword={handleClosechangePassword} /> <div className={classes.loading}> - {loading && ( - <LinearProgress variant="determinate" value={progress} /> - )} + {loading && <LinearProgress variant="determinate" value={progress} />} </div> - <TemporaryDrawer - openDrawer={openDrawer} - setOpenDrawer={setOpenDrawer} - direction="right" - placeholder={i18next.t("add_user_to_group", "Add user to group ...")} - searchTargets={searchGroups} - targets={groups} - existingTargets={groupMemberships} - addElementToTarget={addUserToGroup} - targetName={props.username} - type="group" + <TemporaryDrawer + openDrawer={openDrawer} + setOpenDrawer={setOpenDrawer} + direction="right" + placeholder={i18next.t("add_user_to_group", "Add user to group ...")} + searchTargets={searchGroups} + targets={groups} + existingTargets={groupMemberships} + addElementToTarget={addUserToGroup} + targetName={props.username} + type="group" /> - {!loading && (<GridContainer> - <Grid item xs={12} sm={12} md={6}> - <Card profile> - <CardBody profile> - <div className={classes.root}> - <Grid container spacing={2}> - <Grid item xs={12} sm={12} md={6}> - <CardAvatar - displayProfile - className={classes.cardAvatarMobile} - > - <img - src={ - user.profilePicture - ? "data:image/png;base64, " + user.profilePicture - : noProfilePicture - } - className={classes.editProfilePicture} - alt="..." - /> - </CardAvatar> - </Grid> - <Grid item xs={12} sm={12} md={6}> - <div className={classes.userProfileHeader}> - <div> - <h3 className={classes.cardTitle}> - {user.username} - </h3> - {getUserStatus()} + {!loading && ( + <GridContainer> + <Grid item xs={12} sm={12} md={6}> + <Card profile> + <CardBody profile> + <div className={classes.root}> + <Grid container spacing={2}> + <Grid item xs={12} sm={12} md={6}> + <CardAvatar + displayProfile + className={classes.cardAvatarMobile} + > + <img + src={ + user.profilePicture + ? "data:image/png;base64, " + user.profilePicture + : noProfilePicture + } + className={classes.editProfilePicture} + alt="..." + /> + </CardAvatar> + </Grid> + <Grid item xs={12} sm={12} md={6}> + <div className={classes.userProfileHeader}> + <div> + <h3 className={classes.cardTitle}>{user.username}</h3> + {getUserStatus()} + </div> </div> - </div> + </Grid> + <Grid item xs={12} sm={12} md={6}> + <List dense={false}> + {(user.firstName || user.lastName) && ( + <ListItem> + <ListItemAvatar> + <Avatar> + <PersonIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText + primary={`${user.firstName} ${user.lastName}`} + /> + </ListItem> + )} + {user.phoneNumber && ( + <ListItem> + <ListItemAvatar> + <Avatar> + <PhoneInTalkOutlinedIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary={user.phoneNumber} /> + </ListItem> + )} + {user.organization && ( + <ListItem> + <ListItemAvatar> + <Avatar> + <BusinessCenterOutlinedIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary={user.organization} /> + </ListItem> + )} + </List> + + <List dense={false}> + {user.email && ( + <ListItem> + <ListItemAvatar> + <Avatar> + <AlternateEmailOutlinedIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary={user.email} /> + </ListItem> + )} + {user.phoneNumberExtension && ( + <ListItem> + <ListItemAvatar> + <Avatar> + <PhoneForwardedOutlinedIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary={user.phoneNumberExtension} /> + </ListItem> + )} + {user.mobileNumber && ( + <ListItem> + <ListItemAvatar> + <Avatar> + <SmartphoneOutlinedIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary={user.mobileNumber} /> + </ListItem> + )} + {user.faxNumber && ( + <ListItem> + <ListItemAvatar> + <Avatar> + <LocalPrintshopOutlinedIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary={user.faxNumber} /> + </ListItem> + )} + </List> + </Grid> </Grid> - <Grid item xs={12} sm={12} md={6}> - <List dense={false}> - {(user.firstName || user.lastName) && ( - <ListItem> - <ListItemAvatar> - <Avatar> - <PersonIcon /> - </Avatar> - </ListItemAvatar> - <ListItemText primary={`${user.firstName} ${user.lastName}`} /> - </ListItem> - )} - {user.phoneNumber && ( - <ListItem> - <ListItemAvatar> - <Avatar> - <PhoneInTalkOutlinedIcon /> - </Avatar> - </ListItemAvatar> - <ListItemText primary={user.phoneNumber} /> - </ListItem> - )} - {user.organization && ( - <ListItem> - <ListItemAvatar> - <Avatar> - <BusinessCenterOutlinedIcon /> - </Avatar> - </ListItemAvatar> - <ListItemText primary={user.organization} /> - </ListItem> - )} - </List> - - <List dense={false}> - {user.email && ( - <ListItem> - <ListItemAvatar> - <Avatar> - <AlternateEmailOutlinedIcon /> - </Avatar> - </ListItemAvatar> - <ListItemText primary={user.email} /> - </ListItem> - )} - {user.phoneNumberExtension && ( - <ListItem> - <ListItemAvatar> - <Avatar> - <PhoneForwardedOutlinedIcon /> - </Avatar> - </ListItemAvatar> - <ListItemText primary={user.phoneNumberExtension} /> - </ListItem> - )} - {user.mobileNumber && ( - <ListItem> - <ListItemAvatar> - <Avatar> - <SmartphoneOutlinedIcon /> - </Avatar> - </ListItemAvatar> - <ListItemText primary={user.mobileNumber} /> - </ListItem> - )} - {user.faxNumber && ( - <ListItem> - <ListItemAvatar> - <Avatar> - <LocalPrintshopOutlinedIcon /> - </Avatar> - </ListItemAvatar> - <ListItemText primary={user.faxNumber} /> - </ListItem> - )} - </List> + </div> + </CardBody> + <CardFooter className={classes.profileFooter}> + <Grid container className={classes.footerActionButtons}> + <Grid item> + {canEdit() && ( + <Button + color="info" + className={classes.whiteButtonText} + onClick={() => props.setDisplayUser(false)} + > + <EditIcon /> {i18next.t("edit_profile", "Edit profile")} + </Button> + )} </Grid> - </Grid> - </div> - </CardBody> - <CardFooter className={classes.profileFooter}> - <Grid container className={classes.footerActionButtons}> - <Grid item > - {canEdit() && ( - <Button - color="info" - className={classes.whiteButtonText} - onClick={() => props.setDisplayUser(false)} - > - <EditIcon /> {i18next.t("edit_profile", "Edit profile")} - </Button> - )} + <Grid item> + {auth.isLocalDirectory() && auth.hasAdminScope() && ( + <Button + color="info" + className={classes.whiteButtonText} + onClick={() => { + setChangePasswordOpen(true); + }} + > + <VpnKeyIcon />{" "} + {i18next.t("change_password", "Change password")} + </Button> + )} </Grid> - <Grid item > - {auth.isLocalDirectory() && auth.hasAdminScope() && ( - <Button - color="info" - className={classes.whiteButtonText} - onClick={() => { - setChangePasswordOpen(true); - }} - > - <VpnKeyIcon /> {i18next.t("change_password", "Change password")} - </Button> - )} + </Grid> + + <Grid container className={classes.footerActionButtonsRight}> + <Grid item> + {auth.hasAdminScope() && revoked === false && ( + <Button + color="info" + className={classes.whiteButtonText} + onClick={() => handleClickOpen(user.username)} + > + <DeleteIcon fontSize="small" />{" "} + {i18next.t("revoke_user", "Revoke user")} + </Button> + )} </Grid> - </Grid> - - <Grid container className={classes.footerActionButtonsRight}> - <Grid item> - {auth.hasAdminScope() && revoked === false && ( - <Button - color="info" - className={classes.whiteButtonText} - onClick={() => handleClickOpen(user.username)} - > - <DeleteIcon fontSize="small" /> {i18next.t("revoke_user", "Revoke user")} - </Button> - )} </Grid> - </Grid> - </CardFooter> - </Card> - </Grid> + </CardFooter> + </Card> + </Grid> {auth.hasAdminScope() && ( <GridItem xs={12} sm={12} md={12}> - <Button color="primary" onClick={() => {setOpenDrawer(true)}}><AddCircleOutlineIcon /> {i18next.t("add_user_to_a_group", "Add user to a group")}</Button> - <Table className={classes.table}> - <TableHead> - <TableRow> - <TableCell align="left">{i18next.t("group_name", "Group name")}</TableCell> - <TableCell align="right">{i18next.t("action", "Action")}</TableCell> - </TableRow> - </TableHead> - <TableBody> - {groupMemberships !== [] && groupMemberships.map(group => - <TableRow key={group} className={classes.tableRow}> - <TableCell className={tableCellClasses}> - <Link to={`/group/${group.groupId}`}> - {group.name} - </Link> - </TableCell> - <TableCell align="right" className={classes.tableActions}> - <Button color="primary" onClick={() => removeUserFromGroup(group)}>{i18next.t("remove_from_group", "Remove from group")}</Button> - </TableCell> - </TableRow> - ) } - </TableBody> - </Table> + <Button + color="primary" + onClick={() => { + setOpenDrawer(true); + }} + > + <AddCircleOutlineIcon />{" "} + {i18next.t("add_user_to_a_group", "Add user to a group")} + </Button> + <Table className={classes.table}> + <TableHead> + <TableRow> + <TableCell align="left"> + {i18next.t("group_name", "Group name")} + </TableCell> + <TableCell align="right"> + {i18next.t("action", "Action")} + </TableCell> + </TableRow> + </TableHead> + <TableBody> + {groupMemberships !== [] && + groupMemberships.map((group) => ( + <TableRow key={group} className={classes.tableRow}> + <TableCell className={tableCellClasses}> + <Link to={`/group/${group.groupId}`}> + {group.name} + </Link> + </TableCell> + <TableCell + align="right" + className={classes.tableActions} + > + <Button + color="primary" + onClick={() => removeUserFromGroup(group)} + > + {i18next.t( + "remove_from_group", + "Remove from group" + )} + </Button> + </TableCell> + </TableRow> + ))} + </TableBody> + </Table> </GridItem> )} - </GridContainer> + </GridContainer> )} </div> ); diff --git a/jams-react-client/src/views/UserProfile/EditCreateUserProfile.js b/jams-react-client/src/views/UserProfile/EditCreateUserProfile.js index 84d3f2394ed47c41c332f82948bcfb5c54af7ecc..58832b73d6bb3d36f39960d8b6c18a8b483fefa7 100644 --- a/jams-react-client/src/views/UserProfile/EditCreateUserProfile.js +++ b/jams-react-client/src/views/UserProfile/EditCreateUserProfile.js @@ -140,8 +140,8 @@ const styles = (theme) => ({ display: "flex", flexDirection: "column", "& button": { - width: "100%" - } + width: "100%", + }, }, }, button: { @@ -194,28 +194,28 @@ const styles = (theme) => ({ [theme.breakpoints.down("xs")]: { display: "flex", flexDirection: "column", - alignItems: "center" - } + alignItems: "center", + }, }, profileEditAvatarMobile: { [theme.breakpoints.down("xs")]: { display: "flex", flexDirection: "column", alignItems: "center", - marginTop: 10 - } + marginTop: 10, + }, }, profileEditAvatarInputMobile: { [theme.breakpoints.down("xs")]: { - display: "flex", + display: "flex", flexDirection: "row", - justifyContent: "center", - alignItems: "center" - } + justifyContent: "center", + alignItems: "center", + }, }, whiteButtonText: { color: "white", - } + }, }); const useStyles = makeStyles(styles); @@ -270,7 +270,6 @@ export default function EditCreateUserProfile(props) { }); React.useEffect(() => { - if (!props.createUser) { setLoading(true); const timer = setInterval(() => { @@ -293,7 +292,7 @@ export default function EditCreateUserProfile(props) { ) .then((response) => { const user = response.data; - const values ={ + const values = { username: user.username, firstName: user.firstName, lastName: user.lastName, @@ -304,7 +303,7 @@ export default function EditCreateUserProfile(props) { phoneNumber: user.phoneNumber, phoneNumberExtension: user.phoneNumberExtension, mobileNumber: user.mobileNumber, - } + }; setInitialValues(values); setProfilePicture(user.profilePicture); if (user.profilePicture !== "") { @@ -470,18 +469,41 @@ export default function EditCreateUserProfile(props) { .min(3, i18next.t("minimum_3_characters", "Minimum 3 characters!")) .max(32, i18next.t("maximum_32_characters", "Maximum 32 characters!")) .required(i18next.t("username_is_required", "Username is required!")) - .matches(/^[A-Za-z_][A-Za-z0-9_]*$/, i18next.t("only_alphanumeric_characters", "Only alphanumeric characters!")), + .matches( + /^[A-Za-z_][A-Za-z0-9_]*$/, + i18next.t( + "only_alphanumeric_characters", + "Only alphanumeric characters!" + ) + ), password: props.createUser - ? Yup.string().required(i18next.t("password_is_required", "Password is required!")) + ? Yup.string().required( + i18next.t("password_is_required", "Password is required!") + ) : null, confirmPassword: props.createUser - ? Yup.string().oneOf([Yup.ref("password"), null], i18next.t("password_must_match", "Passwords must match")) + ? Yup.string().oneOf( + [Yup.ref("password"), null], + i18next.t("password_must_match", "Passwords must match") + ) : null, - firstName: Yup.string().min(2, i18next.t("first_name_is_too_short", "First name is too short!")), - lastName: Yup.string().min(2, i18next.t("last_name_is_too_short", "Last Name is too short!")), + firstName: Yup.string().min( + 2, + i18next.t("first_name_is_too_short", "First name is too short!") + ), + lastName: Yup.string().min( + 2, + i18next.t("last_name_is_too_short", "Last Name is too short!") + ), email: Yup.string().email(i18next.t("invalid_email", "Invalid email!")), profilePicture: Yup.string(), - organization: Yup.string().min(2, i18next.t("organization_name_too_short", "Organization name is too short!")), + organization: Yup.string().min( + 2, + i18next.t( + "organization_name_too_short", + "Organization name is too short!" + ) + ), faxNumber: Yup.string().matches( /^(\+\d{1,2}\s?)?1?\-?\.?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/, i18next.t("fax_not_valid", "Fax number not valid!") @@ -506,7 +528,9 @@ export default function EditCreateUserProfile(props) { aria-describedby="alert-dialog-description" classes={{ paper: classes.dialogPaper }} > - <DialogTitle id="alert-dialog-title">{i18next.t("crop_image", "Crop image")}</DialogTitle> + <DialogTitle id="alert-dialog-title"> + {i18next.t("crop_image", "Crop image")} + </DialogTitle> <DialogContent> <div className={classes.cropContainer}> <Cropper @@ -560,386 +584,444 @@ export default function EditCreateUserProfile(props) { </div> </DialogContent> <DialogActions> - <Button onClick={cropProfilePicture} color="info" className={classes.whiteButtonText} autoFocus> + <Button + onClick={cropProfilePicture} + color="info" + className={classes.whiteButtonText} + autoFocus + > {i18next.t("validate", "Validate")} </Button> </DialogActions> </Dialog> <div className={classes.loading}> - {loading && ( - <LinearProgress variant="determinate" value={progress} /> - )} + {loading && <LinearProgress variant="determinate" value={progress} />} </div> - {!loading && (<GridContainer> - <GridItem xs={12} sm={12} md={8}> - <Formik - initialValues={initialValues} - onSubmit={handleFormikSubmit} - validationSchema={EditCreateSchema} - > - {({ isValid, dirty, handleSubmit, setFieldValue, values }) => ( - <form onSubmit={handleSubmit}> - <Card profile> - <CardHeader color="info" stats icon className={classes.profileEditHeaderMobile}> - <p className={classes.cardCategory}> - {props.createUser ? i18next.t("create_new_profile", "Create new profile") : i18next.t("edit_profile", "Edit profile")} - </p> - {props.createUser ? ( - "" - ) : ( - <h3 className={classes.cardTitle}>{userName}</h3> - )} - </CardHeader> - <CardBody profile> - <CardAvatar editProfile className={classes.profileEditAvatarMobile}> - <img - src={profilePicturePreview} - alt="..." - className={classes.editProfilePicture} - onClick={() => { - let pictureChange = document.getElementById( - "change-profile-picture" - ); - pictureChange.click(); - }} - /> - </CardAvatar> - <div className={classes.root}> - <Grid container spacing={5}> - <Grid item xs={12} sm={12} md={12} className={classes.profileEditAvatarInputMobile} > - <input - accept="image/*" - className={classes.input} - id="icon-button-file" - type="file" - onChange={handleProfilePictureChange} - /> - <label htmlFor="icon-button-file"> - <IconButton - id="change-profile-picture" - color="info" - aria-label="upload picture" - component="span" - > - <PhotoCamera /> - </IconButton>{" "} - {i18next.t("change_profile_image", "Change profile image")} - </label> - </Grid> - {props.createUser && ( - <Grid item xs={12} sm={12} md={6}> + {!loading && ( + <GridContainer> + <GridItem xs={12} sm={12} md={8}> + <Formik + initialValues={initialValues} + onSubmit={handleFormikSubmit} + validationSchema={EditCreateSchema} + > + {({ isValid, dirty, handleSubmit, setFieldValue, values }) => ( + <form onSubmit={handleSubmit}> + <Card profile> + <CardHeader + color="info" + stats + icon + className={classes.profileEditHeaderMobile} + > + <p className={classes.cardCategory}> + {props.createUser + ? i18next.t( + "create_new_profile", + "Create new profile" + ) + : i18next.t("edit_profile", "Edit profile")} + </p> + {props.createUser ? ( + "" + ) : ( + <h3 className={classes.cardTitle}>{userName}</h3> + )} + </CardHeader> + <CardBody profile> + <CardAvatar + editProfile + className={classes.profileEditAvatarMobile} + > + <img + src={profilePicturePreview} + alt="..." + className={classes.editProfilePicture} + onClick={() => { + let pictureChange = document.getElementById( + "change-profile-picture" + ); + pictureChange.click(); + }} + /> + </CardAvatar> + <div className={classes.root}> + <Grid container spacing={5}> + <Grid + item + xs={12} + sm={12} + md={12} + className={classes.profileEditAvatarInputMobile} + > + <input + accept="image/*" + className={classes.input} + id="icon-button-file" + type="file" + onChange={handleProfilePictureChange} + /> + <label htmlFor="icon-button-file"> + <IconButton + id="change-profile-picture" + color="info" + aria-label="upload picture" + component="span" + > + <PhotoCamera /> + </IconButton>{" "} + {i18next.t( + "change_profile_image", + "Change profile image" + )} + </label> + </Grid> + {props.createUser && ( + <Grid item xs={12} sm={12} md={6}> + <FormikField + name="username" + label={i18next.t("username", "Username")} + placeholder={i18next.t("username", "Username")} + startAdornment={ + <InputAdornment position="start"> + <AccountCircleIcon /> + </InputAdornment> + } + endAdornment={ + values.username === "" ? ( + "" + ) : userExists ? ( + <CancelIcon style={{ color: "#cc0000" }} /> + ) : ( + <CheckCircleIcon + style={{ color: "#99cc00" }} + /> + ) + } + required + autoComplete="off" + handleChange={checkUserExists} + onKeyUpError={userExists} + onKeyUpErrorMessage={i18next.t( + "username_already_taken", + "Username already taken" + )} + /> + </Grid> + )} + {props.createUser && ( + <Grid item xs={12} sm={12} md={6}></Grid> + )} + {props.createUser && ( + <Grid item xs={12} sm={12} md={6}> + <FormikField + type={passwordVisible ? "text" : "password"} + name="password" + label={i18next.t("password", "Password")} + placeholder={i18next.t("password", "Password")} + startAdornment={ + <InputAdornment position="start"> + <VpnKeyIcon /> + </InputAdornment> + } + endAdornment={ + <IconButton + aria-label="toggle password visibility" + onMouseDown={handleMouseDownPassword} + onMouseUp={handleMouseUpPassword} + > + {passwordVisible ? ( + <VisibilityIcon /> + ) : ( + <VisibilityOffIcon /> + )} + </IconButton> + } + required + autoComplete="off" + handleChange={() => {}} + onKeyUpError={false} + onKeyUpErrorMessage="" + /> + </Grid> + )} + {props.createUser && ( + <Grid item xs={12} sm={12} md={6}> + <FormikField + type={passwordVisible ? "text" : "password"} + name="confirmPassword" + label={i18next.t( + "confirm_password", + "Confirm password" + )} + placeholder={i18next.t( + "confirm_password", + "Confirm password" + )} + startAdornment={ + <InputAdornment position="start"> + <VpnKeyIcon /> + </InputAdornment> + } + endAdornment={ + <IconButton + aria-label="toggle password visibility" + onMouseDown={handleMouseDownPassword} + onMouseUp={handleMouseUpPassword} + > + {passwordVisible ? ( + <VisibilityIcon /> + ) : ( + <VisibilityOffIcon /> + )} + </IconButton> + } + required + autoComplete="off" + handleChange={() => {}} + onKeyUpError={false} + onKeyUpErrorMessage="" + /> + </Grid> + )} + {props.createUser && ( + <Grid + item + align="left" + xs={12} + sm={12} + md={6} + ></Grid> + )} + {props.createUser && ( + <Grid item align="left" xs={12} sm={12} md={6}> + <Button + variant="contained" + color="primary" + size="large" + className={classes.button} + startIcon={<RefreshIcon />} + onClick={() => { + const newGeneratedPassword = passwordGenerator(); + setFieldValue( + "password", + newGeneratedPassword, + false + ); + setFieldValue( + "confirmPassword", + newGeneratedPassword, + false + ); + setCopied(false); + setGenerated(true); + }} + > + {i18next.t("generate", "Generate")} + </Button> + <CopyToClipboard + text={values.password} + onCopy={() => { + setCopied(true); + setGenerated(false); + }} + > + <Button + variant="contained" + color="primary" + size="large" + className={classes.button} + startIcon={<FileCopyIcon />} + > + {i18next.t( + "copy_to_clipboard", + "Copy to clipboard" + )} + </Button> + </CopyToClipboard> + {copied ? ( + <span style={{ marginLeft: "10px" }}> + {i18next.t("copied", "Copied")} + </span> + ) : null} + {generated ? ( + <span style={{ marginLeft: "10px" }}> + {i18next.t("generated", "Generated")} + </span> + ) : null} + </Grid> + )} + <Grid item align="center" xs={12} sm={12} md={6}> <FormikField - name="username" - label={i18next.t("username", "Username")} - placeholder={i18next.t("username", "Username")} + name="firstName" + label={i18next.t("first_name", "First name")} + placeholder={i18next.t( + "first_name", + "First name" + )} startAdornment={ <InputAdornment position="start"> - <AccountCircleIcon /> + <PersonIcon /> </InputAdornment> } - endAdornment={ - values.username === "" ? ( - "" - ) : userExists ? ( - <CancelIcon style={{ color: "#cc0000" }} /> - ) : ( - <CheckCircleIcon - style={{ color: "#99cc00" }} - /> - ) + handleChange={() => {}} + onKeyUpError={false} + onKeyUpErrorMessage="" + /> + </Grid> + <Grid item align="center" xs={12} sm={12} md={6}> + <FormikField + name="lastName" + label={i18next.t("last_name", "Last name")} + placeholder={i18next.t("last_name", "Last name")} + startAdornment={ + <InputAdornment position="start"> + <PersonOutlinedIcon /> + </InputAdornment> } - required - autoComplete="off" - handleChange={checkUserExists} - onKeyUpError={userExists} - onKeyUpErrorMessage={i18next.t("username_already_taken", "Username already taken")} + handleChange={() => {}} + onKeyUpError={false} + onKeyUpErrorMessage="" /> </Grid> - )} - {props.createUser && ( - <Grid item xs={12} sm={12} md={6}></Grid> - )} - {props.createUser && ( - <Grid item xs={12} sm={12} md={6}> + <Grid item align="center" xs={12} sm={12} md={6}> <FormikField - type={passwordVisible ? "text" : "password"} - name="password" - label={i18next.t("password", "Password")} - placeholder={i18next.t("password", "Password")} + name="email" + label={i18next.t("email", "Email")} + placeholder={i18next.t("email", "Email")} startAdornment={ <InputAdornment position="start"> - <VpnKeyIcon /> + <AlternateEmailOutlinedIcon /> </InputAdornment> } - endAdornment={ - <IconButton - aria-label="toggle password visibility" - onMouseDown={handleMouseDownPassword} - onMouseUp={handleMouseUpPassword} - > - {passwordVisible ? ( - <VisibilityIcon /> - ) : ( - <VisibilityOffIcon /> - )} - </IconButton> + handleChange={() => {}} + onKeyUpError={false} + onKeyUpErrorMessage="" + /> + </Grid> + <Grid item align="center" xs={12} sm={12} md={6}> + <FormikField + name="organization" + label={i18next.t("organization", "Organization")} + placeholder={i18next.t( + "organization", + "Organization" + )} + startAdornment={ + <InputAdornment position="start"> + <BusinessCenterOutlinedIcon /> + </InputAdornment> } - required - autoComplete="off" handleChange={() => {}} onKeyUpError={false} onKeyUpErrorMessage="" /> </Grid> - )} - {props.createUser && ( - <Grid item xs={12} sm={12} md={6}> + <Grid item align="center" xs={12} sm={12} md={6}> <FormikField - type={passwordVisible ? "text" : "password"} - name="confirmPassword" - label={i18next.t("confirm_password", "Confirm password")} - placeholder={i18next.t("confirm_password", "Confirm password")} + name="faxNumber" + label={i18next.t("fax_number", "Fax number")} + placeholder={i18next.t( + "fax_number", + "Fax number" + )} startAdornment={ <InputAdornment position="start"> - <VpnKeyIcon /> + <LocalPrintshopOutlinedIcon /> </InputAdornment> } - endAdornment={ - <IconButton - aria-label="toggle password visibility" - onMouseDown={handleMouseDownPassword} - onMouseUp={handleMouseUpPassword} - > - {passwordVisible ? ( - <VisibilityIcon /> - ) : ( - <VisibilityOffIcon /> - )} - </IconButton> + handleChange={() => {}} + onKeyUpError={false} + onKeyUpErrorMessage="" + /> + </Grid> + <Grid item align="center" xs={12} sm={12} md={6}> + <FormikField + name="phoneNumber" + label={i18next.t("phone_number", "Phone number")} + placeholder={i18next.t( + "phone_number", + "Phone number" + )} + startAdornment={ + <InputAdornment position="start"> + <PhoneInTalkOutlinedIcon /> + </InputAdornment> } - required - autoComplete="off" handleChange={() => {}} onKeyUpError={false} onKeyUpErrorMessage="" /> </Grid> - )} - {props.createUser && ( - <Grid item align="left" xs={12} sm={12} md={6}></Grid> - )} - {props.createUser && ( - <Grid item align="left" xs={12} sm={12} md={6}> - <Button - variant="contained" - color="primary" - size="large" - className={classes.button} - startIcon={<RefreshIcon />} - onClick={() => { - const newGeneratedPassword = passwordGenerator(); - setFieldValue( - "password", - newGeneratedPassword, - false - ); - setFieldValue( - "confirmPassword", - newGeneratedPassword, - false - ); - setCopied(false); - setGenerated(true); - }} - > - {i18next.t("generate", "Generate")} - </Button> - <CopyToClipboard - text={values.password} - onCopy={() => { - setCopied(true); - setGenerated(false); - }} - > - <Button - variant="contained" - color="primary" - size="large" - className={classes.button} - startIcon={<FileCopyIcon />} - > - {i18next.t("copy_to_clipboard", "Copy to clipboard")} - </Button> - </CopyToClipboard> - {copied ? ( - <span style={{ marginLeft: "10px" }}>{i18next.t("copied", "Copied")}</span> - ) : null} - {generated ? ( - <span style={{ marginLeft: "10px" }}> - {i18next.t("generated", "Generated")} - </span> - ) : null} + <Grid item align="center" xs={12} sm={12} md={6}> + <FormikField + name="phoneNumberExtension" + label={i18next.t("extension", "Extension")} + placeholder={i18next.t("extension", "Extension")} + startAdornment={ + <InputAdornment position="start"> + <PhoneForwardedOutlinedIcon /> + </InputAdornment> + } + handleChange={() => {}} + onKeyUpError={false} + onKeyUpErrorMessage="" + /> + </Grid> + <Grid item align="center" xs={12} sm={12} md={6}> + <FormikField + name="mobileNumber" + label={i18next.t("mobile", "Mobile")} + placeholder={i18next.t("mobile", "Mobile")} + startAdornment={ + <InputAdornment position="start"> + <SmartphoneOutlinedIcon /> + </InputAdornment> + } + handleChange={() => {}} + onKeyUpError={false} + onKeyUpErrorMessage="" + /> </Grid> - )} - <Grid item align="center" xs={12} sm={12} md={6}> - <FormikField - name="firstName" - label={i18next.t("first_name", "First name")} - placeholder={i18next.t("first_name", "First name")} - startAdornment={ - <InputAdornment position="start"> - <PersonIcon /> - </InputAdornment> - } - handleChange={() => {}} - onKeyUpError={false} - onKeyUpErrorMessage="" - /> - </Grid> - <Grid item align="center" xs={12} sm={12} md={6}> - <FormikField - name="lastName" - label={i18next.t("last_name", "Last name")} - placeholder={i18next.t("last_name", "Last name")} - startAdornment={ - <InputAdornment position="start"> - <PersonOutlinedIcon /> - </InputAdornment> - } - handleChange={() => {}} - onKeyUpError={false} - onKeyUpErrorMessage="" - /> - </Grid> - <Grid item align="center" xs={12} sm={12} md={6}> - <FormikField - name="email" - label={i18next.t("email", "Email")} - placeholder={i18next.t("email", "Email")} - startAdornment={ - <InputAdornment position="start"> - <AlternateEmailOutlinedIcon /> - </InputAdornment> - } - handleChange={() => {}} - onKeyUpError={false} - onKeyUpErrorMessage="" - /> - </Grid> - <Grid item align="center" xs={12} sm={12} md={6}> - <FormikField - name="organization" - label={i18next.t("organization", "Organization")} - placeholder={i18next.t("organization", "Organization")} - startAdornment={ - <InputAdornment position="start"> - <BusinessCenterOutlinedIcon /> - </InputAdornment> - } - handleChange={() => {}} - onKeyUpError={false} - onKeyUpErrorMessage="" - /> - </Grid> - <Grid item align="center" xs={12} sm={12} md={6}> - <FormikField - name="faxNumber" - label={i18next.t("fax_number", "Fax number")} - placeholder={i18next.t("fax_number", "Fax number")} - startAdornment={ - <InputAdornment position="start"> - <LocalPrintshopOutlinedIcon /> - </InputAdornment> - } - handleChange={() => {}} - onKeyUpError={false} - onKeyUpErrorMessage="" - /> - </Grid> - <Grid item align="center" xs={12} sm={12} md={6}> - <FormikField - name="phoneNumber" - label={i18next.t("phone_number", "Phone number")} - placeholder={i18next.t("phone_number", "Phone number")} - startAdornment={ - <InputAdornment position="start"> - <PhoneInTalkOutlinedIcon /> - </InputAdornment> - } - handleChange={() => {}} - onKeyUpError={false} - onKeyUpErrorMessage="" - /> - </Grid> - <Grid item align="center" xs={12} sm={12} md={6}> - <FormikField - name="phoneNumberExtension" - label={i18next.t("extension", "Extension")} - placeholder={i18next.t("extension", "Extension")} - startAdornment={ - <InputAdornment position="start"> - <PhoneForwardedOutlinedIcon /> - </InputAdornment> - } - handleChange={() => {}} - onKeyUpError={false} - onKeyUpErrorMessage="" - /> - </Grid> - <Grid item align="center" xs={12} sm={12} md={6}> - <FormikField - name="mobileNumber" - label={i18next.t("mobile", "Mobile")} - placeholder={i18next.t("mobile", "Mobile")} - startAdornment={ - <InputAdornment position="start"> - <SmartphoneOutlinedIcon /> - </InputAdornment> - } - handleChange={() => {}} - onKeyUpError={false} - onKeyUpErrorMessage="" - /> </Grid> - </Grid> - </div> - </CardBody> - <CardFooter className={classes.alignRight}> - {!props.createUser && ( - <Button - color="info" - className={classes.whiteButtonText} - onClick={handleCancelUpdate} - > - {i18next.t("cancel", "Cancel")} - </Button> - )} - {props.createUser ? ( - <Button - type="submit" - disabled={!isValid || !dirty || userExists} - color="info" - className={classes.whiteButtonText} - > - {i18next.t("create_profile", "Create Profile")} - </Button> - ) : ( - <Button - type="submit" - disabled={!isValid} - color="info" - className={classes.whiteButtonText} - > - {i18next.t("save_profile", "Save Profile")} - </Button> - )} - </CardFooter> - </Card> - </form> - )} - </Formik> - </GridItem> - </GridContainer> + </div> + </CardBody> + <CardFooter className={classes.alignRight}> + {!props.createUser && ( + <Button + color="info" + className={classes.whiteButtonText} + onClick={handleCancelUpdate} + > + {i18next.t("cancel", "Cancel")} + </Button> + )} + {props.createUser ? ( + <Button + type="submit" + disabled={!isValid || !dirty || userExists} + color="info" + className={classes.whiteButtonText} + > + {i18next.t("create_profile", "Create Profile")} + </Button> + ) : ( + <Button + type="submit" + disabled={!isValid} + color="info" + className={classes.whiteButtonText} + > + {i18next.t("save_profile", "Save Profile")} + </Button> + )} + </CardFooter> + </Card> + </form> + )} + </Formik> + </GridItem> + </GridContainer> )} </div> ); diff --git a/jams-react-client/src/views/UserProfile/UserProfile.js b/jams-react-client/src/views/UserProfile/UserProfile.js index abf8477fab633d184d483565b7516d3887457353..62cc5dc841c5cc570c51e492d9ede32439b146e1 100755 --- a/jams-react-client/src/views/UserProfile/UserProfile.js +++ b/jams-react-client/src/views/UserProfile/UserProfile.js @@ -65,7 +65,7 @@ export default function UserProfile(props) { }; React.useEffect(() => { - if(props.username === "null") { + if (props.username === "null") { history.push("/"); } }, []); diff --git a/jams-react-client/src/views/UserProfile/cropImage.js b/jams-react-client/src/views/UserProfile/cropImage.js index bf3a9e6a7dbb466263778da49f0fe5ecfea73827..1bd5b8de102cf0c9c19aa3df2ca752ff6a87b300 100644 --- a/jams-react-client/src/views/UserProfile/cropImage.js +++ b/jams-react-client/src/views/UserProfile/cropImage.js @@ -1,14 +1,14 @@ -const createImage = url => +const createImage = (url) => new Promise((resolve, reject) => { - const image = new Image() - image.addEventListener('load', () => resolve(image)) - image.addEventListener('error', error => reject(error)) - image.setAttribute('crossOrigin', 'anonymous') // needed to avoid cross-origin issues on CodeSandbox - image.src = url - }) + const image = new Image(); + image.addEventListener("load", () => resolve(image)); + image.addEventListener("error", (error) => reject(error)); + image.setAttribute("crossOrigin", "anonymous"); // needed to avoid cross-origin issues on CodeSandbox + image.src = url; + }); function getRadianAngle(degreeValue) { - return (degreeValue * Math.PI) / 180 + return (degreeValue * Math.PI) / 180; } /** @@ -18,49 +18,49 @@ function getRadianAngle(degreeValue) { * @param {number} rotation - optional rotation parameter */ export default async function getCroppedImg(imageSrc, pixelCrop, rotation = 0) { - const image = await createImage(imageSrc) - const canvas = document.createElement('canvas') - const ctx = canvas.getContext('2d') + const image = await createImage(imageSrc); + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d"); - const maxSize = Math.max(image.width, image.height) - const safeArea = 2 * ((maxSize / 2) * Math.sqrt(2)) + const maxSize = Math.max(image.width, image.height); + const safeArea = 2 * ((maxSize / 2) * Math.sqrt(2)); // set each dimensions to double largest dimension to allow for a safe area for the // image to rotate in without being clipped by canvas context - canvas.width = safeArea - canvas.height = safeArea + canvas.width = safeArea; + canvas.height = safeArea; // translate canvas context to a central location on image to allow rotating around the center. - ctx.translate(safeArea / 2, safeArea / 2) - ctx.rotate(getRadianAngle(rotation)) - ctx.translate(-safeArea / 2, -safeArea / 2) + ctx.translate(safeArea / 2, safeArea / 2); + ctx.rotate(getRadianAngle(rotation)); + ctx.translate(-safeArea / 2, -safeArea / 2); // draw rotated image and store data. ctx.drawImage( image, safeArea / 2 - image.width * 0.5, safeArea / 2 - image.height * 0.5 - ) - const data = ctx.getImageData(0, 0, safeArea, safeArea) + ); + const data = ctx.getImageData(0, 0, safeArea, safeArea); // set canvas width to final desired crop size - this will clear existing context - canvas.width = pixelCrop.width - canvas.height = pixelCrop.height + canvas.width = pixelCrop.width; + canvas.height = pixelCrop.height; // paste generated rotate image with correct offsets for x,y crop values. ctx.putImageData( data, 0 - safeArea / 2 + image.width * 0.5 - pixelCrop.x, 0 - safeArea / 2 + image.height * 0.5 - pixelCrop.y - ) + ); // As Base64 string - return canvas.toDataURL('image/jpeg'); + return canvas.toDataURL("image/jpeg"); // As a blob -// return new Promise(resolve => { -// canvas.toBlob(file => { -// resolve(URL.createObjectURL(file)) -// }, 'image/jpeg') -// }) + // return new Promise(resolve => { + // canvas.toBlob(file => { + // resolve(URL.createObjectURL(file)) + // }, 'image/jpeg') + // }) } diff --git a/jams-react-client/src/views/Users/Users.js b/jams-react-client/src/views/Users/Users.js index 90baa046d90171c19b920eac58473dbd4ef49386..59ce0c9f783d6ad7a47f2d5504df8234d75d77d1 100644 --- a/jams-react-client/src/views/Users/Users.js +++ b/jams-react-client/src/views/Users/Users.js @@ -1,5 +1,5 @@ import React, { useState, useEffect, useCallback } from "react"; -import { Link } from 'react-router-dom' +import { Link } from "react-router-dom"; import { useHistory } from "react-router-dom"; // @material-ui/core components import { makeStyles } from "@material-ui/core/styles"; @@ -18,9 +18,9 @@ import UserProfile from "views/UserProfile/UserProfile.js"; import InfoIcon from "@material-ui/icons/Info"; import BusinessOutlinedIcon from "@material-ui/icons/BusinessOutlined"; import Search from "@material-ui/icons/Search"; -import Checkbox from '@material-ui/core/Checkbox'; -import FormGroup from '@material-ui/core/FormGroup'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; +import Checkbox from "@material-ui/core/Checkbox"; +import FormGroup from "@material-ui/core/FormGroup"; +import FormControlLabel from "@material-ui/core/FormControlLabel"; import axios from "axios"; import configApiCall from "api.js"; import auth from "auth.js"; @@ -68,9 +68,8 @@ const styles = { alignItems: "center", }, cardBodyContent: { - - wordWrap: "break-word" - } + wordWrap: "break-word", + }, }; const useStyles = makeStyles(styles); export default function Users(props) { @@ -83,7 +82,7 @@ export default function Users(props) { const [createUser, setCreateUser] = React.useState(false); const [loading, setLoading] = React.useState(false); const [progress, setProgress] = React.useState(0); - const [showRevokedUsers, setShowRevokedUsers] = React.useState(false) + const [showRevokedUsers, setShowRevokedUsers] = React.useState(false); const [searchValue, setSearchValue] = React.useState(""); @@ -181,24 +180,22 @@ export default function Users(props) { <GridItem xs={12} sm={12} md={12}> {auth.isLocalDirectory() && auth.hasAdminScope() && ( <Link to={"/createuser"}> - <Button - variant="contained" - color="primary" - > + <Button variant="contained" color="primary"> <AddCircleOutlineIcon />{" "} {i18next.t("create_user", "Create user")} </Button> </Link> )} <FormControlLabel - control={ - <Checkbox - checked={showRevokedUsers} - onChange={() => setShowRevokedUsers(!showRevokedUsers)} - inputProps={{ 'aria-label': 'primary checkbox' }} - color="primary" - />} - style={{marginLeft: "1rem"}} + control={ + <Checkbox + checked={showRevokedUsers} + onChange={() => setShowRevokedUsers(!showRevokedUsers)} + inputProps={{ "aria-label": "primary checkbox" }} + color="primary" + /> + } + style={{ marginLeft: "1rem" }} label="Display revoked users" /> @@ -210,8 +207,10 @@ export default function Users(props) { className: classes.margin + " " + classes.search, }} inputProps={{ - placeholder: - i18next.t("search_users_using", "Search users using (username, first name, last name)"), + placeholder: i18next.t( + "search_users_using", + "Search users using (username, first name, last name)" + ), inputProps: { "aria-label": i18next.t("search_users", "Search users"), }, @@ -242,7 +241,9 @@ export default function Users(props) { <div className={classes.usersNotFound}> <InfoIcon /> - <p style={{ marginLeft: "10px" }}>{i18next.t("no_users_found", "No users found")}</p> + <p style={{ marginLeft: "10px" }}> + {i18next.t("no_users_found", "No users found")} + </p> </div> )} </GridItem> @@ -258,64 +259,60 @@ export default function Users(props) { return 0; }) .map((user) => ( - <GridItem - xs={12} - sm={6} - md={3} - lg={2} - xl={2} - - key={user.username} - > - <Card profile > + <GridItem xs={12} sm={6} md={3} lg={2} xl={2} key={user.username}> + <Card profile> <Link to={`/user/${user.username}`}> <CardBody profile> <CardAvatar profile> <img src={ user.profilePicture - ? "data:image/png;base64, " + - user.profilePicture + ? "data:image/png;base64, " + user.profilePicture : noProfilePicture } alt="..." /> </CardAvatar> - + <GridContainer - container - direction="column" - justify="flex-end" - alignItems="flex-start" - > - <GridItem style={{ minHeight:"50px"}}> - <h4 className={classes.cardTitle}> + container + direction="column" + justify="flex-end" + alignItems="flex-start" + > + <GridItem style={{ minHeight: "50px" }}> + <h4 className={classes.cardTitle}> {`${user.firstName} ${user.lastName}`} </h4> </GridItem> <GridItem> <ul className={classes.cardBodyContent}> - <li> - <img - src={jami} - width="20px" - alt="Jami" - style={{ minWidth:"20px", marginRight: "10px" }} - />{" "} - {user.username} - </li> - <li> - {user.organization && <BusinessOutlinedIcon - fontSize="small" - style={{ marginRight: "10px" }} - />}{" "} - {user.organization} - </li> - </ul> + <li> + <img + src={jami} + width="20px" + alt="Jami" + style={{ + minWidth: "20px", + marginRight: "10px", + }} + />{" "} + {user.username} + </li> + <li> + {user.organization && ( + <BusinessOutlinedIcon + fontSize="small" + style={{ marginRight: "10px" }} + /> + )}{" "} + {user.organization} + </li> + </ul> </GridItem> </GridContainer> - </CardBody> - </Link> + </CardBody> + </Link> </Card> </GridItem> ))} @@ -324,7 +321,10 @@ export default function Users(props) { <InfoIcon /> <p style={{ marginLeft: "10px" }}> - {i18next.t("no_users_found_matching", "No users found matching search value!")} + {i18next.t( + "no_users_found_matching", + "No users found matching search value!" + )} </p> </div> )}