1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-21 14:50:08 +03:00

F #3951: Update internal grid layout (#165)

* Fix sidebar component
* Add responsive sidebar
* Update internal grid layout
This commit is contained in:
Sergio Betanzos 2020-08-25 21:59:35 +02:00 committed by GitHub
parent 6ece4290cf
commit 26c076710f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 369 additions and 318 deletions

View File

@ -13,7 +13,7 @@
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
import React from 'react';
import React, { useEffect } from 'react';
import { StaticRouter, BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import PropTypes from 'prop-types';
@ -25,7 +25,7 @@ import { TranslateProvider } from 'client/components/HOC';
import Router from 'client/router';
const App = ({ location, context, store }) => {
React.useEffect(() => {
useEffect(() => {
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);

View File

@ -1,10 +1,31 @@
import { createMuiTheme, responsiveFontSizes } from '@material-ui/core';
const defaultBreakpoints = {
xs: 0,
sm: 600,
md: 960,
lg: 1280,
xl: 1920,
// DEVICES
tablet: 640,
laptop: 1024,
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'
@ -47,7 +68,7 @@ const theme = createMuiTheme({
MuiCssBaseline: {
'@global': {
body: {
height: '100vh'
// height: '100vh'
}
// '@font-face': [UbuntuFont]
}

View File

@ -14,22 +14,24 @@
/* -------------------------------------------------------------------------- */
import React from 'react';
import { Box, Link, useTheme } from '@material-ui/core';
import classnames from 'classnames';
import { Box, Link } from '@material-ui/core';
import footerStyles from 'client/components/Footer/styles';
import { by } from 'client/constants';
const { text, url } = by;
const Footer = () => {
const theme = useTheme();
const Footer = React.memo(() => {
const classes = footerStyles();
return (
<Box color={theme.palette.primary.light} className={classnames('footer')}>
<Box className={classes.footer} component="footer">
{`❤️ by `}
<Link href={url}>{text}</Link>
<Link href={url} className={classes.link}>
{text}
</Link>
</Box>
);
};
});
export default Footer;

View File

@ -0,0 +1,19 @@
import { makeStyles } from '@material-ui/core';
export default makeStyles(theme => ({
footer: {
color: theme.palette.primary.light,
position: 'fixed',
bottom: 0,
left: 'auto',
right: 0,
width: '100%',
zIndex: 1100,
backgroundColor: theme.palette.grey[800],
textAlign: 'center',
padding: 5
},
link: {
color: theme.palette.primary.light
}
}));

View File

@ -13,7 +13,7 @@ const InputCode = ({ code, language, ...props }) => {
};
return (
<Box border="1px solid lightgray">
<Box border="1px solid lightgray" height="100%" minHeight={200}>
<AceEditor
wrapEnabled
value={code}
@ -21,10 +21,11 @@ const InputCode = ({ code, language, ...props }) => {
mode="json"
theme="github"
width="100%"
maxLines={Infinity}
minLines={50}
height="100%"
// maxLines={Infinity}
minLines={10}
onChange={handleChange}
name="UNIQUE_ID_OF_DIV"
name="form-control-code"
showPrintMargin={false}
editorProps={{ $blockScrolling: true }}
setOptions={{

View File

@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import { makeStyles, CircularProgress, Button } from '@material-ui/core';
@ -12,7 +13,7 @@ const useStyles = makeStyles(theme => ({
}
}));
export default function ButtonSubmit({ isSubmitting, label, ...rest }) {
const ButtonSubmit = ({ isSubmitting, label, ...rest }) => {
const classes = useStyles();
return (
@ -25,7 +26,19 @@ export default function ButtonSubmit({ isSubmitting, label, ...rest }) {
{...rest}
>
{isSubmitting && <CircularProgress size={24} />}
{!isSubmitting && (label ?? <Translate word={CONSTANT.default.Submit} />)}
{!isSubmitting && <Translate word={label ?? CONSTANT.default.Submit} />}
</Button>
);
}
};
ButtonSubmit.propTypes = {
isSubmitting: PropTypes.bool,
label: PropTypes.string
};
ButtonSubmit.defaultProps = {
isSubmitting: false,
label: CONSTANT.default.Submit
};
export default ButtonSubmit;

View File

@ -16,16 +16,45 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Box, Container } from '@material-ui/core';
import { makeStyles, Box, Container } from '@material-ui/core';
import { Skeleton } from '@material-ui/lab';
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 Sidebar from 'client/components/Sidebar';
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
}
}
}));
const InternalLayout = ({ children, title }) => {
const classes = internalStyles();
const { groups } = useOpenNebula();
const { authUser } = useAuth();
@ -39,17 +68,15 @@ const InternalLayout = ({ children, title }) => {
</Box>
</Box>
) : (
<Box display="flex" width="100%">
<>
<Header title={title} />
<Sidebar />
<Container
component="main"
style={{ paddingTop: 96, paddingBottom: 96, height: '100vh' }}
>
{children}
</Container>
<Box component="main" className={classes.main}>
<Container component="div" className={classes.scrollable}>
{children}
</Container>
</Box>
<Footer />
</Box>
</>
);
};

View File

@ -14,8 +14,7 @@
/* -------------------------------------------------------------------------- */
import React, { useState, useRef, Fragment } from 'react';
import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom';
import {
Button,
Popper,
@ -29,19 +28,22 @@ import {
import AccountCircleIcon from '@material-ui/icons/AccountCircle';
import { Translate } from 'client/components/HOC';
import { PATH } from 'client/router/endpoints';
import { SignOut } from 'client/constants';
import useAuth from 'client/hooks/useAuth';
import FilterPoolSelect from './FilterPoolSelect';
import FilterPoolSelect from 'client/components/Header/FilterPoolSelect';
const User = () => {
const User = React.memo(() => {
const history = useHistory();
const { logout, authUser, isOneAdmin } = useAuth();
const [open, setOpen] = useState(false);
const anchorRef = useRef(null);
const { current } = anchorRef;
const handleToggle = () => {
setOpen(prevOpen => !prevOpen);
};
const handleToggle = () => setOpen(prevOpen => !prevOpen);
const handleLogout = () => logout();
const handleGoToSettings = () => history.push(PATH.SETTINGS);
const handleClose = e => {
if (current && current.contains(e.target)) {
@ -50,11 +52,6 @@ const User = () => {
setOpen(false);
};
const handleLogout = evt => {
evt.preventDefault();
logout();
};
return (
<Fragment>
<Button
@ -66,6 +63,7 @@ const User = () => {
data-cy="header-user-button"
>
<AccountCircleIcon />
<span style={{ paddingLeft: 5 }}>{authUser?.NAME}</span>
</Button>
<Popper
open={open}
@ -85,11 +83,7 @@ const User = () => {
<Paper>
<ClickAwayListener onClickAway={handleClose}>
<MenuList autoFocusItem={open} id="menu-list-grow">
<MenuItem onClick={handleClose} data-cy="header-username">
{authUser?.NAME}
</MenuItem>
<Divider />
<MenuItem onClick={handleClose}>Settings</MenuItem>
<MenuItem onClick={handleGoToSettings}>Settings</MenuItem>
<Divider />
<MenuItem
onClick={handleLogout}
@ -113,10 +107,6 @@ const User = () => {
</Popper>
</Fragment>
);
};
User.propTypes = {};
User.defaultProps = {};
});
export default User;

View File

@ -13,7 +13,7 @@
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
import React, { useState, useRef, Fragment } from 'react';
import React, { useState, useRef } from 'react';
import {
Button,
Popper,
@ -21,15 +21,11 @@ import {
Paper,
MenuItem,
MenuList,
ClickAwayListener,
Divider
ClickAwayListener
} from '@material-ui/core';
import LanguageIcon from '@material-ui/icons/Language';
import { Translate } from 'client/components/HOC';
import { SignOut, Groups } from 'client/constants';
const Zone = () => {
const Zone = React.memo(() => {
const [open, setOpen] = useState(false);
const anchorRef = useRef(null);
const { current } = anchorRef;
@ -46,7 +42,7 @@ const Zone = () => {
};
return (
<Fragment>
<>
<Button
ref={anchorRef}
color="inherit"
@ -81,12 +77,8 @@ const Zone = () => {
</Grow>
)}
</Popper>
</Fragment>
</>
);
};
Zone.propTypes = {};
Zone.defaultProps = {};
});
export default Zone;

View File

@ -0,0 +1,52 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { List, Collapse, ListItem, ListItemText } from '@material-ui/core';
import ExpandLessIcon from '@material-ui/icons/ExpandLess';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import SidebarLink from 'client/components/Sidebar/SidebarLink';
const SidebarCollapseItem = ({ label, routes }) => {
const [expanded, setExpanded] = useState(false);
const handleExpand = () => setExpanded(!expanded);
return (
<>
<ListItem button onClick={handleExpand}>
<ListItemText primary={label} />
{expanded ? <ExpandLessIcon /> : <ExpandMoreIcon />}
</ListItem>
{routes?.map((subItem, index) => (
<Collapse
key={`subitem-${index}`}
in={expanded}
timeout="auto"
unmountOnExit
>
<List component="div" disablePadding>
<SidebarLink {...subItem} />
</List>
</Collapse>
))}
</>
);
};
SidebarCollapseItem.propTypes = {
label: PropTypes.string.isRequired,
routes: PropTypes.arrayOf(
PropTypes.shape({
label: PropTypes.string,
path: PropTypes.string
})
)
};
SidebarCollapseItem.defaultProps = {
label: '',
routes: []
};
export default SidebarCollapseItem;

View File

@ -0,0 +1,63 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom';
import {
withStyles,
Badge,
Typography,
ListItem,
ListItemText,
useMediaQuery
} from '@material-ui/core';
import useGeneral from 'client/hooks/useGeneral';
const StyledBadge = withStyles(() => ({
badge: {
right: -25,
top: 13,
fontSize: '0.7rem'
}
}))(Badge);
const SidebarLink = ({ label, path, devMode }) => {
const history = useHistory();
const isDesktop = useMediaQuery(theme => theme.breakpoints.up('sm'));
const { openMenu } = useGeneral();
const handleClick = () => {
history.push(path);
!isDesktop && openMenu(false);
};
return (
<ListItem button onClick={handleClick}>
<ListItemText
primary={
devMode ? (
<StyledBadge badgeContent="DEV" color="primary">
<Typography>{label}</Typography>
</StyledBadge>
) : (
label
)
}
/>
</ListItem>
);
};
SidebarLink.propTypes = {
label: PropTypes.string.isRequired,
path: PropTypes.string.isRequired,
devMode: PropTypes.bool
};
SidebarLink.defaultProps = {
label: '',
path: '/',
devMode: false
};
export default SidebarLink;

View File

@ -13,61 +13,30 @@
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
import React, { useState } from 'react';
import { useHistory } from 'react-router-dom';
import React from 'react';
import {
Grid,
List,
Drawer,
Divider,
Collapse,
ListItem,
ListItemText
} from '@material-ui/core';
import ExpandLessIcon from '@material-ui/icons/ExpandLess';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import { List, Drawer, Divider, Box } from '@material-ui/core';
import sidebarStyles from 'client/components/Sidebar/styles';
import useGeneral from 'client/hooks/useGeneral';
import endpoints from 'client/router/endpoints';
const LinkItem = React.memo(({ label, path }) => {
const history = useHistory();
import sidebarStyles from 'client/components/Sidebar/styles';
import SidebarLink from 'client/components/Sidebar/SidebarLink';
import SidebarCollapseItem from 'client/components/Sidebar/SidebarCollapseItem';
return (
<ListItem button onClick={() => history.push(path)}>
<ListItemText primary={label} />
</ListItem>
);
});
const CollapseItem = React.memo(({ label, routes }) => {
const [expanded, setExpanded] = useState(false);
const handleExpand = () => setExpanded(!expanded);
return (
<>
<ListItem button onClick={handleExpand}>
<ListItemText primary={label} />
{expanded ? <ExpandLessIcon /> : <ExpandMoreIcon />}
</ListItem>
{routes?.map((subItem, index) => (
<Collapse
key={`subitem-${index}`}
in={expanded}
timeout="auto"
unmountOnExit
>
<List component="div" disablePadding>
<LinkItem {...subItem} />
</List>
</Collapse>
))}
</>
);
});
const Endpoints = React.memo(() =>
endpoints
?.filter(
({ authenticated = true, header = false }) => authenticated && !header
)
?.map((endpoint, index) =>
endpoint.routes ? (
<SidebarCollapseItem key={`item-${index}`} {...endpoint} />
) : (
<SidebarLink key={`item-${index}`} {...endpoint} />
)
)
);
const Sidebar = () => {
const classes = sidebarStyles();
@ -76,29 +45,19 @@ const Sidebar = () => {
return React.useMemo(
() => (
<Drawer anchor="left" open={isOpenMenu} onClose={() => openMenu(false)}>
<div className={classes.menu}>
<Grid container>
<Grid item className={classes.logoWrapper}>
<img
className={classes.logo}
src="/static/logo.png"
alt="Opennebula"
/>
</Grid>
</Grid>
<Divider />
<List>
{endpoints
?.filter(({ authenticated = true }) => authenticated)
?.map((endpoint, index) =>
endpoint.routes ? (
<CollapseItem key={`item-${index}`} {...endpoint} />
) : (
<LinkItem key={`item-${index}`} {...endpoint} />
)
)}
<Box item className={classes.logo}>
<img
className={classes.img}
src="/static/logo.png"
alt="Opennebula"
/>
</Box>
<Divider />
<Box className={classes.menu}>
<List className={classes.list}>
<Endpoints />
</List>
</div>
</Box>
</Drawer>
),
[isOpenMenu, openMenu]

View File

@ -2,21 +2,38 @@ import { makeStyles } from '@material-ui/core';
export default makeStyles(theme => ({
menu: {
width: '15rem',
overflow: 'auto',
textTransform: 'capitalize',
color: theme.palette.secondary.dark
color: 'transparent',
transition: 'color 0.3s',
'&:hover': {
color: theme.palette.primary.light
},
'&::-webkit-scrollbar': {
width: 14
},
'&::-webkit-scrollbar-thumb': {
backgroundClip: 'content-box',
border: '4px solid transparent',
borderRadius: 7,
boxShadow: 'inset 0 0 0 10px'
},
'&::-webkit-scrollbar-button': {
width: 0,
height: 0,
display: 'none'
},
'&::-webkit-scrollbar-corner': {
backgroundColor: 'transparent'
}
},
logoWrapper: {
padding: '1rem 2rem'
list: {
color: theme.palette.common.black
},
logo: {
padding: '1rem 2rem'
},
img: {
width: '100%'
},
nav: {
paddingtop: 0,
paddingBottom: 0
},
subitem: {
paddingLeft: theme.spacing(4)
}
}));

View File

@ -15,12 +15,25 @@
import React from 'react';
import { Box, Typography } from '@material-ui/core';
import { makeStyles, Box, Typography } from '@material-ui/core';
const dashboardStyles = makeStyles(theme => ({
root: {},
title: {
color: theme.palette.common.black
}
}));
function Dashboard() {
const classes = dashboardStyles();
return (
<Box>
<Typography variant="h2" data-cy="dashboard-title">
<Typography
variant="h2"
className={classes.title}
data-cy="dashboard-title"
>
Dashboard
</Typography>
</Box>

View File

@ -65,6 +65,7 @@ function FormUser({ classes, onSubmit, error }) {
required
name="pass"
type="password"
autoComplete="current-password"
label={Tr(Password)}
variant="outlined"
inputRef={register}

View File

@ -10,7 +10,8 @@ export default makeStyles(theme =>
root: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center'
justifyContent: 'center',
height: '100vh'
},
paper: {
overflow: 'hidden',

View File

@ -1,12 +1,11 @@
import React from 'react';
import { object, string, shape, func } from 'prop-types';
import { string, func, objectOf, object } from 'prop-types';
import { useForm, Controller } from 'react-hook-form';
import {
TextField,
Grid,
Typography,
Box,
FormControlLabel,
Checkbox
} from '@material-ui/core';
@ -34,15 +33,19 @@ const ResponseForm = ({
};
return (
<Box width="100%">
<Typography component="h2" variant="h2" style={{ padding: '16px 0' }}>
<>
<Typography
color="textPrimary"
component="h2"
variant="h2"
style={{ padding: '16px 0' }}
>
{name || 'Request'}
</Typography>
<Grid
container
spacing={3}
justify="flex-start"
style={{ height: '100%' }}
component="form"
onSubmit={handleSubmit(onSubmit)}
autoComplete="off"
@ -77,25 +80,23 @@ const ResponseForm = ({
<ButtonSubmit isSubmitting={formState.isSubmitting} />
</Grid>
</Grid>
</Box>
</>
);
};
ResponseForm.propTypes = {
command: shape({
command: objectOf({
name: string.isRequired,
httpMethod: string.isRequired,
schema: object,
params: object
params: object.isRequired
}).isRequired,
handleChangeResponse: func
handleChangeResponse: func.isRequired
};
ResponseForm.defaultProps = {
command: {
name: '',
httpMethod: 'GET',
schema: {},
params: {}
},
handleChangeResponse: () => undefined

View File

@ -16,7 +16,7 @@
import React, { useState, useMemo } from 'react';
import { TextField, Grid, MenuItem } from '@material-ui/core';
import Commands from 'server/utils/constants/commands';
import { Translate } from 'client/components/HOC';
import { Translate, Tr } from 'client/components/HOC';
import InputCode from 'client/components/FormControl/InputCode';
import ResponseForm from 'client/containers/TestApi/ResponseForm';
@ -33,7 +33,7 @@ const TestApi = () => {
fullWidth
select
variant="outlined"
label={<Translate word="Select request" />}
label={Tr('Select request')}
value={name}
onChange={handleChangeCommand}
>
@ -62,7 +62,7 @@ const TestApi = () => {
)}
</Grid>
<Grid item xs={12} md={6}>
<InputCode code={response} />
<InputCode code={response} readOnly />
</Grid>
</Grid>
);

View File

@ -57,11 +57,13 @@ export default [
{
label: 'settings',
path: PATH.SETTINGS,
header: true,
component: Settings
},
{
label: 'test api',
path: PATH.TEST_API,
devMode: true,
component: TestApi
},
{

View File

@ -16,48 +16,49 @@
import React from 'react';
import { Route, Switch } from 'react-router-dom';
import { AuthLayout, GuessLayout } from 'client/components/HOC';
import InternalLayout from 'client/components/HOC/InternalLayout';
import { AuthLayout, GuessLayout, InternalLayout } from 'client/components/HOC';
import Error404 from 'client/containers/Error404';
import Sidebar from 'client/components/Sidebar';
import endpoints from './endpoints';
import endpoints from 'client/router/endpoints';
function Router() {
const renderRoute = ({
label = '',
path = '',
authenticated = true,
component: Component
}) => (
<Route
key={`key-${label.replace(' ', '-')}`}
exact
path={path}
component={() =>
authenticated ? (
<AuthLayout>
<InternalLayout title={label}>
<Component />
</InternalLayout>
</AuthLayout>
) : (
<GuessLayout>
const renderRoute = ({
label = '',
path = '',
authenticated = true,
component: Component
}) => (
<Route
key={`key-${label.replace(' ', '-')}`}
exact
path={path}
component={() =>
authenticated ? (
<AuthLayout>
<InternalLayout title={label}>
<Component />
</GuessLayout>
)
}
/>
);
</InternalLayout>
</AuthLayout>
) : (
<GuessLayout>
<Component />
</GuessLayout>
)
}
/>
);
return (
const Router = () => (
<>
<Sidebar />
<Switch>
{endpoints?.map(({ routes, ...endpoint }) =>
endpoint.path ? renderRoute(endpoint) : routes?.map(renderRoute)
)}
<Route component={Error404} />
</Switch>
);
}
</>
);
export default Router;
export { endpoints };

View File

@ -1,18 +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. */
/* -------------------------------------------------------------------------- */
.content{
background-color: $tertiary;
}

View File

@ -1,29 +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. */
/* -------------------------------------------------------------------------- */
.footer {
position: fixed;
bottom: 0;
left: auto;
right: 0;
width: 100%;
z-index: 1100;
background-color: $quaternary;
text-align: center;
padding: .5rem;
a{
color: $secondary
}
}

View File

@ -1,14 +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. */
/* -------------------------------------------------------------------------- */

View File

@ -13,14 +13,6 @@
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
$primary: #C7C9C8;
$secondary: #FFF;
$tertiary: #FAFAFA;
$quaternary: #353735;
$font_primary: #353735;
$font_secondary: red;
@font-face {
font-family: 'LatoWeb';
src: url('fonts/Lato-Regular.eot'); /* IE9 Compat Modes */
@ -32,24 +24,3 @@ $font_secondary: red;
font-weight: normal;
text-rendering: optimizeLegibility;
}
@import "login";
@import "footer";
@import "menu";
@import "content";
html, body{
font-family: 'LatoWeb';
background-color: $secondary;
color: $font_primary;
min-height: 100vh;
margin: 0px;
display: flex;
width: 100%;
flex-wrap: wrap;
}
#root{
flex-grow: 1;
display: flex;
flex-wrap: wrap;
}

View File

@ -1,34 +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. */
/* -------------------------------------------------------------------------- */
.menu{
color: $secondary;
width: 15rem;
.link{
text-transform: capitalize;
color: $font_primary;
}
.logo-wrapper{
padding: 1rem 2rem;
}
.logo{
width: 100%;
}
.internalNav{
padding-top: 0px;
padding-bottom: 0px;
}
}