Merge pull request #1837 from RafaelTaranto/chore/update-mui-v6
LAM-1414 chore: update mui to v7
This commit is contained in:
commit
8b3f93d8f0
357 changed files with 7823 additions and 14059 deletions
|
|
@ -1,4 +0,0 @@
|
|||
SKIP_PREFLIGHT_CHECK=true
|
||||
HTTPS=true
|
||||
REACT_APP_TYPE_CHECK_SANCTUARY=false
|
||||
PORT=3001
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
server {
|
||||
listen 80;
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
|
||||
try_files $uri /index.html;
|
||||
}
|
||||
|
||||
location /graphql {
|
||||
proxy_pass https://lamassu-admin-server/graphql;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 300;
|
||||
proxy_connect_timeout 300;
|
||||
proxy_send_timeout 300;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
|
||||
}
|
||||
2889
new-lamassu-admin/package-lock.json
generated
2889
new-lamassu-admin/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -5,12 +5,9 @@
|
|||
"type": "module",
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.13.7",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.0",
|
||||
"@lamassu/coins": "v1.6.1",
|
||||
"@mui/icons-material": "^5.17.1",
|
||||
"@mui/material": "^5.17.1",
|
||||
"@mui/styles": "^5.17.1",
|
||||
"@mui/icons-material": "^7.1.0",
|
||||
"@mui/material": "^7.1.0",
|
||||
"@simplewebauthn/browser": "^3.0.0",
|
||||
"apollo-upload-client": "^18.0.0",
|
||||
"bignumber.js": "9.0.0",
|
||||
|
|
@ -33,7 +30,6 @@
|
|||
"react-copy-to-clipboard": "^5.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"react-dropzone": "^11.4.2",
|
||||
"react-material-ui-carousel": "^3.4.2",
|
||||
"react-number-format": "^4.4.1",
|
||||
"react-otp-input": "3.1.1",
|
||||
"react-router-dom": "5.1.2",
|
||||
|
|
@ -44,6 +40,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.16.0",
|
||||
"@tailwindcss/vite": "^4.1.4",
|
||||
"@vitejs/plugin-react-swc": "^3.7.2",
|
||||
"esbuild-plugin-react-virtualized": "^1.0.4",
|
||||
"eslint": "^9.16.0",
|
||||
|
|
@ -53,6 +50,7 @@
|
|||
"globals": "^15.13.0",
|
||||
"lint-staged": "^15.2.10",
|
||||
"prettier": "3.4.1",
|
||||
"tailwindcss": "^4.1.4",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-svgr": "^4.3.0"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
diff --git a/node_modules/react-scripts/config/webpack.config.js b/node_modules/react-scripts/config/webpack.config.js
|
||||
index 80c6ac2..3420936 100644
|
||||
--- a/node_modules/react-scripts/config/webpack.config.js
|
||||
+++ b/node_modules/react-scripts/config/webpack.config.js
|
||||
@@ -752,6 +752,7 @@ module.exports = function (webpackEnv) {
|
||||
formatter: require.resolve('react-dev-utils/eslintFormatter'),
|
||||
eslintPath: require.resolve('eslint'),
|
||||
context: paths.appSrc,
|
||||
+ cache: true,
|
||||
// ESLint class options
|
||||
cwd: paths.appPath,
|
||||
resolvePluginsRelativeTo: __dirname,
|
||||
|
|
@ -1,137 +1,14 @@
|
|||
import { useQuery, gql } from "@apollo/client";
|
||||
import CssBaseline from '@mui/material/CssBaseline'
|
||||
import Grid from '@mui/material/Grid'
|
||||
import Slide from '@mui/material/Slide'
|
||||
import { StylesProvider, jssPreset, makeStyles } from '@mui/styles';
|
||||
import { ThemeProvider, StyledEngineProvider } from '@mui/material/styles';
|
||||
import { create } from 'jss'
|
||||
import extendJss from 'jss-plugin-extend'
|
||||
import React, { useContext, useState } from 'react'
|
||||
import {
|
||||
useLocation,
|
||||
useHistory,
|
||||
BrowserRouter as Router
|
||||
} from 'react-router-dom'
|
||||
import Header from 'src/components/layout/Header'
|
||||
import Sidebar from 'src/components/layout/Sidebar'
|
||||
import TitleSection from 'src/components/layout/TitleSection'
|
||||
import { tree, hasSidebar, Routes, getParent } from 'src/routing/routes'
|
||||
import { ThemeProvider, StyledEngineProvider } from '@mui/material/styles'
|
||||
import React, { useState } from 'react'
|
||||
import { BrowserRouter as Router } from 'react-router-dom'
|
||||
import ApolloProvider from 'src/utils/apollo'
|
||||
|
||||
import AppContext from 'src/AppContext'
|
||||
import global from 'src/styling/global'
|
||||
import theme from 'src/styling/theme'
|
||||
import { backgroundColor, mainWidth } from 'src/styling/variables'
|
||||
|
||||
const jss = create({
|
||||
plugins: [extendJss(), ...jssPreset().plugins]
|
||||
})
|
||||
|
||||
const fill = '100%'
|
||||
const flexDirection = 'column'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
...global,
|
||||
root: {
|
||||
backgroundColor,
|
||||
width: fill,
|
||||
minHeight: fill,
|
||||
display: 'flex',
|
||||
flexDirection
|
||||
},
|
||||
wrapper: {
|
||||
width: mainWidth,
|
||||
height: fill,
|
||||
margin: '0 auto',
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
flexDirection
|
||||
},
|
||||
grid: {
|
||||
flex: 1,
|
||||
height: '100%'
|
||||
},
|
||||
contentWithSidebar: {
|
||||
flex: 1,
|
||||
marginLeft: 48,
|
||||
paddingTop: 15
|
||||
},
|
||||
contentWithoutSidebar: {
|
||||
width: mainWidth
|
||||
}
|
||||
})
|
||||
|
||||
const GET_USER_DATA = gql`
|
||||
query userData {
|
||||
userData {
|
||||
id
|
||||
username
|
||||
role
|
||||
enabled
|
||||
last_accessed
|
||||
last_accessed_from
|
||||
last_accessed_address
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const Main = () => {
|
||||
const classes = useStyles()
|
||||
const location = useLocation()
|
||||
const history = useHistory()
|
||||
const { wizardTested, userData, setUserData } = useContext(AppContext)
|
||||
|
||||
const { loading } = useQuery(GET_USER_DATA, {
|
||||
onCompleted: userResponse => {
|
||||
if (!userData && userResponse?.userData)
|
||||
setUserData(userResponse.userData)
|
||||
}
|
||||
})
|
||||
|
||||
const route = location.pathname
|
||||
|
||||
const sidebar = hasSidebar(route)
|
||||
const parent = sidebar ? getParent(route) : {}
|
||||
|
||||
const is404 = location.pathname === '/404'
|
||||
|
||||
const isSelected = it => location.pathname === it.route
|
||||
|
||||
const onClick = it => history.push(it.route)
|
||||
|
||||
const contentClassName = sidebar
|
||||
? classes.contentWithSidebar
|
||||
: classes.contentWithoutSidebar
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
{!is404 && wizardTested && userData && (
|
||||
<Header tree={tree} user={userData} />
|
||||
)}
|
||||
<main className={classes.wrapper}>
|
||||
{sidebar && !is404 && wizardTested && (
|
||||
<Slide direction="left" in={true} mountOnEnter unmountOnExit>
|
||||
<div>
|
||||
<TitleSection title={parent.title}></TitleSection>
|
||||
</div>
|
||||
</Slide>
|
||||
)}
|
||||
|
||||
<Grid container className={classes.grid}>
|
||||
{sidebar && !is404 && wizardTested && (
|
||||
<Sidebar
|
||||
data={parent.children}
|
||||
isSelected={isSelected}
|
||||
displayName={it => it.label}
|
||||
onClick={onClick}
|
||||
/>
|
||||
)}
|
||||
<div className={contentClassName}>{!loading && <Routes />}</div>
|
||||
</Grid>
|
||||
</main>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
import Main from './Main'
|
||||
import './styling/global/global.css'
|
||||
|
||||
const App = () => {
|
||||
const [wizardTested, setWizardTested] = useState(false)
|
||||
|
|
@ -148,18 +25,16 @@ const App = () => {
|
|||
value={{ wizardTested, setWizardTested, userData, setUserData, setRole }}>
|
||||
<Router>
|
||||
<ApolloProvider>
|
||||
<StylesProvider jss={jss}>
|
||||
<StyledEngineProvider injectFirst>
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline />
|
||||
<Main />
|
||||
</ThemeProvider>
|
||||
</StyledEngineProvider>
|
||||
</StylesProvider>
|
||||
<StyledEngineProvider enableCssLayer>
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline />
|
||||
<Main />
|
||||
</ThemeProvider>
|
||||
</StyledEngineProvider>
|
||||
</ApolloProvider>
|
||||
</Router>
|
||||
</AppContext.Provider>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
|
|
|
|||
83
new-lamassu-admin/src/Main.jsx
Normal file
83
new-lamassu-admin/src/Main.jsx
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
import { useHistory, useLocation } from 'react-router-dom'
|
||||
import React, { useContext } from 'react'
|
||||
import { gql, useQuery } from '@apollo/client'
|
||||
import Slide from '@mui/material/Slide'
|
||||
import Grid from '@mui/material/Grid'
|
||||
|
||||
import Header from './components/layout/Header.jsx'
|
||||
import Sidebar from './components/layout/Sidebar.jsx'
|
||||
import TitleSection from './components/layout/TitleSection.jsx'
|
||||
import { getParent, hasSidebar, Routes, tree } from './routing/routes.jsx'
|
||||
|
||||
import AppContext from './AppContext.js'
|
||||
|
||||
const GET_USER_DATA = gql`
|
||||
query userData {
|
||||
userData {
|
||||
id
|
||||
username
|
||||
role
|
||||
enabled
|
||||
last_accessed
|
||||
last_accessed_from
|
||||
last_accessed_address
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const Main = () => {
|
||||
const location = useLocation()
|
||||
const history = useHistory()
|
||||
const { wizardTested, userData, setUserData } = useContext(AppContext)
|
||||
|
||||
const { loading } = useQuery(GET_USER_DATA, {
|
||||
onCompleted: userResponse => {
|
||||
if (!userData && userResponse?.userData)
|
||||
setUserData(userResponse.userData)
|
||||
}
|
||||
})
|
||||
|
||||
const route = location.pathname
|
||||
|
||||
const sidebar = hasSidebar(route)
|
||||
const parent = sidebar ? getParent(route) : {}
|
||||
|
||||
const is404 = location.pathname === '/404'
|
||||
|
||||
const isSelected = it => location.pathname === it.route
|
||||
|
||||
const onClick = it => history.push(it.route)
|
||||
|
||||
const contentClassName = sidebar ? 'flex-1 ml-12 pt-4' : 'w-[1200px]'
|
||||
|
||||
return (
|
||||
<div className="flex flex-col w-full min-h-full">
|
||||
{!is404 && wizardTested && userData && (
|
||||
<Header tree={tree} user={userData} />
|
||||
)}
|
||||
<main className="flex flex-1 flex-col my-0 mx-auto h-full w-[1200px]">
|
||||
{sidebar && !is404 && wizardTested && (
|
||||
<Slide direction="left" in={true} mountOnEnter unmountOnExit>
|
||||
<div>
|
||||
<TitleSection title={parent.title}></TitleSection>
|
||||
</div>
|
||||
</Slide>
|
||||
)}
|
||||
|
||||
<Grid sx={{ flex: 1, height: 1 }} container>
|
||||
{sidebar && !is404 && wizardTested && (
|
||||
<Sidebar
|
||||
data={parent.children}
|
||||
isSelected={isSelected}
|
||||
displayName={it => it.label}
|
||||
onClick={onClick}
|
||||
/>
|
||||
)}
|
||||
<div className={contentClassName}>{!loading && <Routes />}</div>
|
||||
</Grid>
|
||||
</main>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Main
|
||||
|
|
@ -1,63 +1,48 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import React, { memo } from 'react'
|
||||
import ReactCarousel from 'react-material-ui-carousel'
|
||||
import React, { memo, useState } from 'react'
|
||||
import styles from './Carousel.module.css'
|
||||
import LeftArrow from 'src/styling/icons/arrow/carousel-left-arrow.svg?react'
|
||||
import RightArrow from 'src/styling/icons/arrow/carousel-right-arrow.svg?react'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
imgWrapper: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
display: 'flex'
|
||||
},
|
||||
imgInner: {
|
||||
objectFit: 'contain',
|
||||
objectPosition: 'center',
|
||||
width: 500,
|
||||
height: 400,
|
||||
marginBottom: 40
|
||||
}
|
||||
})
|
||||
|
||||
export const Carousel = memo(({ photosData, slidePhoto }) => {
|
||||
const classes = useStyles()
|
||||
const [activeIndex, setActiveIndex] = useState(0)
|
||||
|
||||
const handlePrev = () => {
|
||||
const newIndex = activeIndex === 0 ? photosData.length - 1 : activeIndex - 1
|
||||
setActiveIndex(newIndex)
|
||||
slidePhoto(newIndex)
|
||||
}
|
||||
|
||||
const handleNext = () => {
|
||||
const newIndex = activeIndex === photosData.length - 1 ? 0 : activeIndex + 1
|
||||
setActiveIndex(newIndex)
|
||||
slidePhoto(newIndex)
|
||||
}
|
||||
|
||||
if (!photosData || photosData.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ReactCarousel
|
||||
PrevIcon={<LeftArrow />}
|
||||
NextIcon={<RightArrow />}
|
||||
navButtonsProps={{
|
||||
style: {
|
||||
backgroundColor: 'transparent',
|
||||
borderRadius: 0,
|
||||
color: 'transparent',
|
||||
opacity: 1
|
||||
}
|
||||
}}
|
||||
navButtonsWrapperProps={{
|
||||
style: {
|
||||
marginLeft: -22,
|
||||
marginRight: -22
|
||||
}
|
||||
}}
|
||||
autoPlay={false}
|
||||
indicators={false}
|
||||
navButtonsAlwaysVisible={true}
|
||||
next={activeIndex => slidePhoto(activeIndex)}
|
||||
prev={activeIndex => slidePhoto(activeIndex)}>
|
||||
{photosData.map((item, i) => (
|
||||
<div key={i}>
|
||||
<div className={classes.imgWrapper}>
|
||||
<img
|
||||
className={classes.imgInner}
|
||||
src={`/${item?.photoDir}/${item?.path}`}
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</ReactCarousel>
|
||||
</>
|
||||
<div className={styles.carouselContainer}>
|
||||
{photosData.length > 1 && (
|
||||
<button onClick={handlePrev} className={styles.navButton}>
|
||||
<LeftArrow />
|
||||
</button>
|
||||
)}
|
||||
|
||||
<div className={styles.imageContainer}>
|
||||
<img
|
||||
className={styles.image}
|
||||
src={`/${photosData[activeIndex]?.photoDir}/${photosData[activeIndex]?.path}`}
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
{photosData.length > 1 && (
|
||||
<button onClick={handleNext} className={styles.navButton}>
|
||||
<RightArrow />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
|
|
|||
45
new-lamassu-admin/src/components/Carousel.module.css
Normal file
45
new-lamassu-admin/src/components/Carousel.module.css
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
.carouselContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.imageContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.image {
|
||||
object-fit: contain;
|
||||
object-position: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.navButton {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
color: transparent;
|
||||
opacity: 1;
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
min-width: 44px;
|
||||
min-height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.navButton:hover {
|
||||
background-color: rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
import Chip from '@mui/material/Chip'
|
||||
import { withStyles } from '@mui/styles'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import {
|
||||
fontColor,
|
||||
inputFontWeight,
|
||||
subheaderColor,
|
||||
smallestFontSize,
|
||||
inputFontFamily
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
backgroundColor: subheaderColor,
|
||||
borderRadius: 4,
|
||||
margin: theme.spacing(0.5, 0.25),
|
||||
height: 18
|
||||
},
|
||||
label: {
|
||||
fontSize: smallestFontSize,
|
||||
color: fontColor,
|
||||
fontWeight: inputFontWeight,
|
||||
fontFamily: inputFontFamily,
|
||||
paddingRight: 4,
|
||||
paddingLeft: 4
|
||||
}
|
||||
})
|
||||
|
||||
const LsChip = memo(({ classes, ...props }) => (
|
||||
<Chip size="small" classes={classes} {...props} />
|
||||
))
|
||||
|
||||
export default withStyles(styles)(LsChip)
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
import Grid from '@mui/material/Grid'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import PropTypes from 'prop-types'
|
||||
import React from 'react'
|
||||
|
||||
import { white } from 'src/styling/variables'
|
||||
import Paper from '@mui/material/Paper'
|
||||
import classnames from 'classnames'
|
||||
|
||||
const cardState = Object.freeze({
|
||||
DEFAULT: 'default',
|
||||
|
|
@ -12,24 +10,11 @@ const cardState = Object.freeze({
|
|||
EXPANDED: 'expanded'
|
||||
})
|
||||
|
||||
const styles = {
|
||||
card: {
|
||||
wordWrap: 'break-word',
|
||||
boxShadow: '0 0 4px 0 rgba(0, 0, 0, 0.08)',
|
||||
borderRadius: 12,
|
||||
padding: 24,
|
||||
backgroundColor: white
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const CollapsibleCard = ({ className, state, shrunkComponent, children }) => {
|
||||
const classes = useStyles()
|
||||
return (
|
||||
<Grid item className={classnames(className, classes.card)}>
|
||||
<Paper className={classnames('p-6', className)}>
|
||||
{state === cardState.SHRUNK ? shrunkComponent : children}
|
||||
</Grid>
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,51 +1,27 @@
|
|||
import Dialog from '@mui/material/Dialog'
|
||||
import DialogActions from '@mui/material/DialogActions'
|
||||
import DialogContent from '@mui/material/DialogContent'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import InputLabel from '@mui/material/InputLabel'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import React, { memo, useState } from 'react'
|
||||
import { H4, P } from 'src/components/typography'
|
||||
import CloseIcon from 'src/styling/icons/action/close/zodiac.svg?react'
|
||||
|
||||
import { Button, IconButton } from 'src/components/buttons'
|
||||
import { Button } from 'src/components/buttons'
|
||||
import { TextInput } from 'src/components/inputs'
|
||||
import { spacer } from 'src/styling/variables'
|
||||
|
||||
import ErrorMessage from './ErrorMessage'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
dialogContent: {
|
||||
width: 434,
|
||||
padding: spacer * 2,
|
||||
paddingRight: spacer * 3.5
|
||||
},
|
||||
dialogTitle: {
|
||||
padding: spacer * 2,
|
||||
paddingRight: spacer * 1.5,
|
||||
display: 'flex',
|
||||
'justify-content': 'space-between',
|
||||
'& > h4': {
|
||||
margin: 0
|
||||
},
|
||||
'& > button': {
|
||||
padding: 0,
|
||||
marginTop: -(spacer / 2)
|
||||
}
|
||||
},
|
||||
dialogActions: {
|
||||
padding: spacer * 4,
|
||||
paddingTop: spacer * 2
|
||||
}
|
||||
})
|
||||
import SvgIcon from '@mui/material/SvgIcon'
|
||||
|
||||
export const DialogTitle = ({ children, onClose }) => {
|
||||
const classes = useStyles()
|
||||
return (
|
||||
<div className={classes.dialogTitle}>
|
||||
<div className="p-4 pr-3 flex justify-between">
|
||||
{children}
|
||||
{onClose && (
|
||||
<IconButton size={16} aria-label="close" onClick={onClose}>
|
||||
<CloseIcon />
|
||||
<IconButton aria-label="close" onClick={onClose} className="p-0 -mt-1">
|
||||
<SvgIcon fontSize="small">
|
||||
<CloseIcon />
|
||||
</SvgIcon>
|
||||
</IconButton>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -67,7 +43,6 @@ export const ConfirmDialog = memo(
|
|||
disabled = false,
|
||||
...props
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
const [value, setValue] = useState(initialValue)
|
||||
const [error, setError] = useState(false)
|
||||
const handleChange = event => setValue(event.target.value)
|
||||
|
|
@ -84,7 +59,7 @@ export const ConfirmDialog = memo(
|
|||
return (
|
||||
<Dialog open={open} aria-labelledby="form-dialog-title" {...props}>
|
||||
<DialogTitle id="customized-dialog-title" onClose={innerOnClose}>
|
||||
<H4>{title}</H4>
|
||||
<H4 noMargin>{title}</H4>
|
||||
</DialogTitle>
|
||||
{errorMessage && (
|
||||
<DialogTitle>
|
||||
|
|
@ -98,7 +73,7 @@ export const ConfirmDialog = memo(
|
|||
</ErrorMessage>
|
||||
</DialogTitle>
|
||||
)}
|
||||
<DialogContent className={classes.dialogContent}>
|
||||
<DialogContent className="w-108 p-4 pr-7">
|
||||
{message && <P>{message}</P>}
|
||||
<InputLabel htmlFor="confirm-input">{confirmationMessage}</InputLabel>
|
||||
<TextInput
|
||||
|
|
@ -116,7 +91,7 @@ export const ConfirmDialog = memo(
|
|||
onChange={handleChange}
|
||||
/>
|
||||
</DialogContent>
|
||||
<DialogActions className={classes.dialogActions}>
|
||||
<DialogActions className="p-8 pt-4">
|
||||
<Button
|
||||
color="green"
|
||||
disabled={isOnErrorState}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,20 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { CopyToClipboard as ReactCopyToClipboard } from 'react-copy-to-clipboard'
|
||||
import Popover from 'src/components/Popper'
|
||||
import Popover from 'src/components/Popper.jsx'
|
||||
import CopyIcon from 'src/styling/icons/action/copy/copy.svg?react'
|
||||
|
||||
import { comet } from 'src/styling/variables'
|
||||
import { comet } from 'src/styling/variables.js'
|
||||
|
||||
import { cpcStyles } from './Transactions.styles'
|
||||
|
||||
const useStyles = makeStyles(cpcStyles)
|
||||
import { Label1, Mono } from './typography/index.jsx'
|
||||
|
||||
const CopyToClipboard = ({
|
||||
className,
|
||||
buttonClassname,
|
||||
children,
|
||||
wrapperClassname,
|
||||
removeSpace = true,
|
||||
...props
|
||||
removeSpace = true
|
||||
}) => {
|
||||
const [anchorEl, setAnchorEl] = useState(null)
|
||||
|
||||
|
|
@ -26,8 +22,6 @@ const CopyToClipboard = ({
|
|||
if (anchorEl) setTimeout(() => setAnchorEl(null), 3000)
|
||||
}, [anchorEl])
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const handleClick = event => {
|
||||
setAnchorEl(anchorEl ? null : event.currentTarget)
|
||||
}
|
||||
|
|
@ -40,16 +34,19 @@ const CopyToClipboard = ({
|
|||
const id = open ? 'simple-popper' : undefined
|
||||
|
||||
return (
|
||||
<div className={classnames(classes.wrapper, wrapperClassname)}>
|
||||
<div className={classnames('flex items-center', wrapperClassname)}>
|
||||
{children && (
|
||||
<>
|
||||
<div className={classnames(classes.address, className)}>
|
||||
<Mono
|
||||
noMargin
|
||||
className={classnames('linebreak-anywhere', className)}>
|
||||
{children}
|
||||
</div>
|
||||
<div className={classnames(classes.buttonWrapper, buttonClassname)}>
|
||||
</Mono>
|
||||
<div className={buttonClassname}>
|
||||
<ReactCopyToClipboard
|
||||
text={removeSpace ? R.replace(/\s/g, '')(children) : children}>
|
||||
<button
|
||||
className="border-0 bg-transparent cursor-pointer"
|
||||
aria-describedby={id}
|
||||
onClick={event => handleClick(event)}>
|
||||
<CopyIcon />
|
||||
|
|
@ -61,12 +58,12 @@ const CopyToClipboard = ({
|
|||
open={open}
|
||||
anchorEl={anchorEl}
|
||||
onClose={handleClose}
|
||||
arrowSize={3}
|
||||
bgColor={comet}
|
||||
className="py-1 px-2"
|
||||
placement="top">
|
||||
<div className={classes.popoverContent}>
|
||||
<div>Copied to clipboard!</div>
|
||||
</div>
|
||||
<Label1 noMargin className="text-white rounded-sm">
|
||||
Copied to clipboard!
|
||||
</Label1>
|
||||
</Popover>
|
||||
</>
|
||||
)}
|
||||
|
|
@ -1,54 +1,25 @@
|
|||
import Dialog from '@mui/material/Dialog'
|
||||
import DialogActions from '@mui/material/DialogActions'
|
||||
import DialogContent from '@mui/material/DialogContent'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import React from 'react'
|
||||
import { H4, P } from 'src/components/typography'
|
||||
import CloseIcon from 'src/styling/icons/action/close/zodiac.svg?react'
|
||||
|
||||
import { Button, IconButton } from 'src/components/buttons'
|
||||
import { spacer } from 'src/styling/variables'
|
||||
import { Button } from 'src/components/buttons'
|
||||
|
||||
import ErrorMessage from './ErrorMessage'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
content: {
|
||||
width: 434,
|
||||
padding: spacer * 2,
|
||||
paddingRight: spacer * 3.5
|
||||
},
|
||||
titleSection: {
|
||||
padding: spacer * 2,
|
||||
paddingRight: spacer * 1.5,
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
margin: 0
|
||||
},
|
||||
actions: {
|
||||
padding: spacer * 4,
|
||||
paddingTop: spacer * 2
|
||||
},
|
||||
title: {
|
||||
margin: 0
|
||||
},
|
||||
closeButton: {
|
||||
padding: 0,
|
||||
marginTop: -(spacer / 2)
|
||||
}
|
||||
})
|
||||
import SvgIcon from '@mui/material/SvgIcon'
|
||||
|
||||
export const DialogTitle = ({ children, close }) => {
|
||||
const classes = useStyles()
|
||||
return (
|
||||
<div className={classes.titleSection}>
|
||||
<div className="p-4 pr-3 flex justify-between m-0">
|
||||
{children}
|
||||
{close && (
|
||||
<IconButton
|
||||
size={16}
|
||||
aria-label="close"
|
||||
onClick={close}
|
||||
className={classes.closeButton}>
|
||||
<CloseIcon />
|
||||
<IconButton aria-label="close" onClick={close} className="p-0 -mt-1">
|
||||
<SvgIcon fontSize="small">
|
||||
<CloseIcon />
|
||||
</SvgIcon>
|
||||
</IconButton>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -65,12 +36,10 @@ export const DeleteDialog = ({
|
|||
extraMessage,
|
||||
errorMessage = ''
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<Dialog open={open} aria-labelledby="form-dialog-title">
|
||||
<DialogTitle close={() => onDismissed()}>
|
||||
<H4 className={classes.title}>{title}</H4>
|
||||
<H4 className="m-0">{title}</H4>
|
||||
</DialogTitle>
|
||||
{errorMessage && (
|
||||
<DialogTitle>
|
||||
|
|
@ -84,11 +53,11 @@ export const DeleteDialog = ({
|
|||
</ErrorMessage>
|
||||
</DialogTitle>
|
||||
)}
|
||||
<DialogContent className={classes.content}>
|
||||
<DialogContent className="w-108 p-4 pr-7">
|
||||
{confirmationMessage && <P>{confirmationMessage}</P>}
|
||||
{extraMessage}
|
||||
</DialogContent>
|
||||
<DialogActions className={classes.actions}>
|
||||
<DialogActions className="p-8 pt-4">
|
||||
<Button onClick={onConfirmed}>Confirm</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
|
|
|
|||
|
|
@ -1,38 +1,16 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React from 'react'
|
||||
import ErrorIcon from 'src/styling/icons/warning-icon/tomato.svg?react'
|
||||
|
||||
import { errorColor } from 'src/styling/variables'
|
||||
|
||||
import { Info3 } from './typography'
|
||||
|
||||
const styles = {
|
||||
wrapper: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
'& > svg': {
|
||||
marginRight: 10
|
||||
}
|
||||
},
|
||||
message: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
color: errorColor,
|
||||
margin: 0,
|
||||
whiteSpace: 'break-spaces'
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const ErrorMessage = ({ className, children, ...props }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const ErrorMessage = ({ className, children }) => {
|
||||
return (
|
||||
<div className={classnames(classes.wrapper, className)}>
|
||||
<ErrorIcon />
|
||||
<Info3 className={classes.message}>{children}</Info3>
|
||||
<div className={classnames('flex items-center', className)}>
|
||||
<ErrorIcon className="mr-3" />
|
||||
<Info3 className="flex items-center text-tomato m-0 whitespace-break-spaces">
|
||||
{children}
|
||||
</Info3>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import ClickAwayListener from '@mui/material/ClickAwayListener'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React, { memo, useState } from 'react'
|
||||
import Popper from 'src/components/Popper'
|
||||
|
|
@ -8,18 +7,8 @@ import ZoomIcon from 'src/styling/icons/circle buttons/search/zodiac.svg?react'
|
|||
|
||||
import { FeatureButton } from 'src/components/buttons'
|
||||
|
||||
import imagePopperStyles from './ImagePopper.styles'
|
||||
|
||||
const useStyles = makeStyles(imagePopperStyles)
|
||||
|
||||
const ImagePopper = memo(
|
||||
({ className, width, height, popupWidth, popupHeight, src }) => {
|
||||
const classes = useStyles({
|
||||
width,
|
||||
height,
|
||||
popupWidth,
|
||||
popupHeight
|
||||
})
|
||||
const [popperAnchorEl, setPopperAnchorEl] = useState(null)
|
||||
|
||||
const handleOpenPopper = event => {
|
||||
|
|
@ -32,23 +21,30 @@ const ImagePopper = memo(
|
|||
|
||||
const popperOpen = Boolean(popperAnchorEl)
|
||||
|
||||
const Image = ({ className }) => (
|
||||
<img className={classnames(className)} src={src} alt="" />
|
||||
const Image = ({ className, style }) => (
|
||||
<img className={classnames(className)} style={style} src={src} alt="" />
|
||||
)
|
||||
|
||||
return (
|
||||
<ClickAwayListener onClickAway={handleClosePopper}>
|
||||
<div className={classnames(classes.row, className)}>
|
||||
<Image className={classes.image} />
|
||||
<div className={classnames('flex flex-row', className)}>
|
||||
<Image
|
||||
className="object-cover rounded-tl-lg"
|
||||
style={{ width, height }}
|
||||
/>
|
||||
<FeatureButton
|
||||
Icon={ZoomIcon}
|
||||
InverseIcon={ZoomIconInverse}
|
||||
className={classes.button}
|
||||
className="rounded-none rounded-tr-lg rounded-br-lg"
|
||||
style={{ height }}
|
||||
onClick={handleOpenPopper}
|
||||
/>
|
||||
<Popper open={popperOpen} anchorEl={popperAnchorEl} placement="top">
|
||||
<div className={classes.popoverContent}>
|
||||
<Image className={classes.popupImage} />
|
||||
<div className="py-2 px-4">
|
||||
<Image
|
||||
className="object-cover"
|
||||
style={{ width: popupWidth, height: popupHeight }}
|
||||
/>
|
||||
</div>
|
||||
</Popper>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
export default {
|
||||
row: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row'
|
||||
},
|
||||
image: ({ width, height }) => ({
|
||||
objectFit: 'cover',
|
||||
borderRadius: '8px 0px 0px 8px',
|
||||
width,
|
||||
height
|
||||
}),
|
||||
popupImage: ({ popupWidth, popupHeight }) => ({
|
||||
objectFit: 'cover',
|
||||
width: popupWidth,
|
||||
height: popupHeight
|
||||
}),
|
||||
button: ({ height }) => ({
|
||||
borderRadius: '0px 8px 8px 0px',
|
||||
height
|
||||
}),
|
||||
popoverContent: {
|
||||
display: 'block',
|
||||
padding: [[10, 15]]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import Box from '@mui/material/Box'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import React from 'react'
|
||||
import { Label1 } from 'src/components/typography'
|
||||
import WarningIcon from 'src/styling/icons/warning-icon/comet.svg?react'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
message: ({ width }) => ({
|
||||
width,
|
||||
marginTop: 4,
|
||||
marginLeft: 16
|
||||
})
|
||||
})
|
||||
|
||||
const InfoMessage = ({ children, width = 330, className }) => {
|
||||
const classes = useStyles({ width })
|
||||
|
||||
return (
|
||||
<Box display="flex" className={className}>
|
||||
<WarningIcon />
|
||||
<Label1 className={classes.message}>{children}</Label1>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export default InfoMessage
|
||||
|
|
@ -1,43 +1,13 @@
|
|||
import Dialog from '@mui/material/Dialog'
|
||||
import DialogContent from '@mui/material/DialogContent'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import SvgIcon from '@mui/material/SvgIcon'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import React, { memo } from 'react'
|
||||
import { H1 } from 'src/components/typography'
|
||||
import CloseIcon from 'src/styling/icons/action/close/zodiac.svg?react'
|
||||
|
||||
import { IconButton } from 'src/components/buttons'
|
||||
import { spacer } from 'src/styling/variables'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
closeButton: {
|
||||
display: 'flex',
|
||||
padding: [[spacer * 2, spacer * 2, 0, spacer * 2]],
|
||||
paddingRight: spacer * 1.5,
|
||||
justifyContent: 'end'
|
||||
},
|
||||
title: {
|
||||
margin: [[0, spacer * 2, spacer, spacer * 2 + 4]]
|
||||
}
|
||||
})
|
||||
|
||||
export const DialogTitle = ({ children, onClose }) => {
|
||||
const classes = useStyles()
|
||||
return (
|
||||
<div className={classes.dialogTitle}>
|
||||
{children}
|
||||
{onClose && (
|
||||
<IconButton size={16} aria-label="close" onClick={onClose}>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const InformativeDialog = memo(
|
||||
({ title = '', open, onDissmised, disabled = false, data, ...props }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const innerOnClose = () => {
|
||||
onDissmised()
|
||||
}
|
||||
|
|
@ -53,13 +23,16 @@ export const InformativeDialog = memo(
|
|||
open={open}
|
||||
aria-labelledby="form-dialog-title"
|
||||
{...props}>
|
||||
<div className={classes.closeButton}>
|
||||
<IconButton size={16} aria-label="close" onClick={innerOnClose}>
|
||||
<div className="flex justify-end pt-4 pr-3 pb-0 pl-4">
|
||||
<IconButton aria-label="close" onClick={innerOnClose}>
|
||||
<SvgIcon fontSize="small">
|
||||
<CloseIcon />
|
||||
</SvgIcon>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</div>
|
||||
<H1 className={classes.title}>{title}</H1>
|
||||
<DialogContent className={classes.dialogContent}>{data}</DialogContent>
|
||||
<H1 className="mt-0 mr-4 mb-2 ml-5">{title}</H1>
|
||||
<DialogContent>{data}</DialogContent>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { useLazyQuery } from "@apollo/client";
|
||||
import { useLazyQuery } from '@apollo/client'
|
||||
import ClickAwayListener from '@mui/material/ClickAwayListener'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import { format, set } from 'date-fns/fp'
|
||||
import FileSaver from 'file-saver'
|
||||
|
|
@ -11,68 +10,32 @@ import DownloadInverseIcon from 'src/styling/icons/button/download/white.svg?rea
|
|||
import Download from 'src/styling/icons/button/download/zodiac.svg?react'
|
||||
|
||||
import { FeatureButton, Link } from 'src/components/buttons'
|
||||
import { primaryColor, offColor, zircon } from 'src/styling/variables'
|
||||
import { formatDate } from 'src/utils/timezones'
|
||||
|
||||
import Popper from './Popper'
|
||||
import DateRangePicker from './date-range-picker/DateRangePicker'
|
||||
import { RadioGroup } from './inputs'
|
||||
import typographyStyles from './typography/styles'
|
||||
import { H4, Info1, Label1, Label2 } from './typography/index.jsx'
|
||||
|
||||
const { info1, label1, label2, h4 } = typographyStyles
|
||||
|
||||
const dateContainerStyles = {
|
||||
wrapper: {
|
||||
height: 46,
|
||||
width: 99
|
||||
},
|
||||
container: {
|
||||
display: 'flex'
|
||||
},
|
||||
monthWeekDayContainer: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
},
|
||||
label: {
|
||||
extend: label1,
|
||||
lineHeight: 1.33,
|
||||
color: primaryColor
|
||||
},
|
||||
bigNumber: {
|
||||
extend: info1,
|
||||
lineHeight: 1,
|
||||
marginRight: 7
|
||||
},
|
||||
monthYear: {
|
||||
extend: label2,
|
||||
lineHeight: 1.17,
|
||||
color: primaryColor
|
||||
},
|
||||
weekDay: {
|
||||
extend: label1,
|
||||
lineHeight: 1.33,
|
||||
color: offColor
|
||||
}
|
||||
}
|
||||
|
||||
const dateContainerUseStyles = makeStyles(dateContainerStyles)
|
||||
|
||||
const DateContainer = ({ date, children, ...props }) => {
|
||||
const classes = dateContainerUseStyles()
|
||||
|
||||
const DateContainer = ({ date, children }) => {
|
||||
return (
|
||||
<div className={classes.wrapper}>
|
||||
<div className={classes.label}>{children}</div>
|
||||
<div className="h-11 w-25">
|
||||
<Label1 noMargin>{children}</Label1>
|
||||
{date && (
|
||||
<>
|
||||
<div className={classes.container}>
|
||||
<div className={classes.bigNumber}>{format('d', date)}</div>
|
||||
<div className={classes.monthWeekDayContainer}>
|
||||
<span className={classes.monthYear}>{`${format(
|
||||
<div className="flex">
|
||||
<Info1 noMargin className="mr-2">
|
||||
{format('d', date)}
|
||||
</Info1>
|
||||
<div className="flex flex-col">
|
||||
<Label2 noMargin>{`${format(
|
||||
'MMM',
|
||||
date
|
||||
)} ${format('yyyy', date)}`}</span>
|
||||
<span className={classes.weekDay}>{format('EEEE', date)}</span>
|
||||
)} ${format('yyyy', date)}`}</Label2>
|
||||
<Label1 noMargin className="text-comet">
|
||||
{format('EEEE', date)}
|
||||
</Label1>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
|
@ -81,54 +44,6 @@ const DateContainer = ({ date, children, ...props }) => {
|
|||
)
|
||||
}
|
||||
|
||||
const styles = {
|
||||
popoverContent: {
|
||||
width: 280
|
||||
},
|
||||
popoverHeader: {
|
||||
extend: h4,
|
||||
padding: [[15, 15, 0, 15]]
|
||||
},
|
||||
radioButtonsContainer: {
|
||||
padding: [[5, 15, 5, 15]]
|
||||
},
|
||||
radioButtons: {
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
flexDirection: 'row',
|
||||
color: primaryColor
|
||||
},
|
||||
dateRangePickerShowing: {
|
||||
display: 'block',
|
||||
height: '100%'
|
||||
},
|
||||
dateRangePickerHidden: {
|
||||
display: 'none',
|
||||
height: 0
|
||||
},
|
||||
download: {
|
||||
padding: [[10, 15]]
|
||||
},
|
||||
dateContainerWrapper: {
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
position: 'relative',
|
||||
backgroundColor: zircon,
|
||||
padding: [[0, 15]],
|
||||
minHeight: 70
|
||||
},
|
||||
arrowContainer: {
|
||||
position: 'absolute',
|
||||
left: 125,
|
||||
top: 26
|
||||
},
|
||||
arrow: {
|
||||
margin: 'auto'
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
const ALL = 'all'
|
||||
const RANGE = 'range'
|
||||
const ADVANCED = 'advanced'
|
||||
|
|
@ -153,11 +68,9 @@ const LogsDownloaderPopover = ({
|
|||
onCompleted: data => createLogsFile(getLogs(data), range)
|
||||
})
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const dateRangePickerClasses = {
|
||||
[classes.dateRangePickerShowing]: selectedRadio === RANGE,
|
||||
[classes.dateRangePickerHidden]: selectedRadio === ALL
|
||||
'block h-full': selectedRadio === RANGE,
|
||||
hidden: selectedRadio === ALL
|
||||
}
|
||||
|
||||
const handleRadioButtons = evt => {
|
||||
|
|
@ -255,26 +168,28 @@ const LogsDownloaderPopover = ({
|
|||
variant="contained"
|
||||
/>
|
||||
<Popper id={id} open={open} anchorEl={anchorEl} placement="bottom">
|
||||
<div className={classes.popoverContent}>
|
||||
<div className={classes.popoverHeader}>{title}</div>
|
||||
<div className={classes.radioButtonsContainer}>
|
||||
<div className="w-70">
|
||||
<H4 noMargin className="p-4 pb-0">
|
||||
{title}
|
||||
</H4>
|
||||
<div className="py-1 px-4">
|
||||
<RadioGroup
|
||||
name="logs-select"
|
||||
value={selectedRadio}
|
||||
options={radioButtonOptions}
|
||||
ariaLabel="logs-select"
|
||||
onChange={handleRadioButtons}
|
||||
className={classes.radioButtons}
|
||||
className="flex flex-row justify-between text-zodiac"
|
||||
/>
|
||||
</div>
|
||||
{selectedRadio === RANGE && (
|
||||
<div className={classnames(dateRangePickerClasses)}>
|
||||
<div className={classes.dateContainerWrapper}>
|
||||
<div className="flex justify-between items-center py-0 px-4 bg-zircon relative min-h-20">
|
||||
{range && (
|
||||
<>
|
||||
<DateContainer date={range.from}>From</DateContainer>
|
||||
<div className={classes.arrowContainer}>
|
||||
<Arrow className={classes.arrow} />
|
||||
<div className="absolute left-31 top-6">
|
||||
<Arrow className="m-auto" />
|
||||
</div>
|
||||
<DateContainer date={range.until}>To</DateContainer>
|
||||
</>
|
||||
|
|
@ -295,18 +210,18 @@ const LogsDownloaderPopover = ({
|
|||
</div>
|
||||
)}
|
||||
{simplified && (
|
||||
<div className={classes.radioButtonsContainer}>
|
||||
<div className="py-1 px-4">
|
||||
<RadioGroup
|
||||
name="simplified-tx-logs"
|
||||
value={selectedAdvancedRadio}
|
||||
options={advancedRadioButtonOptions}
|
||||
ariaLabel="simplified-tx-logs"
|
||||
onChange={handleAdvancedRadioButtons}
|
||||
className={classes.radioButtons}
|
||||
className="flex flex-row justify-between text-zodiac"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className={classes.download}>
|
||||
<div className="py-3 px-4">
|
||||
<Link color="primary" onClick={() => downloadLogs(range, args)}>
|
||||
Download
|
||||
</Link>
|
||||
|
|
|
|||
|
|
@ -1,75 +1,12 @@
|
|||
import MaterialModal from '@mui/material/Modal'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import SvgIcon from '@mui/material/SvgIcon'
|
||||
import Paper from '@mui/material/Paper'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React from 'react'
|
||||
import { H1, H4 } from 'src/components/typography'
|
||||
import CloseIcon from 'src/styling/icons/action/close/zodiac.svg?react'
|
||||
|
||||
import { IconButton } from 'src/components/buttons'
|
||||
|
||||
const styles = {
|
||||
modal: {
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center'
|
||||
},
|
||||
wrapper: ({ width, height }) => ({
|
||||
width,
|
||||
height,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
minHeight: height ?? 400,
|
||||
maxHeight: '90vh',
|
||||
overflowY: 'auto',
|
||||
borderRadius: 8,
|
||||
outline: 0
|
||||
}),
|
||||
infoPanelWrapper: ({ width, infoPanelHeight }) => ({
|
||||
width,
|
||||
height: infoPanelHeight,
|
||||
marginTop: 16,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
minHeight: infoPanelHeight ?? 200,
|
||||
maxHeight: '90vh',
|
||||
overflowY: 'auto',
|
||||
borderRadius: 8,
|
||||
outline: 0
|
||||
}),
|
||||
panelContent: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flex: 1,
|
||||
padding: [[0, 24]]
|
||||
},
|
||||
content: ({ small, xl }) => ({
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flex: 1,
|
||||
padding: xl ? [[0, 60 + 28]] : small ? [[0, 16]] : [[0, 32]]
|
||||
}),
|
||||
button: ({ small, xl }) => ({
|
||||
padding: [[0, 0, xl ? 26 : 0, 0]],
|
||||
margin: xl
|
||||
? [[0, 0, 'auto', 'auto']]
|
||||
: small
|
||||
? [[12, 12, 'auto', 'auto']]
|
||||
: [[16, 16, 'auto', 'auto']]
|
||||
}),
|
||||
header: {
|
||||
display: 'flex'
|
||||
},
|
||||
title: ({ small }) => ({
|
||||
margin: small ? [[20, 0, 8, 16]] : [[28, 0, 8, 32]]
|
||||
})
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const Modal = ({
|
||||
width,
|
||||
height,
|
||||
|
|
@ -86,7 +23,6 @@ const Modal = ({
|
|||
closeOnBackdropClick,
|
||||
...props
|
||||
}) => {
|
||||
const classes = useStyles({ width, height, small, infoPanelHeight, xl })
|
||||
const TitleCase = small ? H4 : H1
|
||||
const closeSize = xl ? 28 : small ? 16 : 20
|
||||
|
||||
|
|
@ -96,24 +32,61 @@ const Modal = ({
|
|||
handleClose()
|
||||
}
|
||||
|
||||
const marginBySize = xl ? 0 : small ? 12 : 16
|
||||
const paddingBySize = xl ? 88 : small ? 16 : 32
|
||||
return (
|
||||
<MaterialModal onClose={innerClose} className={classes.modal} {...props}>
|
||||
<MaterialModal
|
||||
onClose={innerClose}
|
||||
className="flex justify-center flex-col items-center"
|
||||
{...props}>
|
||||
<>
|
||||
<Paper className={classnames(classes.wrapper, className)}>
|
||||
<div className={classes.header}>
|
||||
{title && <TitleCase className={classes.title}>{title}</TitleCase>}
|
||||
<IconButton
|
||||
size={closeSize}
|
||||
className={classes.button}
|
||||
onClick={() => handleClose()}>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
<Paper
|
||||
style={{ width, height, minHeight: height ?? 400 }}
|
||||
className={classnames(
|
||||
'flex flex-col max-h-[90vh] rounded-lg outline-0',
|
||||
className
|
||||
)}>
|
||||
<div className="flex">
|
||||
{title && (
|
||||
<TitleCase
|
||||
className={
|
||||
small ? 'mt-5 mr-0 mb-2 ml-4' : 'mt-7 mr-0 mb-2 ml-8'
|
||||
}>
|
||||
{title}
|
||||
</TitleCase>
|
||||
)}
|
||||
<div
|
||||
className="ml-auto"
|
||||
style={{ marginRight: marginBySize, marginTop: marginBySize }}>
|
||||
<IconButton
|
||||
className="p-0 mb-auto ml-auto"
|
||||
onClick={() => handleClose()}>
|
||||
<SvgIcon fontSize={xl ? 'large' : 'small'}>
|
||||
<CloseIcon />
|
||||
</SvgIcon>
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="w-full flex flex-col flex-1"
|
||||
style={{ paddingRight: paddingBySize, paddingLeft: paddingBySize }}>
|
||||
{children}
|
||||
</div>
|
||||
<div className={classes.content}>{children}</div>
|
||||
</Paper>
|
||||
{infoPanel && (
|
||||
<Paper className={classnames(classes.infoPanelWrapper, className)}>
|
||||
<div className={classes.panelContent}>{infoPanel}</div>
|
||||
<Paper
|
||||
style={{
|
||||
width,
|
||||
height: infoPanelHeight,
|
||||
minHeight: infoPanelHeight ?? 200
|
||||
}}
|
||||
className={classnames(
|
||||
'mt-4 flex flex-col max-h-[90vh] overflow-y-auto rounded-lg outline-0',
|
||||
className
|
||||
)}>
|
||||
<div className="w-full flex flex-col flex-1 py-0 px-6">
|
||||
{infoPanel}
|
||||
</div>
|
||||
</Paper>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { useQuery, useMutation, gql } from "@apollo/client";
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import { useQuery, useMutation, gql } from '@apollo/client'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import ActionButton from 'src/components/buttons/ActionButton'
|
||||
|
|
@ -9,10 +8,8 @@ import ClearAllIconInverse from 'src/styling/icons/stage/spring/empty.svg?react'
|
|||
import ClearAllIcon from 'src/styling/icons/stage/zodiac/empty.svg?react'
|
||||
import ShowUnreadIcon from 'src/styling/icons/stage/zodiac/full.svg?react'
|
||||
|
||||
import styles from './NotificationCenter.styles'
|
||||
import NotificationRow from './NotificationRow'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import classes from './NotificationCenter.module.css'
|
||||
|
||||
const GET_NOTIFICATIONS = gql`
|
||||
query getNotifications {
|
||||
|
|
@ -63,7 +60,6 @@ const NotificationCenter = ({
|
|||
const [xOffset, setXoffset] = useState(300)
|
||||
|
||||
const [showingUnread, setShowingUnread] = useState(false)
|
||||
const classes = useStyles({ buttonCoords, xOffset })
|
||||
const machines = R.compose(
|
||||
R.map(R.prop('name')),
|
||||
R.indexBy(R.prop('deviceId'))
|
||||
|
|
@ -120,7 +116,13 @@ const NotificationCenter = ({
|
|||
<div className={classes.container}>
|
||||
<div className={classes.header}>
|
||||
<H5 className={classes.headerText}>Notifications</H5>
|
||||
<button onClick={close} className={classes.notificationIcon}>
|
||||
<button
|
||||
onClick={close}
|
||||
className={classes.notificationIcon}
|
||||
style={{
|
||||
top: buttonCoords?.y ?? 0,
|
||||
left: buttonCoords?.x ? buttonCoords.x - xOffset : 0
|
||||
}}>
|
||||
<NotificationIconZodiac />
|
||||
{hasUnread && <div className={classes.hasUnread} />}
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,145 @@
|
|||
.container {
|
||||
width: 40vw;
|
||||
height: 110vh;
|
||||
right: 0;
|
||||
background-color: white;
|
||||
box-shadow: 0 0 14px 0 rgba(0, 0, 0, 0.24);
|
||||
}
|
||||
|
||||
.container @media only screen and (max-width: 1920px) {
|
||||
width: 30vw;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.headerText {
|
||||
margin-top: 20px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.actionButtons {
|
||||
display: flex;
|
||||
margin-left: 16px;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.notificationIcon {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
box-shadow: 0 0 0 transparent;
|
||||
border: 0 solid transparent;
|
||||
text-shadow: 0 0 0 transparent;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.clearAllButton {
|
||||
margin-top: -16px;
|
||||
margin-left: 8px;
|
||||
background-color: var(--zircon);
|
||||
}
|
||||
|
||||
.notificationsList {
|
||||
height: 90vh;
|
||||
max-height: 100vh;
|
||||
margin-top: 24px;
|
||||
margin-left: 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
background-color: white;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.notificationRow {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
position: relative;
|
||||
margin-bottom: 16px;
|
||||
padding-top: 12px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.notificationRow > *:first-child {
|
||||
margin-right: 24px;
|
||||
}
|
||||
|
||||
.notificationContent {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.unread {
|
||||
background-color: var(--spring3)
|
||||
}
|
||||
|
||||
.notificationRowIcon {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.notificationRowIcon > * {
|
||||
margin-left: 24px
|
||||
}
|
||||
|
||||
.readIconWrapper {
|
||||
flex-grow: 1
|
||||
}
|
||||
|
||||
.unreadIcon {
|
||||
margin-top: 5px;
|
||||
margin-left: 8px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background-color: var(--spring);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.readIcon {
|
||||
margin-left: 8px;
|
||||
margin-top: 5px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border: 1px solid var(--comet);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.notificationTitle {
|
||||
margin: 0;
|
||||
color: var(--comet);
|
||||
}
|
||||
|
||||
.notificationBody {
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.notificationSubtitle {
|
||||
margin: 0;
|
||||
margin-bottom: 8px;
|
||||
color: var(--comet);
|
||||
}
|
||||
|
||||
.stripes {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
opacity: 60%;
|
||||
}
|
||||
|
||||
.hasUnread {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 16px;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
background-color: var(--spring);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
|
@ -1,143 +0,0 @@
|
|||
import {
|
||||
spacer,
|
||||
white,
|
||||
zircon,
|
||||
secondaryColor,
|
||||
spring3,
|
||||
comet
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
'@media only screen and (max-width: 1920px)': {
|
||||
width: '30vw'
|
||||
},
|
||||
width: '40vw',
|
||||
height: '110vh',
|
||||
right: 0,
|
||||
backgroundColor: white,
|
||||
boxShadow: '0 0 14px 0 rgba(0, 0, 0, 0.24)'
|
||||
},
|
||||
header: {
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between'
|
||||
},
|
||||
headerText: {
|
||||
marginTop: spacer * 2.5,
|
||||
marginLeft: spacer * 3
|
||||
},
|
||||
actionButtons: {
|
||||
display: 'flex',
|
||||
marginLeft: spacer * 2,
|
||||
height: 0
|
||||
},
|
||||
notificationIcon: ({ buttonCoords, xOffset }) => ({
|
||||
position: 'absolute',
|
||||
top: buttonCoords ? buttonCoords.y : 0,
|
||||
left: buttonCoords ? buttonCoords.x - xOffset : 0,
|
||||
cursor: 'pointer',
|
||||
background: 'transparent',
|
||||
boxShadow: '0px 0px 0px transparent',
|
||||
border: '0px solid transparent',
|
||||
textShadow: '0px 0px 0px transparent',
|
||||
outline: 'none'
|
||||
}),
|
||||
clearAllButton: {
|
||||
marginTop: -spacer * 2,
|
||||
marginLeft: spacer,
|
||||
backgroundColor: zircon
|
||||
},
|
||||
notificationsList: {
|
||||
height: '90vh',
|
||||
maxHeight: '100vh',
|
||||
marginTop: spacer * 3,
|
||||
marginLeft: 0,
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden',
|
||||
backgroundColor: white,
|
||||
zIndex: 10
|
||||
},
|
||||
notificationRow: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
position: 'relative',
|
||||
marginBottom: spacer / 2,
|
||||
paddingTop: spacer * 1.5,
|
||||
'& > *:first-child': {
|
||||
marginRight: 24
|
||||
},
|
||||
'& > *': {
|
||||
marginRight: 10
|
||||
},
|
||||
'& > *:last-child': {
|
||||
marginRight: 0
|
||||
}
|
||||
},
|
||||
notificationContent: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
width: 300
|
||||
},
|
||||
unread: {
|
||||
backgroundColor: spring3
|
||||
},
|
||||
notificationRowIcon: {
|
||||
alignSelf: 'center',
|
||||
'& > *': {
|
||||
marginLeft: spacer * 3
|
||||
}
|
||||
},
|
||||
readIconWrapper: {
|
||||
flexGrow: 1
|
||||
},
|
||||
unreadIcon: {
|
||||
marginTop: 2,
|
||||
width: '12px',
|
||||
height: '12px',
|
||||
backgroundColor: secondaryColor,
|
||||
borderRadius: '50%',
|
||||
cursor: 'pointer',
|
||||
zIndex: 1
|
||||
},
|
||||
readIcon: {
|
||||
marginLeft: spacer,
|
||||
marginTop: 5,
|
||||
width: '12px',
|
||||
height: '12px',
|
||||
border: [[1, 'solid', comet]],
|
||||
borderRadius: '50%',
|
||||
cursor: 'pointer',
|
||||
zIndex: 1
|
||||
},
|
||||
notificationTitle: {
|
||||
margin: 0,
|
||||
color: comet
|
||||
},
|
||||
notificationBody: {
|
||||
margin: 0
|
||||
},
|
||||
notificationSubtitle: {
|
||||
margin: 0,
|
||||
marginBottom: spacer,
|
||||
color: comet
|
||||
},
|
||||
stripes: {
|
||||
position: 'absolute',
|
||||
height: '100%',
|
||||
top: '0px',
|
||||
opacity: '60%'
|
||||
},
|
||||
hasUnread: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 16,
|
||||
width: '9px',
|
||||
height: '9px',
|
||||
backgroundColor: secondaryColor,
|
||||
borderRadius: '50%'
|
||||
}
|
||||
}
|
||||
|
||||
export default styles
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import prettyMs from 'pretty-ms'
|
||||
import * as R from 'ramda'
|
||||
|
|
@ -8,8 +7,7 @@ import Wrench from 'src/styling/icons/action/wrench/zodiac.svg?react'
|
|||
import Transaction from 'src/styling/icons/arrow/transaction.svg?react'
|
||||
import WarningIcon from 'src/styling/icons/warning-icon/tomato.svg?react'
|
||||
|
||||
import styles from './NotificationCenter.styles'
|
||||
const useStyles = makeStyles(styles)
|
||||
import classes from './NotificationCenter.module.css'
|
||||
|
||||
const types = {
|
||||
transaction: {
|
||||
|
|
@ -46,8 +44,6 @@ const NotificationRow = ({
|
|||
valid,
|
||||
toggleClear
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const typeDisplay = R.path([type, 'display'])(types) ?? null
|
||||
const icon = R.path([type, 'icon'])(types) ?? (
|
||||
<Wrench height={16} width={16} />
|
||||
|
|
|
|||
|
|
@ -1,120 +1,15 @@
|
|||
import MaterialPopper from '@mui/material/Popper'
|
||||
import Paper from '@mui/material/Paper'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import { white } from 'src/styling/variables'
|
||||
import classes from './Popper.module.css'
|
||||
|
||||
const Popover = ({
|
||||
children,
|
||||
bgColor = white,
|
||||
arrowSize = 6,
|
||||
className,
|
||||
...props
|
||||
}) => {
|
||||
const Popover = ({ children, bgColor = white, className, ...props }) => {
|
||||
const [arrowRef, setArrowRef] = useState(null)
|
||||
|
||||
const styles = {
|
||||
popover: {
|
||||
zIndex: 3000,
|
||||
backgroundColor: bgColor,
|
||||
borderRadius: 4
|
||||
},
|
||||
arrow: {
|
||||
position: 'absolute',
|
||||
fontSize: arrowSize,
|
||||
width: '3em',
|
||||
height: '3em'
|
||||
},
|
||||
arrowBottom: {
|
||||
top: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
borderLeft: [['2em', 'solid', 'transparent']],
|
||||
borderRight: [['2em', 'solid', 'transparent']],
|
||||
borderBottom: [['2em', 'solid', bgColor]],
|
||||
marginTop: '-1.9em',
|
||||
'&:after': {
|
||||
zIndex: -10,
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
width: arrowSize * 3,
|
||||
height: arrowSize * 3,
|
||||
marginLeft: 0,
|
||||
bottom: 0,
|
||||
top: 'calc(50% - 0px)',
|
||||
left: 0,
|
||||
border: '5px solid #fff',
|
||||
borderColor: 'transparent transparent #fff #fff',
|
||||
transformOrigin: '0 0',
|
||||
transform: 'rotate(45deg)',
|
||||
boxShadow:
|
||||
'0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)'
|
||||
}
|
||||
},
|
||||
arrowTop: {
|
||||
bottom: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
borderLeft: [['2em', 'solid', 'transparent']],
|
||||
borderRight: [['2em', 'solid', 'transparent']],
|
||||
borderTop: [['2em', 'solid', bgColor]],
|
||||
marginBottom: '-1.9em',
|
||||
'&:after': {
|
||||
zIndex: -10,
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
width: arrowSize * 3,
|
||||
height: arrowSize * 3,
|
||||
marginLeft: 0,
|
||||
bottom: 0,
|
||||
top: -(arrowSize * 4 + 2),
|
||||
left: 0,
|
||||
border: '5px solid #fff',
|
||||
borderColor: 'transparent transparent #fff #fff',
|
||||
transformOrigin: '0 0',
|
||||
transform: 'rotate(45deg)',
|
||||
boxShadow:
|
||||
'0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)'
|
||||
}
|
||||
},
|
||||
arrowRight: {
|
||||
left: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
borderTop: [['2em', 'solid', 'transparent']],
|
||||
borderBottom: [['2em', 'solid', 'transparent']],
|
||||
borderRight: [['2em', 'solid', bgColor]],
|
||||
marginLeft: '-1.9em'
|
||||
},
|
||||
arrowLeft: {
|
||||
right: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
borderTop: [['2em', 'solid', 'transparent']],
|
||||
borderBottom: [['2em', 'solid', 'transparent']],
|
||||
borderLeft: [['2em', 'solid', bgColor]],
|
||||
marginRight: '-1.9em'
|
||||
},
|
||||
root: {
|
||||
backgroundColor: bgColor
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const getArrowClasses = placement => ({
|
||||
[classes.arrow]: true,
|
||||
[classes.arrowBottom]: placement === 'bottom',
|
||||
[classes.arrowTop]: placement === 'top',
|
||||
[classes.arrowRight]: placement === 'right',
|
||||
[classes.arrowLeft]: placement === 'left'
|
||||
})
|
||||
|
||||
const flipPlacements = {
|
||||
top: ['bottom'],
|
||||
bottom: ['top'],
|
||||
|
|
@ -164,17 +59,16 @@ const Popover = ({
|
|||
<MaterialPopper
|
||||
disablePortal={false}
|
||||
modifiers={modifiers}
|
||||
className={classes.popover}
|
||||
className={classnames(classes.tooltip, 'z-3000 rounded-sm')}
|
||||
{...props}>
|
||||
{({ placement }) => (
|
||||
<Paper className={classnames(classes.root, className)}>
|
||||
<span
|
||||
className={classnames(getArrowClasses(placement))}
|
||||
ref={setArrowRef}
|
||||
/>
|
||||
{children}
|
||||
</Paper>
|
||||
)}
|
||||
<Paper style={{ backgroundColor: bgColor }} className={className}>
|
||||
<span
|
||||
className={classes.newArrow}
|
||||
data-popper-arrow
|
||||
ref={setArrowRef}
|
||||
/>
|
||||
{children}
|
||||
</Paper>
|
||||
</MaterialPopper>
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
33
new-lamassu-admin/src/components/Popper.module.css
Normal file
33
new-lamassu-admin/src/components/Popper.module.css
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
.newArrow,
|
||||
.newArrow::before {
|
||||
position: absolute;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
.newArrow {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.newArrow::before {
|
||||
visibility: visible;
|
||||
content: '';
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.tooltip[data-popper-placement^='top'] > div > span {
|
||||
bottom: -4px;
|
||||
}
|
||||
|
||||
.tooltip[data-popper-placement^='bottom'] > div > span {
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
.tooltip[data-popper-placement^='left'] > div > span {
|
||||
right: -4px;
|
||||
}
|
||||
|
||||
.tooltip[data-popper-placement^='right'] > div > span {
|
||||
left: -4px;
|
||||
}
|
||||
|
|
@ -1,16 +1,11 @@
|
|||
import InputBase from '@mui/material/InputBase'
|
||||
import Paper from '@mui/material/Paper'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import MAutocomplete from '@mui/material/Autocomplete'
|
||||
import classnames from 'classnames'
|
||||
import React, { memo, useState } from 'react'
|
||||
import { P } from 'src/components/typography'
|
||||
import SearchIcon from 'src/styling/icons/circle buttons/search/zodiac.svg?react'
|
||||
|
||||
import styles from './SearchBox.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const SearchBox = memo(
|
||||
({
|
||||
loading = false,
|
||||
|
|
@ -21,13 +16,11 @@ const SearchBox = memo(
|
|||
onChange,
|
||||
...props
|
||||
}) => {
|
||||
const classes = useStyles({ size })
|
||||
|
||||
const [popupOpen, setPopupOpen] = useState(false)
|
||||
|
||||
const inputClasses = {
|
||||
[classes.input]: true,
|
||||
[classes.inputWithPopup]: popupOpen
|
||||
'flex flex-1 h-8 px-2 py-2 font-md items-center rounded-2xl bg-zircon text-comet': true,
|
||||
'rounded-b-none': popupOpen
|
||||
}
|
||||
|
||||
const innerOnChange = filters => onChange(filters)
|
||||
|
|
@ -35,15 +28,16 @@ const SearchBox = memo(
|
|||
return (
|
||||
<MAutocomplete
|
||||
loading={loading}
|
||||
classes={{ option: classes.autocomplete }}
|
||||
value={filters}
|
||||
options={options}
|
||||
getOptionLabel={it => it.label || it.value}
|
||||
renderOption={(props, it) => (
|
||||
<li {...props}>
|
||||
<div className={classes.item}>
|
||||
<P className={classes.itemLabel}>{it.label || it.value}</P>
|
||||
<P className={classes.itemType}>{it.type}</P>
|
||||
<div className="flex flex-row w-full h-8">
|
||||
<P className="m-0 whitespace-nowrap overflow-hidden text-ellipsis">
|
||||
{it.label || it.value}
|
||||
</P>
|
||||
<P className="m-0 ml-auto text-sm text-come">{it.type}</P>
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
|
|
@ -53,25 +47,16 @@ const SearchBox = memo(
|
|||
multiple
|
||||
filterSelectedOptions
|
||||
isOptionEqualToValue={(option, value) => option.type === value.type}
|
||||
PaperComponent={({ children }) => (
|
||||
<Paper elevation={0} className={classes.popup}>
|
||||
<div className={classes.separator} />
|
||||
{children}
|
||||
</Paper>
|
||||
)}
|
||||
renderInput={params => {
|
||||
return (
|
||||
<InputBase
|
||||
ref={params.InputProps.ref}
|
||||
{...params}
|
||||
className={classnames(inputClasses)}
|
||||
startAdornment={<SearchIcon className={classes.iconButton} />}
|
||||
startAdornment={<SearchIcon className="mr-3" />}
|
||||
placeholder={inputPlaceholder}
|
||||
inputProps={{
|
||||
className: classes.bold,
|
||||
classes: {
|
||||
root: classes.size
|
||||
},
|
||||
className: 'font-bold',
|
||||
...params.inputProps
|
||||
}}
|
||||
/>
|
||||
|
|
@ -81,8 +66,17 @@ const SearchBox = memo(
|
|||
onClose={() => setPopupOpen(false)}
|
||||
onChange={(_, filters) => innerOnChange(filters)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
slots={{
|
||||
paper: ({ children }) => (
|
||||
<Paper
|
||||
elevation={0}
|
||||
className="flex flex-col rounded-b-xl bg-zircon shadow-2xl">
|
||||
<div className="w-[88%] h-[1px] my-p mx-auto border-1 border-comet" />
|
||||
{children}
|
||||
</Paper>
|
||||
)
|
||||
}} />
|
||||
);
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
import baseButtonStyles from 'src/components/buttons/BaseButton.styles'
|
||||
import { bySize, bold } from 'src/styling/helpers'
|
||||
import { zircon, comet, primaryColor } from 'src/styling/variables'
|
||||
|
||||
const { baseButton } = baseButtonStyles
|
||||
|
||||
const searchBoxBorderRadius = baseButton.height / 2
|
||||
const searchBoxHeight = 32
|
||||
const popupBorderRadiusFocus = baseButton.height / 4
|
||||
|
||||
const hoverColor = 'rgba(0, 0, 0, 0.08)'
|
||||
const boxShadow = `0 4px 4px 0 ${hoverColor}`
|
||||
|
||||
const styles = {
|
||||
size: ({ size }) => ({
|
||||
marginTop: size === 'lg' ? 0 : 2,
|
||||
...bySize(size)
|
||||
}),
|
||||
bold,
|
||||
autocomplete: {
|
||||
'&[data-focus="true"]': {
|
||||
backgroundColor: hoverColor
|
||||
}
|
||||
},
|
||||
popup: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
borderRadius: [[0, 0, popupBorderRadiusFocus, popupBorderRadiusFocus]],
|
||||
backgroundColor: zircon,
|
||||
boxShadow
|
||||
},
|
||||
separator: {
|
||||
width: '88%',
|
||||
height: 1,
|
||||
margin: '0 auto',
|
||||
border: 'solid 0.5px',
|
||||
borderColor: comet
|
||||
},
|
||||
item: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
height: 36,
|
||||
alignItems: 'center'
|
||||
},
|
||||
itemLabel: {
|
||||
margin: [0],
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis'
|
||||
},
|
||||
itemType: {
|
||||
marginLeft: 'auto',
|
||||
fontSize: 12,
|
||||
color: comet,
|
||||
margin: [0]
|
||||
},
|
||||
input: {
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
width: 273,
|
||||
padding: [[8, 12]],
|
||||
alignItems: 'center',
|
||||
height: searchBoxHeight,
|
||||
borderRadius: searchBoxBorderRadius,
|
||||
backgroundColor: zircon,
|
||||
color: primaryColor
|
||||
},
|
||||
inputWithPopup: {
|
||||
borderRadius: [[popupBorderRadiusFocus, popupBorderRadiusFocus, 0, 0]],
|
||||
boxShadow
|
||||
},
|
||||
iconButton: {
|
||||
marginRight: 12
|
||||
}
|
||||
}
|
||||
|
||||
export default styles
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import Chip from '@mui/material/Chip'
|
||||
import React from 'react'
|
||||
import Chip from 'src/components/Chip'
|
||||
import { P, Label3 } from 'src/components/typography'
|
||||
import CloseIcon from 'src/styling/icons/action/close/zodiac.svg?react'
|
||||
import FilterIcon from 'src/styling/icons/button/filter/white.svg?react'
|
||||
|
|
@ -9,48 +8,39 @@ import ReverseFilterIcon from 'src/styling/icons/button/filter/zodiac.svg?react'
|
|||
import { ActionButton } from 'src/components/buttons'
|
||||
import { onlyFirstToUpper, singularOrPlural } from 'src/utils/string'
|
||||
|
||||
import { chipStyles, styles } from './SearchFilter.styles'
|
||||
|
||||
const useChipStyles = makeStyles(chipStyles)
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const SearchFilter = ({
|
||||
filters,
|
||||
onFilterDelete,
|
||||
deleteAllFilters,
|
||||
entries = 0
|
||||
}) => {
|
||||
const chipClasses = useChipStyles()
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<>
|
||||
<P className={classes.text}>{'Filters:'}</P>
|
||||
<div className={classes.filters}>
|
||||
<div className={classes.chips}>
|
||||
<P className="mx-0">{'Filters:'}</P>
|
||||
<div className="flex mb-4">
|
||||
<div className="mt-auto">
|
||||
{filters.map((f, idx) => (
|
||||
<Chip
|
||||
key={idx}
|
||||
classes={chipClasses}
|
||||
label={`${onlyFirstToUpper(f.type)}: ${f.label || f.value}`}
|
||||
onDelete={() => onFilterDelete(f)}
|
||||
deleteIcon={<CloseIcon className={classes.button} />}
|
||||
deleteIcon={<CloseIcon className="w-2 h-2 mx-2" />}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className={classes.deleteWrapper}>
|
||||
<div className="flex ml-auto justify-end flex-row">
|
||||
{
|
||||
<Label3 className={classes.entries}>{`${entries} ${singularOrPlural(
|
||||
<Label3 className="text-comet m-auto mr-3">{`${entries} ${singularOrPlural(
|
||||
entries,
|
||||
`entry`,
|
||||
`entries`
|
||||
)}`}</Label3>
|
||||
}
|
||||
<ActionButton
|
||||
altTextColor
|
||||
color="secondary"
|
||||
Icon={ReverseFilterIcon}
|
||||
InverseIcon={FilterIcon}
|
||||
className={classes.deleteButton}
|
||||
onClick={deleteAllFilters}>
|
||||
Delete filters
|
||||
</ActionButton>
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
import {
|
||||
primaryColor,
|
||||
zircon,
|
||||
smallestFontSize,
|
||||
inputFontFamily,
|
||||
inputFontWeight,
|
||||
spacer,
|
||||
offColor
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const chipStyles = {
|
||||
root: {
|
||||
marginLeft: 0,
|
||||
height: 20,
|
||||
backgroundColor: zircon,
|
||||
'&:hover, &:focus, &:active': {
|
||||
backgroundColor: zircon
|
||||
},
|
||||
marginBottom: 'auto'
|
||||
},
|
||||
label: {
|
||||
fontSize: smallestFontSize,
|
||||
fontWeight: inputFontWeight,
|
||||
fontFamily: inputFontFamily,
|
||||
paddingRight: 0,
|
||||
paddingLeft: spacer,
|
||||
color: primaryColor
|
||||
}
|
||||
}
|
||||
|
||||
const styles = {
|
||||
button: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
marginLeft: 8,
|
||||
marginRight: 8
|
||||
},
|
||||
text: {
|
||||
marginTop: 0,
|
||||
marginBottom: 0
|
||||
},
|
||||
filters: {
|
||||
display: 'flex',
|
||||
marginBottom: 16
|
||||
},
|
||||
deleteWrapper: {
|
||||
display: 'flex',
|
||||
marginLeft: 'auto',
|
||||
justifyContent: 'flex-end',
|
||||
flexDirection: 'row'
|
||||
},
|
||||
entries: {
|
||||
color: offColor,
|
||||
margin: 'auto',
|
||||
marginRight: 12
|
||||
},
|
||||
chips: {
|
||||
marginTop: 'auto'
|
||||
}
|
||||
}
|
||||
|
||||
export { chipStyles, styles }
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import * as R from 'ramda'
|
||||
import React, { memo } from 'react'
|
||||
import CompleteStageIconSpring from 'src/styling/icons/stage/spring/complete.svg?react'
|
||||
import CurrentStageIconSpring from 'src/styling/icons/stage/spring/current.svg?react'
|
||||
import EmptyStageIconSpring from 'src/styling/icons/stage/spring/empty.svg?react'
|
||||
import CompleteStageIconZodiac from 'src/styling/icons/stage/zodiac/complete.svg?react'
|
||||
import CurrentStageIconZodiac from 'src/styling/icons/stage/zodiac/current.svg?react'
|
||||
import EmptyStageIconZodiac from 'src/styling/icons/stage/zodiac/empty.svg?react'
|
||||
|
||||
import {
|
||||
primaryColor,
|
||||
secondaryColor,
|
||||
offColor,
|
||||
disabledColor
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const styles = {
|
||||
stages: {
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
},
|
||||
wrapper: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
margin: 0
|
||||
},
|
||||
stage: {
|
||||
display: 'flex',
|
||||
height: 28,
|
||||
width: 28,
|
||||
zIndex: 2,
|
||||
'& > svg': {
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
overflow: 'visible'
|
||||
}
|
||||
},
|
||||
separator: {
|
||||
width: 28,
|
||||
height: 2,
|
||||
border: [[2, 'solid']],
|
||||
zIndex: 1
|
||||
},
|
||||
separatorSpring: {
|
||||
borderColor: secondaryColor
|
||||
},
|
||||
separatorZodiac: {
|
||||
borderColor: primaryColor
|
||||
},
|
||||
separatorSpringEmpty: {
|
||||
borderColor: disabledColor
|
||||
},
|
||||
separatorZodiacEmpty: {
|
||||
borderColor: offColor
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const Stage = memo(({ stages, currentStage, color = 'spring', className }) => {
|
||||
if (currentStage < 1 || currentStage > stages)
|
||||
throw Error('Value of currentStage is invalid')
|
||||
if (stages < 1) throw Error('Value of stages is invalid')
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const separatorClasses = {
|
||||
[classes.separator]: true,
|
||||
[classes.separatorSpring]: color === 'spring',
|
||||
[classes.separatorZodiac]: color === 'zodiac'
|
||||
}
|
||||
|
||||
const separatorEmptyClasses = {
|
||||
[classes.separator]: true,
|
||||
[classes.separatorSpringEmpty]: color === 'spring',
|
||||
[classes.separatorZodiacEmpty]: color === 'zodiac'
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classnames(className, classes.stages)}>
|
||||
{R.range(1, currentStage).map(idx => (
|
||||
<div key={idx} className={classes.wrapper}>
|
||||
{idx > 1 && <div className={classnames(separatorClasses)} />}
|
||||
<div className={classes.stage}>
|
||||
{color === 'spring' && <CompleteStageIconSpring />}
|
||||
{color === 'zodiac' && <CompleteStageIconZodiac />}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<div className={classes.wrapper}>
|
||||
{currentStage > 1 && <div className={classnames(separatorClasses)} />}
|
||||
<div className={classes.stage}>
|
||||
{color === 'spring' && <CurrentStageIconSpring />}
|
||||
{color === 'zodiac' && <CurrentStageIconZodiac />}
|
||||
</div>
|
||||
</div>
|
||||
{R.range(currentStage + 1, stages + 1).map(idx => (
|
||||
<div key={idx} className={classes.wrapper}>
|
||||
<div className={classnames(separatorEmptyClasses)} />
|
||||
<div className={classes.stage}>
|
||||
{color === 'spring' && <EmptyStageIconSpring />}
|
||||
{color === 'zodiac' && <EmptyStageIconZodiac />}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
export default Stage
|
||||
|
|
@ -1,59 +1,8 @@
|
|||
import Chip from '@mui/material/Chip'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import React from 'react'
|
||||
|
||||
import {
|
||||
tomato,
|
||||
mistyRose,
|
||||
pumpkin,
|
||||
secondaryColorDarker as spring4,
|
||||
inputFontWeight,
|
||||
spring3,
|
||||
zircon,
|
||||
primaryColor,
|
||||
smallestFontSize,
|
||||
inputFontFamily,
|
||||
spacer,
|
||||
linen
|
||||
} from '../styling/variables'
|
||||
|
||||
const colors = {
|
||||
error: tomato,
|
||||
warning: pumpkin,
|
||||
success: spring4,
|
||||
neutral: primaryColor
|
||||
}
|
||||
|
||||
const backgroundColors = {
|
||||
error: mistyRose,
|
||||
warning: linen,
|
||||
success: spring3,
|
||||
neutral: zircon
|
||||
}
|
||||
|
||||
const useStyles = makeStyles({
|
||||
root: {
|
||||
borderRadius: spacer / 2,
|
||||
marginTop: spacer / 2,
|
||||
marginRight: spacer / 4,
|
||||
marginBottom: spacer / 2,
|
||||
marginLeft: spacer / 4,
|
||||
height: spacer * 3,
|
||||
backgroundColor: ({ type }) => backgroundColors[type]
|
||||
},
|
||||
label: {
|
||||
fontSize: smallestFontSize,
|
||||
fontWeight: inputFontWeight,
|
||||
fontFamily: inputFontFamily,
|
||||
paddingRight: spacer / 2,
|
||||
paddingLeft: spacer / 2,
|
||||
color: ({ type }) => colors[type]
|
||||
}
|
||||
})
|
||||
|
||||
const Status = ({ status }) => {
|
||||
const classes = useStyles({ type: status.type })
|
||||
return <Chip type={status.type} label={status.label} classes={classes} />
|
||||
return <Chip color={status.type} label={status.label} />
|
||||
}
|
||||
|
||||
const MainStatus = ({ statuses }) => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import * as R from 'ramda'
|
||||
import React, { memo } from 'react'
|
||||
|
|
@ -9,79 +8,29 @@ import CompleteStageIconZodiac from 'src/styling/icons/stage/zodiac/complete.svg
|
|||
import CurrentStageIconZodiac from 'src/styling/icons/stage/zodiac/current.svg?react'
|
||||
import EmptyStageIconZodiac from 'src/styling/icons/stage/zodiac/empty.svg?react'
|
||||
|
||||
import {
|
||||
primaryColor,
|
||||
secondaryColor,
|
||||
offColor,
|
||||
disabledColor
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const styles = {
|
||||
stages: {
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
},
|
||||
wrapper: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
margin: 0
|
||||
},
|
||||
stage: {
|
||||
display: 'flex',
|
||||
height: 28,
|
||||
width: 28,
|
||||
zIndex: 2,
|
||||
'& > svg': {
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
overflow: 'visible'
|
||||
}
|
||||
},
|
||||
separator: {
|
||||
width: 28,
|
||||
height: 2,
|
||||
border: [[2, 'solid']],
|
||||
zIndex: 1
|
||||
},
|
||||
separatorSpring: {
|
||||
borderColor: secondaryColor
|
||||
},
|
||||
separatorZodiac: {
|
||||
borderColor: primaryColor
|
||||
},
|
||||
separatorSpringEmpty: {
|
||||
borderColor: disabledColor
|
||||
},
|
||||
separatorZodiacEmpty: {
|
||||
borderColor: offColor
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import classes from './Stepper.module.css'
|
||||
|
||||
const Stepper = memo(({ steps, currentStep, color = 'spring', className }) => {
|
||||
if (currentStep < 1 || currentStep > steps)
|
||||
throw Error('Value of currentStage is invalid')
|
||||
if (steps < 1) throw Error('Value of stages is invalid')
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const separatorClasses = {
|
||||
[classes.separator]: true,
|
||||
[classes.separatorSpring]: color === 'spring',
|
||||
[classes.separatorZodiac]: color === 'zodiac'
|
||||
'w-7 h-[2px] border-2 z-1': true,
|
||||
'border-spring': color === 'spring',
|
||||
'border-zodiac': color === 'zodiac'
|
||||
}
|
||||
|
||||
const separatorEmptyClasses = {
|
||||
[classes.separator]: true,
|
||||
[classes.separatorSpringEmpty]: color === 'spring',
|
||||
[classes.separatorZodiacEmpty]: color === 'zodiac'
|
||||
'w-7 h-[2px] border-2 z-1': true,
|
||||
'border-dust': color === 'spring',
|
||||
'border-comet': color === 'zodiac'
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classnames(className, classes.stages)}>
|
||||
<div className={classnames(className, 'flex items-center')}>
|
||||
{R.range(1, currentStep).map(idx => (
|
||||
<div key={idx} className={classes.wrapper}>
|
||||
<div key={idx} className="flex items-center m-0">
|
||||
{idx > 1 && <div className={classnames(separatorClasses)} />}
|
||||
<div className={classes.stage}>
|
||||
{color === 'spring' && <CompleteStageIconSpring />}
|
||||
|
|
@ -89,7 +38,7 @@ const Stepper = memo(({ steps, currentStep, color = 'spring', className }) => {
|
|||
</div>
|
||||
</div>
|
||||
))}
|
||||
<div className={classes.wrapper}>
|
||||
<div className="flex items-center m-0">
|
||||
{currentStep > 1 && <div className={classnames(separatorClasses)} />}
|
||||
<div className={classes.stage}>
|
||||
{color === 'spring' && <CurrentStageIconSpring />}
|
||||
|
|
@ -97,7 +46,7 @@ const Stepper = memo(({ steps, currentStep, color = 'spring', className }) => {
|
|||
</div>
|
||||
</div>
|
||||
{R.range(currentStep + 1, steps + 1).map(idx => (
|
||||
<div key={idx} className={classes.wrapper}>
|
||||
<div key={idx} className="flex items-center m-0">
|
||||
<div className={classnames(separatorEmptyClasses)} />
|
||||
<div className={classes.stage}>
|
||||
{color === 'spring' && <EmptyStageIconSpring />}
|
||||
|
|
|
|||
12
new-lamassu-admin/src/components/Stepper.module.css
Normal file
12
new-lamassu-admin/src/components/Stepper.module.css
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
.stage {
|
||||
display: flex;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.stage > svg {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: visible;
|
||||
}
|
||||
|
|
@ -1,27 +1,12 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import { spacer, offColor } from 'src/styling/variables'
|
||||
|
||||
import { TL1 } from './typography'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
subtitle: {
|
||||
color: offColor,
|
||||
marginTop: spacer * 2,
|
||||
marginBottom: spacer * 2
|
||||
},
|
||||
extraMarginTop: {
|
||||
marginTop: spacer * 9
|
||||
}
|
||||
})
|
||||
|
||||
const Subtitle = memo(({ children, className, extraMarginTop }) => {
|
||||
const classes = useStyles()
|
||||
const classNames = {
|
||||
[classes.subtitle]: true,
|
||||
[classes.extraMarginTop]: extraMarginTop
|
||||
'text-comet my-4': true,
|
||||
'mt-18': extraMarginTop
|
||||
}
|
||||
|
||||
return <TL1 className={classnames(classNames, className)}>{children}</TL1>
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React from 'react'
|
||||
|
||||
import { Label1 } from './typography'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
wrapper: {
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
},
|
||||
colorIndicator: {
|
||||
borderRadius: 3,
|
||||
height: 12,
|
||||
width: 12,
|
||||
marginRight: 8
|
||||
}
|
||||
})
|
||||
|
||||
const TableLabel = ({ className, label, color, ...props }) => {
|
||||
const classes = useStyles()
|
||||
return (
|
||||
<div className={classnames(classes.wrapper, className)} {...props}>
|
||||
{color && (
|
||||
<div
|
||||
className={classes.colorIndicator}
|
||||
style={{ backgroundColor: color }}
|
||||
/>
|
||||
)}
|
||||
<Label1 {...props}>{label}</Label1>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TableLabel
|
||||
|
|
@ -1,20 +1,9 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import { spacer } from 'src/styling/variables'
|
||||
|
||||
import { H1 } from './typography'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
title: {
|
||||
marginTop: spacer * 3,
|
||||
marginBottom: spacer * 3
|
||||
}
|
||||
})
|
||||
|
||||
const Title = memo(({ children }) => {
|
||||
const classes = useStyles()
|
||||
return <H1 className={classes.title}>{children}</H1>
|
||||
return <H1 className="my-6">{children}</H1>
|
||||
})
|
||||
|
||||
export default Title
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import ClickAwayListener from '@mui/material/ClickAwayListener'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState, memo } from 'react'
|
||||
import Popper from 'src/components/Popper'
|
||||
import HelpIcon from 'src/styling/icons/action/help/zodiac.svg?react'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
const useStyles = {
|
||||
transparentButton: {
|
||||
border: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
|
|
@ -27,10 +26,9 @@ const useStyles = makeStyles({
|
|||
width,
|
||||
padding: [[10, 15]]
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const usePopperHandler = width => {
|
||||
const classes = useStyles({ width })
|
||||
const usePopperHandler = () => {
|
||||
const [helpPopperAnchorEl, setHelpPopperAnchorEl] = useState(null)
|
||||
|
||||
const handleOpenHelpPopper = event => {
|
||||
|
|
@ -48,7 +46,6 @@ const usePopperHandler = width => {
|
|||
const helpPopperOpen = Boolean(helpPopperAnchorEl)
|
||||
|
||||
return {
|
||||
classes,
|
||||
helpPopperAnchorEl,
|
||||
helpPopperOpen,
|
||||
handleOpenHelpPopper,
|
||||
|
|
@ -62,15 +59,13 @@ const HelpTooltip = memo(({ children, width }) => {
|
|||
|
||||
return (
|
||||
<ClickAwayListener onClickAway={handler.handleCloseHelpPopper}>
|
||||
<div
|
||||
className={handler.classes.relativelyPositioned}
|
||||
onMouseLeave={handler.handleCloseHelpPopper}>
|
||||
<div className="relative" onMouseLeave={handler.handleCloseHelpPopper}>
|
||||
{handler.helpPopperOpen && (
|
||||
<div className={handler.classes.safeSpace}></div>
|
||||
<div className="absolute bg-transparent h-10 -left-1/2 w-[200%]"></div>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
className={handler.classes.transparentButton}
|
||||
className="border-0 bg-transparent outline-0 cursor-pointer mt-1"
|
||||
onMouseEnter={handler.openHelpPopper}>
|
||||
<HelpIcon />
|
||||
</button>
|
||||
|
|
@ -79,7 +74,9 @@ const HelpTooltip = memo(({ children, width }) => {
|
|||
anchorEl={handler.helpPopperAnchorEl}
|
||||
arrowEnabled={true}
|
||||
placement="bottom">
|
||||
<div className={handler.classes.popoverContent}>{children}</div>
|
||||
<div className="py-2 px-4" style={{ width }}>
|
||||
{children}
|
||||
</div>
|
||||
</Popper>
|
||||
</div>
|
||||
</ClickAwayListener>
|
||||
|
|
@ -104,7 +101,7 @@ const HoverableTooltip = memo(({ parentElements, children, width }) => {
|
|||
type="button"
|
||||
onMouseEnter={handler.handleOpenHelpPopper}
|
||||
onMouseLeave={handler.handleCloseHelpPopper}
|
||||
className={handler.classes.transparentButton}>
|
||||
className="border-0 bg-transparent outline-0 cursor-pointer mt-1">
|
||||
<HelpIcon />
|
||||
</button>
|
||||
)}
|
||||
|
|
@ -112,7 +109,9 @@ const HoverableTooltip = memo(({ parentElements, children, width }) => {
|
|||
open={handler.helpPopperOpen}
|
||||
anchorEl={handler.helpPopperAnchorEl}
|
||||
placement="bottom">
|
||||
<div className={handler.classes.popoverContent}>{children}</div>
|
||||
<div className="py-2 px-4" style={{ width }}>
|
||||
{children}
|
||||
</div>
|
||||
</Popper>
|
||||
</div>
|
||||
</ClickAwayListener>
|
||||
|
|
|
|||
|
|
@ -1,93 +0,0 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import Chip from '@mui/material/Chip'
|
||||
import * as R from 'ramda'
|
||||
import React from 'react'
|
||||
|
||||
import {
|
||||
secondaryColorLighter,
|
||||
secondaryColorDarker,
|
||||
offErrorColor,
|
||||
errorColor,
|
||||
offColor,
|
||||
inputFontWeight,
|
||||
smallestFontSize,
|
||||
inputFontFamily,
|
||||
spacer
|
||||
} from 'src/styling/variables'
|
||||
import { onlyFirstToUpper } from 'src/utils/string'
|
||||
|
||||
import typographyStyles from './typography/styles'
|
||||
const { label1 } = typographyStyles
|
||||
|
||||
const colors = {
|
||||
running: secondaryColorDarker,
|
||||
notRunning: offErrorColor
|
||||
}
|
||||
|
||||
const backgroundColors = {
|
||||
running: secondaryColorLighter,
|
||||
notRunning: errorColor
|
||||
}
|
||||
|
||||
const styles = {
|
||||
uptimeContainer: {
|
||||
display: 'inline-block',
|
||||
minWidth: 104,
|
||||
margin: [[0, 20]]
|
||||
},
|
||||
name: {
|
||||
extend: label1,
|
||||
paddingLeft: 4,
|
||||
color: offColor
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const useChipStyles = makeStyles({
|
||||
root: {
|
||||
borderRadius: spacer / 2,
|
||||
marginTop: spacer / 2,
|
||||
marginRight: spacer / 4,
|
||||
marginBottom: spacer / 2,
|
||||
marginLeft: spacer / 4,
|
||||
height: spacer * 3,
|
||||
backgroundColor: ({ type }) => backgroundColors[type]
|
||||
},
|
||||
label: {
|
||||
fontSize: smallestFontSize,
|
||||
fontWeight: inputFontWeight,
|
||||
fontFamily: inputFontFamily,
|
||||
padding: [[spacer / 2, spacer]],
|
||||
color: ({ type }) => colors[type]
|
||||
}
|
||||
})
|
||||
|
||||
const Uptime = ({ process, ...props }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const uptime = time => {
|
||||
if (time < 60) return `${time}s`
|
||||
if (time < 3600) return `${Math.floor(time / 60)}m`
|
||||
if (time < 86400) return `${Math.floor(time / 60 / 60)}h`
|
||||
return `${Math.floor(time / 60 / 60 / 24)}d`
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.uptimeContainer}>
|
||||
<div className={classes.name}>{R.toLower(process.name)}</div>
|
||||
<Chip
|
||||
label={
|
||||
process.state === 'RUNNING'
|
||||
? `Running for ${uptime(process.uptime)}`
|
||||
: onlyFirstToUpper(process.state)
|
||||
}
|
||||
classes={useChipStyles({
|
||||
type: process.state === 'RUNNING' ? 'running' : 'notRunning'
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Uptime
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import { useFormikContext, Form, Formik, Field as FormikField } from 'formik'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState, memo } from 'react'
|
||||
|
|
@ -11,13 +10,10 @@ import FalseIcon from 'src/styling/icons/table/false.svg?react'
|
|||
import TrueIcon from 'src/styling/icons/table/true.svg?react'
|
||||
import * as Yup from 'yup'
|
||||
|
||||
import { Link, IconButton } from 'src/components/buttons'
|
||||
import { Link } from 'src/components/buttons'
|
||||
import { RadioGroup } from 'src/components/inputs/formik'
|
||||
import { Table, TableBody, TableRow, TableCell } from 'src/components/table'
|
||||
|
||||
import { booleanPropertiesTableStyles } from './BooleanPropertiesTable.styles'
|
||||
|
||||
const useStyles = makeStyles(booleanPropertiesTableStyles)
|
||||
import SvgIcon from '@mui/material/SvgIcon'
|
||||
|
||||
const BooleanCell = ({ name }) => {
|
||||
const { values } = useFormikContext()
|
||||
|
|
@ -26,6 +22,8 @@ const BooleanCell = ({ name }) => {
|
|||
|
||||
const BooleanPropertiesTable = memo(
|
||||
({ title, disabled, data, elements, save, forcedEditing = false }) => {
|
||||
const [editing, setEditing] = useState(forcedEditing)
|
||||
|
||||
const initialValues = R.fromPairs(
|
||||
elements.map(it => [it.name, data[it.name]?.toString() ?? 'false'])
|
||||
)
|
||||
|
|
@ -39,10 +37,6 @@ const BooleanPropertiesTable = memo(
|
|||
)
|
||||
)
|
||||
|
||||
const [editing, setEditing] = useState(forcedEditing)
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const innerSave = async values => {
|
||||
const toBoolean = (num, _) => R.equals(num, 'true')
|
||||
save(R.mapObjIndexed(toBoolean, R.filter(R.complement(R.isNil))(values)))
|
||||
|
|
@ -54,7 +48,7 @@ const BooleanPropertiesTable = memo(
|
|||
{ display: 'No', code: 'false' }
|
||||
]
|
||||
return (
|
||||
<div className={classes.booleanPropertiesTableWrapper}>
|
||||
<div className="flex w-sm flex-col ">
|
||||
<Formik
|
||||
validateOnBlur={false}
|
||||
validateOnChange={false}
|
||||
|
|
@ -65,16 +59,16 @@ const BooleanPropertiesTable = memo(
|
|||
{({ resetForm }) => {
|
||||
return (
|
||||
<Form>
|
||||
<div className={classes.rowWrapper}>
|
||||
<div className="flex items-center">
|
||||
<H4>{title}</H4>
|
||||
{editing ? (
|
||||
<div className={classes.rightAligned}>
|
||||
<div className="ml-auto">
|
||||
<Link type="submit" color="primary">
|
||||
Save
|
||||
</Link>
|
||||
<Link
|
||||
type="reset"
|
||||
className={classes.rightLink}
|
||||
className="ml-5"
|
||||
onClick={() => {
|
||||
resetForm()
|
||||
setEditing(false)
|
||||
|
|
@ -85,34 +79,30 @@ const BooleanPropertiesTable = memo(
|
|||
</div>
|
||||
) : (
|
||||
<IconButton
|
||||
className={classes.transparentButton}
|
||||
onClick={() => setEditing(true)}
|
||||
size="large">
|
||||
{disabled ? <EditIconDisabled /> : <EditIcon />}
|
||||
className="my-auto mx-3"
|
||||
onClick={() => setEditing(true)}>
|
||||
<SvgIcon fontSize="small">
|
||||
{disabled ? <EditIconDisabled /> : <EditIcon />}
|
||||
</SvgIcon>
|
||||
</IconButton>
|
||||
)}
|
||||
</div>
|
||||
<PromptWhenDirty />
|
||||
<Table className={classes.fillColumn}>
|
||||
<TableBody className={classes.fillColumn}>
|
||||
<Table className="w-full">
|
||||
<TableBody className="w-full">
|
||||
{elements.map((it, idx) => (
|
||||
<TableRow
|
||||
key={idx}
|
||||
size="sm"
|
||||
className={classes.tableRow}>
|
||||
<TableCell className={classes.leftTableCell}>
|
||||
{it.display}
|
||||
</TableCell>
|
||||
<TableCell className={classes.rightTableCell}>
|
||||
className="h-auto py-2 px-4 flex items-center justify-between min-h-8 even:bg-transparent odd:bg-zircon">
|
||||
<TableCell className="p-0 w-50">{it.display}</TableCell>
|
||||
<TableCell className="p-0 flex">
|
||||
{editing && (
|
||||
<FormikField
|
||||
component={RadioGroup}
|
||||
name={it.name}
|
||||
options={radioButtonOptions}
|
||||
className={classnames(
|
||||
classes.radioButtons,
|
||||
classes.rightTableCell
|
||||
)}
|
||||
className="flex flex-row m-[-15px] p-0"
|
||||
/>
|
||||
)}
|
||||
{!editing && <BooleanCell name={it.name} />}
|
||||
|
|
@ -122,11 +112,11 @@ const BooleanPropertiesTable = memo(
|
|||
</TableBody>
|
||||
</Table>
|
||||
</Form>
|
||||
);
|
||||
)
|
||||
}}
|
||||
</Formik>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
import baseStyles from 'src/pages/Logs.styles'
|
||||
import { backgroundColor, zircon } from 'src/styling/variables'
|
||||
|
||||
const { fillColumn } = baseStyles
|
||||
|
||||
const booleanPropertiesTableStyles = {
|
||||
booleanPropertiesTableWrapper: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: 396
|
||||
},
|
||||
tableRow: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
'&:nth-child(even)': {
|
||||
backgroundColor: backgroundColor
|
||||
},
|
||||
'&:nth-child(odd)': {
|
||||
backgroundColor: zircon
|
||||
},
|
||||
minHeight: 32,
|
||||
height: 'auto',
|
||||
padding: [[8, 16, 8, 24]],
|
||||
boxShadow: '0 0 0 0 rgba(0, 0, 0, 0)'
|
||||
},
|
||||
leftTableCell: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'left',
|
||||
width: 200,
|
||||
padding: [0]
|
||||
},
|
||||
rightTableCell: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'right',
|
||||
padding: [0]
|
||||
},
|
||||
transparentButton: {
|
||||
'& > *': {
|
||||
margin: 'auto 12px'
|
||||
},
|
||||
'& button': {
|
||||
border: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
cursor: 'pointer'
|
||||
}
|
||||
},
|
||||
rowWrapper: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
position: 'relative',
|
||||
flex: 'wrap'
|
||||
},
|
||||
rightAligned: {
|
||||
marginLeft: 'auto'
|
||||
},
|
||||
radioButtons: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
margin: [-15]
|
||||
},
|
||||
rightLink: {
|
||||
marginLeft: '20px'
|
||||
},
|
||||
fillColumn,
|
||||
popoverContent: {
|
||||
width: 272,
|
||||
padding: [[10, 15]]
|
||||
}
|
||||
}
|
||||
|
||||
export { booleanPropertiesTableStyles }
|
||||
|
|
@ -1,34 +1,41 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import styles from './ActionButton.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import moduleStyles from './ActionButton.module.css'
|
||||
|
||||
const ActionButton = memo(
|
||||
({ className, Icon, InverseIcon, color, children, ...props }) => {
|
||||
const classes = useStyles()
|
||||
({
|
||||
className,
|
||||
altTextColor,
|
||||
Icon,
|
||||
InverseIcon,
|
||||
color,
|
||||
center,
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
const classNames = {
|
||||
[classes.actionButton]: true,
|
||||
[classes.primary]: color === 'primary',
|
||||
[classes.secondary]: color === 'secondary',
|
||||
[classes.spring]: color === 'spring',
|
||||
[classes.tomato]: color === 'tomato'
|
||||
[moduleStyles.actionButton]: true,
|
||||
[moduleStyles.altText]: altTextColor || color !== 'primary',
|
||||
[moduleStyles.primary]: color === 'primary',
|
||||
[moduleStyles.secondary]: color === 'secondary',
|
||||
[moduleStyles.spring]: color === 'spring',
|
||||
[moduleStyles.tomato]: color === 'tomato',
|
||||
[moduleStyles.center]: center
|
||||
}
|
||||
|
||||
return (
|
||||
<button className={classnames(classNames, className)} {...props}>
|
||||
{Icon && (
|
||||
<div className={classes.actionButtonIcon}>
|
||||
<div className={moduleStyles.actionButtonIcon}>
|
||||
<Icon />
|
||||
</div>
|
||||
)}
|
||||
{InverseIcon && (
|
||||
<div
|
||||
className={classnames(
|
||||
classes.actionButtonIcon,
|
||||
classes.actionButtonIconActive
|
||||
moduleStyles.actionButtonIcon,
|
||||
moduleStyles.actionButtonIconActive
|
||||
)}>
|
||||
<InverseIcon />
|
||||
</div>
|
||||
|
|
|
|||
145
new-lamassu-admin/src/components/buttons/ActionButton.module.css
Normal file
145
new-lamassu-admin/src/components/buttons/ActionButton.module.css
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
.actionButton {
|
||||
composes: p from '../typography/typography.module.css';
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
height: 28px;
|
||||
outline: 0;
|
||||
border-radius: 6px;
|
||||
padding: 0 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.actionButton.altText {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.primary {
|
||||
background-color: var(--zircon);
|
||||
}
|
||||
|
||||
.primary:hover {
|
||||
background-color: var(--zircon2);
|
||||
}
|
||||
|
||||
.primary:active {
|
||||
background-color: var(--comet);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.primary .actionButtonIconActive {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.primary:active .actionButtonIcon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.primary:active .actionButtonIconActive {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.secondary {
|
||||
background-color: var(--comet);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.secondary:hover {
|
||||
background-color: var(--comet2);
|
||||
}
|
||||
|
||||
.secondary:active {
|
||||
background-color: var(--comet3);
|
||||
}
|
||||
|
||||
.secondary .actionButtonIcon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.secondary .actionButtonIconActive {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.secondary:active .actionButtonIcon {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.secondary:active .actionButtonIconActive {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.spring {
|
||||
background-color: var(--spring2);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.spring:hover {
|
||||
background-color: var(--spring);
|
||||
}
|
||||
|
||||
.spring:active {
|
||||
background-color: var(--spring4);
|
||||
}
|
||||
|
||||
.spring .actionButtonIcon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.spring .actionButtonIconActive {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.spring:active .actionButtonIcon {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.spring:active .actionButtonIconActive {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tomato {
|
||||
background-color: var(--tomato);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.tomato:hover {
|
||||
background-color: var(--tomato);
|
||||
}
|
||||
|
||||
.tomato:active {
|
||||
background-color: var(--tomato);
|
||||
}
|
||||
|
||||
.tomato .actionButtonIcon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tomato .actionButtonIconActive {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.tomato:active .actionButtonIcon {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.tomato:active .actionButtonIconActive {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.actionButtonIcon {
|
||||
display: flex;
|
||||
padding-right: 7px;
|
||||
}
|
||||
|
||||
.actionButtonIcon svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.center {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.actionButtonIconActive {
|
||||
}
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
import typographyStyles from 'src/components/typography/styles'
|
||||
import {
|
||||
white,
|
||||
subheaderColor,
|
||||
subheaderDarkColor,
|
||||
offColor,
|
||||
offDarkColor,
|
||||
offDarkerColor,
|
||||
secondaryColor,
|
||||
secondaryColorDark,
|
||||
secondaryColorDarker,
|
||||
errorColor,
|
||||
errorColorDark,
|
||||
errorColorDarker
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const { p } = typographyStyles
|
||||
|
||||
const colors = (color1, color2, color3) => {
|
||||
return {
|
||||
backgroundColor: color1,
|
||||
'&:hover': {
|
||||
backgroundColor: color2
|
||||
},
|
||||
'&:active': {
|
||||
backgroundColor: color3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
actionButton: {
|
||||
extend: p,
|
||||
cursor: 'pointer',
|
||||
border: 'none',
|
||||
height: 28,
|
||||
outline: 0,
|
||||
borderRadius: 6,
|
||||
padding: '0 8px',
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
},
|
||||
primary: {
|
||||
extend: colors(subheaderColor, subheaderDarkColor, offColor),
|
||||
'&:active': {
|
||||
color: white,
|
||||
'& $actionButtonIcon': {
|
||||
display: 'none'
|
||||
},
|
||||
'& $actionButtonIconActive': {
|
||||
display: 'flex'
|
||||
}
|
||||
},
|
||||
'& $actionButtonIconActive': {
|
||||
display: 'none'
|
||||
}
|
||||
},
|
||||
secondary: {
|
||||
extend: colors(offColor, offDarkColor, offDarkerColor),
|
||||
color: white,
|
||||
'&:active': {
|
||||
'& $actionButtonIcon': {
|
||||
display: 'flex'
|
||||
},
|
||||
'& $actionButtonIconActive': {
|
||||
display: 'none'
|
||||
}
|
||||
},
|
||||
'& $actionButtonIcon': {
|
||||
display: 'none'
|
||||
},
|
||||
'& $actionButtonIconActive': {
|
||||
display: 'flex'
|
||||
}
|
||||
},
|
||||
spring: {
|
||||
extend: colors(secondaryColorDark, secondaryColor, secondaryColorDarker),
|
||||
color: white,
|
||||
'&:active': {
|
||||
'& $actionButtonIcon': {
|
||||
display: 'flex'
|
||||
},
|
||||
'& $actionButtonIconActive': {
|
||||
display: 'none'
|
||||
}
|
||||
},
|
||||
'& $actionButtonIcon': {
|
||||
display: 'none'
|
||||
},
|
||||
'& $actionButtonIconActive': {
|
||||
display: 'flex'
|
||||
}
|
||||
},
|
||||
tomato: {
|
||||
extend: colors(errorColorDark, errorColor, errorColorDarker),
|
||||
color: white,
|
||||
'&:active': {
|
||||
'& $actionButtonIcon': {
|
||||
display: 'flex'
|
||||
},
|
||||
'& $actionButtonIconActive': {
|
||||
display: 'none'
|
||||
}
|
||||
},
|
||||
'& $actionButtonIcon': {
|
||||
display: 'none'
|
||||
},
|
||||
'& $actionButtonIconActive': {
|
||||
display: 'flex'
|
||||
}
|
||||
},
|
||||
actionButtonIcon: {
|
||||
display: 'flex',
|
||||
paddingRight: 7,
|
||||
'@global': {
|
||||
svg: {
|
||||
width: 14,
|
||||
height: 14
|
||||
}
|
||||
}
|
||||
},
|
||||
actionButtonIconActive: {}
|
||||
}
|
||||
|
|
@ -1,47 +1,10 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React, { memo } from 'react'
|
||||
import AddIcon from 'src/styling/icons/button/add/zodiac.svg?react'
|
||||
|
||||
import typographyStyles from 'src/components/typography/styles'
|
||||
import { zircon, zircon2, comet, fontColor, white } from 'src/styling/variables'
|
||||
|
||||
const { p } = typographyStyles
|
||||
|
||||
const styles = {
|
||||
button: {
|
||||
extend: p,
|
||||
border: 'none',
|
||||
backgroundColor: zircon,
|
||||
cursor: 'pointer',
|
||||
outline: 0,
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
width: 167,
|
||||
height: 48,
|
||||
color: fontColor,
|
||||
'&:hover': {
|
||||
backgroundColor: zircon2
|
||||
},
|
||||
'&:active': {
|
||||
backgroundColor: comet,
|
||||
color: white,
|
||||
'& svg g *': {
|
||||
stroke: white
|
||||
}
|
||||
},
|
||||
'& svg': {
|
||||
marginRight: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import classes from './AddButton.module.css'
|
||||
|
||||
const SimpleButton = memo(({ className, children, ...props }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<button className={classnames(classes.button, className)} {...props}>
|
||||
<AddIcon />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
.button {
|
||||
composes: p from '../typography/typography.module.css';
|
||||
border: none;
|
||||
background-color: var(--zircon);
|
||||
cursor: pointer;
|
||||
outline: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 167px;
|
||||
height: 48px;
|
||||
color: var(--zodiac);
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: var(--zircon2);
|
||||
}
|
||||
|
||||
.button:active {
|
||||
background-color: var(--comet);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.button:active svg g * {
|
||||
stroke: white;
|
||||
}
|
||||
|
||||
.button svg {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
|
@ -1,25 +1,37 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import styles from './Button.styles'
|
||||
import moduleStyles from './Button.module.css'
|
||||
import { spacer } from '../../styling/variables.js'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
const pickSize = size => {
|
||||
switch (size) {
|
||||
case 'xl':
|
||||
return spacer * 7.625
|
||||
case 'sm':
|
||||
return spacer * 4
|
||||
case 'lg':
|
||||
default:
|
||||
return spacer * 5
|
||||
}
|
||||
}
|
||||
|
||||
const ActionButton = memo(
|
||||
({
|
||||
size = 'lg',
|
||||
children,
|
||||
className,
|
||||
buttonClassName,
|
||||
backgroundColor,
|
||||
...props
|
||||
}) => {
|
||||
const classes = useStyles({ size, backgroundColor })
|
||||
({ size = 'lg', children, className, buttonClassName, ...props }) => {
|
||||
const height = pickSize(size)
|
||||
|
||||
return (
|
||||
<div className={classnames(className, classes.wrapper)}>
|
||||
<div className={className} style={{ height: height + height / 12 }}>
|
||||
<button
|
||||
className={classnames(buttonClassName, classes.button)}
|
||||
className={classnames(
|
||||
buttonClassName,
|
||||
moduleStyles.button,
|
||||
'text-white',
|
||||
{
|
||||
[moduleStyles.buttonSm]: size === 'sm',
|
||||
[moduleStyles.buttonXl]: size === 'xl'
|
||||
}
|
||||
)}
|
||||
{...props}>
|
||||
{children}
|
||||
</button>
|
||||
|
|
|
|||
49
new-lamassu-admin/src/components/buttons/Button.module.css
Normal file
49
new-lamassu-admin/src/components/buttons/Button.module.css
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
.button {
|
||||
composes: h3 from '../typography/typography.module.css';
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
outline: 0;
|
||||
font-weight: 900;
|
||||
background-color: var(--spring);
|
||||
height: 40px;
|
||||
padding: 0 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 3px var(--spring4);
|
||||
}
|
||||
|
||||
.buttonXl {
|
||||
composes: h1 from '../typography/typography.module.css';
|
||||
height: 61px;
|
||||
border-radius: 15px
|
||||
}
|
||||
|
||||
.buttonSm {
|
||||
height: 32px;
|
||||
padding: 0 16px;
|
||||
border-radius: 8px
|
||||
}
|
||||
|
||||
.button:disabled {
|
||||
background-color: var(--dust);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.button:disabled:hover {
|
||||
background-color: var(--dust);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.button:disabled:active {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: var(--spring2);
|
||||
box-shadow: 0 3px var(--spring4);
|
||||
}
|
||||
|
||||
.button:active {
|
||||
margin-top: 2px;
|
||||
background-color: var(--spring2);
|
||||
box-shadow: 0 2px var(--spring4);
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
import typographyStyles from 'src/components/typography/styles'
|
||||
import {
|
||||
white,
|
||||
disabledColor,
|
||||
secondaryColor,
|
||||
secondaryColorDark,
|
||||
secondaryColorDarker,
|
||||
offColor,
|
||||
offDarkColor,
|
||||
offDarkerColor,
|
||||
spacer
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const { h1, h3 } = typographyStyles
|
||||
|
||||
const pickSize = size => {
|
||||
switch (size) {
|
||||
case 'xl':
|
||||
return spacer * 7.625
|
||||
case 'sm':
|
||||
return spacer * 4
|
||||
case 'lg':
|
||||
default:
|
||||
return spacer * 5
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
wrapper: ({ size }) => {
|
||||
const height = pickSize(size)
|
||||
const shadowSize = height / 12
|
||||
return { height: height + shadowSize / 2 }
|
||||
},
|
||||
button: ({ size, backgroundColor }) => {
|
||||
const height = pickSize(size)
|
||||
const shadowSize = size === 'xl' ? 3 : height / 12
|
||||
const padding = size === 'xl' ? 20 : height / 2
|
||||
const isGrey = backgroundColor === 'grey'
|
||||
|
||||
return {
|
||||
extend: size === 'xl' ? h1 : h3,
|
||||
border: 'none',
|
||||
color: white,
|
||||
cursor: 'pointer',
|
||||
fontWeight: 900,
|
||||
outline: 0,
|
||||
backgroundColor: isGrey ? offDarkColor : secondaryColor,
|
||||
'&:disabled': {
|
||||
backgroundColor: disabledColor,
|
||||
boxShadow: 'none',
|
||||
'&:hover': {
|
||||
backgroundColor: disabledColor,
|
||||
boxShadow: 'none'
|
||||
},
|
||||
'&:active': {
|
||||
marginTop: 0
|
||||
}
|
||||
},
|
||||
shadowSize,
|
||||
height,
|
||||
padding: `0 ${padding}px`,
|
||||
borderRadius: height / 4,
|
||||
boxShadow: `0 ${shadowSize}px ${isGrey ? offColor : secondaryColorDark}`,
|
||||
'&:hover': {
|
||||
backgroundColor: isGrey ? offColor : secondaryColorDark,
|
||||
boxShadow: `0 ${shadowSize}px ${
|
||||
isGrey ? offDarkerColor : secondaryColorDarker
|
||||
}`
|
||||
},
|
||||
'&:active': {
|
||||
marginTop: shadowSize / 2,
|
||||
backgroundColor: isGrey ? offDarkColor : secondaryColorDark,
|
||||
boxShadow: `0 ${shadowSize / 2}px ${
|
||||
isGrey ? offDarkerColor : secondaryColorDarker
|
||||
}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React, { memo } from 'react'
|
||||
import DeleteIcon from 'src/styling/icons/button/cancel/zodiac.svg?react'
|
||||
|
||||
import typographyStyles from 'src/components/typography/styles'
|
||||
import { zircon, zircon2, comet, fontColor, white } from 'src/styling/variables'
|
||||
|
||||
const { p } = typographyStyles
|
||||
|
||||
const styles = {
|
||||
button: {
|
||||
extend: p,
|
||||
border: 'none',
|
||||
backgroundColor: zircon,
|
||||
cursor: 'pointer',
|
||||
outline: 0,
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
width: 167,
|
||||
height: 48,
|
||||
color: fontColor,
|
||||
'&:hover': {
|
||||
backgroundColor: zircon2
|
||||
},
|
||||
'&:active': {
|
||||
backgroundColor: comet,
|
||||
color: white,
|
||||
'& svg g *': {
|
||||
stroke: white
|
||||
}
|
||||
},
|
||||
'& svg': {
|
||||
marginRight: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const SimpleButton = memo(({ className, children, ...props }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<button className={classnames(classes.button, className)} {...props}>
|
||||
<DeleteIcon />
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
})
|
||||
|
||||
export default SimpleButton
|
||||
|
|
@ -1,47 +1,19 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import baseButtonStyles from './BaseButton.styles'
|
||||
|
||||
const { baseButton, primary } = baseButtonStyles
|
||||
|
||||
const styles = {
|
||||
featureButton: {
|
||||
extend: baseButton,
|
||||
width: baseButton.height,
|
||||
borderRadius: baseButton.height / 2,
|
||||
display: 'flex',
|
||||
padding: 0
|
||||
},
|
||||
primary,
|
||||
buttonIcon: {
|
||||
margin: 'auto',
|
||||
'& svg': {
|
||||
width: 16,
|
||||
height: 16,
|
||||
overflow: 'visible',
|
||||
'& g': {
|
||||
strokeWidth: 1.8
|
||||
}
|
||||
}
|
||||
},
|
||||
buttonIconActive: {} // required to extend primary
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import classes from './FeatureButton.module.css'
|
||||
|
||||
const FeatureButton = memo(
|
||||
({ className, Icon, InverseIcon, children, ...props }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const classNames = {
|
||||
[classes.featureButton]: true,
|
||||
[classes.primary]: true
|
||||
}
|
||||
|
||||
return (
|
||||
<button className={classnames(classNames, className)} {...props}>
|
||||
<button
|
||||
className={classnames(
|
||||
classes.baseButton,
|
||||
classes.roundButton,
|
||||
classes.primary,
|
||||
className
|
||||
)}
|
||||
{...props}>
|
||||
{Icon && (
|
||||
<div className={classes.buttonIcon}>
|
||||
<Icon />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
.baseButton {
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
outline: 0;
|
||||
height: 32px;
|
||||
color: var(--zodiac);
|
||||
}
|
||||
|
||||
.roundButton {
|
||||
width: 32px;
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.roundButton .buttonIcon {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.roundButton .buttonIcon svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.roundButton .buttonIcon svg g {
|
||||
stroke-width: 2px;
|
||||
}
|
||||
|
||||
.baseButton:active {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.primary {
|
||||
background-color: var(--zircon);
|
||||
}
|
||||
|
||||
.primary:hover {
|
||||
background-color: var(--zircon2);
|
||||
}
|
||||
|
||||
.primary:active {
|
||||
background-color: var(--comet);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.primary .buttonIconActive {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.primary:active .buttonIcon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.primary:active .buttonIconActive {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.secondary {
|
||||
background-color: var(--comet);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.secondary:hover {
|
||||
background-color: var(--comet2);
|
||||
}
|
||||
|
||||
.secondary:active {
|
||||
background-color: white;
|
||||
color: var(--zodiac);
|
||||
}
|
||||
|
||||
.secondary .buttonIcon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.secondary .buttonIconActive {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.secondary:active .buttonIcon {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.secondary:active .buttonIconActive {
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -1,68 +1,9 @@
|
|||
import ClickAwayListener from '@mui/material/ClickAwayListener'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React, { useState, memo } from 'react'
|
||||
import Popover from 'src/components/Popper'
|
||||
|
||||
import typographyStyles from 'src/components/typography/styles'
|
||||
import {
|
||||
subheaderColor,
|
||||
subheaderDarkColor,
|
||||
offColor
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const { info2 } = typographyStyles
|
||||
|
||||
const colors = (color1, color2, color3) => {
|
||||
return {
|
||||
backgroundColor: color1,
|
||||
'&:hover': {
|
||||
backgroundColor: color2
|
||||
},
|
||||
'&:active': {
|
||||
backgroundColor: color3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const styles = {
|
||||
idButton: {
|
||||
width: 34,
|
||||
height: 28,
|
||||
display: 'flex',
|
||||
borderRadius: 4,
|
||||
padding: 0,
|
||||
border: 'none',
|
||||
cursor: 'pointer'
|
||||
},
|
||||
buttonIcon: {
|
||||
margin: 'auto',
|
||||
lineHeight: 1,
|
||||
'& svg': {
|
||||
overflow: 'visible'
|
||||
}
|
||||
},
|
||||
closed: {
|
||||
extend: colors(subheaderColor, subheaderDarkColor, offColor)
|
||||
},
|
||||
open: {
|
||||
extend: colors(offColor, offColor, offColor)
|
||||
},
|
||||
popoverContent: {
|
||||
extend: info2,
|
||||
padding: 8,
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderRadius: 4,
|
||||
'& img': {
|
||||
height: 145,
|
||||
minWidth: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import classes from './IDButton.module.css'
|
||||
|
||||
const IDButton = memo(
|
||||
({
|
||||
|
|
@ -77,8 +18,6 @@ const IDButton = memo(
|
|||
}) => {
|
||||
const [anchorEl, setAnchorEl] = useState(null)
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const open = Boolean(anchorEl)
|
||||
const id = open ? `simple-popper-${name}` : undefined
|
||||
|
||||
|
|
@ -127,7 +66,6 @@ const IDButton = memo(
|
|||
open={open}
|
||||
anchorEl={anchorEl}
|
||||
onClose={handleClose}
|
||||
arrowSize={3}
|
||||
placement="top"
|
||||
flip>
|
||||
<div className={classes.popoverContent}>
|
||||
|
|
|
|||
58
new-lamassu-admin/src/components/buttons/IDButton.module.css
Normal file
58
new-lamassu-admin/src/components/buttons/IDButton.module.css
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
.idButton {
|
||||
width: 34px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
border-radius: 4px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.buttonIcon {
|
||||
margin: auto;
|
||||
line-height: 1px;
|
||||
}
|
||||
|
||||
.buttonIcon svg {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.closed {
|
||||
background-color: var(--zircon);
|
||||
}
|
||||
|
||||
.closed:hover {
|
||||
background-color: var(--zircon2);
|
||||
}
|
||||
|
||||
.closed:active {
|
||||
background-color: var(--comet);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.open {
|
||||
background-color: var(--comet);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.open:hover {
|
||||
background-color: var(--comet2);
|
||||
}
|
||||
|
||||
.open:active {
|
||||
background-color: var(--comet3);
|
||||
}
|
||||
|
||||
.popoverContent {
|
||||
composes: info2 from '../typography/typography.module.css';
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.popoverContent img {
|
||||
height: 145px;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
import IconB from '@mui/material/IconButton'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import React from 'react'
|
||||
|
||||
import { comet } from 'src/styling/variables'
|
||||
|
||||
const styles = {
|
||||
root: ({ size }) => ({
|
||||
width: size,
|
||||
height: size,
|
||||
'& svg': {
|
||||
flex: 1
|
||||
},
|
||||
'&:hover': {
|
||||
backgroundColor: 'inherit'
|
||||
},
|
||||
'&:hover rect': {
|
||||
stroke: comet
|
||||
},
|
||||
'&:hover polygon': {
|
||||
stroke: comet
|
||||
},
|
||||
'&:hover path': {
|
||||
stroke: comet
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const IconButton = ({ size, children, onClick, ...props }) => {
|
||||
const classes = useStyles({ size })
|
||||
return (
|
||||
<IconB
|
||||
{...props}
|
||||
size="small"
|
||||
classes={{ root: classes.root }}
|
||||
disableRipple
|
||||
onClick={onClick}>
|
||||
{children}
|
||||
</IconB>
|
||||
)
|
||||
}
|
||||
|
||||
export default IconButton
|
||||
|
|
@ -1,14 +1,10 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import styles from './Link.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import classes from './Link.module.css'
|
||||
|
||||
const Link = memo(
|
||||
({ submit, className, children, color = 'primary', ...props }) => {
|
||||
const classes = useStyles()
|
||||
const classNames = {
|
||||
[classes.link]: true,
|
||||
[classes.primary]: color === 'primary',
|
||||
|
|
|
|||
47
new-lamassu-admin/src/components/buttons/Link.module.css
Normal file
47
new-lamassu-admin/src/components/buttons/Link.module.css
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
.link {
|
||||
composes: h4 from '../typography/typography.module.css';
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.primary {
|
||||
box-shadow: inset 0 -4px 0 0 rgba(72, 246, 148, 0.8);
|
||||
}
|
||||
|
||||
.primary:hover {
|
||||
box-shadow: none;
|
||||
background-color: rgba(72, 246, 148, 0.8);
|
||||
}
|
||||
|
||||
.secondary {
|
||||
box-shadow: inset 0 -4px 0 0 rgba(255, 88, 74, 0.8);
|
||||
}
|
||||
|
||||
.secondary:hover {
|
||||
box-shadow: none;
|
||||
background-color: rgba(255, 88, 74, 0.8);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.noColor {
|
||||
box-shadow: inset 0 -4px 0 0 rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.noColor:hover {
|
||||
box-shadow: none;
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.action {
|
||||
box-shadow: inset 0 -4px 0 0 rgba(72, 246, 148, 0.8);
|
||||
color: var(--zircon);
|
||||
}
|
||||
|
||||
.action:hover {
|
||||
box-shadow: none;
|
||||
background-color: rgba(72, 246, 148, 0.8);
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
import { alpha } from '@mui/material/styles'
|
||||
|
||||
import typographyStyles from 'src/components/typography/styles'
|
||||
import {
|
||||
white,
|
||||
linkPrimaryColor,
|
||||
linkSecondaryColor,
|
||||
zircon
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const { h4 } = typographyStyles
|
||||
|
||||
const color = color => ({
|
||||
boxShadow: `inset 0 -4px 0 0 ${alpha(color, 0.8)}`,
|
||||
'&:hover': {
|
||||
boxShadow: 'none',
|
||||
backgroundColor: alpha(color, 0.8)
|
||||
}
|
||||
})
|
||||
|
||||
export default {
|
||||
link: {
|
||||
extend: h4,
|
||||
textDecoration: 'none',
|
||||
border: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
cursor: 'pointer',
|
||||
padding: '0',
|
||||
height: '100%'
|
||||
},
|
||||
primary: {
|
||||
extend: color(linkPrimaryColor)
|
||||
},
|
||||
secondary: {
|
||||
extend: color(linkSecondaryColor),
|
||||
'&:hover': {
|
||||
color: white
|
||||
}
|
||||
},
|
||||
noColor: {
|
||||
extend: color(white)
|
||||
},
|
||||
action: {
|
||||
extend: color(linkPrimaryColor),
|
||||
color: zircon
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,9 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React, { memo, useState } from 'react'
|
||||
import { H4 } from 'src/components/typography'
|
||||
import CancelIconInverse from 'src/styling/icons/button/cancel/white.svg?react'
|
||||
|
||||
import subpageButtonStyles from './SubpageButton.styles'
|
||||
|
||||
const useStyles = makeStyles(subpageButtonStyles)
|
||||
import classes from './SubpageButton.module.css'
|
||||
|
||||
const SubpageButton = memo(
|
||||
({
|
||||
|
|
@ -19,11 +16,10 @@ const SubpageButton = memo(
|
|||
}) => {
|
||||
const [active, setActive] = useState(false)
|
||||
const isActive = forceDisable ? false : active
|
||||
const classes = useStyles()
|
||||
const classNames = {
|
||||
[classes.button]: true,
|
||||
[classes.normalButton]: !isActive,
|
||||
[classes.activeButton]: isActive
|
||||
[classes.normal]: !isActive,
|
||||
[classes.active]: isActive
|
||||
}
|
||||
|
||||
const normalButton = <Icon className={classes.buttonIcon} />
|
||||
|
|
@ -36,7 +32,7 @@ const SubpageButton = memo(
|
|||
classes.buttonIconActiveLeft
|
||||
)}
|
||||
/>
|
||||
<H4 className={classes.white}>{children}</H4>
|
||||
<H4 className="text-white">{children}</H4>
|
||||
<CancelIconInverse
|
||||
className={classnames(
|
||||
classes.buttonIcon,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
.button {
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
outline: 0;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
color: white;
|
||||
border-radius: 16px;
|
||||
background-color: var(--zircon);
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: var(--zircon2);
|
||||
}
|
||||
|
||||
.normal {
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.active {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
background-color: var(--comet);
|
||||
font-weight: bold;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.active:hover {
|
||||
background-color: var(--comet);
|
||||
}
|
||||
|
||||
.buttonIcon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.buttonIcon g {
|
||||
stroke-width: 1.8px;
|
||||
}
|
||||
|
||||
.buttonIconActiveLeft {
|
||||
margin-right: 12px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.buttonIconActiveRight {
|
||||
margin-right: 5px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
|
@ -1,31 +1,18 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import React from 'react'
|
||||
import InverseLinkIcon from 'src/styling/icons/action/external link/white.svg?react'
|
||||
import LinkIcon from 'src/styling/icons/action/external link/zodiac.svg?react'
|
||||
|
||||
import { ActionButton } from 'src/components/buttons'
|
||||
import { spacer, primaryColor } from 'src/styling/variables'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
actionButton: {
|
||||
marginBottom: spacer * 4
|
||||
},
|
||||
actionButtonLink: {
|
||||
textDecoration: 'none',
|
||||
color: primaryColor
|
||||
}
|
||||
})
|
||||
|
||||
const SupportLinkButton = ({ link, label }) => {
|
||||
const classes = useStyles()
|
||||
return (
|
||||
<a
|
||||
className={classes.actionButtonLink}
|
||||
className="no-underline text-zodiac"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href={link}>
|
||||
<ActionButton
|
||||
className={classes.actionButton}
|
||||
className="mb-8"
|
||||
color="primary"
|
||||
Icon={LinkIcon}
|
||||
InverseIcon={InverseLinkIcon}>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
import ActionButton from './ActionButton'
|
||||
import AddButton from './AddButton'
|
||||
import Button from './Button'
|
||||
import DeleteButton from './DeleteButton'
|
||||
import FeatureButton from './FeatureButton'
|
||||
import IDButton from './IDButton'
|
||||
import IconButton from './IconButton'
|
||||
import Link from './Link'
|
||||
import SubpageButton from './SubpageButton'
|
||||
import SupportLinkButton from './SupportLinkButton'
|
||||
|
|
@ -14,10 +12,8 @@ export {
|
|||
Link,
|
||||
ActionButton,
|
||||
FeatureButton,
|
||||
IconButton,
|
||||
IDButton,
|
||||
AddButton,
|
||||
SupportLinkButton,
|
||||
SubpageButton,
|
||||
DeleteButton
|
||||
SubpageButton
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import {
|
||||
add,
|
||||
differenceInMonths,
|
||||
|
|
@ -18,77 +17,12 @@ import React, { useState } from 'react'
|
|||
import Arrow from 'src/styling/icons/arrow/month_change.svg?react'
|
||||
import RightArrow from 'src/styling/icons/arrow/month_change_right.svg?react'
|
||||
|
||||
import typographyStyles from 'src/components/typography/styles'
|
||||
import { primaryColor, zircon } from 'src/styling/variables'
|
||||
|
||||
import Tile from './Tile'
|
||||
|
||||
const { p, label2 } = typographyStyles
|
||||
|
||||
const styles = {
|
||||
wrapper: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center'
|
||||
},
|
||||
button: {
|
||||
outline: 'none'
|
||||
},
|
||||
navbar: {
|
||||
extend: p,
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
padding: [[15, 15]],
|
||||
color: primaryColor,
|
||||
'& button': {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: 0,
|
||||
border: 'none',
|
||||
backgroundColor: zircon,
|
||||
cursor: 'pointer',
|
||||
borderRadius: '50%',
|
||||
width: 20,
|
||||
height: 20,
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
'& svg': {
|
||||
position: 'absolute',
|
||||
left: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
table: {
|
||||
borderCollapse: 'collapse',
|
||||
width: '100%',
|
||||
color: primaryColor,
|
||||
'& tr': {
|
||||
'&:first-child': {
|
||||
paddingLeft: 5
|
||||
},
|
||||
'&:last-child': {
|
||||
paddingRight: 5
|
||||
}
|
||||
},
|
||||
'& th, & td': {
|
||||
margin: 0,
|
||||
padding: [[3, 0, 3, 0]]
|
||||
},
|
||||
'& th': {
|
||||
extend: label2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import classes from './Calendar.module.css'
|
||||
|
||||
const Calendar = ({ minDate, maxDate, handleSelect, ...props }) => {
|
||||
const [currentDisplayedMonth, setCurrentDisplayedMonth] = useState(new Date())
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const weekdays = Array.from(Array(7)).map((_, i) =>
|
||||
format('EEEEE', add({ days: i }, startOfWeek(new Date())))
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
.wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.button {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
font-size: 14px;
|
||||
font-family: var(--museo);
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 15px 15px;
|
||||
color: var(--zodiac);
|
||||
}
|
||||
|
||||
.navbar button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background-color: var(--zircon);
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.navbar button svg {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
color: var(--zodiac);
|
||||
}
|
||||
|
||||
.table tr:first-child {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.table tr:last-child {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.table th,
|
||||
.table td {
|
||||
margin: 0;
|
||||
padding: 3px 0 3px 0;
|
||||
}
|
||||
|
||||
.table th {
|
||||
font-size: 13px;
|
||||
font-family: var(--museo);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import { compareAsc, differenceInDays, set } from 'date-fns/fp'
|
||||
import * as R from 'ramda'
|
||||
|
|
@ -6,15 +5,6 @@ import React, { useState, useEffect } from 'react'
|
|||
|
||||
import Calendar from './Calendar'
|
||||
|
||||
const styles = {
|
||||
wrapper: {
|
||||
backgroundColor: 'white',
|
||||
borderRadius: 10
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const DateRangePicker = ({ minDate, maxDate, className, onRangeChange }) => {
|
||||
const [from, setFrom] = useState(null)
|
||||
const [to, setTo] = useState(null)
|
||||
|
|
@ -23,8 +13,6 @@ const DateRangePicker = ({ minDate, maxDate, className, onRangeChange }) => {
|
|||
onRangeChange(from, to)
|
||||
}, [from, onRangeChange, to])
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const handleSelect = day => {
|
||||
if (
|
||||
(maxDate && compareAsc(maxDate, day) > 0) ||
|
||||
|
|
@ -55,7 +43,7 @@ const DateRangePicker = ({ minDate, maxDate, className, onRangeChange }) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className={classnames(classes.wrapper, className)}>
|
||||
<div className={classnames('bg-white rounded-xl', className)}>
|
||||
<Calendar
|
||||
from={from}
|
||||
to={to}
|
||||
|
|
|
|||
|
|
@ -1,76 +1,15 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React from 'react'
|
||||
|
||||
import typographyStyles from 'src/components/typography/styles'
|
||||
import {
|
||||
primaryColor,
|
||||
spring2,
|
||||
spring3,
|
||||
disabledColor
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const { label1 } = typographyStyles
|
||||
|
||||
const styles = {
|
||||
wrapper: {
|
||||
height: 26,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
position: 'relative',
|
||||
overflow: 'hidden'
|
||||
},
|
||||
button: {
|
||||
outline: 'none',
|
||||
extend: label1,
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
backgroundColor: 'transparent',
|
||||
color: primaryColor,
|
||||
zIndex: 2
|
||||
},
|
||||
lowerBound: {
|
||||
left: '50%'
|
||||
},
|
||||
upperBound: {
|
||||
right: '50%'
|
||||
},
|
||||
selected: {
|
||||
width: 26,
|
||||
height: 26,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: spring2,
|
||||
borderRadius: '50%',
|
||||
position: 'absolute',
|
||||
zIndex: 1
|
||||
},
|
||||
between: {
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
zIndex: 0,
|
||||
backgroundColor: spring3
|
||||
},
|
||||
disabled: {
|
||||
color: disabledColor,
|
||||
cursor: 'default'
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import classes from './Tile.module.css'
|
||||
|
||||
const Tile = ({
|
||||
isLowerBound,
|
||||
isUpperBound,
|
||||
isBetween,
|
||||
isDisabled,
|
||||
children,
|
||||
...props
|
||||
children
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
const selected = isLowerBound || isUpperBound
|
||||
|
||||
const rangeClasses = {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
.wrapper {
|
||||
height: 26px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.button {
|
||||
outline: none;
|
||||
font-size: 13px;
|
||||
font-family: var(--museo);
|
||||
font-weight: 500;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
color: var(--zodiac);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.lowerBound {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.upperBound {
|
||||
right: 50%;
|
||||
}
|
||||
|
||||
.selected {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: var(--spring2);
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.between {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 0;
|
||||
background-color: var(--spring3);
|
||||
}
|
||||
|
||||
.disabled {
|
||||
color: var(--dust);
|
||||
cursor: default;
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import React, { useState, memo } from 'react'
|
||||
import { H4, P } from 'src/components/typography'
|
||||
import EditIconDisabled from 'src/styling/icons/action/edit/disabled.svg?react'
|
||||
import EditIcon from 'src/styling/icons/action/edit/enabled.svg?react'
|
||||
|
||||
import { Link } from 'src/components/buttons'
|
||||
import { RadioGroup } from 'src/components/inputs'
|
||||
|
||||
import { editablePropertyStyles } from './EditableProperty.styles'
|
||||
|
||||
const useStyles = makeStyles(editablePropertyStyles)
|
||||
|
||||
const EditableProperty = memo(
|
||||
({ title, prefixText, disabled, options, code, save }) => {
|
||||
const [editing, setEditing] = useState(false)
|
||||
const [currentCode, setCurrentCode] = useState(code)
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const innerSave = () => {
|
||||
save(currentCode)
|
||||
setEditing(false)
|
||||
}
|
||||
|
||||
const innerCancel = () => setEditing(false)
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={classes.rowWrapper}>
|
||||
<H4>{title}</H4>
|
||||
{editing ? (
|
||||
<div className={classes.leftSpace}>
|
||||
<Link
|
||||
className={classes.leftSpace}
|
||||
onClick={innerCancel}
|
||||
color="secondary">
|
||||
Cancel
|
||||
</Link>
|
||||
<Link
|
||||
className={classes.leftSpace}
|
||||
onClick={innerSave}
|
||||
color="primary">
|
||||
Save
|
||||
</Link>
|
||||
</div>
|
||||
) : (
|
||||
<div className={classes.transparentButton}>
|
||||
<button disabled={disabled} onClick={() => setEditing(true)}>
|
||||
{disabled ? <EditIconDisabled /> : <EditIcon />}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{editing ? (
|
||||
<RadioGroup
|
||||
options={options}
|
||||
value={currentCode}
|
||||
onChange={event => setCurrentCode(event.target.value)}
|
||||
className={classes.radioButtons}
|
||||
/>
|
||||
) : (
|
||||
<P>
|
||||
{`${prefixText} ${options
|
||||
.find(it => it.code === currentCode)
|
||||
.display.toLowerCase()}`}
|
||||
</P>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
export default EditableProperty
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
const optionsRowHeigth = 43
|
||||
|
||||
const editablePropertyStyles = {
|
||||
transparentButton: {
|
||||
'& > *': {
|
||||
margin: 'auto 12px'
|
||||
},
|
||||
'& button': {
|
||||
border: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
cursor: 'pointer'
|
||||
}
|
||||
},
|
||||
rowWrapper: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
position: 'relative',
|
||||
flex: 'wrap',
|
||||
height: optionsRowHeigth
|
||||
},
|
||||
rightAligned: {
|
||||
display: 'flex',
|
||||
position: 'absolute',
|
||||
right: 0
|
||||
},
|
||||
radioButtons: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
height: optionsRowHeigth
|
||||
},
|
||||
leftSpace: {
|
||||
marginLeft: '20px'
|
||||
}
|
||||
}
|
||||
|
||||
export { editablePropertyStyles }
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
import EditableProperty from './EditableProperty'
|
||||
|
||||
export { EditableProperty }
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import * as R from 'ramda'
|
||||
import React, { useContext } from 'react'
|
||||
|
|
@ -13,14 +12,6 @@ import { sentenceCase } from 'src/utils/string'
|
|||
|
||||
import TableCtx from './Context'
|
||||
|
||||
const styles = {
|
||||
orderedBySpan: {
|
||||
whiteSpace: 'nowrap'
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const groupSecondHeader = elements => {
|
||||
const doubleHeader = R.prop('doubleHeader')
|
||||
const sameDoubleHeader = (a, b) => doubleHeader(a) === doubleHeader(b)
|
||||
|
|
@ -46,7 +37,6 @@ const groupSecondHeader = elements => {
|
|||
}
|
||||
|
||||
const Header = () => {
|
||||
const classes = useStyles()
|
||||
const {
|
||||
elements,
|
||||
enableEdit,
|
||||
|
|
@ -79,7 +69,7 @@ const Header = () => {
|
|||
idx
|
||||
) => {
|
||||
const orderClasses = classnames({
|
||||
[classes.orderedBySpan]:
|
||||
'whitespace-nowrap':
|
||||
R.isNil(header) && !R.isNil(orderedBy) && R.equals(name, orderedBy.code)
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import Switch from '@mui/material/Switch'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import SvgIcon from '@mui/material/SvgIcon'
|
||||
import classnames from 'classnames'
|
||||
import { Field, useFormikContext } from 'formik'
|
||||
import * as R from 'ramda'
|
||||
|
|
@ -13,15 +14,12 @@ import DisabledEditIcon from 'src/styling/icons/action/edit/disabled.svg?react'
|
|||
import EditIcon from 'src/styling/icons/action/edit/enabled.svg?react'
|
||||
import StripesSvg from 'src/styling/icons/stripes.svg?react'
|
||||
|
||||
import { Link, IconButton } from 'src/components/buttons'
|
||||
import { Link } from 'src/components/buttons'
|
||||
|
||||
import TableCtx from './Context'
|
||||
import styles from './Row.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import moduleStyles from './Row.module.css'
|
||||
|
||||
const ActionCol = ({ disabled, editing }) => {
|
||||
const classes = useStyles()
|
||||
const { values, submitForm, resetForm } = useFormikContext()
|
||||
const {
|
||||
editWidth,
|
||||
|
|
@ -59,7 +57,7 @@ const ActionCol = ({ disabled, editing }) => {
|
|||
{editing && (
|
||||
<Td textAlign="center" width={actionColSize}>
|
||||
<Link
|
||||
className={classes.saveButton}
|
||||
className={moduleStyles.saveButton}
|
||||
type="submit"
|
||||
color="primary"
|
||||
onClick={submitForm}>
|
||||
|
|
@ -76,10 +74,11 @@ const ActionCol = ({ disabled, editing }) => {
|
|||
<Td textAlign="center" width={editWidth}>
|
||||
<IconButton
|
||||
disabled={disableEdit}
|
||||
className={classes.editButton}
|
||||
onClick={() => onEdit && onEdit(values.id)}
|
||||
size="large">
|
||||
{disableEdit ? <DisabledEditIcon /> : <EditIcon />}
|
||||
size="small">
|
||||
<SvgIcon>
|
||||
{disableEdit ? <DisabledEditIcon /> : <EditIcon />}
|
||||
</SvgIcon>
|
||||
</IconButton>
|
||||
</Td>
|
||||
)}
|
||||
|
|
@ -90,8 +89,10 @@ const ActionCol = ({ disabled, editing }) => {
|
|||
onClick={() => {
|
||||
setDeleteDialog(true)
|
||||
}}
|
||||
size="large">
|
||||
{disabled ? <DisabledDeleteIcon /> : <DeleteIcon />}
|
||||
size="small">
|
||||
<SvgIcon>
|
||||
{disabled ? <DisabledDeleteIcon /> : <DeleteIcon />}
|
||||
</SvgIcon>
|
||||
</IconButton>
|
||||
<DeleteDialog
|
||||
open={deleteDialog}
|
||||
|
|
@ -116,7 +117,7 @@ const ActionCol = ({ disabled, editing }) => {
|
|||
</Td>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
const ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => {
|
||||
|
|
@ -151,11 +152,6 @@ const ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => {
|
|||
const isEditing = editing && isEditable(editable)
|
||||
const isField = !bypassField
|
||||
|
||||
const classes = useStyles({
|
||||
textAlign: isEditing ? editingAlign : textAlign,
|
||||
size
|
||||
})
|
||||
|
||||
const innerProps = {
|
||||
fullWidth: true,
|
||||
autoFocus: focus,
|
||||
|
|
@ -165,16 +161,20 @@ const ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => {
|
|||
...inputProps
|
||||
}
|
||||
|
||||
const newAlign = isEditing ? editingAlign : textAlign
|
||||
const justifyContent = newAlign === 'right' ? 'flex-end' : newAlign
|
||||
const style = suffix || prefix ? { justifyContent } : {}
|
||||
|
||||
return (
|
||||
<div className={classes.fields}>
|
||||
<div className={moduleStyles.fields}>
|
||||
{fields.map((f, idx) => (
|
||||
<Td
|
||||
style={style}
|
||||
key={idx}
|
||||
className={{
|
||||
[classes.extraPaddingRight]: extraPaddingRight,
|
||||
[classes.extraPadding]: extraPadding,
|
||||
[classes.withSuffix]: suffix,
|
||||
[classes.withPrefix]: prefix
|
||||
[moduleStyles.extraPaddingRight]: extraPaddingRight,
|
||||
[moduleStyles.extraPadding]: extraPadding,
|
||||
'flex items-center': suffix || prefix
|
||||
}}
|
||||
width={width}
|
||||
size={size}
|
||||
|
|
@ -182,7 +182,7 @@ const ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => {
|
|||
textAlign={textAlign}>
|
||||
{prefix && !isHidden(values) && (
|
||||
<PrefixComponent
|
||||
className={classes.prefix}
|
||||
className={moduleStyles.prefix}
|
||||
style={isEditing ? {} : textStyle(values, isEditing)}>
|
||||
{typeof prefix === 'function' ? prefix(f) : prefix}
|
||||
</PrefixComponent>
|
||||
|
|
@ -200,7 +200,7 @@ const ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => {
|
|||
)}
|
||||
{suffix && !isHidden(values) && (
|
||||
<SuffixComponent
|
||||
className={classes.suffix}
|
||||
className={moduleStyles.suffix}
|
||||
style={isEditing ? {} : textStyle(values, isEditing)}>
|
||||
{suffix}
|
||||
</SuffixComponent>
|
||||
|
|
@ -241,8 +241,6 @@ const ERow = ({ editing, disabled, lastOfGroup, newRow }) => {
|
|||
stripeWhen
|
||||
} = useContext(TableCtx)
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const shouldStripe = !editing && stripeWhen && stripeWhen(values)
|
||||
|
||||
const innerElements = shouldStripe ? groupStriped(elements) : elements
|
||||
|
|
@ -261,7 +259,7 @@ const ERow = ({ editing, disabled, lastOfGroup, newRow }) => {
|
|||
)
|
||||
|
||||
const classNames = {
|
||||
[classes.lastOfGroup]: lastOfGroup
|
||||
[moduleStyles.lastOfGroup]: lastOfGroup
|
||||
}
|
||||
|
||||
const touchedErrors = R.pick(R.keys(touched), errors)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
.saveButton {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.lastOfGroup {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.extraPadding {
|
||||
padding-left: 35px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
.extraPaddingRight {
|
||||
padding-right: 39px;
|
||||
}
|
||||
|
||||
.suffix {
|
||||
margin: 0 0 0 7px;
|
||||
}
|
||||
|
||||
.prefix {
|
||||
margin: 0 7px 0 0;
|
||||
}
|
||||
|
||||
.fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
import { bySize, bold } from 'src/styling/helpers'
|
||||
|
||||
export default {
|
||||
saveButton: {
|
||||
marginRight: 20
|
||||
},
|
||||
lastOfGroup: {
|
||||
marginBottom: 24
|
||||
},
|
||||
extraPadding: {
|
||||
paddingLeft: 35,
|
||||
paddingRight: 30
|
||||
},
|
||||
extraPaddingRight: {
|
||||
paddingRight: 39
|
||||
},
|
||||
withSuffix: ({ textAlign }) => {
|
||||
const justifyContent = textAlign === 'right' ? 'flex-end' : textAlign
|
||||
return {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent
|
||||
}
|
||||
},
|
||||
suffix: {
|
||||
margin: [[0, 0, 0, 7]]
|
||||
},
|
||||
withPrefix: ({ textAlign }) => {
|
||||
const justifyContent = textAlign === 'right' ? 'flex-end' : textAlign
|
||||
return {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent
|
||||
}
|
||||
},
|
||||
prefix: {
|
||||
margin: [[0, 7, 0, 0]]
|
||||
},
|
||||
size: ({ size }) => bySize(size),
|
||||
bold,
|
||||
fields: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import { Form, Formik } from 'formik'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
|
|
@ -13,13 +12,11 @@ import { AddButton } from 'src/components/buttons/index'
|
|||
import TableCtx from './Context'
|
||||
import Header from './Header'
|
||||
import ERow from './Row'
|
||||
import styles from './Table.styles'
|
||||
import classes from './Table.module.css'
|
||||
|
||||
const ACTION_COL_SIZE = 87
|
||||
const DEFAULT_COL_SIZE = 100
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const getWidth = R.compose(
|
||||
R.reduce(R.add)(0),
|
||||
R.map(it => it.width ?? DEFAULT_COL_SIZE)
|
||||
|
|
@ -129,8 +126,6 @@ const ETable = ({
|
|||
|
||||
const width = getWidth(elements) + actionColSize
|
||||
|
||||
const classes = useStyles({ width })
|
||||
|
||||
const showButtonOnEmpty = !data.length && enableCreate && !adding
|
||||
const canAdd = !forceDisable && !editingId && !disableAdd && !adding
|
||||
const showTable = adding || data.length !== 0
|
||||
|
|
@ -162,7 +157,7 @@ const ETable = ({
|
|||
|
||||
return (
|
||||
<TableCtx.Provider value={ctxValue}>
|
||||
<div className={classes.wrapper}>
|
||||
<div style={{ width }}>
|
||||
{showButtonOnEmpty && canAdd && (
|
||||
<AddButton onClick={addField}>{createText}</AddButton>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
.addLink {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
color: var(--comet);
|
||||
}
|
||||
|
||||
.outerHeader {
|
||||
min-height: 16px;
|
||||
margin-bottom: 24px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import { offColor } from 'src/styling/variables'
|
||||
|
||||
export default {
|
||||
wrapper: ({ width }) => ({
|
||||
width: width
|
||||
}),
|
||||
addLink: {
|
||||
marginLeft: 'auto'
|
||||
},
|
||||
title: {
|
||||
margin: 0,
|
||||
color: offColor
|
||||
},
|
||||
outerHeader: {
|
||||
minHeight: 16,
|
||||
marginBottom: 24,
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center'
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,10 @@
|
|||
import Card from '@mui/material/Card'
|
||||
import CardContent from '@mui/material/CardContent'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React from 'react'
|
||||
|
||||
import { Link } from 'src/components/buttons'
|
||||
|
||||
import styles from './Table.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import styles from './Table.module.css'
|
||||
|
||||
const Table = ({ children, className, ...props }) => (
|
||||
<div className={classnames(className)} {...props}>
|
||||
|
|
@ -17,17 +13,12 @@ const Table = ({ children, className, ...props }) => (
|
|||
)
|
||||
|
||||
const THead = ({ children, className }) => {
|
||||
const classes = useStyles()
|
||||
return <div className={classnames(className, classes.header)}>{children}</div>
|
||||
return <div className={classnames(className, styles.header)}>{children}</div>
|
||||
}
|
||||
|
||||
const TDoubleLevelHead = ({ children, className }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<div className={classnames(className, classes.doubleHeader)}>
|
||||
{children}
|
||||
</div>
|
||||
<div className={classnames(className, styles.doubleHeader)}>{children}</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -36,6 +27,7 @@ const TBody = ({ children, className }) => {
|
|||
}
|
||||
|
||||
const Td = ({
|
||||
style = {},
|
||||
children,
|
||||
header,
|
||||
className,
|
||||
|
|
@ -45,15 +37,28 @@ const Td = ({
|
|||
textAlign,
|
||||
action
|
||||
}) => {
|
||||
const classes = useStyles({ textAlign, width, size })
|
||||
const classNames = {
|
||||
[classes.td]: true,
|
||||
[classes.tdHeader]: header,
|
||||
[classes.actionCol]: action,
|
||||
[classes.size]: !header,
|
||||
[classes.bold]: !header && bold
|
||||
const inlineStyle = {
|
||||
...style,
|
||||
width,
|
||||
textAlign,
|
||||
fontSize: size === 'sm' ? '14px' : size === 'lg' ? '24px' : ''
|
||||
}
|
||||
return <div data-cy={`td-${header}`} className={classnames(className, classNames)}>{children}</div>
|
||||
|
||||
const cssClasses = {
|
||||
[styles.td]: !header,
|
||||
[styles.tdHeader]: header,
|
||||
'font-bold': !header && (bold || size === 'lg'),
|
||||
[styles.actionCol]: action
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
data-cy={`td-${header}`}
|
||||
className={classnames(className, cssClasses)}
|
||||
style={inlineStyle}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const Th = ({ children, ...props }) => {
|
||||
|
|
@ -65,11 +70,11 @@ const Th = ({ children, ...props }) => {
|
|||
}
|
||||
|
||||
const ThDoubleLevel = ({ title, children, className, width }) => {
|
||||
const classes = useStyles({ width })
|
||||
|
||||
return (
|
||||
<div className={classnames(className, classes.thDoubleLevel)}>
|
||||
<div>{title}</div>
|
||||
<div
|
||||
className={classnames(className, styles.thDoubleLevel)}
|
||||
style={{ width }}>
|
||||
<div className={styles.thDoubleLevelFirst}>{title}</div>
|
||||
<div>{children}</div>
|
||||
</div>
|
||||
)
|
||||
|
|
@ -85,23 +90,30 @@ const Tr = ({
|
|||
size,
|
||||
newRow
|
||||
}) => {
|
||||
const classes = useStyles({ size })
|
||||
const cardClasses = { root: classes.cardContentRoot }
|
||||
const classNames = {
|
||||
[classes.tr]: true,
|
||||
[classes.trError]: error,
|
||||
[classes.card]: true,
|
||||
[classes.trAdding]: newRow,
|
||||
className
|
||||
const inlineStyle = {
|
||||
minHeight: size === 'sm' ? '34px' : size === 'lg' ? '68px' : '48px'
|
||||
}
|
||||
const cardClasses = {
|
||||
[styles.card]: true,
|
||||
[styles.trError]: error,
|
||||
[styles.trAdding]: newRow
|
||||
}
|
||||
|
||||
const mainContentClasses = {
|
||||
[styles.mainContent]: true,
|
||||
[styles.sizeSm]: size === 'sm',
|
||||
[styles.sizeLg]: size === 'lg'
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card className={classnames(classNames, className)} onClick={onClick}>
|
||||
<CardContent classes={cardClasses}>
|
||||
<div className={classes.mainContent}>{children}</div>
|
||||
<Card className={classnames(className, cardClasses)} onClick={onClick}>
|
||||
<CardContent className={styles.cardContentRoot}>
|
||||
<div className={classnames(mainContentClasses)} style={inlineStyle}>
|
||||
{children}
|
||||
</div>
|
||||
{error && shouldShowError && (
|
||||
<div className={classes.errorContent}>{errorMessage}</div>
|
||||
<div className={styles.errorContent}>{errorMessage}</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
|
|
|||
106
new-lamassu-admin/src/components/fake-table/Table.module.css
Normal file
106
new-lamassu-admin/src/components/fake-table/Table.module.css
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
.header {
|
||||
composes: tl2 from '../typography/typography.module.css';
|
||||
background-color: var(--zodiac);
|
||||
height: 32px;
|
||||
text-align: left;
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.doubleHeader {
|
||||
composes: tl2 from '../typography/typography.module.css';
|
||||
background-color: var(--zodiac);
|
||||
height: 64px;
|
||||
color: white;
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.thDoubleLevel {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.thDoubleLevelFirst {
|
||||
composes: label1 from '../typography/typography.module.css';
|
||||
margin: 0 10px;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: var(--comet);
|
||||
color: white;
|
||||
border-radius: 0 0 8px 8px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.thDoubleLevel > :last-child {
|
||||
padding: 0 11px;
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.cellDoubleLevel {
|
||||
display: flex;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.td {
|
||||
padding: 1px 24px 0 24px;
|
||||
}
|
||||
|
||||
.tdHeader {
|
||||
vertical-align: middle;
|
||||
display: table-cell;
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.trError {
|
||||
background-color: var(--misty-rose);
|
||||
}
|
||||
|
||||
.trAdding {
|
||||
background-color: var(--spring3);
|
||||
}
|
||||
|
||||
.mainContent {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cardContentRoot {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.cardContentRoot:last-child {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.card {
|
||||
composes: p from '../typography/typography.module.css';
|
||||
margin: 4px 0 0 0;
|
||||
width: 100%;
|
||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.card:before {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.actionCol {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.errorContent {
|
||||
padding: 12px 0 12px 24px;
|
||||
color: var(--tomato);
|
||||
}
|
||||
|
||||
.sizeSm {
|
||||
min-height: 34px;
|
||||
}
|
||||
|
||||
.sizeLg {
|
||||
min-height: 68px;
|
||||
}
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
import typographyStyles from 'src/components/typography/styles'
|
||||
import { bySize, bold } from 'src/styling/helpers'
|
||||
import {
|
||||
tableHeaderColor,
|
||||
tableHeaderHeight,
|
||||
tableErrorColor,
|
||||
tableSuccessColor,
|
||||
spacer,
|
||||
white,
|
||||
tableDoubleHeaderHeight,
|
||||
offColor,
|
||||
errorColor
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const { tl2, p, label1 } = typographyStyles
|
||||
|
||||
export default {
|
||||
size: ({ size }) => bySize(size),
|
||||
bold,
|
||||
header: {
|
||||
extend: tl2,
|
||||
backgroundColor: tableHeaderColor,
|
||||
height: tableHeaderHeight,
|
||||
textAlign: 'left',
|
||||
color: white,
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
},
|
||||
doubleHeader: {
|
||||
extend: tl2,
|
||||
backgroundColor: tableHeaderColor,
|
||||
height: tableDoubleHeaderHeight,
|
||||
color: white,
|
||||
display: 'table-row'
|
||||
},
|
||||
thDoubleLevel: ({ width }) => ({
|
||||
width,
|
||||
display: 'table-cell',
|
||||
'& > :first-child': {
|
||||
margin: [[0, 10]],
|
||||
extend: label1,
|
||||
fontWeight: 700,
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: offColor,
|
||||
color: white,
|
||||
borderRadius: [[0, 0, 8, 8]],
|
||||
height: 28
|
||||
},
|
||||
'& > :last-child': {
|
||||
padding: [[0, 11]],
|
||||
display: 'table-cell',
|
||||
verticalAlign: 'middle',
|
||||
height: tableDoubleHeaderHeight - 28
|
||||
}
|
||||
}),
|
||||
cellDoubleLevel: {
|
||||
display: 'flex',
|
||||
padding: [[0, spacer * 2]]
|
||||
},
|
||||
td: ({ textAlign, width }) => ({
|
||||
width,
|
||||
padding: [[1, spacer * 3, 0, spacer * 3]],
|
||||
textAlign
|
||||
}),
|
||||
tdHeader: {
|
||||
verticalAlign: 'middle',
|
||||
display: 'table-cell',
|
||||
padding: [[0, spacer * 3]]
|
||||
},
|
||||
trError: {
|
||||
backgroundColor: tableErrorColor
|
||||
},
|
||||
trAdding: {
|
||||
backgroundColor: tableSuccessColor
|
||||
},
|
||||
mainContent: ({ size }) => {
|
||||
const sizes = {
|
||||
sm: 34,
|
||||
lg: 68
|
||||
}
|
||||
const minHeight = sizes[size] || 48
|
||||
return {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
minHeight
|
||||
}
|
||||
},
|
||||
// mui-overrides
|
||||
cardContentRoot: {
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
'&:last-child': {
|
||||
padding: 0
|
||||
}
|
||||
},
|
||||
card: {
|
||||
extend: p,
|
||||
'&:before': {
|
||||
height: 0
|
||||
},
|
||||
margin: [[4, 0, 0, 0]],
|
||||
width: '100%',
|
||||
boxShadow: [[0, 0, 4, 0, 'rgba(0, 0, 0, 0.08)']]
|
||||
},
|
||||
actionCol: {
|
||||
marginLeft: 'auto'
|
||||
},
|
||||
errorContent: {
|
||||
padding: [[12, 0, 12, 24]],
|
||||
color: errorColor
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,11 @@
|
|||
import Box from '@mui/material/Box'
|
||||
import MAutocomplete from '@mui/material/Autocomplete'
|
||||
import classnames from 'classnames'
|
||||
import sort from 'match-sorter'
|
||||
import * as R from 'ramda'
|
||||
import React from 'react'
|
||||
import { HoverableTooltip } from 'src/components/Tooltip'
|
||||
import { P } from 'src/components/typography'
|
||||
|
||||
import { errorColor, orangeYellow, spring4 } from 'src/styling/variables'
|
||||
|
||||
import TextInput from './TextInput'
|
||||
|
||||
const Autocomplete = ({
|
||||
|
|
@ -82,7 +80,6 @@ const Autocomplete = ({
|
|||
openOnFocus
|
||||
autoHighlight
|
||||
disableClearable
|
||||
ChipProps={{ onDelete: null }}
|
||||
clearOnEscape
|
||||
isOptionEqualToValue={R.eqProps(valueProp)}
|
||||
{...props}
|
||||
|
|
@ -104,39 +101,30 @@ const Autocomplete = ({
|
|||
if (!props.warning && !props.warningMessage)
|
||||
return <li {...iprops}>{R.path([labelProp])(props)}</li>
|
||||
|
||||
const warningColors = {
|
||||
clean: spring4,
|
||||
partial: orangeYellow,
|
||||
important: errorColor
|
||||
const className = {
|
||||
'flex w-4 h-4 rounded-md': true,
|
||||
'bg-spring4': props.warning === 'clean',
|
||||
'bg-orange-yellow': props.warning === 'partial',
|
||||
'bg-tomato': props.warning === 'important'
|
||||
}
|
||||
|
||||
const hoverableElement = (
|
||||
<Box
|
||||
width={18}
|
||||
height={18}
|
||||
borderRadius="6px"
|
||||
bgcolor={warningColors[props.warning]}
|
||||
/>
|
||||
)
|
||||
const hoverableElement = <div className={classnames(className)} />
|
||||
|
||||
return (
|
||||
<li {...iprops}>
|
||||
<Box
|
||||
width="100%"
|
||||
display="flex"
|
||||
flexDirection="row"
|
||||
justifyContent="space-between"
|
||||
alignItems="center">
|
||||
<Box>{R.path([labelProp])(props)}</Box>
|
||||
<div className="flex flex-row justify-between items-center w-full">
|
||||
<div className="flex">{R.path([labelProp])(props)}</div>
|
||||
<HoverableTooltip parentElements={hoverableElement} width={250}>
|
||||
<P>{props.warningMessage}</P>
|
||||
</HoverableTooltip>
|
||||
</Box>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
slotProps={{
|
||||
chip: { onDelete: null }
|
||||
}} />
|
||||
);
|
||||
}
|
||||
|
||||
export default Autocomplete
|
||||
|
|
|
|||
|
|
@ -1,60 +1,22 @@
|
|||
import Checkbox from '@mui/material/Checkbox'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import CheckBoxIcon from '@mui/icons-material/CheckBox'
|
||||
import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'
|
||||
import React from 'react'
|
||||
import { Label2, Info3 } from 'src/components/typography'
|
||||
import WarningIcon from 'src/styling/icons/warning-icon/comet.svg?react'
|
||||
|
||||
import {
|
||||
fontSize2,
|
||||
fontSize3,
|
||||
secondaryColor,
|
||||
offColor
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
root: {
|
||||
color: secondaryColor,
|
||||
'&.Mui-checked': {
|
||||
color: secondaryColor
|
||||
}
|
||||
},
|
||||
checked: {},
|
||||
checkBoxLabel: {
|
||||
display: 'flex'
|
||||
},
|
||||
wrapper: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
'& > svg': {
|
||||
marginRight: 10
|
||||
}
|
||||
},
|
||||
message: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
color: offColor,
|
||||
margin: 0,
|
||||
whiteSpace: 'break-spaces'
|
||||
}
|
||||
})
|
||||
import { fontSize2, fontSize3 } from 'src/styling/variables'
|
||||
|
||||
const CheckboxInput = ({ name, onChange, value, settings, ...props }) => {
|
||||
const { enabled, label, disabledMessage, rightSideLabel } = settings
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<>
|
||||
{enabled ? (
|
||||
<div className={classes.checkBoxLabel}>
|
||||
<div className="flex">
|
||||
{!rightSideLabel && <Label2>{label}</Label2>}
|
||||
<Checkbox
|
||||
id={name}
|
||||
classes={{
|
||||
root: classes.root,
|
||||
checked: classes.checked
|
||||
}}
|
||||
onChange={onChange}
|
||||
value={value}
|
||||
checked={value}
|
||||
|
|
@ -70,9 +32,11 @@ const CheckboxInput = ({ name, onChange, value, settings, ...props }) => {
|
|||
{rightSideLabel && <Label2>{label}</Label2>}
|
||||
</div>
|
||||
) : (
|
||||
<div className={classes.wrapper}>
|
||||
<div className="flex items-center gap-2">
|
||||
<WarningIcon />
|
||||
<Info3 className={classes.message}>{disabledMessage}</Info3>
|
||||
<Info3 className="flex items-center text-comet m-0 whitespace-break-spaces">
|
||||
{disabledMessage}
|
||||
</Info3>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,8 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React from 'react'
|
||||
import OtpInput from 'react-otp-input'
|
||||
|
||||
import typographyStyles from 'src/components/typography/styles'
|
||||
|
||||
import styles from './CodeInput.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
const useTypographyStyles = makeStyles(typographyStyles)
|
||||
import classes from './CodeInput.module.css'
|
||||
|
||||
const CodeInput = ({
|
||||
name,
|
||||
|
|
@ -19,9 +13,6 @@ const CodeInput = ({
|
|||
inputStyle,
|
||||
containerStyle
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
const typographyClasses = useTypographyStyles()
|
||||
|
||||
return (
|
||||
<OtpInput
|
||||
id={name}
|
||||
|
|
@ -30,19 +21,15 @@ const CodeInput = ({
|
|||
numInputs={numInputs}
|
||||
renderSeparator={<span> </span>}
|
||||
shouldAutoFocus
|
||||
containerStyle={classnames(containerStyle, classes.container)}
|
||||
containerStyle={classnames(containerStyle, 'justify-evenly')}
|
||||
inputStyle={classnames(
|
||||
inputStyle,
|
||||
classes.input,
|
||||
typographyClasses.confirmationCode,
|
||||
error && classes.error
|
||||
'font-museo font-black text-4xl',
|
||||
error && 'border-tomato'
|
||||
)}
|
||||
inputType={'tel'}
|
||||
renderInput={(props) => (
|
||||
<input
|
||||
{...props}
|
||||
/>
|
||||
)}
|
||||
renderInput={props => <input {...props} />}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
.input {
|
||||
width: 3.5rem !important;
|
||||
height: 5rem;
|
||||
border: 2px solid;
|
||||
border-color: var(--zircon);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.input:focus {
|
||||
border: 2px solid;
|
||||
border-color: var(--zodiac);
|
||||
border-radius: 4px;
|
||||
outline: none;
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
import { primaryColor, zircon, errorColor } from 'src/styling/variables'
|
||||
|
||||
const styles = {
|
||||
input: {
|
||||
width: '3.5rem !important',
|
||||
height: '5rem',
|
||||
border: '2px solid',
|
||||
borderColor: zircon,
|
||||
borderRadius: '4px',
|
||||
'&:focus': {
|
||||
border: '2px solid',
|
||||
borderColor: primaryColor,
|
||||
borderRadius: '4px',
|
||||
'&:focus': {
|
||||
outline: 'none'
|
||||
}
|
||||
},
|
||||
},
|
||||
error: {
|
||||
borderColor: errorColor
|
||||
},
|
||||
container: {
|
||||
justifyContent: 'space-evenly'
|
||||
}
|
||||
}
|
||||
|
||||
export default styles
|
||||
|
|
@ -1,31 +1,10 @@
|
|||
import Radio from '@mui/material/Radio'
|
||||
import MRadioGroup from '@mui/material/RadioGroup'
|
||||
import FormControlLabel from '@mui/material/FormControlLabel'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React from 'react'
|
||||
import { Label1 } from 'src/components/typography'
|
||||
|
||||
import { offColor, secondaryColor } from 'src/styling/variables'
|
||||
const styles = {
|
||||
label: {
|
||||
height: 16,
|
||||
lineHeight: '16px',
|
||||
margin: [[0, 0, 4, 0]],
|
||||
paddingLeft: 3
|
||||
},
|
||||
subtitle: {
|
||||
marginTop: -8,
|
||||
marginLeft: 32,
|
||||
color: offColor
|
||||
},
|
||||
radio: {
|
||||
color: secondaryColor
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const RadioGroup = ({
|
||||
name,
|
||||
label,
|
||||
|
|
@ -36,10 +15,11 @@ const RadioGroup = ({
|
|||
labelClassName,
|
||||
radioClassName
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
return (
|
||||
<>
|
||||
{label && <Label1 className={classes.label}>{label}</Label1>}
|
||||
{label && (
|
||||
<Label1 className="h-4 leading-4 m-0 mb-1 pl-1">{label}</Label1>
|
||||
)}
|
||||
<MRadioGroup
|
||||
name={name}
|
||||
value={value}
|
||||
|
|
@ -51,12 +31,16 @@ const RadioGroup = ({
|
|||
<FormControlLabel
|
||||
disabled={option.disabled}
|
||||
value={option.code}
|
||||
control={<Radio className={classnames(classes.radio, radioClassName)} />}
|
||||
control={
|
||||
<Radio
|
||||
className={classnames('text-spring', radioClassName)}
|
||||
/>
|
||||
}
|
||||
label={option.display}
|
||||
className={classnames(labelClassName)}
|
||||
/>
|
||||
{option.subtitle && (
|
||||
<Label1 className={classes.subtitle}>{option.subtitle}</Label1>
|
||||
<Label1 className="-mt-2 ml-8">{option.subtitle}</Label1>
|
||||
)}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,12 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import { useSelect } from 'downshift'
|
||||
import * as R from 'ramda'
|
||||
import React from 'react'
|
||||
import Arrowdown from 'src/styling/icons/action/arrow/regular.svg?react'
|
||||
|
||||
import styles from './Select.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import styles from './Select.module.css'
|
||||
|
||||
function Select({ className, label, items, ...props }) {
|
||||
const classes = useStyles()
|
||||
|
||||
const {
|
||||
isOpen,
|
||||
|
|
@ -28,18 +24,18 @@ function Select({ className, label, items, ...props }) {
|
|||
})
|
||||
|
||||
const selectClassNames = {
|
||||
[classes.select]: true,
|
||||
[classes.selectFiltered]: props.defaultAsFilter
|
||||
[styles.select]: true,
|
||||
[styles.selectFiltered]: props.defaultAsFilter
|
||||
? true
|
||||
: !R.equals(selectedItem, props.default),
|
||||
[classes.open]: isOpen
|
||||
[styles.open]: isOpen
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classnames(selectClassNames, className)}>
|
||||
<label {...getLabelProps()}>{label}</label>
|
||||
<button {...getToggleButtonProps()}>
|
||||
<span className={classes.selectedItem}>{selectedItem.display}</span>
|
||||
<span className={styles.selectedItem}>{selectedItem.display}</span>
|
||||
<Arrowdown />
|
||||
</button>
|
||||
<ul {...getMenuProps()}>
|
||||
|
|
|
|||
100
new-lamassu-admin/src/components/inputs/base/Select.module.css
Normal file
100
new-lamassu-admin/src/components/inputs/base/Select.module.css
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
.selectedItem {
|
||||
width: 111px;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.select {
|
||||
width: 152px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.select label {
|
||||
font-size: 13px;
|
||||
font-family: var(--museo);
|
||||
font-weight: 500;
|
||||
color: var(--comet);
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.select button {
|
||||
font-size: 14px;
|
||||
font-family: var(--museo);
|
||||
font-weight: 500;
|
||||
position: relative;
|
||||
border: 0;
|
||||
background-color: var(--zircon);
|
||||
width: 152px;
|
||||
padding: 6px 0 6px 12px;
|
||||
border-radius: 20px;
|
||||
line-height: 1.14;
|
||||
text-align: left;
|
||||
color: var(--comet);
|
||||
cursor: pointer;
|
||||
outline: 0 none;
|
||||
}
|
||||
|
||||
.select ul {
|
||||
max-height: 200px;
|
||||
width: 152px;
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
border-top: 0;
|
||||
padding: 0;
|
||||
border-radius: 0 0 8px 8px;
|
||||
background-color: var(--zircon);
|
||||
outline: 0 none;
|
||||
}
|
||||
|
||||
.select ul li {
|
||||
font-size: 14px;
|
||||
font-family: var(--museo);
|
||||
font-weight: 500;
|
||||
list-style-type: none;
|
||||
padding: 6px 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.select ul li span {
|
||||
width: 100%;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.select ul li:hover {
|
||||
background-color: var(--comet);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.select svg {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 14px;
|
||||
fill: var(--comet);
|
||||
}
|
||||
|
||||
.selectFiltered button {
|
||||
background-color: var(--comet);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.selectFiltered ul li {
|
||||
background-color: var(--comet);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.selectFiltered ul li:hover {
|
||||
background-color: var(--zircon);
|
||||
color: var(--comet);
|
||||
}
|
||||
|
||||
.selectFiltered svg {
|
||||
fill: white !important;
|
||||
}
|
||||
|
||||
.open button {
|
||||
border-radius: 8px 8px 0 0;
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
import { subheaderColor, offColor, white } from '../../../styling/variables'
|
||||
import typographyStyles from '../../typography/styles'
|
||||
|
||||
const { p, label1 } = typographyStyles
|
||||
|
||||
const WIDTH = 152
|
||||
|
||||
export default {
|
||||
selectedItem: {
|
||||
width: WIDTH - 41,
|
||||
display: 'block',
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden'
|
||||
},
|
||||
select: {
|
||||
width: WIDTH,
|
||||
zIndex: 1,
|
||||
'& label': {
|
||||
extend: label1,
|
||||
color: offColor,
|
||||
paddingLeft: 10
|
||||
},
|
||||
'& button': {
|
||||
extend: p,
|
||||
position: 'relative',
|
||||
border: 0,
|
||||
backgroundColor: subheaderColor,
|
||||
width: WIDTH,
|
||||
padding: [[6, 0, 6, 12]],
|
||||
borderRadius: 20,
|
||||
lineHeight: '1.14',
|
||||
textAlign: 'left',
|
||||
color: offColor,
|
||||
cursor: 'pointer',
|
||||
outline: '0 none'
|
||||
},
|
||||
'& ul': {
|
||||
maxHeight: '200px',
|
||||
width: WIDTH,
|
||||
overflowY: 'auto',
|
||||
position: 'absolute',
|
||||
margin: 0,
|
||||
borderTop: 0,
|
||||
padding: 0,
|
||||
borderRadius: [[0, 0, 8, 8]],
|
||||
backgroundColor: subheaderColor,
|
||||
outline: '0 none',
|
||||
'& li': {
|
||||
extend: p,
|
||||
listStyleType: 'none',
|
||||
padding: [[6, 12]],
|
||||
cursor: 'pointer',
|
||||
'& span': {
|
||||
width: '100%',
|
||||
display: 'block',
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap'
|
||||
}
|
||||
},
|
||||
'& li:hover': {
|
||||
backgroundColor: offColor,
|
||||
color: white
|
||||
}
|
||||
},
|
||||
'& svg': {
|
||||
position: 'absolute',
|
||||
top: 12,
|
||||
right: 14,
|
||||
fill: offColor
|
||||
}
|
||||
},
|
||||
selectFiltered: {
|
||||
'& button': {
|
||||
backgroundColor: offColor,
|
||||
color: white
|
||||
},
|
||||
'& ul': {
|
||||
'& li': {
|
||||
backgroundColor: offColor,
|
||||
color: white
|
||||
},
|
||||
'& li:hover': {
|
||||
backgroundColor: subheaderColor,
|
||||
color: offColor
|
||||
}
|
||||
},
|
||||
'& svg': {
|
||||
fill: [[white], '!important']
|
||||
}
|
||||
},
|
||||
open: {
|
||||
'& button': {
|
||||
borderRadius: [[8, 8, 0, 0]]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,9 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import TextField from '@mui/material/TextField'
|
||||
import classnames from 'classnames'
|
||||
import * as R from 'ramda'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import styles from './TextInput.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import styles from './TextInput.module.css'
|
||||
|
||||
const TextInput = memo(
|
||||
({
|
||||
|
|
@ -19,6 +16,7 @@ const TextInput = memo(
|
|||
suffix,
|
||||
textAlign,
|
||||
width,
|
||||
inputClasses,
|
||||
// lg or sm
|
||||
size,
|
||||
bold,
|
||||
|
|
@ -26,11 +24,23 @@ const TextInput = memo(
|
|||
InputProps,
|
||||
...props
|
||||
}) => {
|
||||
const classes = useStyles({ textAlign, width, size })
|
||||
const isTextFilled = !error && !R.isNil(value) && !R.isEmpty(value)
|
||||
const filled = isPasswordFilled || isTextFilled
|
||||
const inputClasses = {
|
||||
[classes.bold]: bold
|
||||
|
||||
const style = {
|
||||
width: width,
|
||||
textAlign: textAlign
|
||||
}
|
||||
|
||||
const sizeClass =
|
||||
size === 'sm'
|
||||
? styles.sizeSm
|
||||
: size === 'lg'
|
||||
? styles.sizeLg
|
||||
: styles.size
|
||||
|
||||
const divClass = {
|
||||
[styles.bold]: bold
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
@ -41,17 +51,22 @@ const TextInput = memo(
|
|||
onBlur={onBlur}
|
||||
error={error}
|
||||
value={value}
|
||||
classes={{ root: classes.root }}
|
||||
className={className}
|
||||
InputProps={{
|
||||
className: classnames(inputClasses),
|
||||
classes: {
|
||||
root: classes.size,
|
||||
underline: filled ? classes.underline : null
|
||||
style={style}
|
||||
{...props}
|
||||
slotProps={{
|
||||
input: {
|
||||
className: classnames(divClass),
|
||||
classes: {
|
||||
root: sizeClass,
|
||||
underline: filled ? styles.underline : null,
|
||||
input: inputClasses
|
||||
},
|
||||
...InputProps
|
||||
},
|
||||
...InputProps
|
||||
}}
|
||||
{...props} />
|
||||
|
||||
htmlInput: { style: { textAlign } }
|
||||
}} />
|
||||
);
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
.size {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.sizeSm {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.sizeLg {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.underline:before {
|
||||
border-bottom-color: var(--spring);
|
||||
}
|
||||
|
||||
.underline:hover:not(.Mui-disabled)::before {
|
||||
border-bottom-color: var(--spring);
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
import { bySize, bold } from 'src/styling/helpers'
|
||||
import { secondaryColor } from 'src/styling/variables'
|
||||
|
||||
export default {
|
||||
size: ({ size }) => ({
|
||||
marginTop: size === 'lg' ? 0 : 2,
|
||||
...bySize(size)
|
||||
}),
|
||||
bold,
|
||||
root: ({ width, textAlign }) => ({
|
||||
width,
|
||||
'& input': {
|
||||
textAlign
|
||||
}
|
||||
}),
|
||||
underline: {
|
||||
'&:before': {
|
||||
borderBottomColor: secondaryColor
|
||||
},
|
||||
'&:hover:not(.Mui-disabled)::before': {
|
||||
borderBottomColor: secondaryColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +1,8 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import MUIToggleButtonGroup from '@mui/material/ToggleButtonGroup'
|
||||
import ToggleButton from '@mui/material/ToggleButton'
|
||||
import React from 'react'
|
||||
import { H4, P } from 'src/components/typography'
|
||||
|
||||
import { backgroundColor, comet } from 'src/styling/variables'
|
||||
const styles = {
|
||||
noTextTransform: {
|
||||
textTransform: 'none'
|
||||
},
|
||||
flex: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'start',
|
||||
width: '90%',
|
||||
overflow: 'hidden',
|
||||
maxHeight: 80
|
||||
},
|
||||
buttonTextContent: {
|
||||
marginLeft: 32,
|
||||
textTransform: 'none',
|
||||
textAlign: 'left'
|
||||
},
|
||||
button: {
|
||||
backgroundColor: backgroundColor,
|
||||
marginBottom: 16
|
||||
},
|
||||
paragraph: {
|
||||
color: comet,
|
||||
marginTop: -10
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
const ToggleButtonGroup = ({
|
||||
name,
|
||||
orientation = 'vertical',
|
||||
|
|
@ -42,7 +12,6 @@ const ToggleButtonGroup = ({
|
|||
size = 'small',
|
||||
...props
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
return (
|
||||
<MUIToggleButtonGroup
|
||||
size={size}
|
||||
|
|
@ -54,15 +23,15 @@ const ToggleButtonGroup = ({
|
|||
{props.options.map(option => {
|
||||
return (
|
||||
<ToggleButton
|
||||
className={classes.button}
|
||||
className="bg-ghost"
|
||||
value={option.value}
|
||||
aria-label={option.value}
|
||||
key={option.value}>
|
||||
<div className={classes.flex}>
|
||||
<div className="flex items-center justify-start w-9/10 overflow-hidden max-h-20">
|
||||
<option.icon />
|
||||
<div className={classes.buttonTextContent}>
|
||||
<div className="ml-8 normal-case text-left">
|
||||
<H4>{option.title}</H4>
|
||||
<P className={classes.paragraph}> {option.description}</P>
|
||||
<P className="text-comet -mt-2"> {option.description}</P>
|
||||
</div>
|
||||
</div>
|
||||
</ToggleButton>
|
||||
|
|
|
|||
|
|
@ -1,54 +1,59 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import Chip from '@mui/material/Chip'
|
||||
import classnames from 'classnames'
|
||||
import React from 'react'
|
||||
import Chip from 'src/components/Chip'
|
||||
import { Info2, Label1, Label2 } from 'src/components/typography'
|
||||
|
||||
import { numberToFiatAmount } from 'src/utils/number'
|
||||
|
||||
import { cashboxStyles, gridStyles } from './Cashbox.styles'
|
||||
import classes from './Cashbox.module.css'
|
||||
import { primaryColor as zodiac, tomato } from '../../../styling/variables.js'
|
||||
|
||||
const cashboxClasses = makeStyles(cashboxStyles)
|
||||
const gridClasses = makeStyles(gridStyles)
|
||||
const colors = {
|
||||
cashOut: {
|
||||
empty: tomato,
|
||||
full: zodiac
|
||||
},
|
||||
cashIn: {
|
||||
empty: zodiac,
|
||||
full: tomato
|
||||
}
|
||||
}
|
||||
|
||||
const Cashbox = ({
|
||||
percent = 0,
|
||||
cashOut = false,
|
||||
width,
|
||||
height,
|
||||
width = 80,
|
||||
height = 118,
|
||||
className,
|
||||
emptyPartClassName,
|
||||
labelClassName,
|
||||
applyColorVariant,
|
||||
applyFiatBalanceAlertsStyling,
|
||||
omitInnerPercentage,
|
||||
isLow
|
||||
}) => {
|
||||
const classes = cashboxClasses({
|
||||
percent,
|
||||
cashOut,
|
||||
width,
|
||||
height,
|
||||
applyColorVariant,
|
||||
isLow
|
||||
})
|
||||
const ltHalf = percent <= 51
|
||||
|
||||
const showCashBox = {
|
||||
[classes.fiatBalanceAlertCashbox]: applyFiatBalanceAlertsStyling,
|
||||
[classes.cashbox]: !applyFiatBalanceAlertsStyling
|
||||
}
|
||||
const color =
|
||||
colors[cashOut ? 'cashOut' : 'cashIn'][!isLow ? 'full' : 'empty']
|
||||
|
||||
return (
|
||||
<div className={classnames(className, showCashBox)}>
|
||||
<div className={classnames(emptyPartClassName, classes.emptyPart)}>
|
||||
<div
|
||||
style={{ height, width, backgroundColor: color, borderColor: color }}
|
||||
className={classnames(className, classes.cashbox)}>
|
||||
<div
|
||||
className={classnames(emptyPartClassName, classes.emptyPart)}
|
||||
style={{ height: `${100 - percent}%` }}>
|
||||
{!omitInnerPercentage && ltHalf && (
|
||||
<Label2 className={labelClassName}>{percent.toFixed(0)}%</Label2>
|
||||
<Label2
|
||||
style={{ color }}
|
||||
className={classnames(labelClassName, classes.emptyPartP)}>
|
||||
{percent.toFixed(0)}%
|
||||
</Label2>
|
||||
)}
|
||||
</div>
|
||||
<div className={classes.fullPart}>
|
||||
<div style={{ backgroundColor: color }}>
|
||||
{!omitInnerPercentage && !ltHalf && (
|
||||
<Label2 className={labelClassName}>{percent.toFixed(0)}%</Label2>
|
||||
<Label2 className={classnames(classes.fullPartP, labelClassName)}>
|
||||
{percent.toFixed(0)}%
|
||||
</Label2>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -71,7 +76,6 @@ const CashIn = ({
|
|||
}) => {
|
||||
const percent = (100 * notes) / capacity
|
||||
const isLow = percent < threshold
|
||||
const classes = gridClasses()
|
||||
return (
|
||||
<>
|
||||
<div className={classes.row}>
|
||||
|
|
@ -117,7 +121,6 @@ const CashOut = ({
|
|||
}) => {
|
||||
const percent = (100 * notes) / capacity
|
||||
const isLow = percent < threshold
|
||||
const classes = gridClasses()
|
||||
return (
|
||||
<>
|
||||
<div className={classes.row}>
|
||||
|
|
@ -136,10 +139,7 @@ const CashOut = ({
|
|||
<div className={classes.col2}>
|
||||
<div className={classes.innerRow}>
|
||||
<Info2 className={classes.noMarginText}>{notes}</Info2>
|
||||
<Chip
|
||||
className={classes.chip}
|
||||
label={`${denomination} ${currency.code}`}
|
||||
/>
|
||||
<Chip label={`${denomination} ${currency.code}`} />
|
||||
</div>
|
||||
<div className={classes.innerRow}>
|
||||
<Label1 className={classes.noMarginText}>
|
||||
|
|
@ -163,7 +163,6 @@ const CashOutLite = ({
|
|||
}) => {
|
||||
const percent = (100 * notes) / capacity
|
||||
const isLow = percent < threshold
|
||||
const classes = gridClasses()
|
||||
return (
|
||||
<div className={classes.col}>
|
||||
<Cashbox
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
.row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.innerRow {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.col2 {
|
||||
margin-left: 14px;
|
||||
}
|
||||
|
||||
.noMarginText {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.link {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.fullPartP {
|
||||
color: white;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.emptyPart {
|
||||
background-color: var(--ghost);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.emptyPartP {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.cashbox {
|
||||
border: 2px solid;
|
||||
text-align: end;
|
||||
display: inline-block;
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
import { spacer, tomato, primaryColor as zodiac } from 'src/styling/variables'
|
||||
|
||||
const colors = {
|
||||
cashOut: {
|
||||
empty: tomato,
|
||||
full: zodiac
|
||||
},
|
||||
cashIn: {
|
||||
empty: zodiac,
|
||||
full: tomato
|
||||
}
|
||||
}
|
||||
|
||||
const colorPicker = ({ cashOut, applyColorVariant, isLow }) => {
|
||||
return colors[cashOut ? 'cashOut' : 'cashIn'][
|
||||
applyColorVariant || !isLow ? 'full' : 'empty'
|
||||
]
|
||||
}
|
||||
|
||||
const cashboxStyles = {
|
||||
cashbox: {
|
||||
borderColor: colorPicker,
|
||||
backgroundColor: colorPicker,
|
||||
height: ({ height }) => height ?? 118,
|
||||
width: ({ width }) => width ?? 80,
|
||||
border: '2px solid',
|
||||
textAlign: 'end',
|
||||
display: 'inline-block'
|
||||
},
|
||||
fiatBalanceAlertCashbox: {
|
||||
borderColor: colorPicker,
|
||||
backgroundColor: colorPicker,
|
||||
height: 118,
|
||||
width: 80,
|
||||
border: '4px solid'
|
||||
},
|
||||
emptyPart: {
|
||||
backgroundColor: 'white',
|
||||
height: ({ percent }) => `${100 - percent}%`,
|
||||
position: 'relative',
|
||||
'& > p': {
|
||||
color: colorPicker,
|
||||
display: 'inline-block',
|
||||
position: 'absolute',
|
||||
margin: 0,
|
||||
bottom: 0,
|
||||
right: 0
|
||||
}
|
||||
},
|
||||
fullPart: {
|
||||
backgroundColor: colorPicker,
|
||||
'& > p': {
|
||||
color: 'white',
|
||||
display: 'inline'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const gridStyles = {
|
||||
row: {
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
},
|
||||
col: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center'
|
||||
},
|
||||
innerRow: {
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-start'
|
||||
},
|
||||
col2: {
|
||||
marginLeft: 14
|
||||
},
|
||||
noMarginText: {
|
||||
marginTop: 0,
|
||||
marginBottom: 0
|
||||
},
|
||||
link: {
|
||||
marginTop: spacer
|
||||
},
|
||||
chip: {
|
||||
margin: [[0, 0, 0, 7]]
|
||||
}
|
||||
}
|
||||
|
||||
export { cashboxStyles, gridStyles }
|
||||
|
|
@ -1,30 +1,19 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classNames from 'classnames'
|
||||
import React, { memo, useState } from 'react'
|
||||
import { CashOut } from 'src/components/inputs/cashbox/Cashbox'
|
||||
|
||||
import { NumberInput } from '../base'
|
||||
const useStyles = makeStyles({
|
||||
flex: {
|
||||
display: 'flex'
|
||||
},
|
||||
cashCassette: {
|
||||
height: 36,
|
||||
marginRight: 14
|
||||
}
|
||||
})
|
||||
|
||||
const CashCassetteInput = memo(
|
||||
({ decimalPlaces, width, threshold, inputClassName, ...props }) => {
|
||||
const classes = useStyles()
|
||||
const { name, onChange, onBlur, value } = props.field
|
||||
const { touched, errors } = props.form
|
||||
const [notes, setNotes] = useState(value)
|
||||
const error = !!(touched[name] && errors[name])
|
||||
return (
|
||||
<div className={classes.flex}>
|
||||
<div className="flex">
|
||||
<CashOut
|
||||
className={classNames(classes.cashCassette, inputClassName)}
|
||||
className={classNames('h-9 mr-4', inputClassName)}
|
||||
notes={notes}
|
||||
editingMode={true}
|
||||
width={width}
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
import typographyStyles from 'src/components/typography/styles'
|
||||
import {
|
||||
fontColor,
|
||||
offColor,
|
||||
inputFontSize,
|
||||
inputFontWeight
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const { info3 } = typographyStyles
|
||||
|
||||
const styles = {
|
||||
masked: {
|
||||
position: 'absolute',
|
||||
bottom: 5,
|
||||
left: 4,
|
||||
color: fontColor,
|
||||
fontSize: inputFontSize,
|
||||
fontWeight: inputFontWeight
|
||||
},
|
||||
secretSpan: {
|
||||
extend: info3,
|
||||
color: offColor
|
||||
},
|
||||
hideSpan: {
|
||||
display: 'none'
|
||||
},
|
||||
maskedInput: {
|
||||
'& input': {
|
||||
pointerEvents: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
zIndex: -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { styles }
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import { useQuery, gql } from "@apollo/client";
|
||||
import { useQuery, gql } from '@apollo/client'
|
||||
import ClickAwayListener from '@mui/material/ClickAwayListener'
|
||||
import Popper from '@mui/material/Popper'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import * as R from 'ramda'
|
||||
import React, { memo, useState, useEffect, useRef } from 'react'
|
||||
|
|
@ -16,9 +15,7 @@ import NotificationIcon from 'src/styling/icons/menu/notification.svg?react'
|
|||
import NotificationCenter from 'src/components/NotificationCenter'
|
||||
import AddMachine from 'src/pages/AddMachine'
|
||||
|
||||
import styles from './Header.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import styles from './Header.module.css'
|
||||
|
||||
const HAS_UNREAD = gql`
|
||||
query getUnread {
|
||||
|
|
@ -26,22 +23,22 @@ const HAS_UNREAD = gql`
|
|||
}
|
||||
`
|
||||
|
||||
const Subheader = ({ item, classes, user }) => {
|
||||
const Subheader = ({ item, user }) => {
|
||||
const [prev, setPrev] = useState(null)
|
||||
|
||||
return (
|
||||
<div className={classes.subheader}>
|
||||
<div className={classes.content}>
|
||||
<div className={styles.subheader}>
|
||||
<div className={styles.content}>
|
||||
<nav>
|
||||
<ul className={classes.subheaderUl}>
|
||||
<ul className={styles.subheaderUl}>
|
||||
{item.children.map((it, idx) => {
|
||||
if (!R.includes(user.role, it.allowedRoles)) return <></>
|
||||
return (
|
||||
<li key={idx} className={classes.subheaderLi}>
|
||||
<li key={idx} className={styles.subheaderLi}>
|
||||
<NavLink
|
||||
to={{ pathname: it.route, state: { prev } }}
|
||||
className={classes.subheaderLink}
|
||||
activeClassName={classes.activeSubheaderLink}
|
||||
className={styles.subheaderLink}
|
||||
activeClassName={styles.activeSubheaderLink}
|
||||
isActive={match => {
|
||||
if (!match) return false
|
||||
setPrev(it.route)
|
||||
|
|
@ -72,7 +69,6 @@ const Header = memo(({ tree, user }) => {
|
|||
const notifCenterButtonRef = useRef()
|
||||
const popperRef = useRef()
|
||||
const history = useHistory()
|
||||
const classes = useStyles()
|
||||
|
||||
useEffect(() => {
|
||||
if (data?.hasUnreadNotifications) return setHasUnread(true)
|
||||
|
|
@ -112,20 +108,20 @@ const Header = memo(({ tree, user }) => {
|
|||
const popperOpen = Boolean(anchorEl)
|
||||
const id = popperOpen ? 'notifications-popper' : undefined
|
||||
return (
|
||||
<header className={classes.headerContainer}>
|
||||
<div className={classes.header}>
|
||||
<div className={classes.content}>
|
||||
<header className={styles.headerContainer}>
|
||||
<div className={styles.header}>
|
||||
<div className={styles.content}>
|
||||
<div
|
||||
onClick={() => {
|
||||
setActive(false)
|
||||
history.push('/dashboard')
|
||||
}}
|
||||
className={classnames(classes.logo, classes.logoLink)}>
|
||||
className={classnames(styles.logo, styles.logoLink)}>
|
||||
<Logo />
|
||||
<H4 className={classes.white}>Lamassu Admin</H4>
|
||||
<H4 className="text-white">Lamassu Admin</H4>
|
||||
</div>
|
||||
<nav className={classes.nav}>
|
||||
<ul className={classes.ul}>
|
||||
<nav className={styles.nav}>
|
||||
<ul className={styles.ul}>
|
||||
{tree.map((it, idx) => {
|
||||
if (!R.includes(user.role, it.allowedRoles)) return <></>
|
||||
return (
|
||||
|
|
@ -137,11 +133,11 @@ const Header = memo(({ tree, user }) => {
|
|||
setActive(it)
|
||||
return true
|
||||
}}
|
||||
className={classnames(classes.link, classes.whiteLink)}
|
||||
activeClassName={classes.activeLink}>
|
||||
<li className={classes.li}>
|
||||
className={classnames(styles.link)}
|
||||
activeClassName={styles.activeLink}>
|
||||
<li className={styles.li}>
|
||||
<span
|
||||
className={classes.forceSize}
|
||||
className={styles.forceSize}
|
||||
data-forcesize={it.label}>
|
||||
{it.label}
|
||||
</span>
|
||||
|
|
@ -151,8 +147,9 @@ const Header = memo(({ tree, user }) => {
|
|||
})}
|
||||
</ul>
|
||||
</nav>
|
||||
<div className={classes.actionButtonsContainer}>
|
||||
<div className={styles.actionButtonsContainer}>
|
||||
<ActionButton
|
||||
altTextColor
|
||||
color="secondary"
|
||||
Icon={AddIcon}
|
||||
InverseIcon={AddIconReverse}
|
||||
|
|
@ -163,16 +160,16 @@ const Header = memo(({ tree, user }) => {
|
|||
<div ref={notifCenterButtonRef}>
|
||||
<button
|
||||
onClick={handleClick}
|
||||
className={classes.notificationIcon}>
|
||||
className={styles.notificationIcon}>
|
||||
<NotificationIcon />
|
||||
{hasUnread && <div className={classes.hasUnread} />}
|
||||
{hasUnread && <div className={styles.hasUnread} />}
|
||||
</button>
|
||||
<Popper
|
||||
ref={popperRef}
|
||||
id={id}
|
||||
open={popperOpen}
|
||||
anchorEl={anchorEl}
|
||||
className={classes.popper}
|
||||
className={styles.popper}
|
||||
disablePortal={false}
|
||||
placement="bottom-end"
|
||||
modifiers={[
|
||||
|
|
@ -187,8 +184,8 @@ const Header = memo(({ tree, user }) => {
|
|||
name: 'preventOverflow',
|
||||
enabled: true,
|
||||
options: {
|
||||
rootBoundary: 'viewport',
|
||||
},
|
||||
rootBoundary: 'viewport'
|
||||
}
|
||||
}
|
||||
]}>
|
||||
<NotificationCenter
|
||||
|
|
@ -204,9 +201,7 @@ const Header = memo(({ tree, user }) => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{active && active.children && (
|
||||
<Subheader item={active} classes={classes} user={user} />
|
||||
)}
|
||||
{active && active.children && <Subheader item={active} user={user} />}
|
||||
{open && <AddMachine close={() => setOpen(false)} onPaired={onPaired} />}
|
||||
</header>
|
||||
)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue