From 78d699561c046be645b54cf059588bf9b012213a Mon Sep 17 00:00:00 2001 From: Sergio Betanzos Date: Wed, 26 Aug 2020 18:42:25 +0200 Subject: [PATCH] F #3951: Update app layouts & sidebar (#169) * F #3951: Update app layouts and router * F #3951: Fix footer component * F #3951: Add loading screen & update sidebar * F #3951: Add responsiveness to sidebar --- src/fireedge/package.json | 2 +- src/fireedge/src/public/actions/general.js | 8 +- src/fireedge/src/public/app.js | 36 ++-- src/fireedge/src/public/assets/theme.js | 198 +++++++++--------- .../src/public/components/Footer/index.js | 6 +- .../src/public/components/Footer/styles.js | 6 +- .../components/FormControl/SubmitButton.js | 4 +- .../src/public/components/HOC/GuessLayout.js | 49 ----- .../index.js} | 68 ++---- .../components/HOC/InternalLayout/styles.js | 47 +++++ .../HOC/{AuthLayout.js => MainLayout.js} | 58 +++-- .../src/public/components/HOC/index.js | 10 +- .../src/public/components/Header/User.js | 7 +- .../src/public/components/Header/index.js | 31 ++- .../public/components/LoadingScreen/index.js | 34 +++ .../components/Sidebar/SidebarCollapseItem.js | 37 +++- .../public/components/Sidebar/SidebarLink.js | 38 +++- .../src/public/components/Sidebar/index.js | 54 +++-- .../src/public/components/Sidebar/styles.js | 92 +++++++- src/fireedge/src/public/constants/index.js | 7 +- .../src/public/containers/Login/Form2fa.js | 26 ++- .../src/public/containers/Login/FormUser.js | 23 +- .../src/public/containers/Login/index.js | 8 +- src/fireedge/src/public/hooks/useAuth.js | 12 +- src/fireedge/src/public/hooks/useGeneral.js | 8 +- src/fireedge/src/public/icons/logo.js | 98 +++++++++ src/fireedge/src/public/reducers/general.js | 5 +- src/fireedge/src/public/router/endpoints.js | 44 +++- src/fireedge/src/public/router/index.js | 28 +-- src/fireedge/src/public/utils/helpers.js | 1 + 30 files changed, 705 insertions(+), 340 deletions(-) delete mode 100644 src/fireedge/src/public/components/HOC/GuessLayout.js rename src/fireedge/src/public/components/HOC/{InternalLayout.js => InternalLayout/index.js} (57%) create mode 100644 src/fireedge/src/public/components/HOC/InternalLayout/styles.js rename src/fireedge/src/public/components/HOC/{AuthLayout.js => MainLayout.js} (52%) create mode 100644 src/fireedge/src/public/components/LoadingScreen/index.js create mode 100644 src/fireedge/src/public/icons/logo.js create mode 100644 src/fireedge/src/public/utils/helpers.js diff --git a/src/fireedge/package.json b/src/fireedge/package.json index c285080f8c..d80e8c51f3 100644 --- a/src/fireedge/package.json +++ b/src/fireedge/package.json @@ -36,7 +36,7 @@ "axios": "^0.19.2", "body-parser": "^1.19.0", "btoa": "^1.2.1", - "classnames": "^2.2.6", + "clsx": "^1.1.1", "colors": "^1.4.0", "compression": "^1.7.4", "concurrently": "^5.2.0", diff --git a/src/fireedge/src/public/actions/general.js b/src/fireedge/src/public/actions/general.js index abd007ecdf..8b1f6dfafc 100644 --- a/src/fireedge/src/public/actions/general.js +++ b/src/fireedge/src/public/actions/general.js @@ -1,11 +1,13 @@ const CHANGE_ZONE = 'CHANGE_ZONE'; const DISPLAY_LOADING = 'DISPLAY_LOADING'; const TOGGLE_MENU = 'TOGGLE_MENU'; +const FIX_MENU = 'FIX_MENU'; const Actions = { CHANGE_ZONE, DISPLAY_LOADING, - TOGGLE_MENU + TOGGLE_MENU, + FIX_MENU }; module.exports = { @@ -21,5 +23,9 @@ module.exports = { openMenu: isOpen => ({ type: TOGGLE_MENU, isOpen + }), + fixMenu: isFixed => ({ + type: FIX_MENU, + isFixed }) }; diff --git a/src/fireedge/src/public/app.js b/src/fireedge/src/public/app.js index 31dd644b60..34468fe3ab 100644 --- a/src/fireedge/src/public/app.js +++ b/src/fireedge/src/public/app.js @@ -18,9 +18,9 @@ import { StaticRouter, BrowserRouter } from 'react-router-dom'; import { Provider } from 'react-redux'; import PropTypes from 'prop-types'; -import { CssBaseline, ThemeProvider } from '@material-ui/core'; +import { CssBaseline, ThemeProvider, StylesProvider } from '@material-ui/core'; -import theme from 'client/assets/theme'; +import theme, { generateClassName } from 'client/assets/theme'; import { TranslateProvider } from 'client/components/HOC'; import Router from 'client/router'; @@ -35,21 +35,23 @@ const App = ({ location, context, store }) => { return ( - - - {location && context ? ( - // server build - - - - ) : ( - // browser build - - - - )} - - + + + + {location && context ? ( + // server build + + + + ) : ( + // browser build + + + + )} + + + ); }; diff --git a/src/fireedge/src/public/assets/theme.js b/src/fireedge/src/public/assets/theme.js index 5eedfe133f..3ba75349d2 100644 --- a/src/fireedge/src/public/assets/theme.js +++ b/src/fireedge/src/public/assets/theme.js @@ -1,6 +1,14 @@ -import { createMuiTheme, responsiveFontSizes } from '@material-ui/core'; +import { + createMuiTheme, + responsiveFontSizes, + createGenerateClassName +} from '@material-ui/core'; -const defaultBreakpoints = { +export const generateClassName = createGenerateClassName({ + productionPrefix: 'one-' +}); + +export const defaultBreakpoints = { xs: 0, sm: 600, md: 960, @@ -12,99 +20,95 @@ const defaultBreakpoints = { desktop: 1280 }; -const theme = createMuiTheme({ - typography: { - fontFamily: ['Ubuntu', 'Lato'].join(',') - }, - overrides: { - MuiDrawer: { - paper: { - width: 360, - overflow: 'hidden', - [`@media (max-width: ${defaultBreakpoints.tablet}px)`]: { - width: '100%' - } - } - }, - MuiFormControl: { - root: { - margin: '.5rem 0' - } - }, - MuiExpansionPanel: { - root: { - minHeight: 56, - boxShadow: 'none', - '&:not(:last-child)': { - borderBottom: 0 - }, - '&$expanded': { - minHeight: 56, - margin: '0' - } - }, - content: { - '&$expanded': { - margin: '0' - } - }, - expanded: {} - }, - MuiExpansionPanelSummary: { - root: { - '&$disabled': { - opacity: 1 - } - }, - content: { - margin: 8, - '&$expanded': { - margin: 8 - } - }, - disabled: {}, - expanded: {} - }, - MuiCssBaseline: { - '@global': { - body: { - // height: '100vh' - } - // '@font-face': [UbuntuFont] - } - } - }, - palette: { - common: { black: '#000', white: '#fff' }, - background: { - paper: '#fff', - default: '#fafafa' - }, - primary: { - light: 'rgba(191, 230, 242, 1)', - main: 'rgba(64, 179, 217, 1)', - dark: 'rgba(0, 152, 195, 1)', - contrastText: '#fff' - }, - secondary: { - light: 'rgba(199, 201, 200, 1)', - main: 'rgba(87, 92, 91, 1)', - dark: 'rgba(53, 55, 53, 1)', - contrastText: '#fff' - }, - error: { - light: '#e57373', - main: '#f44336', - dark: '#d32f2f', - contrastText: '#fff' - }, - text: { - primary: 'rgba(0, 0, 0, 0.87)', - secondary: 'rgba(0, 0, 0, 0.54)', - disabled: 'rgba(0, 0, 0, 0.38)', - hint: 'rgba(0, 0, 0, 0.38)' - } - } -}); +export const sidebarWidth = { + minified: 60, + fixed: 240 +}; -export default responsiveFontSizes(theme); +export default responsiveFontSizes( + createMuiTheme({ + typography: { + fontFamily: ['Ubuntu', 'Lato'].join(',') + }, + overrides: { + MuiFormControl: { + root: { + margin: '.5rem 0' + } + }, + MuiExpansionPanel: { + root: { + minHeight: 56, + boxShadow: 'none', + '&:not(:last-child)': { + borderBottom: 0 + }, + '&$expanded': { + minHeight: 56, + margin: '0' + } + }, + content: { + '&$expanded': { + margin: '0' + } + }, + expanded: {} + }, + MuiExpansionPanelSummary: { + root: { + '&$disabled': { + opacity: 1 + } + }, + content: { + margin: 8, + '&$expanded': { + margin: 8 + } + }, + disabled: {}, + expanded: {} + }, + MuiCssBaseline: { + '@global': { + body: { + // height: '100vh' + } + // '@font-face': [UbuntuFont] + } + } + }, + palette: { + common: { black: '#000', white: '#fff' }, + background: { + paper: '#fff', + default: '#fafafa' + }, + primary: { + light: 'rgba(191, 230, 242, 1)', + main: 'rgba(64, 179, 217, 1)', + dark: 'rgba(0, 152, 195, 1)', + contrastText: '#fff' + }, + secondary: { + light: 'rgba(199, 201, 200, 1)', + main: 'rgba(87, 92, 91, 1)', + dark: 'rgba(53, 55, 53, 1)', + contrastText: '#fff' + }, + error: { + light: '#e57373', + main: '#f44336', + dark: '#d32f2f', + contrastText: '#fff' + }, + text: { + primary: 'rgba(0, 0, 0, 0.87)', + secondary: 'rgba(0, 0, 0, 0.54)', + disabled: 'rgba(0, 0, 0, 0.38)', + hint: 'rgba(0, 0, 0, 0.38)' + } + } + }) +); diff --git a/src/fireedge/src/public/components/Footer/index.js b/src/fireedge/src/public/components/Footer/index.js index cc11e4d636..80ad160676 100644 --- a/src/fireedge/src/public/components/Footer/index.js +++ b/src/fireedge/src/public/components/Footer/index.js @@ -26,7 +26,11 @@ const Footer = React.memo(() => { return ( - {`❤️ by `} + {'Made with'} + + {'❤️'} + + {'by'} {text} diff --git a/src/fireedge/src/public/components/Footer/styles.js b/src/fireedge/src/public/components/Footer/styles.js index a616d4e49f..a647b591c5 100644 --- a/src/fireedge/src/public/components/Footer/styles.js +++ b/src/fireedge/src/public/components/Footer/styles.js @@ -3,7 +3,7 @@ import { makeStyles } from '@material-ui/core'; export default makeStyles(theme => ({ footer: { color: theme.palette.primary.light, - position: 'fixed', + position: 'absolute', bottom: 0, left: 'auto', right: 0, @@ -13,6 +13,10 @@ export default makeStyles(theme => ({ textAlign: 'center', padding: 5 }, + heartIcon: { + margin: theme.spacing(0, 1), + color: theme.palette.error.dark + }, link: { color: theme.palette.primary.light } diff --git a/src/fireedge/src/public/components/FormControl/SubmitButton.js b/src/fireedge/src/public/components/FormControl/SubmitButton.js index 7c7635df3b..86c6d1a85b 100644 --- a/src/fireedge/src/public/components/FormControl/SubmitButton.js +++ b/src/fireedge/src/public/components/FormControl/SubmitButton.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { makeStyles, CircularProgress, Button } from '@material-ui/core'; -import { Translate } from 'client/components/HOC'; +import { Tr } from 'client/components/HOC'; import * as CONSTANT from 'client/constants'; const useStyles = makeStyles(theme => ({ @@ -26,7 +26,7 @@ const ButtonSubmit = ({ isSubmitting, label, ...rest }) => { {...rest} > {isSubmitting && } - {!isSubmitting && } + {!isSubmitting && Tr(label)} ); }; diff --git a/src/fireedge/src/public/components/HOC/GuessLayout.js b/src/fireedge/src/public/components/HOC/GuessLayout.js deleted file mode 100644 index 3873a61195..0000000000 --- a/src/fireedge/src/public/components/HOC/GuessLayout.js +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ -/* not use this file except in compliance with the License. You may obtain */ -/* a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -/* See the License for the specific language governing permissions and */ -/* limitations under the License. */ -/* -------------------------------------------------------------------------- */ - -import React, { Fragment } from 'react'; -import PropTypes from 'prop-types'; -import { Redirect } from 'react-router-dom'; - -import { LinearProgress } from '@material-ui/core'; - -import useAuth from 'client/hooks/useAuth'; -import { PATH } from 'client/router/endpoints'; - -const GuessLayout = ({ children }) => { - const { isLoginInProcess, isLogged, firstRender } = useAuth(); - - if (firstRender) { - return ; - } else if (isLogged && !isLoginInProcess) { - return ; - } - - return {children}; -}; - -GuessLayout.propTypes = { - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node, - PropTypes.string - ]) -}; - -GuessLayout.defaultProps = { - children: '' -}; - -export default GuessLayout; diff --git a/src/fireedge/src/public/components/HOC/InternalLayout.js b/src/fireedge/src/public/components/HOC/InternalLayout/index.js similarity index 57% rename from src/fireedge/src/public/components/HOC/InternalLayout.js rename to src/fireedge/src/public/components/HOC/InternalLayout/index.js index e6042f167e..798a9a3615 100644 --- a/src/fireedge/src/public/components/HOC/InternalLayout.js +++ b/src/fireedge/src/public/components/HOC/InternalLayout/index.js @@ -15,68 +15,32 @@ import React from 'react'; import PropTypes from 'prop-types'; +import clsx from 'clsx'; -import { makeStyles, Box, Container } from '@material-ui/core'; -import { Skeleton } from '@material-ui/lab'; +import { Box, Container } from '@material-ui/core'; +import useGeneral from 'client/hooks/useGeneral'; -import useAuth from 'client/hooks/useAuth'; -import useOpenNebula from 'client/hooks/useOpennebula'; -import Header from 'client/components/Header'; import Footer from 'client/components/Footer'; +import Header from 'client/components/Header'; -const internalStyles = makeStyles(theme => ({ - root: { - display: 'flex', - width: '100%' - }, - main: { - paddingTop: 64, - paddingBottom: 30, - height: '100vh', - width: '100vw' - }, - scrollable: { - paddingTop: theme.spacing(2), - paddingBottom: theme.spacing(2), - height: '100%', - overflow: 'auto', - '&::-webkit-scrollbar': { - width: 14 - }, - '&::-webkit-scrollbar-thumb': { - backgroundClip: 'content-box', - border: '4px solid transparent', - borderRadius: 7, - boxShadow: 'inset 0 0 0 10px', - color: theme.palette.primary.light - } - } -})); +import internalStyles from 'client/components/HOC/InternalLayout/styles'; -const InternalLayout = ({ children, title }) => { +const InternalLayout = ({ authRoute, label, children }) => { const classes = internalStyles(); - const { groups } = useOpenNebula(); - const { authUser } = useAuth(); + const { isFixMenu } = useGeneral(); - const isAuthenticating = Boolean(!authUser && !groups?.length); - - return isAuthenticating ? ( - - - - - - - ) : ( - <> -
+ return authRoute ? ( + +
{children}