chore: reformat code
This commit is contained in:
parent
3d930aa73b
commit
aedabcbdee
509 changed files with 6030 additions and 4266 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"trailingComma": "none",
|
"trailingComma": "all",
|
||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
"semi": false,
|
"semi": false,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import js from '@eslint/js'
|
||||||
import globals from 'globals'
|
import globals from 'globals'
|
||||||
import pluginReact from 'eslint-plugin-react'
|
import pluginReact from 'eslint-plugin-react'
|
||||||
import json from '@eslint/json'
|
import json from '@eslint/json'
|
||||||
import css from '@eslint/css'
|
|
||||||
import { defineConfig, globalIgnores } from 'eslint/config'
|
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||||
import reactCompiler from 'eslint-plugin-react-compiler'
|
import reactCompiler from 'eslint-plugin-react-compiler'
|
||||||
import eslintConfigPrettier from 'eslint-config-prettier/flat'
|
import eslintConfigPrettier from 'eslint-config-prettier/flat'
|
||||||
|
|
@ -16,7 +15,13 @@ export default defineConfig([
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
files: ['packages/admin-ui/**/*.{js,mjs,jsx}'],
|
files: ['packages/admin-ui/**/*.{js,mjs,jsx}'],
|
||||||
languageOptions: { sourceType: 'module', globals: globals.browser }
|
languageOptions: {
|
||||||
|
sourceType: 'module',
|
||||||
|
globals: {
|
||||||
|
...globals.browser,
|
||||||
|
process: 'readonly'
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
files: ['packages/server/**/*.{js,cjs}'],
|
files: ['packages/server/**/*.{js,cjs}'],
|
||||||
|
|
@ -35,15 +40,8 @@ export default defineConfig([
|
||||||
language: 'json/json',
|
language: 'json/json',
|
||||||
extends: ['json/recommended']
|
extends: ['json/recommended']
|
||||||
},
|
},
|
||||||
{
|
|
||||||
files: ['**/*.css'],
|
|
||||||
plugins: { css },
|
|
||||||
language: 'css/css',
|
|
||||||
extends: ['css/recommended']
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
rules: {
|
rules: {
|
||||||
// 'no-unused-vars': 'on',
|
|
||||||
'react/prop-types': 'off',
|
'react/prop-types': 'off',
|
||||||
'react/display-name': 'off',
|
'react/display-name': 'off',
|
||||||
'react/no-unescaped-entities': 'off',
|
'react/no-unescaped-entities': 'off',
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ const Main = () => {
|
||||||
onCompleted: userResponse => {
|
onCompleted: userResponse => {
|
||||||
if (!userData && userResponse?.userData)
|
if (!userData && userResponse?.userData)
|
||||||
setUserData(userResponse.userData)
|
setUserData(userResponse.userData)
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const route = location.pathname
|
const route = location.pathname
|
||||||
|
|
|
||||||
|
|
@ -42,4 +42,4 @@
|
||||||
|
|
||||||
.navButton:hover {
|
.navButton:hover {
|
||||||
background-color: rgba(0, 0, 0, 0.04);
|
background-color: rgba(0, 0, 0, 0.04);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import classnames from 'classnames'
|
||||||
const cardState = Object.freeze({
|
const cardState = Object.freeze({
|
||||||
DEFAULT: 'default',
|
DEFAULT: 'default',
|
||||||
SHRUNK: 'shrunk',
|
SHRUNK: 'shrunk',
|
||||||
EXPANDED: 'expanded'
|
EXPANDED: 'expanded',
|
||||||
})
|
})
|
||||||
|
|
||||||
const CollapsibleCard = ({ className, state, shrunkComponent, children }) => {
|
const CollapsibleCard = ({ className, state, shrunkComponent, children }) => {
|
||||||
|
|
@ -19,7 +19,7 @@ const CollapsibleCard = ({ className, state, shrunkComponent, children }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
CollapsibleCard.propTypes = {
|
CollapsibleCard.propTypes = {
|
||||||
shrunkComponent: PropTypes.node.isRequired
|
shrunkComponent: PropTypes.node.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CollapsibleCard
|
export default CollapsibleCard
|
||||||
|
|
|
||||||
|
|
@ -101,5 +101,5 @@ export const ConfirmDialog = memo(
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ const CopyToClipboard = ({
|
||||||
buttonClassname,
|
buttonClassname,
|
||||||
children,
|
children,
|
||||||
wrapperClassname,
|
wrapperClassname,
|
||||||
removeSpace = true
|
removeSpace = true,
|
||||||
}) => {
|
}) => {
|
||||||
const [anchorEl, setAnchorEl] = useState(null)
|
const [anchorEl, setAnchorEl] = useState(null)
|
||||||
|
|
||||||
|
|
@ -68,7 +68,7 @@ const CopyToClipboard = ({
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CopyToClipboard
|
export default CopyToClipboard
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ export const DeleteDialog = ({
|
||||||
item = 'item',
|
item = 'item',
|
||||||
confirmationMessage = `Are you sure you want to delete this ${item}?`,
|
confirmationMessage = `Are you sure you want to delete this ${item}?`,
|
||||||
extraMessage,
|
extraMessage,
|
||||||
errorMessage = ''
|
errorMessage = '',
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} aria-labelledby="form-dialog-title">
|
<Dialog open={open} aria-labelledby="form-dialog-title">
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ const ImagePopper = memo(
|
||||||
</div>
|
</div>
|
||||||
</ClickAwayListener>
|
</ClickAwayListener>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default ImagePopper
|
export default ImagePopper
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { H1 } from 'src/components/typography'
|
||||||
import CloseIcon from 'src/styling/icons/action/close/zodiac.svg?react'
|
import CloseIcon from 'src/styling/icons/action/close/zodiac.svg?react'
|
||||||
|
|
||||||
export const InformativeDialog = memo(
|
export const InformativeDialog = memo(
|
||||||
({ title = '', open, onDissmised, disabled = false, data, ...props }) => {
|
({ title = '', open, onDissmised, data, ...props }) => {
|
||||||
const innerOnClose = () => {
|
const innerOnClose = () => {
|
||||||
onDissmised()
|
onDissmised()
|
||||||
}
|
}
|
||||||
|
|
@ -16,8 +16,8 @@ export const InformativeDialog = memo(
|
||||||
<Dialog
|
<Dialog
|
||||||
PaperProps={{
|
PaperProps={{
|
||||||
style: {
|
style: {
|
||||||
borderRadius: 8
|
borderRadius: 8,
|
||||||
}
|
},
|
||||||
}}
|
}}
|
||||||
fullWidth
|
fullWidth
|
||||||
open={open}
|
open={open}
|
||||||
|
|
@ -35,5 +35,5 @@ export const InformativeDialog = memo(
|
||||||
<DialogContent>{data}</DialogContent>
|
<DialogContent>{data}</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import { formatDate } from 'src/utils/timezones'
|
||||||
import Popper from './Popper'
|
import Popper from './Popper'
|
||||||
import DateRangePicker from './date-range-picker/DateRangePicker'
|
import DateRangePicker from './date-range-picker/DateRangePicker'
|
||||||
import { RadioGroup } from './inputs'
|
import { RadioGroup } from './inputs'
|
||||||
import typographyStyles from './typography/styles'
|
|
||||||
import { H4, Info1, Label1, Label2 } from './typography/index.jsx'
|
import { H4, Info1, Label1, Label2 } from './typography/index.jsx'
|
||||||
|
|
||||||
const DateContainer = ({ date, children }) => {
|
const DateContainer = ({ date, children }) => {
|
||||||
|
|
@ -31,7 +30,7 @@ const DateContainer = ({ date, children }) => {
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Label2 noMargin>{`${format(
|
<Label2 noMargin>{`${format(
|
||||||
'MMM',
|
'MMM',
|
||||||
date
|
date,
|
||||||
)} ${format('yyyy', date)}`}</Label2>
|
)} ${format('yyyy', date)}`}</Label2>
|
||||||
<Label1 noMargin className="text-comet">
|
<Label1 noMargin className="text-comet">
|
||||||
{format('EEEE', date)}
|
{format('EEEE', date)}
|
||||||
|
|
@ -57,7 +56,7 @@ const LogsDownloaderPopover = ({
|
||||||
getLogs,
|
getLogs,
|
||||||
timezone,
|
timezone,
|
||||||
simplified,
|
simplified,
|
||||||
className
|
className,
|
||||||
}) => {
|
}) => {
|
||||||
const [selectedRadio, setSelectedRadio] = useState(ALL)
|
const [selectedRadio, setSelectedRadio] = useState(ALL)
|
||||||
const [selectedAdvancedRadio, setSelectedAdvancedRadio] = useState(ADVANCED)
|
const [selectedAdvancedRadio, setSelectedAdvancedRadio] = useState(ADVANCED)
|
||||||
|
|
@ -65,12 +64,12 @@ const LogsDownloaderPopover = ({
|
||||||
const [range, setRange] = useState({ from: null, until: null })
|
const [range, setRange] = useState({ from: null, until: null })
|
||||||
const [anchorEl, setAnchorEl] = useState(null)
|
const [anchorEl, setAnchorEl] = useState(null)
|
||||||
const [fetchLogs] = useLazyQuery(query, {
|
const [fetchLogs] = useLazyQuery(query, {
|
||||||
onCompleted: data => createLogsFile(getLogs(data), range)
|
onCompleted: data => createLogsFile(getLogs(data), range),
|
||||||
})
|
})
|
||||||
|
|
||||||
const dateRangePickerClasses = {
|
const dateRangePickerClasses = {
|
||||||
'block h-full': selectedRadio === RANGE,
|
'block h-full': selectedRadio === RANGE,
|
||||||
hidden: selectedRadio === ALL
|
hidden: selectedRadio === ALL,
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRadioButtons = evt => {
|
const handleRadioButtons = evt => {
|
||||||
|
|
@ -88,7 +87,7 @@ const LogsDownloaderPopover = ({
|
||||||
(from, until) => {
|
(from, until) => {
|
||||||
setRange({ from, until })
|
setRange({ from, until })
|
||||||
},
|
},
|
||||||
[setRange]
|
[setRange],
|
||||||
)
|
)
|
||||||
|
|
||||||
const downloadLogs = (range, args) => {
|
const downloadLogs = (range, args) => {
|
||||||
|
|
@ -97,8 +96,8 @@ const LogsDownloaderPopover = ({
|
||||||
variables: {
|
variables: {
|
||||||
...args,
|
...args,
|
||||||
simplified: selectedAdvancedRadio === SIMPLIFIED,
|
simplified: selectedAdvancedRadio === SIMPLIFIED,
|
||||||
excludeTestingCustomers: true
|
excludeTestingCustomers: true,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,8 +111,8 @@ const LogsDownloaderPopover = ({
|
||||||
from: range.from,
|
from: range.from,
|
||||||
until: range.until,
|
until: range.until,
|
||||||
simplified: selectedAdvancedRadio === SIMPLIFIED,
|
simplified: selectedAdvancedRadio === SIMPLIFIED,
|
||||||
excludeTestingCustomers: true
|
excludeTestingCustomers: true,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -124,7 +123,7 @@ const LogsDownloaderPopover = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
const blob = new window.Blob([logs], {
|
const blob = new window.Blob([logs], {
|
||||||
type: 'text/plain;charset=utf-8'
|
type: 'text/plain;charset=utf-8',
|
||||||
})
|
})
|
||||||
|
|
||||||
FileSaver.saveAs(
|
FileSaver.saveAs(
|
||||||
|
|
@ -132,8 +131,8 @@ const LogsDownloaderPopover = ({
|
||||||
selectedRadio === ALL
|
selectedRadio === ALL
|
||||||
? `${formatDateFile(new Date())}_${name}.csv`
|
? `${formatDateFile(new Date())}_${name}.csv`
|
||||||
: `${formatDateFile(range.from)}_${formatDateFile(
|
: `${formatDateFile(range.from)}_${formatDateFile(
|
||||||
range.until
|
range.until,
|
||||||
)}_${name}.csv`
|
)}_${name}.csv`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,12 +146,12 @@ const LogsDownloaderPopover = ({
|
||||||
|
|
||||||
const radioButtonOptions = [
|
const radioButtonOptions = [
|
||||||
{ display: 'All logs', code: ALL },
|
{ display: 'All logs', code: ALL },
|
||||||
{ display: 'Date range', code: RANGE }
|
{ display: 'Date range', code: RANGE },
|
||||||
]
|
]
|
||||||
|
|
||||||
const advancedRadioButtonOptions = [
|
const advancedRadioButtonOptions = [
|
||||||
{ display: 'Advanced logs', code: ADVANCED },
|
{ display: 'Advanced logs', code: ADVANCED },
|
||||||
{ display: 'Simplified logs', code: SIMPLIFIED }
|
{ display: 'Simplified logs', code: SIMPLIFIED },
|
||||||
]
|
]
|
||||||
|
|
||||||
const open = Boolean(anchorEl)
|
const open = Boolean(anchorEl)
|
||||||
|
|
@ -201,9 +200,9 @@ const LogsDownloaderPopover = ({
|
||||||
hours: 23,
|
hours: 23,
|
||||||
minutes: 59,
|
minutes: 59,
|
||||||
seconds: 59,
|
seconds: 59,
|
||||||
milliseconds: 999
|
milliseconds: 999,
|
||||||
},
|
},
|
||||||
new Date()
|
new Date(),
|
||||||
)}
|
)}
|
||||||
onRangeChange={handleRangeChange}
|
onRangeChange={handleRangeChange}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,12 @@ const Modal = ({
|
||||||
infoPanel,
|
infoPanel,
|
||||||
handleClose,
|
handleClose,
|
||||||
children,
|
children,
|
||||||
secondaryModal,
|
|
||||||
className,
|
className,
|
||||||
closeOnEscape,
|
closeOnEscape,
|
||||||
closeOnBackdropClick,
|
closeOnBackdropClick,
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
const TitleCase = small ? H4 : H1
|
const TitleCase = small ? H4 : H1
|
||||||
const closeSize = xl ? 28 : small ? 16 : 20
|
|
||||||
|
|
||||||
const innerClose = (evt, reason) => {
|
const innerClose = (evt, reason) => {
|
||||||
if (!closeOnBackdropClick && reason === 'backdropClick') return
|
if (!closeOnBackdropClick && reason === 'backdropClick') return
|
||||||
|
|
@ -44,7 +42,7 @@ const Modal = ({
|
||||||
style={{ width, height, minHeight: height ?? 400 }}
|
style={{ width, height, minHeight: height ?? 400 }}
|
||||||
className={classnames(
|
className={classnames(
|
||||||
'flex flex-col max-h-[90vh] rounded-lg outline-0',
|
'flex flex-col max-h-[90vh] rounded-lg outline-0',
|
||||||
className
|
className,
|
||||||
)}>
|
)}>
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
{title && (
|
{title && (
|
||||||
|
|
@ -78,11 +76,11 @@ const Modal = ({
|
||||||
style={{
|
style={{
|
||||||
width,
|
width,
|
||||||
height: infoPanelHeight,
|
height: infoPanelHeight,
|
||||||
minHeight: infoPanelHeight ?? 200
|
minHeight: infoPanelHeight ?? 200,
|
||||||
}}
|
}}
|
||||||
className={classnames(
|
className={classnames(
|
||||||
'mt-4 flex flex-col max-h-[90vh] overflow-y-auto rounded-lg outline-0',
|
'mt-4 flex flex-col max-h-[90vh] overflow-y-auto rounded-lg outline-0',
|
||||||
className
|
className,
|
||||||
)}>
|
)}>
|
||||||
<div className="w-full flex flex-col flex-1 py-0 px-6">
|
<div className="w-full flex flex-col flex-1 py-0 px-6">
|
||||||
{infoPanel}
|
{infoPanel}
|
||||||
|
|
|
||||||
|
|
@ -52,28 +52,28 @@ const NotificationCenter = ({
|
||||||
hasUnreadProp,
|
hasUnreadProp,
|
||||||
buttonCoords,
|
buttonCoords,
|
||||||
popperRef,
|
popperRef,
|
||||||
refetchHasUnreadHeader
|
refetchHasUnreadHeader,
|
||||||
}) => {
|
}) => {
|
||||||
const { data, loading } = useQuery(GET_NOTIFICATIONS, {
|
const { data, loading } = useQuery(GET_NOTIFICATIONS, {
|
||||||
pollInterval: 60000
|
pollInterval: 60000,
|
||||||
})
|
})
|
||||||
const [xOffset, setXoffset] = useState(300)
|
const [xOffset, setXoffset] = useState(300)
|
||||||
|
|
||||||
const [showingUnread, setShowingUnread] = useState(false)
|
const [showingUnread, setShowingUnread] = useState(false)
|
||||||
const machines = R.compose(
|
const machines = R.compose(
|
||||||
R.map(R.prop('name')),
|
R.map(R.prop('name')),
|
||||||
R.indexBy(R.prop('deviceId'))
|
R.indexBy(R.prop('deviceId')),
|
||||||
)(R.path(['machines'])(data) ?? [])
|
)(R.path(['machines'])(data) ?? [])
|
||||||
const notifications = R.path(['notifications'])(data) ?? []
|
const notifications = R.path(['notifications'])(data) ?? []
|
||||||
const [hasUnread, setHasUnread] = useState(hasUnreadProp)
|
const [hasUnread, setHasUnread] = useState(hasUnreadProp)
|
||||||
|
|
||||||
const [toggleClearNotification] = useMutation(TOGGLE_CLEAR_NOTIFICATION, {
|
const [toggleClearNotification] = useMutation(TOGGLE_CLEAR_NOTIFICATION, {
|
||||||
onError: () => console.error('Error while clearing notification'),
|
onError: () => console.error('Error while clearing notification'),
|
||||||
refetchQueries: () => ['getNotifications']
|
refetchQueries: () => ['getNotifications'],
|
||||||
})
|
})
|
||||||
const [clearAllNotifications] = useMutation(CLEAR_ALL_NOTIFICATIONS, {
|
const [clearAllNotifications] = useMutation(CLEAR_ALL_NOTIFICATIONS, {
|
||||||
onError: () => console.error('Error while clearing all notifications'),
|
onError: () => console.error('Error while clearing all notifications'),
|
||||||
refetchQueries: () => ['getNotifications']
|
refetchQueries: () => ['getNotifications'],
|
||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -103,7 +103,7 @@ const NotificationCenter = ({
|
||||||
valid={n.valid}
|
valid={n.valid}
|
||||||
toggleClear={() =>
|
toggleClear={() =>
|
||||||
toggleClearNotification({
|
toggleClearNotification({
|
||||||
variables: { id: n.id, read: !n.read }
|
variables: { id: n.id, read: !n.read },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
@ -121,7 +121,7 @@ const NotificationCenter = ({
|
||||||
className={classes.notificationIcon}
|
className={classes.notificationIcon}
|
||||||
style={{
|
style={{
|
||||||
top: buttonCoords?.y ?? 0,
|
top: buttonCoords?.y ?? 0,
|
||||||
left: buttonCoords?.x ? buttonCoords.x - xOffset : 0
|
left: buttonCoords?.x ? buttonCoords.x - xOffset : 0,
|
||||||
}}>
|
}}>
|
||||||
<NotificationIconZodiac />
|
<NotificationIconZodiac />
|
||||||
{hasUnread && <div className={classes.hasUnread} />}
|
{hasUnread && <div className={classes.hasUnread} />}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,10 @@
|
||||||
box-shadow: 0 0 14px 0 rgba(0, 0, 0, 0.24);
|
box-shadow: 0 0 14px 0 rgba(0, 0, 0, 0.24);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container @media only screen and (max-width: 1920px) {
|
@media only screen and (max-width: 1920px) {
|
||||||
width: 30vw;
|
.container {
|
||||||
|
width: 30vw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
|
|
@ -75,7 +77,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.unread {
|
.unread {
|
||||||
background-color: var(--spring3)
|
background-color: var(--spring3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.notificationRowIcon {
|
.notificationRowIcon {
|
||||||
|
|
@ -83,11 +85,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.notificationRowIcon > * {
|
.notificationRowIcon > * {
|
||||||
margin-left: 24px
|
margin-left: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.readIconWrapper {
|
.readIconWrapper {
|
||||||
flex-grow: 1
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.unreadIcon {
|
.unreadIcon {
|
||||||
|
|
@ -118,7 +120,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.notificationBody {
|
.notificationBody {
|
||||||
margin: 0
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notificationSubtitle {
|
.notificationSubtitle {
|
||||||
|
|
@ -142,4 +144,4 @@
|
||||||
height: 9px;
|
height: 9px;
|
||||||
background-color: var(--spring);
|
background-color: var(--spring);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,37 +12,36 @@ import classes from './NotificationCenter.module.css'
|
||||||
const types = {
|
const types = {
|
||||||
transaction: {
|
transaction: {
|
||||||
display: 'Transactions',
|
display: 'Transactions',
|
||||||
icon: <Transaction height={16} width={16} />
|
icon: <Transaction height={16} width={16} />,
|
||||||
},
|
},
|
||||||
highValueTransaction: {
|
highValueTransaction: {
|
||||||
display: 'Transactions',
|
display: 'Transactions',
|
||||||
icon: <Transaction height={16} width={16} />
|
icon: <Transaction height={16} width={16} />,
|
||||||
},
|
},
|
||||||
fiatBalance: {
|
fiatBalance: {
|
||||||
display: 'Maintenance',
|
display: 'Maintenance',
|
||||||
icon: <Wrench height={16} width={16} />
|
icon: <Wrench height={16} width={16} />,
|
||||||
},
|
},
|
||||||
cryptoBalance: {
|
cryptoBalance: {
|
||||||
display: 'Maintenance',
|
display: 'Maintenance',
|
||||||
icon: <Wrench height={16} width={16} />
|
icon: <Wrench height={16} width={16} />,
|
||||||
},
|
},
|
||||||
compliance: {
|
compliance: {
|
||||||
display: 'Compliance',
|
display: 'Compliance',
|
||||||
icon: <WarningIcon height={16} width={16} />
|
icon: <WarningIcon height={16} width={16} />,
|
||||||
},
|
},
|
||||||
error: { display: 'Error', icon: <WarningIcon height={16} width={16} /> }
|
error: { display: 'Error', icon: <WarningIcon height={16} width={16} /> },
|
||||||
}
|
}
|
||||||
|
|
||||||
const NotificationRow = ({
|
const NotificationRow = ({
|
||||||
id,
|
id,
|
||||||
type,
|
type,
|
||||||
detail,
|
|
||||||
message,
|
message,
|
||||||
deviceName,
|
deviceName,
|
||||||
created,
|
created,
|
||||||
read,
|
read,
|
||||||
valid,
|
valid,
|
||||||
toggleClear
|
toggleClear,
|
||||||
}) => {
|
}) => {
|
||||||
const typeDisplay = R.path([type, 'display'])(types) ?? null
|
const typeDisplay = R.path([type, 'display'])(types) ?? null
|
||||||
const icon = R.path([type, 'icon'])(types) ?? (
|
const icon = R.path([type, 'icon'])(types) ?? (
|
||||||
|
|
@ -50,7 +49,7 @@ const NotificationRow = ({
|
||||||
)
|
)
|
||||||
const age = prettyMs(new Date().getTime() - new Date(created).getTime(), {
|
const age = prettyMs(new Date().getTime() - new Date(created).getTime(), {
|
||||||
compact: true,
|
compact: true,
|
||||||
verbose: true
|
verbose: true,
|
||||||
})
|
})
|
||||||
const notificationTitle =
|
const notificationTitle =
|
||||||
typeDisplay && deviceName
|
typeDisplay && deviceName
|
||||||
|
|
@ -61,13 +60,13 @@ const NotificationRow = ({
|
||||||
|
|
||||||
const iconClass = {
|
const iconClass = {
|
||||||
[classes.readIcon]: read,
|
[classes.readIcon]: read,
|
||||||
[classes.unreadIcon]: !read
|
[classes.unreadIcon]: !read,
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classnames(
|
className={classnames(
|
||||||
classes.notificationRow,
|
classes.notificationRow,
|
||||||
!read && valid ? classes.unread : ''
|
!read && valid ? classes.unread : '',
|
||||||
)}>
|
)}>
|
||||||
<div className={classes.notificationRowIcon}>
|
<div className={classes.notificationRowIcon}>
|
||||||
<div>{icon}</div>
|
<div>{icon}</div>
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
import NotificationCenter from './NotificationCenter'
|
import NotificationCenter from './NotificationCenter'
|
||||||
|
|
||||||
export default NotificationCenter
|
export default NotificationCenter
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ const Popover = ({ children, bgColor = white, className, ...props }) => {
|
||||||
top: ['bottom'],
|
top: ['bottom'],
|
||||||
bottom: ['top'],
|
bottom: ['top'],
|
||||||
left: ['right'],
|
left: ['right'],
|
||||||
right: ['left']
|
right: ['left'],
|
||||||
}
|
}
|
||||||
|
|
||||||
const modifiers = [
|
const modifiers = [
|
||||||
|
|
@ -22,36 +22,36 @@ const Popover = ({ children, bgColor = white, className, ...props }) => {
|
||||||
name: 'flip',
|
name: 'flip',
|
||||||
enabled: R.defaultTo(false, props.flip),
|
enabled: R.defaultTo(false, props.flip),
|
||||||
options: {
|
options: {
|
||||||
allowedAutoPlacements: flipPlacements[props.placement]
|
allowedAutoPlacements: flipPlacements[props.placement],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'preventOverflow',
|
name: 'preventOverflow',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
options: {
|
options: {
|
||||||
rootBoundary: 'scrollParent'
|
rootBoundary: 'scrollParent',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'offset',
|
name: 'offset',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
options: {
|
options: {
|
||||||
offset: [0, 10]
|
offset: [0, 10],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'arrow',
|
name: 'arrow',
|
||||||
enabled: R.defaultTo(true, props.showArrow),
|
enabled: R.defaultTo(true, props.showArrow),
|
||||||
options: {
|
options: {
|
||||||
element: arrowRef
|
element: arrowRef,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'computeStyles',
|
name: 'computeStyles',
|
||||||
options: {
|
options: {
|
||||||
gpuAcceleration: false
|
gpuAcceleration: false,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -30,4 +30,4 @@
|
||||||
|
|
||||||
.tooltip[data-popper-placement^='right'] > div > span {
|
.tooltip[data-popper-placement^='right'] > div > span {
|
||||||
left: -4px;
|
left: -4px;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ const SearchBox = memo(
|
||||||
filters = [],
|
filters = [],
|
||||||
options = [],
|
options = [],
|
||||||
inputPlaceholder = '',
|
inputPlaceholder = '',
|
||||||
size,
|
|
||||||
onChange,
|
onChange,
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
|
|
@ -20,7 +19,7 @@ const SearchBox = memo(
|
||||||
|
|
||||||
const inputClasses = {
|
const inputClasses = {
|
||||||
'flex flex-1 h-8 px-2 py-2 font-md items-center rounded-2xl bg-zircon text-comet': true,
|
'flex flex-1 h-8 px-2 py-2 font-md items-center rounded-2xl bg-zircon text-comet': true,
|
||||||
'rounded-b-none': popupOpen
|
'rounded-b-none': popupOpen,
|
||||||
}
|
}
|
||||||
|
|
||||||
const innerOnChange = filters => onChange(filters)
|
const innerOnChange = filters => onChange(filters)
|
||||||
|
|
@ -57,7 +56,7 @@ const SearchBox = memo(
|
||||||
placeholder={inputPlaceholder}
|
placeholder={inputPlaceholder}
|
||||||
inputProps={{
|
inputProps={{
|
||||||
className: 'font-bold',
|
className: 'font-bold',
|
||||||
...params.inputProps
|
...params.inputProps,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
@ -74,10 +73,11 @@ const SearchBox = memo(
|
||||||
<div className="w-[88%] h-[1px] my-p mx-auto border-1 border-comet" />
|
<div className="w-[88%] h-[1px] my-p mx-auto border-1 border-comet" />
|
||||||
{children}
|
{children}
|
||||||
</Paper>
|
</Paper>
|
||||||
)
|
),
|
||||||
}} />
|
}}
|
||||||
);
|
/>
|
||||||
}
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default SearchBox
|
export default SearchBox
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ const SearchFilter = ({
|
||||||
filters,
|
filters,
|
||||||
onFilterDelete,
|
onFilterDelete,
|
||||||
deleteAllFilters,
|
deleteAllFilters,
|
||||||
entries = 0
|
entries = 0,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
@ -33,7 +33,7 @@ const SearchFilter = ({
|
||||||
<Label3 className="text-comet m-auto mr-3">{`${entries} ${singularOrPlural(
|
<Label3 className="text-comet m-auto mr-3">{`${entries} ${singularOrPlural(
|
||||||
entries,
|
entries,
|
||||||
`entry`,
|
`entry`,
|
||||||
`entries`
|
`entries`,
|
||||||
)}`}</Label3>
|
)}`}</Label3>
|
||||||
}
|
}
|
||||||
<ActionButton
|
<ActionButton
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,13 @@ const Stepper = memo(({ steps, currentStep, color = 'spring', className }) => {
|
||||||
const separatorClasses = {
|
const separatorClasses = {
|
||||||
'w-7 h-[2px] border-2 z-1': true,
|
'w-7 h-[2px] border-2 z-1': true,
|
||||||
'border-spring': color === 'spring',
|
'border-spring': color === 'spring',
|
||||||
'border-zodiac': color === 'zodiac'
|
'border-zodiac': color === 'zodiac',
|
||||||
}
|
}
|
||||||
|
|
||||||
const separatorEmptyClasses = {
|
const separatorEmptyClasses = {
|
||||||
'w-7 h-[2px] border-2 z-1': true,
|
'w-7 h-[2px] border-2 z-1': true,
|
||||||
'border-dust': color === 'spring',
|
'border-dust': color === 'spring',
|
||||||
'border-comet': color === 'zodiac'
|
'border-comet': color === 'zodiac',
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,4 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { TL1 } from './typography'
|
||||||
const Subtitle = memo(({ children, className, extraMarginTop }) => {
|
const Subtitle = memo(({ children, className, extraMarginTop }) => {
|
||||||
const classNames = {
|
const classNames = {
|
||||||
'text-comet my-4': true,
|
'text-comet my-4': true,
|
||||||
'mt-18': extraMarginTop
|
'mt-18': extraMarginTop,
|
||||||
}
|
}
|
||||||
|
|
||||||
return <TL1 className={classnames(classNames, className)}>{children}</TL1>
|
return <TL1 className={classnames(classNames, className)}>{children}</TL1>
|
||||||
|
|
|
||||||
|
|
@ -4,30 +4,6 @@ import React, { useState, memo } from 'react'
|
||||||
import Popper from 'src/components/Popper'
|
import Popper from 'src/components/Popper'
|
||||||
import HelpIcon from 'src/styling/icons/action/help/zodiac.svg?react'
|
import HelpIcon from 'src/styling/icons/action/help/zodiac.svg?react'
|
||||||
|
|
||||||
const useStyles = {
|
|
||||||
transparentButton: {
|
|
||||||
border: 'none',
|
|
||||||
backgroundColor: 'transparent',
|
|
||||||
outline: 'none',
|
|
||||||
cursor: 'pointer',
|
|
||||||
marginTop: 4
|
|
||||||
},
|
|
||||||
relativelyPositioned: {
|
|
||||||
position: 'relative'
|
|
||||||
},
|
|
||||||
safeSpace: {
|
|
||||||
position: 'absolute',
|
|
||||||
backgroundColor: '#0000',
|
|
||||||
height: 40,
|
|
||||||
left: '-50%',
|
|
||||||
width: '200%'
|
|
||||||
},
|
|
||||||
popoverContent: ({ width }) => ({
|
|
||||||
width,
|
|
||||||
padding: [[10, 15]]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const usePopperHandler = () => {
|
const usePopperHandler = () => {
|
||||||
const [helpPopperAnchorEl, setHelpPopperAnchorEl] = useState(null)
|
const [helpPopperAnchorEl, setHelpPopperAnchorEl] = useState(null)
|
||||||
|
|
||||||
|
|
@ -50,7 +26,7 @@ const usePopperHandler = () => {
|
||||||
helpPopperOpen,
|
helpPopperOpen,
|
||||||
handleOpenHelpPopper,
|
handleOpenHelpPopper,
|
||||||
openHelpPopper,
|
openHelpPopper,
|
||||||
handleCloseHelpPopper
|
handleCloseHelpPopper,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,27 +25,27 @@ const BooleanPropertiesTable = memo(
|
||||||
const [editing, setEditing] = useState(forcedEditing)
|
const [editing, setEditing] = useState(forcedEditing)
|
||||||
|
|
||||||
const initialValues = R.fromPairs(
|
const initialValues = R.fromPairs(
|
||||||
elements.map(it => [it.name, data[it.name]?.toString() ?? 'false'])
|
elements.map(it => [it.name, data[it.name]?.toString() ?? 'false']),
|
||||||
)
|
)
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape(
|
const validationSchema = Yup.object().shape(
|
||||||
R.fromPairs(
|
R.fromPairs(
|
||||||
elements.map(it => [
|
elements.map(it => [
|
||||||
it.name,
|
it.name,
|
||||||
Yup.mixed().oneOf(['true', 'false', true, false]).required()
|
Yup.mixed().oneOf(['true', 'false', true, false]).required(),
|
||||||
])
|
]),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
const innerSave = async values => {
|
const innerSave = async values => {
|
||||||
const toBoolean = (num, _) => R.equals(num, 'true')
|
const toBoolean = num => R.equals(num, 'true')
|
||||||
save(R.mapObjIndexed(toBoolean, R.filter(R.complement(R.isNil))(values)))
|
save(R.mapObjIndexed(toBoolean, R.filter(R.complement(R.isNil))(values)))
|
||||||
setEditing(false)
|
setEditing(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const radioButtonOptions = [
|
const radioButtonOptions = [
|
||||||
{ display: 'Yes', code: 'true' },
|
{ display: 'Yes', code: 'true' },
|
||||||
{ display: 'No', code: 'false' }
|
{ display: 'No', code: 'false' },
|
||||||
]
|
]
|
||||||
return (
|
return (
|
||||||
<div className="flex w-sm flex-col ">
|
<div className="flex w-sm flex-col ">
|
||||||
|
|
@ -117,7 +117,7 @@ const BooleanPropertiesTable = memo(
|
||||||
</Formik>
|
</Formik>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default BooleanPropertiesTable
|
export default BooleanPropertiesTable
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ const ActionButton = memo(
|
||||||
[moduleStyles.secondary]: color === 'secondary',
|
[moduleStyles.secondary]: color === 'secondary',
|
||||||
[moduleStyles.spring]: color === 'spring',
|
[moduleStyles.spring]: color === 'spring',
|
||||||
[moduleStyles.tomato]: color === 'tomato',
|
[moduleStyles.tomato]: color === 'tomato',
|
||||||
[moduleStyles.center]: center
|
[moduleStyles.center]: center,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -35,7 +35,7 @@ const ActionButton = memo(
|
||||||
<div
|
<div
|
||||||
className={classnames(
|
className={classnames(
|
||||||
moduleStyles.actionButtonIcon,
|
moduleStyles.actionButtonIcon,
|
||||||
moduleStyles.actionButtonIconActive
|
moduleStyles.actionButtonIconActive,
|
||||||
)}>
|
)}>
|
||||||
<InverseIcon />
|
<InverseIcon />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -43,7 +43,7 @@ const ActionButton = memo(
|
||||||
{children && <div>{children}</div>}
|
{children && <div>{children}</div>}
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default ActionButton
|
export default ActionButton
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,18 @@ import {
|
||||||
subheaderColor,
|
subheaderColor,
|
||||||
subheaderDarkColor,
|
subheaderDarkColor,
|
||||||
offColor,
|
offColor,
|
||||||
offDarkColor
|
offDarkColor,
|
||||||
} from 'src/styling/variables'
|
} from 'src/styling/variables'
|
||||||
|
|
||||||
const colors = (color1, color2, color3) => {
|
const colors = (color1, color2, color3) => {
|
||||||
return {
|
return {
|
||||||
backgroundColor: color1,
|
backgroundColor: color1,
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
backgroundColor: color2
|
backgroundColor: color2,
|
||||||
},
|
},
|
||||||
'&:active': {
|
'&:active': {
|
||||||
backgroundColor: color3
|
backgroundColor: color3,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,23 +30,23 @@ export default {
|
||||||
height: buttonHeight,
|
height: buttonHeight,
|
||||||
color: fontColor,
|
color: fontColor,
|
||||||
'&:active': {
|
'&:active': {
|
||||||
color: white
|
color: white,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
primary: {
|
primary: {
|
||||||
extend: colors(subheaderColor, subheaderDarkColor, offColor),
|
extend: colors(subheaderColor, subheaderDarkColor, offColor),
|
||||||
'&:active': {
|
'&:active': {
|
||||||
color: white,
|
color: white,
|
||||||
'& $buttonIcon': {
|
'& $buttonIcon': {
|
||||||
display: 'none'
|
display: 'none',
|
||||||
},
|
},
|
||||||
'& $buttonIconActive': {
|
'& $buttonIconActive': {
|
||||||
display: 'block'
|
display: 'block',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
'& $buttonIconActive': {
|
'& $buttonIconActive': {
|
||||||
display: 'none'
|
display: 'none',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
extend: colors(offColor, offDarkColor, white),
|
extend: colors(offColor, offDarkColor, white),
|
||||||
|
|
@ -54,17 +54,17 @@ export default {
|
||||||
'&:active': {
|
'&:active': {
|
||||||
color: fontColor,
|
color: fontColor,
|
||||||
'& $buttonIcon': {
|
'& $buttonIcon': {
|
||||||
display: 'flex'
|
display: 'flex',
|
||||||
},
|
},
|
||||||
'& $buttonIconActive': {
|
'& $buttonIconActive': {
|
||||||
display: 'none'
|
display: 'none',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
'& $buttonIcon': {
|
'& $buttonIcon': {
|
||||||
display: 'none'
|
display: 'none',
|
||||||
},
|
},
|
||||||
'& $buttonIconActive': {
|
'& $buttonIconActive': {
|
||||||
display: 'flex'
|
display: 'flex',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,15 +29,15 @@ const ActionButton = memo(
|
||||||
'text-white',
|
'text-white',
|
||||||
{
|
{
|
||||||
[moduleStyles.buttonSm]: size === 'sm',
|
[moduleStyles.buttonSm]: size === 'sm',
|
||||||
[moduleStyles.buttonXl]: size === 'xl'
|
[moduleStyles.buttonXl]: size === 'xl',
|
||||||
}
|
},
|
||||||
)}
|
)}
|
||||||
{...props}>
|
{...props}>
|
||||||
{children}
|
{children}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default ActionButton
|
export default ActionButton
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,13 @@
|
||||||
.buttonXl {
|
.buttonXl {
|
||||||
composes: h1 from '../typography/typography.module.css';
|
composes: h1 from '../typography/typography.module.css';
|
||||||
height: 61px;
|
height: 61px;
|
||||||
border-radius: 15px
|
border-radius: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttonSm {
|
.buttonSm {
|
||||||
height: 32px;
|
height: 32px;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
border-radius: 8px
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:disabled {
|
.button:disabled {
|
||||||
|
|
@ -46,4 +46,4 @@
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
background-color: var(--spring2);
|
background-color: var(--spring2);
|
||||||
box-shadow: 0 2px var(--spring4);
|
box-shadow: 0 2px var(--spring4);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ const FeatureButton = memo(
|
||||||
classes.baseButton,
|
classes.baseButton,
|
||||||
classes.roundButton,
|
classes.roundButton,
|
||||||
classes.primary,
|
classes.primary,
|
||||||
className
|
className,
|
||||||
)}
|
)}
|
||||||
{...props}>
|
{...props}>
|
||||||
{Icon && (
|
{Icon && (
|
||||||
|
|
@ -23,7 +23,7 @@ const FeatureButton = memo(
|
||||||
<div
|
<div
|
||||||
className={classnames(
|
className={classnames(
|
||||||
classes.buttonIcon,
|
classes.buttonIcon,
|
||||||
classes.buttonIconActive
|
classes.buttonIconActive,
|
||||||
)}>
|
)}>
|
||||||
<InverseIcon />
|
<InverseIcon />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -31,7 +31,7 @@ const FeatureButton = memo(
|
||||||
{children}
|
{children}
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default FeatureButton
|
export default FeatureButton
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ const IDButton = memo(
|
||||||
className,
|
className,
|
||||||
Icon,
|
Icon,
|
||||||
InverseIcon,
|
InverseIcon,
|
||||||
popoverWidth = 152,
|
|
||||||
children,
|
children,
|
||||||
popoverClassname,
|
popoverClassname,
|
||||||
...props
|
...props
|
||||||
|
|
@ -25,11 +24,11 @@ const IDButton = memo(
|
||||||
[classes.idButton]: true,
|
[classes.idButton]: true,
|
||||||
[classes.primary]: true,
|
[classes.primary]: true,
|
||||||
[classes.open]: open,
|
[classes.open]: open,
|
||||||
[classes.closed]: !open
|
[classes.closed]: !open,
|
||||||
}
|
}
|
||||||
|
|
||||||
const iconClassNames = {
|
const iconClassNames = {
|
||||||
[classes.buttonIcon]: true
|
[classes.buttonIcon]: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleClick = event => {
|
const handleClick = event => {
|
||||||
|
|
@ -74,7 +73,7 @@ const IDButton = memo(
|
||||||
</Popover>
|
</Popover>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default IDButton
|
export default IDButton
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const Link = memo(
|
||||||
[classes.primary]: color === 'primary',
|
[classes.primary]: color === 'primary',
|
||||||
[classes.secondary]: color === 'secondary',
|
[classes.secondary]: color === 'secondary',
|
||||||
[classes.noColor]: color === 'noColor',
|
[classes.noColor]: color === 'noColor',
|
||||||
[classes.action]: color === 'action'
|
[classes.action]: color === 'action',
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -21,7 +21,7 @@ const Link = memo(
|
||||||
{children}
|
{children}
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default Link
|
export default Link
|
||||||
|
|
|
||||||
|
|
@ -44,4 +44,4 @@
|
||||||
.action:hover {
|
.action:hover {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
background-color: rgba(72, 246, 148, 0.8);
|
background-color: rgba(72, 246, 148, 0.8);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,14 @@ const SubpageButton = memo(
|
||||||
InverseIcon,
|
InverseIcon,
|
||||||
toggle,
|
toggle,
|
||||||
forceDisable = false,
|
forceDisable = false,
|
||||||
children
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
const [active, setActive] = useState(false)
|
const [active, setActive] = useState(false)
|
||||||
const isActive = forceDisable ? false : active
|
const isActive = forceDisable ? false : active
|
||||||
const classNames = {
|
const classNames = {
|
||||||
[classes.button]: true,
|
[classes.button]: true,
|
||||||
[classes.normal]: !isActive,
|
[classes.normal]: !isActive,
|
||||||
[classes.active]: isActive
|
[classes.active]: isActive,
|
||||||
}
|
}
|
||||||
|
|
||||||
const normalButton = <Icon className={classes.buttonIcon} />
|
const normalButton = <Icon className={classes.buttonIcon} />
|
||||||
|
|
@ -29,14 +29,14 @@ const SubpageButton = memo(
|
||||||
<InverseIcon
|
<InverseIcon
|
||||||
className={classnames(
|
className={classnames(
|
||||||
classes.buttonIcon,
|
classes.buttonIcon,
|
||||||
classes.buttonIconActiveLeft
|
classes.buttonIconActiveLeft,
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<H4 className="text-white">{children}</H4>
|
<H4 className="text-white">{children}</H4>
|
||||||
<CancelIconInverse
|
<CancelIconInverse
|
||||||
className={classnames(
|
className={classnames(
|
||||||
classes.buttonIcon,
|
classes.buttonIcon,
|
||||||
classes.buttonIconActiveRight
|
classes.buttonIconActiveRight,
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|
@ -56,7 +56,7 @@ const SubpageButton = memo(
|
||||||
{isActive ? activeButton : normalButton}
|
{isActive ? activeButton : normalButton}
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default SubpageButton
|
export default SubpageButton
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.active:hover {
|
.active:hover {
|
||||||
background-color: var(--comet);
|
background-color: var(--comet);
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttonIcon {
|
.buttonIcon {
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ export default {
|
||||||
extend: baseButton,
|
extend: baseButton,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
color: white,
|
color: white,
|
||||||
borderRadius: baseButton.height / 2
|
borderRadius: baseButton.height / 2,
|
||||||
},
|
},
|
||||||
normalButton: {
|
normalButton: {
|
||||||
width: baseButton.height
|
width: baseButton.height,
|
||||||
},
|
},
|
||||||
activeButton: {
|
activeButton: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
|
@ -21,26 +21,26 @@ export default {
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
padding: '0 5px',
|
padding: '0 5px',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
backgroundColor: offColor
|
backgroundColor: offColor,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
buttonIcon: {
|
buttonIcon: {
|
||||||
width: 16,
|
width: 16,
|
||||||
height: 16,
|
height: 16,
|
||||||
overflow: 'visible',
|
overflow: 'visible',
|
||||||
'& g': {
|
'& g': {
|
||||||
strokeWidth: 1.8
|
strokeWidth: 1.8,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
buttonIconActiveLeft: {
|
buttonIconActiveLeft: {
|
||||||
marginRight: 12,
|
marginRight: 12,
|
||||||
marginLeft: 4
|
marginLeft: 4,
|
||||||
},
|
},
|
||||||
buttonIconActiveRight: {
|
buttonIconActiveRight: {
|
||||||
marginRight: 5,
|
marginRight: 5,
|
||||||
marginLeft: 20
|
marginLeft: 20,
|
||||||
},
|
},
|
||||||
white: {
|
white: {
|
||||||
color: white
|
color: white,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,5 +15,5 @@ export {
|
||||||
IDButton,
|
IDButton,
|
||||||
AddButton,
|
AddButton,
|
||||||
SupportLinkButton,
|
SupportLinkButton,
|
||||||
SubpageButton
|
SubpageButton,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import {
|
||||||
lastDayOfMonth,
|
lastDayOfMonth,
|
||||||
startOfMonth,
|
startOfMonth,
|
||||||
startOfWeek,
|
startOfWeek,
|
||||||
sub
|
sub,
|
||||||
} from 'date-fns/fp'
|
} from 'date-fns/fp'
|
||||||
import * as R from 'ramda'
|
import * as R from 'ramda'
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
|
|
@ -24,7 +24,7 @@ const Calendar = ({ minDate, maxDate, handleSelect, ...props }) => {
|
||||||
const [currentDisplayedMonth, setCurrentDisplayedMonth] = useState(new Date())
|
const [currentDisplayedMonth, setCurrentDisplayedMonth] = useState(new Date())
|
||||||
|
|
||||||
const weekdays = Array.from(Array(7)).map((_, i) =>
|
const weekdays = Array.from(Array(7)).map((_, i) =>
|
||||||
format('EEEEE', add({ days: i }, startOfWeek(new Date())))
|
format('EEEEE', add({ days: i }, startOfWeek(new Date()))),
|
||||||
)
|
)
|
||||||
|
|
||||||
const monthLength = month => getDaysInMonth(month)
|
const monthLength = month => getDaysInMonth(month)
|
||||||
|
|
@ -33,21 +33,21 @@ const Calendar = ({ minDate, maxDate, handleSelect, ...props }) => {
|
||||||
const lastMonth = sub({ months: 1 }, month)
|
const lastMonth = sub({ months: 1 }, month)
|
||||||
const lastMonthRange = R.range(0, getDay(startOfMonth(month))).reverse()
|
const lastMonthRange = R.range(0, getDay(startOfMonth(month))).reverse()
|
||||||
const lastMonthDays = R.map(i =>
|
const lastMonthDays = R.map(i =>
|
||||||
sub({ days: i }, lastDayOfMonth(lastMonth))
|
sub({ days: i }, lastDayOfMonth(lastMonth)),
|
||||||
)(lastMonthRange)
|
)(lastMonthRange)
|
||||||
|
|
||||||
const thisMonthRange = R.range(0, monthLength(month))
|
const thisMonthRange = R.range(0, monthLength(month))
|
||||||
const thisMonthDays = R.map(i => add({ days: i }, startOfMonth(month)))(
|
const thisMonthDays = R.map(i => add({ days: i }, startOfMonth(month)))(
|
||||||
thisMonthRange
|
thisMonthRange,
|
||||||
)
|
)
|
||||||
|
|
||||||
const nextMonth = add({ months: 1 }, month)
|
const nextMonth = add({ months: 1 }, month)
|
||||||
const nextMonthRange = R.range(
|
const nextMonthRange = R.range(
|
||||||
0,
|
0,
|
||||||
42 - lastMonthDays.length - thisMonthDays.length
|
42 - lastMonthDays.length - thisMonthDays.length,
|
||||||
)
|
)
|
||||||
const nextMonthDays = R.map(i => add({ days: i }, startOfMonth(nextMonth)))(
|
const nextMonthDays = R.map(i => add({ days: i }, startOfMonth(nextMonth)))(
|
||||||
nextMonthRange
|
nextMonthRange,
|
||||||
)
|
)
|
||||||
|
|
||||||
return R.concat(R.concat(lastMonthDays, thisMonthDays), nextMonthDays)
|
return R.concat(R.concat(lastMonthDays, thisMonthDays), nextMonthDays)
|
||||||
|
|
@ -63,7 +63,7 @@ const Calendar = ({ minDate, maxDate, handleSelect, ...props }) => {
|
||||||
isSameMonth(minDate, prevMonth) ||
|
isSameMonth(minDate, prevMonth) ||
|
||||||
differenceInMonths(minDate, prevMonth) > 0
|
differenceInMonths(minDate, prevMonth) > 0
|
||||||
? prevMonth
|
? prevMonth
|
||||||
: currentDisplayedMonth
|
: currentDisplayedMonth,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -75,7 +75,7 @@ const Calendar = ({ minDate, maxDate, handleSelect, ...props }) => {
|
||||||
isSameMonth(maxDate, nextMonth) ||
|
isSameMonth(maxDate, nextMonth) ||
|
||||||
differenceInMonths(nextMonth, maxDate) > 0
|
differenceInMonths(nextMonth, maxDate) > 0
|
||||||
? nextMonth
|
? nextMonth
|
||||||
: currentDisplayedMonth
|
: currentDisplayedMonth,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -91,7 +91,7 @@ const Calendar = ({ minDate, maxDate, handleSelect, ...props }) => {
|
||||||
<span>
|
<span>
|
||||||
{`${format('MMMM', currentDisplayedMonth)} ${format(
|
{`${format('MMMM', currentDisplayedMonth)} ${format(
|
||||||
'yyyy',
|
'yyyy',
|
||||||
currentDisplayedMonth
|
currentDisplayedMonth,
|
||||||
)}`}
|
)}`}
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table th,
|
.table th,
|
||||||
.table td {
|
.table td {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 3px 0 3px 0;
|
padding: 3px 0 3px 0;
|
||||||
|
|
@ -63,4 +63,4 @@
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-family: var(--museo);
|
font-family: var(--museo);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,14 @@ const DateRangePicker = ({ minDate, maxDate, className, onRangeChange }) => {
|
||||||
if (from && !to) {
|
if (from && !to) {
|
||||||
if (differenceInDays(from, day) >= 0) {
|
if (differenceInDays(from, day) >= 0) {
|
||||||
setTo(
|
setTo(
|
||||||
set({ hours: 23, minutes: 59, seconds: 59, milliseconds: 999 }, day)
|
set({ hours: 23, minutes: 59, seconds: 59, milliseconds: 999 }, day),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
setTo(
|
setTo(
|
||||||
set(
|
set(
|
||||||
{ hours: 23, minutes: 59, seconds: 59, milliseconds: 999 },
|
{ hours: 23, minutes: 59, seconds: 59, milliseconds: 999 },
|
||||||
R.clone(from)
|
R.clone(from),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
setFrom(day)
|
setFrom(day)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,24 +8,24 @@ const Tile = ({
|
||||||
isUpperBound,
|
isUpperBound,
|
||||||
isBetween,
|
isBetween,
|
||||||
isDisabled,
|
isDisabled,
|
||||||
children
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
const selected = isLowerBound || isUpperBound
|
const selected = isLowerBound || isUpperBound
|
||||||
|
|
||||||
const rangeClasses = {
|
const rangeClasses = {
|
||||||
[classes.between]: isBetween && !(isLowerBound && isUpperBound),
|
[classes.between]: isBetween && !(isLowerBound && isUpperBound),
|
||||||
[classes.lowerBound]: isLowerBound && !isUpperBound,
|
[classes.lowerBound]: isLowerBound && !isUpperBound,
|
||||||
[classes.upperBound]: isUpperBound && !isLowerBound
|
[classes.upperBound]: isUpperBound && !isLowerBound,
|
||||||
}
|
}
|
||||||
|
|
||||||
const buttonWrapperClasses = {
|
const buttonWrapperClasses = {
|
||||||
[classes.wrapper]: true,
|
[classes.wrapper]: true,
|
||||||
[classes.selected]: selected
|
[classes.selected]: selected,
|
||||||
}
|
}
|
||||||
|
|
||||||
const buttonClasses = {
|
const buttonClasses = {
|
||||||
[classes.button]: true,
|
[classes.button]: true,
|
||||||
[classes.disabled]: isDisabled
|
[classes.disabled]: isDisabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import {
|
||||||
Td,
|
Td,
|
||||||
THead,
|
THead,
|
||||||
TDoubleLevelHead,
|
TDoubleLevelHead,
|
||||||
ThDoubleLevel
|
ThDoubleLevel,
|
||||||
} from 'src/components/fake-table/Table'
|
} from 'src/components/fake-table/Table'
|
||||||
|
|
||||||
import { sentenceCase } from 'src/utils/string'
|
import { sentenceCase } from 'src/utils/string'
|
||||||
|
|
@ -24,11 +24,11 @@ const groupSecondHeader = elements => {
|
||||||
{
|
{
|
||||||
width: R.sum(R.map(R.prop('width'), group)),
|
width: R.sum(R.map(R.prop('width'), group)),
|
||||||
elements: group,
|
elements: group,
|
||||||
name: doubleHeader(group[0])
|
name: doubleHeader(group[0]),
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
),
|
),
|
||||||
R.reduce(R.concat, [])
|
R.reduce(R.concat, []),
|
||||||
)
|
)
|
||||||
|
|
||||||
return R.all(R.pipe(doubleHeader, R.isNil), elements)
|
return R.all(R.pipe(doubleHeader, R.isNil), elements)
|
||||||
|
|
@ -47,7 +47,7 @@ const Header = () => {
|
||||||
enableToggle,
|
enableToggle,
|
||||||
toggleWidth,
|
toggleWidth,
|
||||||
orderedBy,
|
orderedBy,
|
||||||
DEFAULT_COL_SIZE
|
DEFAULT_COL_SIZE,
|
||||||
} = useContext(TableCtx)
|
} = useContext(TableCtx)
|
||||||
|
|
||||||
const mapElement2 = (it, idx) => {
|
const mapElement2 = (it, idx) => {
|
||||||
|
|
@ -66,11 +66,13 @@ const Header = () => {
|
||||||
|
|
||||||
const mapElement = (
|
const mapElement = (
|
||||||
{ name, display, width = DEFAULT_COL_SIZE, header, textAlign },
|
{ name, display, width = DEFAULT_COL_SIZE, header, textAlign },
|
||||||
idx
|
idx,
|
||||||
) => {
|
) => {
|
||||||
const orderClasses = classnames({
|
const orderClasses = classnames({
|
||||||
'whitespace-nowrap':
|
'whitespace-nowrap':
|
||||||
R.isNil(header) && !R.isNil(orderedBy) && R.equals(name, orderedBy.code)
|
R.isNil(header) &&
|
||||||
|
!R.isNil(orderedBy) &&
|
||||||
|
R.equals(name, orderedBy.code),
|
||||||
})
|
})
|
||||||
|
|
||||||
const attachOrderedByToComplexHeader = header => {
|
const attachOrderedByToComplexHeader = header => {
|
||||||
|
|
@ -82,6 +84,7 @@ const Header = () => {
|
||||||
spanChild.props.children = R.append(' -', spanChild.props.children)
|
spanChild.props.children = R.append(' -', spanChild.props.children)
|
||||||
return cloneHeader
|
return cloneHeader
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
return header
|
return header
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const NamespacedTable = ({
|
||||||
|
|
||||||
const innerData = R.map(it => ({
|
const innerData = R.map(it => ({
|
||||||
id: it,
|
id: it,
|
||||||
...fromNamespace(it)(data)
|
...fromNamespace(it)(data),
|
||||||
}))(namespaces)
|
}))(namespaces)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ const ActionCol = ({ disabled, editing }) => {
|
||||||
forceAdd,
|
forceAdd,
|
||||||
clearError,
|
clearError,
|
||||||
actionColSize,
|
actionColSize,
|
||||||
error
|
error,
|
||||||
} = useContext(TableCtx)
|
} = useContext(TableCtx)
|
||||||
|
|
||||||
const disableEdit = disabled || (disableRowEdit && disableRowEdit(values))
|
const disableEdit = disabled || (disableRowEdit && disableRowEdit(values))
|
||||||
|
|
@ -136,10 +136,10 @@ const ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => {
|
||||||
PrefixComponent = Label2,
|
PrefixComponent = Label2,
|
||||||
suffix,
|
suffix,
|
||||||
SuffixComponent = Label2,
|
SuffixComponent = Label2,
|
||||||
textStyle = it => {},
|
textStyle = () => {},
|
||||||
isHidden = it => false,
|
isHidden = () => false,
|
||||||
view = it => it?.toString(),
|
view = it => it?.toString(),
|
||||||
inputProps = {}
|
inputProps = {},
|
||||||
} = config
|
} = config
|
||||||
|
|
||||||
const fields = names ?? [name]
|
const fields = names ?? [name]
|
||||||
|
|
@ -158,7 +158,7 @@ const ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => {
|
||||||
size,
|
size,
|
||||||
bold,
|
bold,
|
||||||
textAlign: isEditing ? editingAlign : textAlign,
|
textAlign: isEditing ? editingAlign : textAlign,
|
||||||
...inputProps
|
...inputProps,
|
||||||
}
|
}
|
||||||
|
|
||||||
const newAlign = isEditing ? editingAlign : textAlign
|
const newAlign = isEditing ? editingAlign : textAlign
|
||||||
|
|
@ -174,7 +174,7 @@ const ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => {
|
||||||
className={{
|
className={{
|
||||||
[moduleStyles.extraPaddingRight]: extraPaddingRight,
|
[moduleStyles.extraPaddingRight]: extraPaddingRight,
|
||||||
[moduleStyles.extraPadding]: extraPadding,
|
[moduleStyles.extraPadding]: extraPadding,
|
||||||
'flex items-center': suffix || prefix
|
'flex items-center': suffix || prefix,
|
||||||
}}
|
}}
|
||||||
width={width}
|
width={width}
|
||||||
size={size}
|
size={size}
|
||||||
|
|
@ -225,7 +225,7 @@ const groupStriped = elements => {
|
||||||
return R.insert(
|
return R.insert(
|
||||||
index,
|
index,
|
||||||
{ width, editable: false, view: () => <StripesSvg /> },
|
{ width, editable: false, view: () => <StripesSvg /> },
|
||||||
noStripe
|
noStripe,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,7 +238,7 @@ const ERow = ({ editing, disabled, lastOfGroup, newRow }) => {
|
||||||
error,
|
error,
|
||||||
enableToggle,
|
enableToggle,
|
||||||
rowSize,
|
rowSize,
|
||||||
stripeWhen
|
stripeWhen,
|
||||||
} = useContext(TableCtx)
|
} = useContext(TableCtx)
|
||||||
|
|
||||||
const shouldStripe = !editing && stripeWhen && stripeWhen(values)
|
const shouldStripe = !editing && stripeWhen && stripeWhen(values)
|
||||||
|
|
@ -255,11 +255,11 @@ const ERow = ({ editing, disabled, lastOfGroup, newRow }) => {
|
||||||
: -1
|
: -1
|
||||||
|
|
||||||
const elementToFocusIndex = innerElements.findIndex(
|
const elementToFocusIndex = innerElements.findIndex(
|
||||||
it => it.editable === undefined || it.editable
|
it => it.editable === undefined || it.editable,
|
||||||
)
|
)
|
||||||
|
|
||||||
const classNames = {
|
const classNames = {
|
||||||
[moduleStyles.lastOfGroup]: lastOfGroup
|
[moduleStyles.lastOfGroup]: lastOfGroup,
|
||||||
}
|
}
|
||||||
|
|
||||||
const touchedErrors = R.pick(R.keys(touched), errors)
|
const touchedErrors = R.pick(R.keys(touched), errors)
|
||||||
|
|
|
||||||
|
|
@ -26,4 +26,4 @@
|
||||||
.fields {
|
.fields {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ const DEFAULT_COL_SIZE = 100
|
||||||
|
|
||||||
const getWidth = R.compose(
|
const getWidth = R.compose(
|
||||||
R.reduce(R.add)(0),
|
R.reduce(R.add)(0),
|
||||||
R.map(it => it.width ?? DEFAULT_COL_SIZE)
|
R.map(it => it.width ?? DEFAULT_COL_SIZE),
|
||||||
)
|
)
|
||||||
|
|
||||||
const ETable = ({
|
const ETable = ({
|
||||||
|
|
@ -54,7 +54,7 @@ const ETable = ({
|
||||||
createText = 'Add override',
|
createText = 'Add override',
|
||||||
forceAdd = false,
|
forceAdd = false,
|
||||||
tbodyWrapperClass,
|
tbodyWrapperClass,
|
||||||
orderedBy = null
|
orderedBy = null,
|
||||||
}) => {
|
}) => {
|
||||||
const [editingId, setEditingId] = useState(null)
|
const [editingId, setEditingId] = useState(null)
|
||||||
const [adding, setAdding] = useState(false)
|
const [adding, setAdding] = useState(false)
|
||||||
|
|
@ -80,6 +80,7 @@ const ETable = ({
|
||||||
try {
|
try {
|
||||||
await save({ [name]: list }, it)
|
await save({ [name]: list }, it)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
setSaving(false)
|
setSaving(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -152,7 +153,7 @@ const ETable = ({
|
||||||
stripeWhen,
|
stripeWhen,
|
||||||
forceAdd,
|
forceAdd,
|
||||||
orderedBy,
|
orderedBy,
|
||||||
DEFAULT_COL_SIZE
|
DEFAULT_COL_SIZE,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -35,20 +35,20 @@ const Td = ({
|
||||||
size,
|
size,
|
||||||
bold,
|
bold,
|
||||||
textAlign,
|
textAlign,
|
||||||
action
|
action,
|
||||||
}) => {
|
}) => {
|
||||||
const inlineStyle = {
|
const inlineStyle = {
|
||||||
...style,
|
...style,
|
||||||
width,
|
width,
|
||||||
textAlign,
|
textAlign,
|
||||||
fontSize: size === 'sm' ? '14px' : size === 'lg' ? '24px' : ''
|
fontSize: size === 'sm' ? '14px' : size === 'lg' ? '24px' : '',
|
||||||
}
|
}
|
||||||
|
|
||||||
const cssClasses = {
|
const cssClasses = {
|
||||||
[styles.td]: !header,
|
[styles.td]: !header,
|
||||||
[styles.tdHeader]: header,
|
[styles.tdHeader]: header,
|
||||||
'font-bold': !header && (bold || size === 'lg'),
|
'font-bold': !header && (bold || size === 'lg'),
|
||||||
[styles.actionCol]: action
|
[styles.actionCol]: action,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -88,21 +88,21 @@ const Tr = ({
|
||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
size,
|
size,
|
||||||
newRow
|
newRow,
|
||||||
}) => {
|
}) => {
|
||||||
const inlineStyle = {
|
const inlineStyle = {
|
||||||
minHeight: size === 'sm' ? '34px' : size === 'lg' ? '68px' : '48px'
|
minHeight: size === 'sm' ? '34px' : size === 'lg' ? '68px' : '48px',
|
||||||
}
|
}
|
||||||
const cardClasses = {
|
const cardClasses = {
|
||||||
[styles.card]: true,
|
[styles.card]: true,
|
||||||
[styles.trError]: error,
|
[styles.trError]: error,
|
||||||
[styles.trAdding]: newRow
|
[styles.trAdding]: newRow,
|
||||||
}
|
}
|
||||||
|
|
||||||
const mainContentClasses = {
|
const mainContentClasses = {
|
||||||
[styles.mainContent]: true,
|
[styles.mainContent]: true,
|
||||||
[styles.sizeSm]: size === 'sm',
|
[styles.sizeSm]: size === 'sm',
|
||||||
[styles.sizeLg]: size === 'lg'
|
[styles.sizeLg]: size === 'lg',
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -141,5 +141,5 @@ export {
|
||||||
Td,
|
Td,
|
||||||
Th,
|
Th,
|
||||||
ThDoubleLevel,
|
ThDoubleLevel,
|
||||||
EditCell
|
EditCell,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import { P } from 'src/components/typography'
|
||||||
import TextInput from './TextInput'
|
import TextInput from './TextInput'
|
||||||
|
|
||||||
const Autocomplete = ({
|
const Autocomplete = ({
|
||||||
optionsLimit = 5, // set limit = null for no limit
|
|
||||||
limit,
|
limit,
|
||||||
options,
|
options,
|
||||||
label,
|
label,
|
||||||
|
|
@ -17,7 +16,6 @@ const Autocomplete = ({
|
||||||
multiple,
|
multiple,
|
||||||
onChange,
|
onChange,
|
||||||
labelProp,
|
labelProp,
|
||||||
shouldStayOpen,
|
|
||||||
value: outsideValue,
|
value: outsideValue,
|
||||||
error,
|
error,
|
||||||
fullWidth,
|
fullWidth,
|
||||||
|
|
@ -61,11 +59,11 @@ const Autocomplete = ({
|
||||||
const filterOptions = (array, { inputValue }) =>
|
const filterOptions = (array, { inputValue }) =>
|
||||||
R.union(
|
R.union(
|
||||||
R.isEmpty(inputValue) ? valueArray() : [],
|
R.isEmpty(inputValue) ? valueArray() : [],
|
||||||
filter(array, inputValue)
|
filter(array, inputValue),
|
||||||
).slice(
|
).slice(
|
||||||
0,
|
0,
|
||||||
R.defaultTo(undefined)(limit) &&
|
R.defaultTo(undefined)(limit) &&
|
||||||
Math.max(limit, R.isEmpty(inputValue) ? valueArray().length : 0)
|
Math.max(limit, R.isEmpty(inputValue) ? valueArray().length : 0),
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -105,7 +103,7 @@ const Autocomplete = ({
|
||||||
'flex w-4 h-4 rounded-md': true,
|
'flex w-4 h-4 rounded-md': true,
|
||||||
'bg-spring4': props.warning === 'clean',
|
'bg-spring4': props.warning === 'clean',
|
||||||
'bg-orange-yellow': props.warning === 'partial',
|
'bg-orange-yellow': props.warning === 'partial',
|
||||||
'bg-tomato': props.warning === 'important'
|
'bg-tomato': props.warning === 'important',
|
||||||
}
|
}
|
||||||
|
|
||||||
const hoverableElement = <div className={classnames(className)} />
|
const hoverableElement = <div className={classnames(className)} />
|
||||||
|
|
@ -122,9 +120,10 @@ const Autocomplete = ({
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
slotProps={{
|
slotProps={{
|
||||||
chip: { onDelete: null }
|
chip: { onDelete: null },
|
||||||
}} />
|
}}
|
||||||
);
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Autocomplete
|
export default Autocomplete
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ const CodeInput = ({
|
||||||
numInputs,
|
numInputs,
|
||||||
error,
|
error,
|
||||||
inputStyle,
|
inputStyle,
|
||||||
containerStyle
|
containerStyle,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<OtpInput
|
<OtpInput
|
||||||
|
|
@ -26,7 +26,7 @@ const CodeInput = ({
|
||||||
inputStyle,
|
inputStyle,
|
||||||
classes.input,
|
classes.input,
|
||||||
'font-museo font-black text-4xl',
|
'font-museo font-black text-4xl',
|
||||||
error && 'border-tomato'
|
error && 'border-tomato',
|
||||||
)}
|
)}
|
||||||
inputType={'tel'}
|
inputType={'tel'}
|
||||||
renderInput={props => <input {...props} />}
|
renderInput={props => <input {...props} />}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ const Dropdown = ({ label, name, options, onChange, value, className }) => {
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Dropdown
|
export default Dropdown
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ const NumberInput = memo(
|
||||||
bold,
|
bold,
|
||||||
className,
|
className,
|
||||||
decimalPlaces,
|
decimalPlaces,
|
||||||
InputProps,
|
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -41,14 +40,14 @@ const NumberInput = memo(
|
||||||
onChange({
|
onChange({
|
||||||
target: {
|
target: {
|
||||||
id: name,
|
id: name,
|
||||||
value: values.floatValue
|
value: values.floatValue,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default NumberInput
|
export default NumberInput
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ const RadioGroup = ({
|
||||||
onChange,
|
onChange,
|
||||||
className,
|
className,
|
||||||
labelClassName,
|
labelClassName,
|
||||||
radioClassName
|
radioClassName,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ const SecretInput = memo(
|
||||||
placeholder={isPasswordFilled ? placeholder : ''}
|
placeholder={isPasswordFilled ? placeholder : ''}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default SecretInput
|
export default SecretInput
|
||||||
|
|
|
||||||
|
|
@ -7,20 +7,19 @@ import Arrowdown from 'src/styling/icons/action/arrow/regular.svg?react'
|
||||||
import styles from './Select.module.css'
|
import styles from './Select.module.css'
|
||||||
|
|
||||||
function Select({ className, label, items, ...props }) {
|
function Select({ className, label, items, ...props }) {
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isOpen,
|
isOpen,
|
||||||
selectedItem,
|
selectedItem,
|
||||||
getToggleButtonProps,
|
getToggleButtonProps,
|
||||||
getLabelProps,
|
getLabelProps,
|
||||||
getMenuProps,
|
getMenuProps,
|
||||||
getItemProps
|
getItemProps,
|
||||||
} = useSelect({
|
} = useSelect({
|
||||||
items,
|
items,
|
||||||
selectedItem: props.selectedItem,
|
selectedItem: props.selectedItem,
|
||||||
onSelectedItemChange: item => {
|
onSelectedItemChange: item => {
|
||||||
props.onSelectedItemChange(item.selectedItem)
|
props.onSelectedItemChange(item.selectedItem)
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const selectClassNames = {
|
const selectClassNames = {
|
||||||
|
|
@ -28,7 +27,7 @@ function Select({ className, label, items, ...props }) {
|
||||||
[styles.selectFiltered]: props.defaultAsFilter
|
[styles.selectFiltered]: props.defaultAsFilter
|
||||||
? true
|
? true
|
||||||
: !R.equals(selectedItem, props.default),
|
: !R.equals(selectedItem, props.default),
|
||||||
[styles.open]: isOpen
|
[styles.open]: isOpen,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -97,4 +97,4 @@
|
||||||
|
|
||||||
.open button {
|
.open button {
|
||||||
border-radius: 8px 8px 0 0;
|
border-radius: 8px 8px 0 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ const TextInput = memo(
|
||||||
onBlur,
|
onBlur,
|
||||||
value,
|
value,
|
||||||
error,
|
error,
|
||||||
suffix,
|
|
||||||
textAlign,
|
textAlign,
|
||||||
width,
|
width,
|
||||||
inputClasses,
|
inputClasses,
|
||||||
|
|
@ -29,7 +28,7 @@ const TextInput = memo(
|
||||||
|
|
||||||
const style = {
|
const style = {
|
||||||
width: width,
|
width: width,
|
||||||
textAlign: textAlign
|
textAlign: textAlign,
|
||||||
}
|
}
|
||||||
|
|
||||||
const sizeClass =
|
const sizeClass =
|
||||||
|
|
@ -40,7 +39,7 @@ const TextInput = memo(
|
||||||
: styles.size
|
: styles.size
|
||||||
|
|
||||||
const divClass = {
|
const divClass = {
|
||||||
[styles.bold]: bold
|
[styles.bold]: bold,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -60,15 +59,16 @@ const TextInput = memo(
|
||||||
classes: {
|
classes: {
|
||||||
root: sizeClass,
|
root: sizeClass,
|
||||||
underline: filled ? styles.underline : null,
|
underline: filled ? styles.underline : null,
|
||||||
input: inputClasses
|
input: inputClasses,
|
||||||
},
|
},
|
||||||
...InputProps
|
...InputProps,
|
||||||
},
|
},
|
||||||
|
|
||||||
htmlInput: { style: { textAlign } }
|
htmlInput: { style: { textAlign } },
|
||||||
}} />
|
}}
|
||||||
);
|
/>
|
||||||
}
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default TextInput
|
export default TextInput
|
||||||
|
|
|
||||||
|
|
@ -21,4 +21,4 @@
|
||||||
|
|
||||||
.underline:hover:not(.Mui-disabled)::before {
|
.underline:hover:not(.Mui-disabled)::before {
|
||||||
border-bottom-color: var(--spring);
|
border-bottom-color: var(--spring);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import RadioGroup from './RadioGroup'
|
||||||
import SecretInput from './SecretInput'
|
import SecretInput from './SecretInput'
|
||||||
import TextInput from './TextInput'
|
import TextInput from './TextInput'
|
||||||
import ToggleButtonGroup from './ToggleButtonGroup'
|
import ToggleButtonGroup from './ToggleButtonGroup'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Checkbox,
|
Checkbox,
|
||||||
CodeInput,
|
CodeInput,
|
||||||
|
|
@ -16,5 +17,5 @@ export {
|
||||||
RadioGroup,
|
RadioGroup,
|
||||||
Autocomplete,
|
Autocomplete,
|
||||||
ToggleButtonGroup,
|
ToggleButtonGroup,
|
||||||
Dropdown
|
Dropdown,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,12 @@ import { primaryColor as zodiac, tomato } from '../../../styling/variables.js'
|
||||||
const colors = {
|
const colors = {
|
||||||
cashOut: {
|
cashOut: {
|
||||||
empty: tomato,
|
empty: tomato,
|
||||||
full: zodiac
|
full: zodiac,
|
||||||
},
|
},
|
||||||
cashIn: {
|
cashIn: {
|
||||||
empty: zodiac,
|
empty: zodiac,
|
||||||
full: tomato
|
full: tomato,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const Cashbox = ({
|
const Cashbox = ({
|
||||||
|
|
@ -28,7 +28,7 @@ const Cashbox = ({
|
||||||
emptyPartClassName,
|
emptyPartClassName,
|
||||||
labelClassName,
|
labelClassName,
|
||||||
omitInnerPercentage,
|
omitInnerPercentage,
|
||||||
isLow
|
isLow,
|
||||||
}) => {
|
}) => {
|
||||||
const ltHalf = percent <= 51
|
const ltHalf = percent <= 51
|
||||||
const color =
|
const color =
|
||||||
|
|
@ -72,7 +72,7 @@ const CashIn = ({
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
total,
|
total,
|
||||||
omitInnerPercentage
|
omitInnerPercentage,
|
||||||
}) => {
|
}) => {
|
||||||
const percent = (100 * notes) / capacity
|
const percent = (100 * notes) / capacity
|
||||||
const isLow = percent < threshold
|
const isLow = percent < threshold
|
||||||
|
|
@ -117,7 +117,7 @@ const CashOut = ({
|
||||||
threshold,
|
threshold,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
omitInnerPercentage
|
omitInnerPercentage,
|
||||||
}) => {
|
}) => {
|
||||||
const percent = (100 * notes) / capacity
|
const percent = (100 * notes) / capacity
|
||||||
const isLow = percent < threshold
|
const isLow = percent < threshold
|
||||||
|
|
@ -159,7 +159,7 @@ const CashOutLite = ({
|
||||||
currency,
|
currency,
|
||||||
notes,
|
notes,
|
||||||
threshold,
|
threshold,
|
||||||
width
|
width,
|
||||||
}) => {
|
}) => {
|
||||||
const percent = (100 * notes) / capacity
|
const percent = (100 * notes) / capacity
|
||||||
const isLow = percent < threshold
|
const isLow = percent < threshold
|
||||||
|
|
|
||||||
|
|
@ -49,4 +49,4 @@
|
||||||
border: 2px solid;
|
border: 2px solid;
|
||||||
text-align: end;
|
text-align: end;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ const CashCassetteInput = memo(
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default CashCassetteInput
|
export default CashCassetteInput
|
||||||
|
|
|
||||||
|
|
@ -3,20 +3,13 @@ import React, { memo } from 'react'
|
||||||
import { Checkbox } from '../base'
|
import { Checkbox } from '../base'
|
||||||
|
|
||||||
const CheckboxInput = memo(
|
const CheckboxInput = memo(
|
||||||
({
|
({ label, enabled = true, disabledMessage = '', ...props }) => {
|
||||||
label,
|
|
||||||
textAlign,
|
|
||||||
fullWidth,
|
|
||||||
enabled = true,
|
|
||||||
disabledMessage = '',
|
|
||||||
...props
|
|
||||||
}) => {
|
|
||||||
const { name, onChange, value } = props.field
|
const { name, onChange, value } = props.field
|
||||||
|
|
||||||
const settings = {
|
const settings = {
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
label: label,
|
label: label,
|
||||||
disabledMessage: disabledMessage
|
disabledMessage: disabledMessage,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -28,7 +21,7 @@ const CheckboxInput = memo(
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default CheckboxInput
|
export default CheckboxInput
|
||||||
|
|
|
||||||
|
|
@ -15,5 +15,5 @@ export {
|
||||||
SecretInput,
|
SecretInput,
|
||||||
RadioGroup,
|
RadioGroup,
|
||||||
CashCassetteInput,
|
CashCassetteInput,
|
||||||
Dropdown
|
Dropdown,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,5 +14,5 @@ export {
|
||||||
Select,
|
Select,
|
||||||
RadioGroup,
|
RadioGroup,
|
||||||
CashIn,
|
CashIn,
|
||||||
CashOut
|
CashOut,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -177,16 +177,16 @@ const Header = memo(({ tree, user }) => {
|
||||||
name: 'offset',
|
name: 'offset',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
options: {
|
options: {
|
||||||
offset: ['100vw', '100vw']
|
offset: ['100vw', '100vw'],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'preventOverflow',
|
name: 'preventOverflow',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
options: {
|
options: {
|
||||||
rootBoundary: 'viewport'
|
rootBoundary: 'viewport',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]}>
|
]}>
|
||||||
<NotificationCenter
|
<NotificationCenter
|
||||||
popperRef={popperRef}
|
popperRef={popperRef}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.li::after {
|
.li::after {
|
||||||
content: "";
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
background: white;
|
background: white;
|
||||||
width: 0;
|
width: 0;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ const Sidebar = ({
|
||||||
onClick,
|
onClick,
|
||||||
children,
|
children,
|
||||||
itemRender,
|
itemRender,
|
||||||
loading = false
|
loading = false,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.sidebar}>
|
<div className={styles.sidebar}>
|
||||||
|
|
@ -30,7 +30,7 @@ const Sidebar = ({
|
||||||
[styles.activeLink]: isSelected(it),
|
[styles.activeLink]: isSelected(it),
|
||||||
[styles.customRenderActiveLink]: itemRender && isSelected(it),
|
[styles.customRenderActiveLink]: itemRender && isSelected(it),
|
||||||
[styles.customRenderLink]: itemRender,
|
[styles.customRenderLink]: itemRender,
|
||||||
[styles.link]: true
|
[styles.link]: true,
|
||||||
})}>
|
})}>
|
||||||
{itemRender ? itemRender(it, isSelected(it)) : displayName(it)}
|
{itemRender ? itemRender(it, isSelected(it)) : displayName(it)}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -54,7 +54,7 @@ const Stepper = ({ step, it, idx, steps }) => {
|
||||||
className={classnames({
|
className={classnames({
|
||||||
[styles.itemText]: true,
|
[styles.itemText]: true,
|
||||||
[styles.itemTextActive]: active,
|
[styles.itemTextActive]: active,
|
||||||
[styles.itemTextPast]: past
|
[styles.itemTextPast]: past,
|
||||||
})}>
|
})}>
|
||||||
{it.label}
|
{it.label}
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -65,7 +65,7 @@ const Stepper = ({ step, it, idx, steps }) => {
|
||||||
<div
|
<div
|
||||||
className={classnames({
|
className={classnames({
|
||||||
[styles.stepperPath]: true,
|
[styles.stepperPath]: true,
|
||||||
[styles.stepperPast]: past
|
[styles.stepperPast]: past,
|
||||||
})}></div>
|
})}></div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.link::after {
|
.link::after {
|
||||||
content: "";
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
background: var(--zodiac);
|
background: var(--zodiac);
|
||||||
width: 4px;
|
width: 4px;
|
||||||
|
|
@ -103,4 +103,4 @@
|
||||||
|
|
||||||
.stepperPast {
|
.stepperPast {
|
||||||
border: 1px solid var(--zodiac);
|
border: 1px solid var(--zodiac);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,13 @@ const TitleSection = ({
|
||||||
buttons = [],
|
buttons = [],
|
||||||
children,
|
children,
|
||||||
appendix,
|
appendix,
|
||||||
appendixRight
|
appendixRight,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classnames(
|
className={classnames(
|
||||||
'flex justify-between items-center flex-row',
|
'flex justify-between items-center flex-row',
|
||||||
className
|
className,
|
||||||
)}>
|
)}>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Title>{title}</Title>
|
<Title>{title}</Title>
|
||||||
|
|
@ -44,7 +44,7 @@ const TitleSection = ({
|
||||||
{button.text}
|
{button.text}
|
||||||
</Info1>
|
</Info1>
|
||||||
</SubpageButton>
|
</SubpageButton>
|
||||||
)
|
),
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ const STATES = {
|
||||||
EMPTY: 'EMPTY',
|
EMPTY: 'EMPTY',
|
||||||
RUNNING: 'RUNNING',
|
RUNNING: 'RUNNING',
|
||||||
FAILURE: 'FAILURE',
|
FAILURE: 'FAILURE',
|
||||||
FILLED: 'FILLED'
|
FILLED: 'FILLED',
|
||||||
}
|
}
|
||||||
|
|
||||||
const MACHINE = gql`
|
const MACHINE = gql`
|
||||||
|
|
@ -47,7 +47,7 @@ const MACHINE_LOGS = gql`
|
||||||
|
|
||||||
const createCsv = async ({ machineLogsCsv }) => {
|
const createCsv = async ({ machineLogsCsv }) => {
|
||||||
const machineLogs = new Blob([machineLogsCsv], {
|
const machineLogs = new Blob([machineLogsCsv], {
|
||||||
type: 'text/plain;charset=utf-8'
|
type: 'text/plain;charset=utf-8',
|
||||||
})
|
})
|
||||||
|
|
||||||
FileSaver.saveAs(machineLogs, 'machineLogs.csv')
|
FileSaver.saveAs(machineLogs, 'machineLogs.csv')
|
||||||
|
|
@ -59,11 +59,11 @@ const DiagnosticsModal = ({ onClose, deviceId, sendAction }) => {
|
||||||
let timeout = null
|
let timeout = null
|
||||||
|
|
||||||
const [fetchSummary, { loading }] = useLazyQuery(MACHINE_LOGS, {
|
const [fetchSummary, { loading }] = useLazyQuery(MACHINE_LOGS, {
|
||||||
onCompleted: data => createCsv(data)
|
onCompleted: data => createCsv(data),
|
||||||
})
|
})
|
||||||
|
|
||||||
const { data, stopPolling, startPolling } = useQuery(MACHINE, {
|
const { data, stopPolling, startPolling } = useQuery(MACHINE, {
|
||||||
variables: { deviceId }
|
variables: { deviceId },
|
||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -168,8 +168,8 @@ const DiagnosticsModal = ({ onClose, deviceId, sendAction }) => {
|
||||||
variables: {
|
variables: {
|
||||||
from: subMinutes(new Date(timestamp), 5),
|
from: subMinutes(new Date(timestamp), 5),
|
||||||
deviceId,
|
deviceId,
|
||||||
limit: 500
|
limit: 500,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
className="mt-auto ml-auto mr-2 mb-0">
|
className="mt-auto ml-auto mr-2 mb-0">
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ const isStaticState = machineState => {
|
||||||
'unpaired',
|
'unpaired',
|
||||||
'maintenance',
|
'maintenance',
|
||||||
'virgin',
|
'virgin',
|
||||||
'wifiList'
|
'wifiList',
|
||||||
]
|
]
|
||||||
return staticStates.includes(machineState)
|
return staticStates.includes(machineState)
|
||||||
}
|
}
|
||||||
|
|
@ -73,7 +73,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
||||||
|
|
||||||
const [fetchMachineEvents, { loading: loadingEvents }] = useLazyQuery(
|
const [fetchMachineEvents, { loading: loadingEvents }] = useLazyQuery(
|
||||||
MACHINE,
|
MACHINE,
|
||||||
preflightOptions
|
preflightOptions,
|
||||||
)
|
)
|
||||||
|
|
||||||
const [simpleMachineAction] = useMutation(MACHINE_ACTION)
|
const [simpleMachineAction] = useMutation(MACHINE_ACTION)
|
||||||
|
|
@ -86,7 +86,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
||||||
onCompleted: () => {
|
onCompleted: () => {
|
||||||
onActionSuccess && onActionSuccess()
|
onActionSuccess && onActionSuccess()
|
||||||
setAction({ display: action.display, command: null })
|
setAction({ display: action.display, command: null })
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const confirmDialogOpen = Boolean(action.command)
|
const confirmDialogOpen = Boolean(action.command)
|
||||||
|
|
@ -100,7 +100,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
||||||
? warningMessage
|
? warningMessage
|
||||||
: null
|
: null
|
||||||
setAction({ ...actionToDo, message })
|
setAction({ ...actionToDo, message })
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
fetchMachineEvents()
|
fetchMachineEvents()
|
||||||
}
|
}
|
||||||
|
|
@ -118,7 +118,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
||||||
setAction({
|
setAction({
|
||||||
command: 'rename',
|
command: 'rename',
|
||||||
display: 'Rename',
|
display: 'Rename',
|
||||||
confirmationMessage: 'Write the new name for this machine'
|
confirmationMessage: 'Write the new name for this machine',
|
||||||
})
|
})
|
||||||
}>
|
}>
|
||||||
Rename
|
Rename
|
||||||
|
|
@ -131,7 +131,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setAction({
|
setAction({
|
||||||
command: 'unpair',
|
command: 'unpair',
|
||||||
display: 'Unpair'
|
display: 'Unpair',
|
||||||
})
|
})
|
||||||
}>
|
}>
|
||||||
Unpair
|
Unpair
|
||||||
|
|
@ -144,7 +144,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setAction({
|
setAction({
|
||||||
command: 'reboot',
|
command: 'reboot',
|
||||||
display: 'Reboot'
|
display: 'Reboot',
|
||||||
})
|
})
|
||||||
}>
|
}>
|
||||||
Reboot
|
Reboot
|
||||||
|
|
@ -159,7 +159,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
||||||
command: 'shutdown',
|
command: 'shutdown',
|
||||||
display: 'Shutdown',
|
display: 'Shutdown',
|
||||||
message:
|
message:
|
||||||
'In order to bring it back online, the machine will need to be visited and its power reset.'
|
'In order to bring it back online, the machine will need to be visited and its power reset.',
|
||||||
})
|
})
|
||||||
}>
|
}>
|
||||||
Shutdown
|
Shutdown
|
||||||
|
|
@ -172,7 +172,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
machineStatusPreflight({
|
machineStatusPreflight({
|
||||||
command: 'restartServices',
|
command: 'restartServices',
|
||||||
display: 'Restart services for'
|
display: 'Restart services for',
|
||||||
})
|
})
|
||||||
}}>
|
}}>
|
||||||
Restart services
|
Restart services
|
||||||
|
|
@ -188,7 +188,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
||||||
command: 'emptyUnit',
|
command: 'emptyUnit',
|
||||||
display: 'Empty',
|
display: 'Empty',
|
||||||
message:
|
message:
|
||||||
"Triggering this action will move all cash inside the machine towards its cashbox (if possible), allowing for the collection of cash from the machine via only its cashbox. Depending on how full the cash units are, it's possible that this action will need to be used more than once to ensure that the unit is left completely empty."
|
"Triggering this action will move all cash inside the machine towards its cashbox (if possible), allowing for the collection of cash from the machine via only its cashbox. Depending on how full the cash units are, it's possible that this action will need to be used more than once to ensure that the unit is left completely empty.",
|
||||||
})
|
})
|
||||||
}}>
|
}}>
|
||||||
Empty Unit
|
Empty Unit
|
||||||
|
|
@ -205,7 +205,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
||||||
command: 'refillUnit',
|
command: 'refillUnit',
|
||||||
display: 'Refill',
|
display: 'Refill',
|
||||||
message:
|
message:
|
||||||
'Triggering this action will refill the recyclers in this machine, by using bills present in its cassettes. This action may require manual operation of the cassettes and close attention to make sure that the denominations in the cassettes match the denominations in the recyclers.'
|
'Triggering this action will refill the recyclers in this machine, by using bills present in its cassettes. This action may require manual operation of the cassettes and close attention to make sure that the denominations in the cassettes match the denominations in the recyclers.',
|
||||||
})
|
})
|
||||||
}}>
|
}}>
|
||||||
Refill Unit
|
Refill Unit
|
||||||
|
|
@ -228,8 +228,8 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
||||||
simpleMachineAction({
|
simpleMachineAction({
|
||||||
variables: {
|
variables: {
|
||||||
deviceId: machine.deviceId,
|
deviceId: machine.deviceId,
|
||||||
action: 'diagnostics'
|
action: 'diagnostics',
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
deviceId={machine.deviceId}
|
deviceId={machine.deviceId}
|
||||||
|
|
@ -253,8 +253,8 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
||||||
variables: {
|
variables: {
|
||||||
deviceId: machine.deviceId,
|
deviceId: machine.deviceId,
|
||||||
action: `${action?.command}`,
|
action: `${action?.command}`,
|
||||||
...(action?.command === 'rename' && { newName: value })
|
...(action?.command === 'rename' && { newName: value }),
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
onDismissed={() => {
|
onDismissed={() => {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import {
|
||||||
TBody,
|
TBody,
|
||||||
Td,
|
Td,
|
||||||
Th,
|
Th,
|
||||||
Tr
|
Tr,
|
||||||
} from 'src/components/fake-table/Table'
|
} from 'src/components/fake-table/Table'
|
||||||
import EditIcon from 'src/styling/icons/action/edit/white.svg?react'
|
import EditIcon from 'src/styling/icons/action/edit/white.svg?react'
|
||||||
|
|
||||||
|
|
@ -19,7 +19,7 @@ const SingleRowTable = ({
|
||||||
title,
|
title,
|
||||||
items,
|
items,
|
||||||
onEdit,
|
onEdit,
|
||||||
className
|
className,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const EmptyTable = memo(({ message, className }) => {
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
className,
|
className,
|
||||||
'flex flex-col items-center w-full mt-13 text-sm font-bold font-museo'
|
'flex flex-col items-center w-full mt-13 text-sm font-bold font-museo',
|
||||||
)}>
|
)}>
|
||||||
<EmptyTableIcon />
|
<EmptyTableIcon />
|
||||||
<H4>{message}</H4>
|
<H4>{message}</H4>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ const Table = memo(({ className, children, ...props }) => {
|
||||||
{...props}
|
{...props}
|
||||||
className={classnames(
|
className={classnames(
|
||||||
'table-fixed border-separate border-spacing-0',
|
'table-fixed border-separate border-spacing-0',
|
||||||
className
|
className,
|
||||||
)}>
|
)}>
|
||||||
{children}
|
{children}
|
||||||
</table>
|
</table>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ const TableCell = memo(
|
||||||
({ colspan, rightAlign, className, children, ...props }) => {
|
({ colspan, rightAlign, className, children, ...props }) => {
|
||||||
const styles = {
|
const styles = {
|
||||||
[classes.tableCell]: true,
|
[classes.tableCell]: true,
|
||||||
'text-right': rightAlign
|
'text-right': rightAlign,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -18,7 +18,7 @@ const TableCell = memo(
|
||||||
{children}
|
{children}
|
||||||
</td>
|
</td>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default TableCell
|
export default TableCell
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ const TableHeaderCell = memo(
|
||||||
({ rightAlign, children, className, ...props }) => {
|
({ rightAlign, children, className, ...props }) => {
|
||||||
const styles = {
|
const styles = {
|
||||||
'bg-zodiac text-white py-0 px-6 h-8 text-sm text-left': true,
|
'bg-zodiac text-white py-0 px-6 h-8 text-sm text-left': true,
|
||||||
'text-right': rightAlign
|
'text-right': rightAlign,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -13,7 +13,7 @@ const TableHeaderCell = memo(
|
||||||
{children}
|
{children}
|
||||||
</th>
|
</th>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default TableHeaderCell
|
export default TableHeaderCell
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const TableRow = memo(
|
||||||
'h-8': !header && size === 'sm',
|
'h-8': !header && size === 'sm',
|
||||||
'h-9 font-bold text-base ': !header && size === 'lg',
|
'h-9 font-bold text-base ': !header && size === 'lg',
|
||||||
'bg-misty-rose': error,
|
'bg-misty-rose': error,
|
||||||
'bg-spring3': success
|
'bg-spring3': success,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -16,7 +16,7 @@ const TableRow = memo(
|
||||||
{children}
|
{children}
|
||||||
</tr>
|
</tr>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default TableRow
|
export default TableRow
|
||||||
|
|
|
||||||
|
|
@ -15,5 +15,5 @@ export {
|
||||||
TableHead,
|
TableHead,
|
||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
TableBody
|
TableBody,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import {
|
||||||
AutoSizer,
|
AutoSizer,
|
||||||
List,
|
List,
|
||||||
CellMeasurer,
|
CellMeasurer,
|
||||||
CellMeasurerCache
|
CellMeasurerCache,
|
||||||
} from 'react-virtualized'
|
} from 'react-virtualized'
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
|
|
@ -13,7 +13,7 @@ import {
|
||||||
THead,
|
THead,
|
||||||
Tr,
|
Tr,
|
||||||
Td,
|
Td,
|
||||||
Th
|
Th,
|
||||||
} from 'src/components/fake-table/Table'
|
} from 'src/components/fake-table/Table'
|
||||||
import { H4 } from 'src/components/typography'
|
import { H4 } from 'src/components/typography'
|
||||||
import ExpandClosedIcon from 'src/styling/icons/action/expand/closed.svg?react'
|
import ExpandClosedIcon from 'src/styling/icons/action/expand/closed.svg?react'
|
||||||
|
|
@ -40,7 +40,7 @@ const Row = ({
|
||||||
const trClasses = {
|
const trClasses = {
|
||||||
'cursor-pointer': hasPointer,
|
'cursor-pointer': hasPointer,
|
||||||
'border-2 border-transparent': true,
|
'border-2 border-transparent': true,
|
||||||
'border-2 border-zircon shadow-md': expanded
|
'border-2 border-zircon shadow-md': expanded,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -79,7 +79,7 @@ const Row = ({
|
||||||
<div className="pb-3">
|
<div className="pb-3">
|
||||||
<Tr
|
<Tr
|
||||||
className={classnames({
|
className={classnames({
|
||||||
'border-2 border-zircon shadow-md': expanded
|
'border-2 border-zircon shadow-md': expanded,
|
||||||
})}>
|
})}>
|
||||||
<Td width={width}>
|
<Td width={width}>
|
||||||
<Details it={data} timezone={props.timezone} />
|
<Details it={data} timezone={props.timezone} />
|
||||||
|
|
@ -126,7 +126,7 @@ const DataTable = ({
|
||||||
|
|
||||||
const cache = new CellMeasurerCache({
|
const cache = new CellMeasurerCache({
|
||||||
defaultHeight: 58,
|
defaultHeight: 58,
|
||||||
fixedWidth: true
|
fixedWidth: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
function rowRenderer({ index, key, parent, style }) {
|
function rowRenderer({ index, key, parent, style }) {
|
||||||
|
|
@ -168,12 +168,12 @@ const DataTable = ({
|
||||||
<div
|
<div
|
||||||
className={classnames({
|
className={classnames({
|
||||||
'flex flex-1 flex-col': true,
|
'flex flex-1 flex-col': true,
|
||||||
[className]: !!className
|
[className]: !!className,
|
||||||
})}>
|
})}>
|
||||||
<Table
|
<Table
|
||||||
className={classnames(
|
className={classnames(
|
||||||
'mb-12 min-h-50 flex-1 flex flex-col',
|
'mb-12 min-h-50 flex-1 flex flex-col',
|
||||||
tableClassName
|
tableClassName,
|
||||||
)}
|
)}
|
||||||
style={{ width }}>
|
style={{ width }}>
|
||||||
<THead>
|
<THead>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ function H1({ children, noMargin, className, ...props }) {
|
||||||
const classNames = {
|
const classNames = {
|
||||||
[styles.h1]: true,
|
[styles.h1]: true,
|
||||||
[styles.noMargin]: noMargin,
|
[styles.noMargin]: noMargin,
|
||||||
[className]: !!className
|
[className]: !!className,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -21,7 +21,7 @@ function H2({ children, noMargin, className, ...props }) {
|
||||||
const classNames = {
|
const classNames = {
|
||||||
[styles.h2]: true,
|
[styles.h2]: true,
|
||||||
[styles.noMargin]: noMargin,
|
[styles.noMargin]: noMargin,
|
||||||
[className]: !!className
|
[className]: !!className,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -35,7 +35,7 @@ function H3({ children, noMargin, className, ...props }) {
|
||||||
const classNames = {
|
const classNames = {
|
||||||
[styles.h3]: true,
|
[styles.h3]: true,
|
||||||
[styles.noMargin]: noMargin,
|
[styles.noMargin]: noMargin,
|
||||||
[className]: !!className
|
[className]: !!className,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -49,7 +49,7 @@ function H4({ children, noMargin, className, ...props }) {
|
||||||
const classNames = {
|
const classNames = {
|
||||||
[styles.h4]: true,
|
[styles.h4]: true,
|
||||||
[styles.noMargin]: noMargin,
|
[styles.noMargin]: noMargin,
|
||||||
[className]: !!className
|
[className]: !!className,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -63,7 +63,7 @@ function H5({ children, noMargin, className, ...props }) {
|
||||||
const classNames = {
|
const classNames = {
|
||||||
[styles.h5]: true,
|
[styles.h5]: true,
|
||||||
[styles.noMargin]: noMargin,
|
[styles.noMargin]: noMargin,
|
||||||
[className]: !!className
|
[className]: !!className,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -90,7 +90,7 @@ function pBuilder(elementClass) {
|
||||||
[className]: !!className,
|
[className]: !!className,
|
||||||
[styles[elementClass]]: elementClass,
|
[styles[elementClass]]: elementClass,
|
||||||
[styles.inline]: inline,
|
[styles.inline]: inline,
|
||||||
[styles.noMargin]: noMargin
|
[styles.noMargin]: noMargin,
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<p className={classnames(classNames)} {...props}>
|
<p className={classnames(classNames)} {...props}>
|
||||||
|
|
@ -115,5 +115,5 @@ export {
|
||||||
Mono,
|
Mono,
|
||||||
Label1,
|
Label1,
|
||||||
Label2,
|
Label2,
|
||||||
Label3
|
Label3,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,132 +7,132 @@ import {
|
||||||
fontSize5,
|
fontSize5,
|
||||||
fontPrimary,
|
fontPrimary,
|
||||||
fontSecondary,
|
fontSecondary,
|
||||||
fontMonospaced
|
fontMonospaced,
|
||||||
} from 'src/styling/variables'
|
} from 'src/styling/variables'
|
||||||
|
|
||||||
const base = {
|
const base = {
|
||||||
lineHeight: '120%',
|
lineHeight: '120%',
|
||||||
color: fontColor
|
color: fontColor,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
base: {
|
base: {
|
||||||
lineHeight: '120%',
|
lineHeight: '120%',
|
||||||
color: fontColor
|
color: fontColor,
|
||||||
},
|
},
|
||||||
h1: {
|
h1: {
|
||||||
extend: base,
|
extend: base,
|
||||||
fontSize: fontSize1,
|
fontSize: fontSize1,
|
||||||
fontFamily: fontPrimary,
|
fontFamily: fontPrimary,
|
||||||
fontWeight: 900
|
fontWeight: 900,
|
||||||
},
|
},
|
||||||
h2: {
|
h2: {
|
||||||
extend: base,
|
extend: base,
|
||||||
fontSize: fontSize2,
|
fontSize: fontSize2,
|
||||||
fontFamily: fontPrimary,
|
fontFamily: fontPrimary,
|
||||||
fontWeight: 900
|
fontWeight: 900,
|
||||||
},
|
},
|
||||||
h3: {
|
h3: {
|
||||||
extend: base,
|
extend: base,
|
||||||
fontSize: fontSize4,
|
fontSize: fontSize4,
|
||||||
fontFamily: fontPrimary,
|
fontFamily: fontPrimary,
|
||||||
fontWeight: 900
|
fontWeight: 900,
|
||||||
},
|
},
|
||||||
h4: {
|
h4: {
|
||||||
extend: base,
|
extend: base,
|
||||||
fontSize: fontSize4,
|
fontSize: fontSize4,
|
||||||
fontFamily: fontPrimary,
|
fontFamily: fontPrimary,
|
||||||
fontWeight: 700
|
fontWeight: 700,
|
||||||
},
|
},
|
||||||
h5: {
|
h5: {
|
||||||
extend: base,
|
extend: base,
|
||||||
fontSize: fontSize3,
|
fontSize: fontSize3,
|
||||||
fontFamily: fontPrimary,
|
fontFamily: fontPrimary,
|
||||||
fontWeight: 700
|
fontWeight: 700,
|
||||||
},
|
},
|
||||||
p: {
|
p: {
|
||||||
...base,
|
...base,
|
||||||
fontSize: fontSize4,
|
fontSize: fontSize4,
|
||||||
fontFamily: fontSecondary,
|
fontFamily: fontSecondary,
|
||||||
fontWeight: 500
|
fontWeight: 500,
|
||||||
},
|
},
|
||||||
tl1: {
|
tl1: {
|
||||||
extend: base,
|
extend: base,
|
||||||
fontSize: fontSize2,
|
fontSize: fontSize2,
|
||||||
fontFamily: fontSecondary,
|
fontFamily: fontSecondary,
|
||||||
fontWeight: 700
|
fontWeight: 700,
|
||||||
},
|
},
|
||||||
tl2: {
|
tl2: {
|
||||||
extend: base,
|
extend: base,
|
||||||
fontSize: fontSize4,
|
fontSize: fontSize4,
|
||||||
fontFamily: fontSecondary,
|
fontFamily: fontSecondary,
|
||||||
fontWeight: 700
|
fontWeight: 700,
|
||||||
},
|
},
|
||||||
info1: {
|
info1: {
|
||||||
extend: base,
|
extend: base,
|
||||||
fontSize: fontSize1,
|
fontSize: fontSize1,
|
||||||
fontFamily: fontSecondary,
|
fontFamily: fontSecondary,
|
||||||
fontWeight: 700
|
fontWeight: 700,
|
||||||
},
|
},
|
||||||
info2: {
|
info2: {
|
||||||
extend: base,
|
extend: base,
|
||||||
fontSize: fontSize3,
|
fontSize: fontSize3,
|
||||||
fontFamily: fontSecondary,
|
fontFamily: fontSecondary,
|
||||||
fontWeight: 700
|
fontWeight: 700,
|
||||||
},
|
},
|
||||||
info3: {
|
info3: {
|
||||||
extend: base,
|
extend: base,
|
||||||
fontSize: fontSize3,
|
fontSize: fontSize3,
|
||||||
fontFamily: fontSecondary,
|
fontFamily: fontSecondary,
|
||||||
fontWeight: 500
|
fontWeight: 500,
|
||||||
},
|
},
|
||||||
mono: {
|
mono: {
|
||||||
extend: base,
|
extend: base,
|
||||||
fontSize: fontSize4,
|
fontSize: fontSize4,
|
||||||
fontFamily: fontMonospaced,
|
fontFamily: fontMonospaced,
|
||||||
fontWeight: 500
|
fontWeight: 500,
|
||||||
},
|
},
|
||||||
monoBold: {
|
monoBold: {
|
||||||
fontWeight: 700
|
fontWeight: 700,
|
||||||
},
|
},
|
||||||
monoSmall: {
|
monoSmall: {
|
||||||
fontSize: fontSize5
|
fontSize: fontSize5,
|
||||||
},
|
},
|
||||||
inputFont: {
|
inputFont: {
|
||||||
fontSize: fontSize2,
|
fontSize: fontSize2,
|
||||||
fontFamily: fontSecondary,
|
fontFamily: fontSecondary,
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
lineHeight: '110%',
|
lineHeight: '110%',
|
||||||
color: fontColor
|
color: fontColor,
|
||||||
},
|
},
|
||||||
regularLabel: {
|
regularLabel: {
|
||||||
fontSize: fontSize4,
|
fontSize: fontSize4,
|
||||||
fontFamily: fontSecondary,
|
fontFamily: fontSecondary,
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
lineHeight: '110%'
|
lineHeight: '110%',
|
||||||
},
|
},
|
||||||
label1: {
|
label1: {
|
||||||
fontSize: fontSize5,
|
fontSize: fontSize5,
|
||||||
fontFamily: fontSecondary,
|
fontFamily: fontSecondary,
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
color: fontColor
|
color: fontColor,
|
||||||
},
|
},
|
||||||
label2: {
|
label2: {
|
||||||
fontSize: fontSize5,
|
fontSize: fontSize5,
|
||||||
fontFamily: fontSecondary,
|
fontFamily: fontSecondary,
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
color: fontColor
|
color: fontColor,
|
||||||
},
|
},
|
||||||
label3: {
|
label3: {
|
||||||
fontSize: fontSize4,
|
fontSize: fontSize4,
|
||||||
fontFamily: fontSecondary,
|
fontFamily: fontSecondary,
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
color: fontColor
|
color: fontColor,
|
||||||
},
|
},
|
||||||
inline: {
|
inline: {
|
||||||
display: 'inline'
|
display: 'inline',
|
||||||
},
|
},
|
||||||
noMargin: {
|
noMargin: {
|
||||||
margin: 0
|
margin: 0,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,5 @@ ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<App />
|
<App />
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
document.getElementById('root')
|
document.getElementById('root'),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ const QrCodeComponent = ({ qrCode, name, count, onPaired }) => {
|
||||||
if (hasNewMachine) {
|
if (hasNewMachine) {
|
||||||
timeout.current = setTimeout(
|
timeout.current = setTimeout(
|
||||||
() => onPaired(addedMachine),
|
() => onPaired(addedMachine),
|
||||||
CLOSE_SCREEN_TIMEOUT
|
CLOSE_SCREEN_TIMEOUT,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +111,7 @@ const QrCodeComponent = ({ qrCode, name, count, onPaired }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
name: ''
|
name: '',
|
||||||
}
|
}
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
|
|
@ -124,9 +124,9 @@ const validationSchema = Yup.object().shape({
|
||||||
(value, context) =>
|
(value, context) =>
|
||||||
!R.includes(
|
!R.includes(
|
||||||
R.toLower(value),
|
R.toLower(value),
|
||||||
R.map(R.toLower, context.options.context.machineNames)
|
R.map(R.toLower, context.options.context.machineNames),
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
})
|
})
|
||||||
|
|
||||||
const MachineNameComponent = ({ nextStep, setQrCode, setName }) => {
|
const MachineNameComponent = ({ nextStep, setQrCode, setName }) => {
|
||||||
|
|
@ -138,7 +138,7 @@ const MachineNameComponent = ({ nextStep, setQrCode, setName }) => {
|
||||||
setQrCode(createPairingTotem)
|
setQrCode(createPairingTotem)
|
||||||
nextStep()
|
nextStep()
|
||||||
},
|
},
|
||||||
onError: e => console.log(e)
|
onError: e => console.log(e),
|
||||||
})
|
})
|
||||||
|
|
||||||
const { data } = useQuery(GET_MACHINES)
|
const { data } = useQuery(GET_MACHINES)
|
||||||
|
|
@ -147,7 +147,7 @@ const MachineNameComponent = ({ nextStep, setQrCode, setName }) => {
|
||||||
const uniqueNameValidator = value => {
|
const uniqueNameValidator = value => {
|
||||||
try {
|
try {
|
||||||
validationSchema.validateSync(value, {
|
validationSchema.validateSync(value, {
|
||||||
context: { machineNames: machineNames }
|
context: { machineNames: machineNames },
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return error
|
return error
|
||||||
|
|
@ -189,12 +189,12 @@ const MachineNameComponent = ({ nextStep, setQrCode, setName }) => {
|
||||||
const steps = [
|
const steps = [
|
||||||
{
|
{
|
||||||
label: 'Machine name',
|
label: 'Machine name',
|
||||||
component: MachineNameComponent
|
component: MachineNameComponent,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Scan QR code',
|
label: 'Scan QR code',
|
||||||
component: QrCodeComponent
|
component: QrCodeComponent,
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const renderStepper = (step, it, idx) => {
|
const renderStepper = (step, it, idx) => {
|
||||||
|
|
@ -208,7 +208,7 @@ const renderStepper = (step, it, idx) => {
|
||||||
className={classnames({
|
className={classnames({
|
||||||
'mr-6 text-comet': true,
|
'mr-6 text-comet': true,
|
||||||
'text-zodiac font-bold': active,
|
'text-zodiac font-bold': active,
|
||||||
'text-zodiac': past
|
'text-zodiac': past,
|
||||||
})}>
|
})}>
|
||||||
{it.label}
|
{it.label}
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -219,7 +219,7 @@ const renderStepper = (step, it, idx) => {
|
||||||
<div
|
<div
|
||||||
className={classnames({
|
className={classnames({
|
||||||
'absolute h-7 w-px border border-comet border-solid right-2 top-[18px]': true,
|
'absolute h-7 w-px border border-comet border-solid right-2 top-[18px]': true,
|
||||||
'border-zodiac': past
|
'border-zodiac': past,
|
||||||
})}></div>
|
})}></div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -26,29 +26,29 @@ const REPRESENTING_OPTIONS = [
|
||||||
{ code: 'overTime', display: 'Over time' },
|
{ code: 'overTime', display: 'Over time' },
|
||||||
{ code: 'volumeOverTime', display: 'Volume' },
|
{ code: 'volumeOverTime', display: 'Volume' },
|
||||||
{ code: 'topMachines', display: 'Top machines' },
|
{ code: 'topMachines', display: 'Top machines' },
|
||||||
{ code: 'hourOfTheDay', display: 'Hour of the day' }
|
{ code: 'hourOfTheDay', display: 'Hour of the day' },
|
||||||
]
|
]
|
||||||
const PERIOD_OPTIONS = [
|
const PERIOD_OPTIONS = [
|
||||||
{ code: 'day', display: 'Last 24 hours' },
|
{ code: 'day', display: 'Last 24 hours' },
|
||||||
{ code: 'threeDays', display: 'Last 3 days' },
|
{ code: 'threeDays', display: 'Last 3 days' },
|
||||||
{ code: 'week', display: 'Last 7 days' },
|
{ code: 'week', display: 'Last 7 days' },
|
||||||
{ code: 'month', display: 'Last 30 days' }
|
{ code: 'month', display: 'Last 30 days' },
|
||||||
]
|
]
|
||||||
const TIME_OPTIONS = {
|
const TIME_OPTIONS = {
|
||||||
day: DAY,
|
day: DAY,
|
||||||
threeDays: 3 * DAY,
|
threeDays: 3 * DAY,
|
||||||
week: WEEK,
|
week: WEEK,
|
||||||
month: MONTH
|
month: MONTH,
|
||||||
}
|
}
|
||||||
|
|
||||||
const DAY_OPTIONS = R.map(
|
const DAY_OPTIONS = R.map(
|
||||||
it => ({
|
it => ({
|
||||||
code: R.toLower(it),
|
code: R.toLower(it),
|
||||||
display: it
|
display: it,
|
||||||
}),
|
}),
|
||||||
Array.from(Array(7)).map((_, i) =>
|
Array.from(Array(7)).map((_, i) =>
|
||||||
format('EEEE', add({ days: i }, startOfWeek(new Date())))
|
format('EEEE', add({ days: i }, startOfWeek(new Date()))),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
const GET_TRANSACTIONS = gql`
|
const GET_TRANSACTIONS = gql`
|
||||||
|
|
@ -112,7 +112,7 @@ const OverviewEntry = ({ label, value, oldValue, currency }) => {
|
||||||
const growthClasses = {
|
const growthClasses = {
|
||||||
'font-bold': true,
|
'font-bold': true,
|
||||||
'text-malachite': R.gt(value, oldValue),
|
'text-malachite': R.gt(value, oldValue),
|
||||||
'text-tomato': R.gt(oldValue, value)
|
'text-tomato': R.gt(oldValue, value),
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -139,8 +139,8 @@ const Analytics = () => {
|
||||||
variables: {
|
variables: {
|
||||||
from: subDays(65, endOfToday()),
|
from: subDays(65, endOfToday()),
|
||||||
until: endOfToday(),
|
until: endOfToday(),
|
||||||
excludeTestingCustomers: true
|
excludeTestingCustomers: true,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
const { data: configResponse, loading: configLoading } = useQuery(GET_DATA)
|
const { data: configResponse, loading: configLoading } = useQuery(GET_DATA)
|
||||||
|
|
||||||
|
|
@ -148,7 +148,7 @@ const Analytics = () => {
|
||||||
const [period, setPeriod] = useState(PERIOD_OPTIONS[0])
|
const [period, setPeriod] = useState(PERIOD_OPTIONS[0])
|
||||||
const [machine, setMachine] = useState(MACHINE_OPTIONS[0])
|
const [machine, setMachine] = useState(MACHINE_OPTIONS[0])
|
||||||
const [selectedDay, setSelectedDay] = useState(
|
const [selectedDay, setSelectedDay] = useState(
|
||||||
R.equals(representing.code, 'hourOfTheDay') ? DAY_OPTIONS[0] : null
|
R.equals(representing.code, 'hourOfTheDay') ? DAY_OPTIONS[0] : null,
|
||||||
)
|
)
|
||||||
|
|
||||||
const loading = txLoading || configLoading
|
const loading = txLoading || configLoading
|
||||||
|
|
@ -175,20 +175,20 @@ const Analytics = () => {
|
||||||
tx =>
|
tx =>
|
||||||
(!tx.dispensed || !tx.expired) &&
|
(!tx.dispensed || !tx.expired) &&
|
||||||
(tx.sendConfirmed || tx.dispense) &&
|
(tx.sendConfirmed || tx.dispense) &&
|
||||||
!tx.hasError
|
!tx.hasError,
|
||||||
)
|
),
|
||||||
) ?? []
|
) ?? []
|
||||||
|
|
||||||
const machineOptions = R.clone(MACHINE_OPTIONS)
|
const machineOptions = R.clone(MACHINE_OPTIONS)
|
||||||
|
|
||||||
R.forEach(
|
R.forEach(
|
||||||
m => machineOptions.push({ code: m.deviceId, display: m.name }),
|
m => machineOptions.push({ code: m.deviceId, display: m.name }),
|
||||||
machines
|
machines,
|
||||||
)
|
)
|
||||||
|
|
||||||
const machineTxs = R.filter(
|
const machineTxs = R.filter(
|
||||||
tx => (machine.code === 'all' ? true : tx.deviceId === machine.code),
|
tx => (machine.code === 'all' ? true : tx.deviceId === machine.code),
|
||||||
data
|
data,
|
||||||
)
|
)
|
||||||
|
|
||||||
const filteredData = timeInterval => ({
|
const filteredData = timeInterval => ({
|
||||||
|
|
@ -213,35 +213,35 @@ const Analytics = () => {
|
||||||
txDay < Date.now() - TIME_OPTIONS[timeInterval] &&
|
txDay < Date.now() - TIME_OPTIONS[timeInterval] &&
|
||||||
txDay >= Date.now() - 2 * TIME_OPTIONS[timeInterval]
|
txDay >= Date.now() - 2 * TIME_OPTIONS[timeInterval]
|
||||||
)
|
)
|
||||||
}) ?? []
|
}) ?? [],
|
||||||
})
|
})
|
||||||
|
|
||||||
const txs = {
|
const txs = {
|
||||||
current: filteredData(period.code).current.length,
|
current: filteredData(period.code).current.length,
|
||||||
previous: filteredData(period.code).previous.length
|
previous: filteredData(period.code).previous.length,
|
||||||
}
|
}
|
||||||
|
|
||||||
const median = values => (values.length === 0 ? 0 : R.median(values))
|
const median = values => (values.length === 0 ? 0 : R.median(values))
|
||||||
|
|
||||||
const medianAmount = {
|
const medianAmount = {
|
||||||
current: median(R.map(d => d.fiat, filteredData(period.code).current)),
|
current: median(R.map(d => d.fiat, filteredData(period.code).current)),
|
||||||
previous: median(R.map(d => d.fiat, filteredData(period.code).previous))
|
previous: median(R.map(d => d.fiat, filteredData(period.code).previous)),
|
||||||
}
|
}
|
||||||
|
|
||||||
const txVolume = {
|
const txVolume = {
|
||||||
current: R.sum(R.map(d => d.fiat, filteredData(period.code).current)),
|
current: R.sum(R.map(d => d.fiat, filteredData(period.code).current)),
|
||||||
previous: R.sum(R.map(d => d.fiat, filteredData(period.code).previous))
|
previous: R.sum(R.map(d => d.fiat, filteredData(period.code).previous)),
|
||||||
}
|
}
|
||||||
|
|
||||||
const commissions = {
|
const commissions = {
|
||||||
current: R.sum(R.map(d => d.profit, filteredData(period.code).current)),
|
current: R.sum(R.map(d => d.profit, filteredData(period.code).current)),
|
||||||
previous: R.sum(R.map(d => d.profit, filteredData(period.code).previous))
|
previous: R.sum(R.map(d => d.profit, filteredData(period.code).previous)),
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRepresentationChange = newRepresentation => {
|
const handleRepresentationChange = newRepresentation => {
|
||||||
setRepresenting(newRepresentation)
|
setRepresenting(newRepresentation)
|
||||||
setSelectedDay(
|
setSelectedDay(
|
||||||
R.equals(newRepresentation.code, 'hourOfTheDay') ? DAY_OPTIONS[0] : null
|
R.equals(newRepresentation.code, 'hourOfTheDay') ? DAY_OPTIONS[0] : null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,20 +13,19 @@ const GraphTooltip = ({
|
||||||
coords,
|
coords,
|
||||||
data,
|
data,
|
||||||
dateInterval,
|
dateInterval,
|
||||||
period,
|
|
||||||
currency,
|
currency,
|
||||||
representing
|
representing,
|
||||||
}) => {
|
}) => {
|
||||||
const formattedDateInterval = !R.includes('hourOfDay', representing.code)
|
const formattedDateInterval = !R.includes('hourOfDay', representing.code)
|
||||||
? [
|
? [
|
||||||
formatDate(dateInterval[1], null, 'MMM d'),
|
formatDate(dateInterval[1], null, 'MMM d'),
|
||||||
formatDate(dateInterval[1], null, 'HH:mm'),
|
formatDate(dateInterval[1], null, 'HH:mm'),
|
||||||
formatDate(dateInterval[0], null, 'HH:mm')
|
formatDate(dateInterval[0], null, 'HH:mm'),
|
||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
formatDate(dateInterval[1], null, 'MMM d'),
|
formatDate(dateInterval[1], null, 'MMM d'),
|
||||||
formatDateNonUtc(dateInterval[1], 'HH:mm'),
|
formatDateNonUtc(dateInterval[1], 'HH:mm'),
|
||||||
formatDateNonUtc(dateInterval[0], 'HH:mm')
|
formatDateNonUtc(dateInterval[0], 'HH:mm'),
|
||||||
]
|
]
|
||||||
|
|
||||||
const transactions = R.reduce(
|
const transactions = R.reduce(
|
||||||
|
|
@ -37,7 +36,7 @@ const GraphTooltip = ({
|
||||||
return acc
|
return acc
|
||||||
},
|
},
|
||||||
{ volume: 0, cashIn: 0, cashOut: 0 },
|
{ volume: 0, cashIn: 0, cashOut: 0 },
|
||||||
data
|
data,
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import classes from './wrappers.module.css'
|
||||||
|
|
||||||
const options = [
|
const options = [
|
||||||
{ code: 'hourOfDayTransactions', display: 'Transactions' },
|
{ code: 'hourOfDayTransactions', display: 'Transactions' },
|
||||||
{ code: 'hourOfDayVolume', display: 'Volume' }
|
{ code: 'hourOfDayVolume', display: 'Volume' },
|
||||||
]
|
]
|
||||||
|
|
||||||
const HourOfDayBarGraphHeader = ({
|
const HourOfDayBarGraphHeader = ({
|
||||||
|
|
@ -26,13 +26,13 @@ const HourOfDayBarGraphHeader = ({
|
||||||
dayOptions,
|
dayOptions,
|
||||||
handleDayChange,
|
handleDayChange,
|
||||||
timezone,
|
timezone,
|
||||||
currency
|
currency,
|
||||||
}) => {
|
}) => {
|
||||||
const [graphType /*, setGraphType */] = useState(options[0].code)
|
const [graphType /*, setGraphType */] = useState(options[0].code)
|
||||||
|
|
||||||
const legend = {
|
const legend = {
|
||||||
cashIn: <div className={classes.cashInIcon}></div>,
|
cashIn: <div className={classes.cashInIcon}></div>,
|
||||||
cashOut: <div className={classes.cashOutIcon}></div>
|
cashOut: <div className={classes.cashOutIcon}></div>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const offset = getTimezoneOffset(timezone)
|
const offset = getTimezoneOffset(timezone)
|
||||||
|
|
@ -41,7 +41,7 @@ const HourOfDayBarGraphHeader = ({
|
||||||
(acc, value) => {
|
(acc, value) => {
|
||||||
const created = new Date(value.created)
|
const created = new Date(value.created)
|
||||||
created.setTime(
|
created.setTime(
|
||||||
created.getTime() + created.getTimezoneOffset() * MINUTE + offset
|
created.getTime() + created.getTimezoneOffset() * MINUTE + offset,
|
||||||
)
|
)
|
||||||
switch (created.getDay()) {
|
switch (created.getDay()) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|
@ -71,7 +71,7 @@ const HourOfDayBarGraphHeader = ({
|
||||||
return acc
|
return acc
|
||||||
},
|
},
|
||||||
R.fromPairs(R.map(it => [it.code, []], dayOptions)),
|
R.fromPairs(R.map(it => [it.code, []], dayOptions)),
|
||||||
data
|
data,
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const OverTimeDotGraphHeader = ({
|
||||||
selectedMachine,
|
selectedMachine,
|
||||||
handleMachineChange,
|
handleMachineChange,
|
||||||
timezone,
|
timezone,
|
||||||
currency
|
currency,
|
||||||
}) => {
|
}) => {
|
||||||
const [logarithmic, setLogarithmic] = useState()
|
const [logarithmic, setLogarithmic] = useState()
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ const OverTimeDotGraphHeader = ({
|
||||||
d="M 5 6 l 20 0"
|
d="M 5 6 l 20 0"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
)
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import classes from './wrappers.module.css'
|
||||||
|
|
||||||
const options = [
|
const options = [
|
||||||
{ code: 'topMachinesTransactions', display: 'Transactions' },
|
{ code: 'topMachinesTransactions', display: 'Transactions' },
|
||||||
{ code: 'topMachinesVolume', display: 'Volume' }
|
{ code: 'topMachinesVolume', display: 'Volume' },
|
||||||
]
|
]
|
||||||
|
|
||||||
const TopMachinesBarGraphHeader = ({
|
const TopMachinesBarGraphHeader = ({
|
||||||
|
|
@ -18,13 +18,13 @@ const TopMachinesBarGraphHeader = ({
|
||||||
machines,
|
machines,
|
||||||
selectedMachine,
|
selectedMachine,
|
||||||
timezone,
|
timezone,
|
||||||
currency
|
currency,
|
||||||
}) => {
|
}) => {
|
||||||
const [graphType /*, setGraphType */] = useState(options[0].code)
|
const [graphType /*, setGraphType */] = useState(options[0].code)
|
||||||
|
|
||||||
const legend = {
|
const legend = {
|
||||||
cashIn: <div className={classes.cashInIcon}></div>,
|
cashIn: <div className={classes.cashInIcon}></div>,
|
||||||
cashOut: <div className={classes.cashOutIcon}></div>
|
cashOut: <div className={classes.cashOutIcon}></div>,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const VolumeOverTimeGraphHeader = ({
|
||||||
selectedMachine,
|
selectedMachine,
|
||||||
handleMachineChange,
|
handleMachineChange,
|
||||||
timezone,
|
timezone,
|
||||||
currency
|
currency,
|
||||||
}) => {
|
}) => {
|
||||||
const [logarithmic, setLogarithmic] = useState()
|
const [logarithmic, setLogarithmic] = useState()
|
||||||
|
|
||||||
|
|
@ -42,7 +42,7 @@ const VolumeOverTimeGraphHeader = ({
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
)
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
.graphHeaderRight {
|
.graphHeaderRight {
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 30px
|
gap: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cashInIcon {
|
.cashInIcon {
|
||||||
|
|
@ -45,12 +45,12 @@
|
||||||
.graphHeaderSwitchBox {
|
.graphHeaderSwitchBox {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
/*'& > *': {*/
|
/*'& > *': {*/
|
||||||
/* margin: 0*/
|
/* margin: 0*/
|
||||||
/*},*/
|
/*},*/
|
||||||
/*'& > :first-child': {*/
|
/*'& > :first-child': {*/
|
||||||
/* marginBottom: 2,*/
|
/* marginBottom: 2,*/
|
||||||
/* extend: label1,*/
|
/* extend: label1,*/
|
||||||
/* color: offColor*/
|
/* color: offColor*/
|
||||||
/*}*/
|
/*}*/
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ const GraphWrapper = ({
|
||||||
selectedMachine,
|
selectedMachine,
|
||||||
machines,
|
machines,
|
||||||
selectedDay,
|
selectedDay,
|
||||||
log
|
log,
|
||||||
}) => {
|
}) => {
|
||||||
const [selectionCoords, setSelectionCoords] = useState(null)
|
const [selectionCoords, setSelectionCoords] = useState(null)
|
||||||
const [selectionDateInterval, setSelectionDateInterval] = useState(null)
|
const [selectionDateInterval, setSelectionDateInterval] = useState(null)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import {
|
||||||
subheaderDarkColor,
|
subheaderDarkColor,
|
||||||
fontColor,
|
fontColor,
|
||||||
fontSecondary,
|
fontSecondary,
|
||||||
subheaderColor
|
subheaderColor,
|
||||||
} from 'src/styling/variables'
|
} from 'src/styling/variables'
|
||||||
import { MINUTE } from 'src/utils/time'
|
import { MINUTE } from 'src/utils/time'
|
||||||
import { toUtc } from 'src/utils/timezones'
|
import { toUtc } from 'src/utils/timezones'
|
||||||
|
|
@ -22,7 +22,6 @@ const Graph = ({
|
||||||
setSelectionCoords,
|
setSelectionCoords,
|
||||||
setSelectionData,
|
setSelectionData,
|
||||||
setSelectionDateInterval,
|
setSelectionDateInterval,
|
||||||
selectedMachine
|
|
||||||
}) => {
|
}) => {
|
||||||
const ref = useRef(null)
|
const ref = useRef(null)
|
||||||
|
|
||||||
|
|
@ -36,9 +35,9 @@ const Graph = ({
|
||||||
top: 25,
|
top: 25,
|
||||||
right: 0.5,
|
right: 0.5,
|
||||||
bottom: 27,
|
bottom: 27,
|
||||||
left: 36.5
|
left: 36.5,
|
||||||
}),
|
}),
|
||||||
[]
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
const offset = getTimezoneOffset(timezone)
|
const offset = getTimezoneOffset(timezone)
|
||||||
|
|
@ -64,7 +63,7 @@ const Graph = ({
|
||||||
const tzCreated = new Date(it.created).setTime(
|
const tzCreated = new Date(it.created).setTime(
|
||||||
new Date(it.created).getTime() +
|
new Date(it.created).getTime() +
|
||||||
new Date(it.created).getTimezoneOffset() * MINUTE +
|
new Date(it.created).getTimezoneOffset() * MINUTE +
|
||||||
offset
|
offset,
|
||||||
)
|
)
|
||||||
const created = new Date(tzCreated)
|
const created = new Date(tzCreated)
|
||||||
|
|
||||||
|
|
@ -77,7 +76,7 @@ const Graph = ({
|
||||||
created.getUTCHours() < new Date(upperBound).getUTCHours())
|
created.getUTCHours() < new Date(upperBound).getUTCHours())
|
||||||
)
|
)
|
||||||
}, data),
|
}, data),
|
||||||
[data, offset]
|
[data, offset],
|
||||||
)
|
)
|
||||||
|
|
||||||
const txClassByHourInterval = useCallback(
|
const txClassByHourInterval = useCallback(
|
||||||
|
|
@ -91,16 +90,16 @@ const Graph = ({
|
||||||
return acc
|
return acc
|
||||||
},
|
},
|
||||||
{ cashIn: 0, cashOut: 0 },
|
{ cashIn: 0, cashOut: 0 },
|
||||||
filterByHourInterval(lowerBound, upperBound)
|
filterByHourInterval(lowerBound, upperBound),
|
||||||
),
|
),
|
||||||
[filterByHourInterval]
|
[filterByHourInterval],
|
||||||
)
|
)
|
||||||
|
|
||||||
const x = d3
|
const x = d3
|
||||||
.scaleUtc()
|
.scaleUtc()
|
||||||
.domain([
|
.domain([
|
||||||
toUtc(startOfDay(new Date())),
|
toUtc(startOfDay(new Date())),
|
||||||
toUtc(add({ days: 1 }, startOfDay(new Date())))
|
toUtc(add({ days: 1 }, startOfDay(new Date()))),
|
||||||
])
|
])
|
||||||
.rangeRound([GRAPH_MARGIN.left, GRAPH_WIDTH - GRAPH_MARGIN.right])
|
.rangeRound([GRAPH_MARGIN.left, GRAPH_WIDTH - GRAPH_MARGIN.right])
|
||||||
|
|
||||||
|
|
@ -111,7 +110,7 @@ const Graph = ({
|
||||||
const upperBound = R.clone(it)
|
const upperBound = R.clone(it)
|
||||||
return [lowerBound, filterByHourInterval(lowerBound, upperBound)]
|
return [lowerBound, filterByHourInterval(lowerBound, upperBound)]
|
||||||
},
|
},
|
||||||
R.init(getTickIntervals(x.domain(), 2))
|
R.init(getTickIntervals(x.domain(), 2)),
|
||||||
)
|
)
|
||||||
|
|
||||||
const groupedByTxClass = R.map(
|
const groupedByTxClass = R.map(
|
||||||
|
|
@ -121,7 +120,7 @@ const Graph = ({
|
||||||
const upperBound = R.clone(it)
|
const upperBound = R.clone(it)
|
||||||
return [lowerBound, txClassByHourInterval(lowerBound, upperBound)]
|
return [lowerBound, txClassByHourInterval(lowerBound, upperBound)]
|
||||||
},
|
},
|
||||||
R.init(getTickIntervals(x.domain(), 2))
|
R.init(getTickIntervals(x.domain(), 2)),
|
||||||
)
|
)
|
||||||
|
|
||||||
const y = d3
|
const y = d3
|
||||||
|
|
@ -130,13 +129,13 @@ const Graph = ({
|
||||||
0,
|
0,
|
||||||
d3.max(
|
d3.max(
|
||||||
groupedByTxClass.map(it => it[1]),
|
groupedByTxClass.map(it => it[1]),
|
||||||
d => d.cashIn + d.cashOut
|
d => d.cashIn + d.cashOut,
|
||||||
) !== 0
|
) !== 0
|
||||||
? d3.max(
|
? d3.max(
|
||||||
groupedByTxClass.map(it => it[1]),
|
groupedByTxClass.map(it => it[1]),
|
||||||
d => d.cashIn + d.cashOut
|
d => d.cashIn + d.cashOut,
|
||||||
)
|
)
|
||||||
: 50
|
: 50,
|
||||||
])
|
])
|
||||||
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
|
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
|
||||||
|
|
||||||
|
|
@ -145,15 +144,15 @@ const Graph = ({
|
||||||
g
|
g
|
||||||
.attr(
|
.attr(
|
||||||
'transform',
|
'transform',
|
||||||
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
|
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
|
||||||
)
|
)
|
||||||
.call(
|
.call(
|
||||||
d3
|
d3
|
||||||
.axisBottom(x)
|
.axisBottom(x)
|
||||||
.ticks(d3.timeHour.every(2))
|
.ticks(d3.timeHour.every(2))
|
||||||
.tickFormat(d3.timeFormat('%H:%M'))
|
.tickFormat(d3.timeFormat('%H:%M')),
|
||||||
),
|
),
|
||||||
[GRAPH_MARGIN, x]
|
[GRAPH_MARGIN, x],
|
||||||
)
|
)
|
||||||
|
|
||||||
const buildYAxis = useCallback(
|
const buildYAxis = useCallback(
|
||||||
|
|
@ -165,10 +164,10 @@ const Graph = ({
|
||||||
.axisLeft(y)
|
.axisLeft(y)
|
||||||
.ticks(GRAPH_HEIGHT / 100)
|
.ticks(GRAPH_HEIGHT / 100)
|
||||||
.tickSize(0)
|
.tickSize(0)
|
||||||
.tickFormat(``)
|
.tickFormat(``),
|
||||||
)
|
)
|
||||||
.call(g => g.select('.domain').remove()),
|
.call(g => g.select('.domain').remove()),
|
||||||
[GRAPH_MARGIN, y]
|
[GRAPH_MARGIN, y],
|
||||||
)
|
)
|
||||||
|
|
||||||
const buildVerticalLines = useCallback(
|
const buildVerticalLines = useCallback(
|
||||||
|
|
@ -195,7 +194,7 @@ const Graph = ({
|
||||||
})
|
})
|
||||||
.attr('y1', GRAPH_MARGIN.top)
|
.attr('y1', GRAPH_MARGIN.top)
|
||||||
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom),
|
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom),
|
||||||
[GRAPH_MARGIN, x]
|
[GRAPH_MARGIN, x],
|
||||||
)
|
)
|
||||||
|
|
||||||
const buildHoverableEventRects = useCallback(
|
const buildHoverableEventRects = useCallback(
|
||||||
|
|
@ -227,15 +226,15 @@ const Graph = ({
|
||||||
const endDate = R.clone(date)
|
const endDate = R.clone(date)
|
||||||
|
|
||||||
const filteredData = groupedByDateInterval.find(it =>
|
const filteredData = groupedByDateInterval.find(it =>
|
||||||
R.equals(startDate, it[0])
|
R.equals(startDate, it[0]),
|
||||||
)[1]
|
)[1]
|
||||||
|
|
||||||
const rectXCoords = {
|
const rectXCoords = {
|
||||||
left: R.clone(d.target.getBoundingClientRect().x),
|
left: R.clone(d.target.getBoundingClientRect().x),
|
||||||
right: R.clone(
|
right: R.clone(
|
||||||
d.target.getBoundingClientRect().x +
|
d.target.getBoundingClientRect().x +
|
||||||
d.target.getBoundingClientRect().width
|
d.target.getBoundingClientRect().width,
|
||||||
)
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
const xCoord =
|
const xCoord =
|
||||||
|
|
@ -248,18 +247,18 @@ const Graph = ({
|
||||||
setSelectionData(filteredData)
|
setSelectionData(filteredData)
|
||||||
setSelectionCoords({
|
setSelectionCoords({
|
||||||
x: Math.round(xCoord),
|
x: Math.round(xCoord),
|
||||||
y: Math.round(yCoord)
|
y: Math.round(yCoord),
|
||||||
})
|
})
|
||||||
|
|
||||||
d3.select(`#event-rect-${x(d.target.__data__)}`).attr(
|
d3.select(`#event-rect-${x(d.target.__data__)}`).attr(
|
||||||
'fill',
|
'fill',
|
||||||
subheaderColor
|
subheaderColor,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.on('mouseleave', d => {
|
.on('mouseleave', d => {
|
||||||
d3.select(`#event-rect-${x(d.target.__data__)}`).attr(
|
d3.select(`#event-rect-${x(d.target.__data__)}`).attr(
|
||||||
'fill',
|
'fill',
|
||||||
'transparent'
|
'transparent',
|
||||||
)
|
)
|
||||||
setSelectionDateInterval(null)
|
setSelectionDateInterval(null)
|
||||||
setSelectionData(null)
|
setSelectionData(null)
|
||||||
|
|
@ -271,8 +270,8 @@ const Graph = ({
|
||||||
setSelectionCoords,
|
setSelectionCoords,
|
||||||
setSelectionData,
|
setSelectionData,
|
||||||
setSelectionDateInterval,
|
setSelectionDateInterval,
|
||||||
x
|
x,
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
const buildEventRects = useCallback(
|
const buildEventRects = useCallback(
|
||||||
|
|
@ -298,7 +297,7 @@ const Graph = ({
|
||||||
.attr('height', GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top)
|
.attr('height', GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top)
|
||||||
.attr('stroke', 'transparent')
|
.attr('stroke', 'transparent')
|
||||||
.attr('fill', 'transparent'),
|
.attr('fill', 'transparent'),
|
||||||
[GRAPH_MARGIN, x]
|
[GRAPH_MARGIN, x],
|
||||||
)
|
)
|
||||||
|
|
||||||
const formatTicksText = useCallback(
|
const formatTicksText = useCallback(
|
||||||
|
|
@ -309,7 +308,7 @@ const Graph = ({
|
||||||
.style('fill', fontColor)
|
.style('fill', fontColor)
|
||||||
.style('stroke-width', 0.5)
|
.style('stroke-width', 0.5)
|
||||||
.style('font-family', fontSecondary),
|
.style('font-family', fontSecondary),
|
||||||
[]
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
const drawCashIn = useCallback(
|
const drawCashIn = useCallback(
|
||||||
|
|
@ -334,7 +333,7 @@ const Graph = ({
|
||||||
GRAPH_HEIGHT -
|
GRAPH_HEIGHT -
|
||||||
y(interval[1].cashIn) -
|
y(interval[1].cashIn) -
|
||||||
GRAPH_MARGIN.bottom -
|
GRAPH_MARGIN.bottom -
|
||||||
BAR_MARGIN / 2
|
BAR_MARGIN / 2,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.attr('width', d => {
|
.attr('width', d => {
|
||||||
|
|
@ -348,7 +347,7 @@ const Graph = ({
|
||||||
})
|
})
|
||||||
.attr('rx', 2.5)
|
.attr('rx', 2.5)
|
||||||
},
|
},
|
||||||
[x, y, GRAPH_MARGIN, groupedByTxClass]
|
[x, y, GRAPH_MARGIN, groupedByTxClass],
|
||||||
)
|
)
|
||||||
|
|
||||||
const drawCashOut = useCallback(
|
const drawCashOut = useCallback(
|
||||||
|
|
@ -377,7 +376,7 @@ const Graph = ({
|
||||||
GRAPH_HEIGHT -
|
GRAPH_HEIGHT -
|
||||||
y(interval[1].cashOut) -
|
y(interval[1].cashOut) -
|
||||||
GRAPH_MARGIN.bottom -
|
GRAPH_MARGIN.bottom -
|
||||||
BAR_MARGIN / 2
|
BAR_MARGIN / 2,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.attr('width', d => {
|
.attr('width', d => {
|
||||||
|
|
@ -391,7 +390,7 @@ const Graph = ({
|
||||||
})
|
})
|
||||||
.attr('rx', 2.5)
|
.attr('rx', 2.5)
|
||||||
},
|
},
|
||||||
[x, y, GRAPH_MARGIN, groupedByTxClass]
|
[x, y, GRAPH_MARGIN, groupedByTxClass],
|
||||||
)
|
)
|
||||||
|
|
||||||
const drawChart = useCallback(() => {
|
const drawChart = useCallback(() => {
|
||||||
|
|
@ -417,7 +416,7 @@ const Graph = ({
|
||||||
buildVerticalLines,
|
buildVerticalLines,
|
||||||
drawCashIn,
|
drawCashIn,
|
||||||
formatTicksText,
|
formatTicksText,
|
||||||
drawCashOut
|
drawCashOut,
|
||||||
])
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -433,5 +432,5 @@ export default memo(
|
||||||
(prev, next) =>
|
(prev, next) =>
|
||||||
R.equals(prev.period, next.period) &&
|
R.equals(prev.period, next.period) &&
|
||||||
R.equals(prev.selectedDay, next.selectedDay) &&
|
R.equals(prev.selectedDay, next.selectedDay) &&
|
||||||
R.equals(prev.selectedMachine, next.selectedMachine)
|
R.equals(prev.selectedMachine, next.selectedMachine),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import {
|
||||||
fontColor,
|
fontColor,
|
||||||
primaryColor,
|
primaryColor,
|
||||||
fontSecondary,
|
fontSecondary,
|
||||||
subheaderColor
|
subheaderColor,
|
||||||
} from 'src/styling/variables'
|
} from 'src/styling/variables'
|
||||||
import { numberToFiatAmount } from 'src/utils/number'
|
import { numberToFiatAmount } from 'src/utils/number'
|
||||||
import { MINUTE, DAY, WEEK, MONTH } from 'src/utils/time'
|
import { MINUTE, DAY, WEEK, MONTH } from 'src/utils/time'
|
||||||
|
|
@ -25,7 +25,7 @@ const Graph = ({
|
||||||
setSelectionCoords,
|
setSelectionCoords,
|
||||||
setSelectionData,
|
setSelectionData,
|
||||||
setSelectionDateInterval,
|
setSelectionDateInterval,
|
||||||
log = false
|
log = false,
|
||||||
}) => {
|
}) => {
|
||||||
const ref = useRef(null)
|
const ref = useRef(null)
|
||||||
|
|
||||||
|
|
@ -38,9 +38,9 @@ const Graph = ({
|
||||||
top: 25,
|
top: 25,
|
||||||
right: 3.5,
|
right: 3.5,
|
||||||
bottom: 27,
|
bottom: 27,
|
||||||
left: 38
|
left: 38,
|
||||||
}),
|
}),
|
||||||
[]
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
const offset = getTimezoneOffset(timezone)
|
const offset = getTimezoneOffset(timezone)
|
||||||
|
|
@ -50,7 +50,7 @@ const Graph = ({
|
||||||
day: [NOW - DAY, NOW],
|
day: [NOW - DAY, NOW],
|
||||||
threeDays: [NOW - 3 * DAY, NOW],
|
threeDays: [NOW - 3 * DAY, NOW],
|
||||||
week: [NOW - WEEK, NOW],
|
week: [NOW - WEEK, NOW],
|
||||||
month: [NOW - MONTH, NOW]
|
month: [NOW - MONTH, NOW],
|
||||||
}
|
}
|
||||||
|
|
||||||
const dataPoints = useMemo(
|
const dataPoints = useMemo(
|
||||||
|
|
@ -59,28 +59,28 @@ const Graph = ({
|
||||||
freq: 24,
|
freq: 24,
|
||||||
step: 60 * 60 * 1000,
|
step: 60 * 60 * 1000,
|
||||||
tick: d3.utcHour.every(1),
|
tick: d3.utcHour.every(1),
|
||||||
labelFormat: '%H:%M'
|
labelFormat: '%H:%M',
|
||||||
},
|
},
|
||||||
threeDays: {
|
threeDays: {
|
||||||
freq: 12,
|
freq: 12,
|
||||||
step: 6 * 60 * 60 * 1000,
|
step: 6 * 60 * 60 * 1000,
|
||||||
tick: d3.utcDay.every(1),
|
tick: d3.utcDay.every(1),
|
||||||
labelFormat: '%a %d'
|
labelFormat: '%a %d',
|
||||||
},
|
},
|
||||||
week: {
|
week: {
|
||||||
freq: 7,
|
freq: 7,
|
||||||
step: 24 * 60 * 60 * 1000,
|
step: 24 * 60 * 60 * 1000,
|
||||||
tick: d3.utcDay.every(1),
|
tick: d3.utcDay.every(1),
|
||||||
labelFormat: '%a %d'
|
labelFormat: '%a %d',
|
||||||
},
|
},
|
||||||
month: {
|
month: {
|
||||||
freq: 30,
|
freq: 30,
|
||||||
step: 24 * 60 * 60 * 1000,
|
step: 24 * 60 * 60 * 1000,
|
||||||
tick: d3.utcDay.every(1),
|
tick: d3.utcDay.every(1),
|
||||||
labelFormat: '%d'
|
labelFormat: '%d',
|
||||||
}
|
},
|
||||||
}),
|
}),
|
||||||
[]
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
const getPastAndCurrentDayLabels = useCallback(d => {
|
const getPastAndCurrentDayLabels = useCallback(d => {
|
||||||
|
|
@ -97,11 +97,11 @@ const Graph = ({
|
||||||
const previousDateMonth = previousDate.getUTCMonth()
|
const previousDateMonth = previousDate.getUTCMonth()
|
||||||
|
|
||||||
const daysOfWeek = Array.from(Array(7)).map((_, i) =>
|
const daysOfWeek = Array.from(Array(7)).map((_, i) =>
|
||||||
format('EEE', add({ days: i }, startOfWeek(new Date())))
|
format('EEE', add({ days: i }, startOfWeek(new Date()))),
|
||||||
)
|
)
|
||||||
|
|
||||||
const months = Array.from(Array(12)).map((_, i) =>
|
const months = Array.from(Array(12)).map((_, i) =>
|
||||||
format('LLL', add({ months: i }, startOfYear(new Date())))
|
format('LLL', add({ months: i }, startOfYear(new Date()))),
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -112,7 +112,7 @@ const Graph = ({
|
||||||
current:
|
current:
|
||||||
currentDateMonth !== previousDateMonth
|
currentDateMonth !== previousDateMonth
|
||||||
? months[currentDateMonth]
|
? months[currentDateMonth]
|
||||||
: `${daysOfWeek[currentDateWeekday]} ${currentDateDay}`
|
: `${daysOfWeek[currentDateWeekday]} ${currentDateDay}`,
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
|
@ -134,7 +134,7 @@ const Graph = ({
|
||||||
|
|
||||||
return points
|
return points
|
||||||
},
|
},
|
||||||
[NOW, dataPoints, period.code]
|
[NOW, dataPoints, period.code],
|
||||||
)
|
)
|
||||||
|
|
||||||
const buildAreas = useCallback(
|
const buildAreas = useCallback(
|
||||||
|
|
@ -159,7 +159,7 @@ const Graph = ({
|
||||||
|
|
||||||
return points
|
return points
|
||||||
},
|
},
|
||||||
[NOW, dataPoints, period.code]
|
[NOW, dataPoints, period.code],
|
||||||
)
|
)
|
||||||
|
|
||||||
const x = d3
|
const x = d3
|
||||||
|
|
@ -177,7 +177,7 @@ const Graph = ({
|
||||||
.scaleLinear()
|
.scaleLinear()
|
||||||
.domain([
|
.domain([
|
||||||
0,
|
0,
|
||||||
(d3.max(data, d => new BigNumber(d.fiat).toNumber()) ?? 1000) * 1.03
|
(d3.max(data, d => new BigNumber(d.fiat).toNumber()) ?? 1000) * 1.03,
|
||||||
])
|
])
|
||||||
.nice()
|
.nice()
|
||||||
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
|
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
|
||||||
|
|
@ -186,7 +186,7 @@ const Graph = ({
|
||||||
.scaleLog()
|
.scaleLog()
|
||||||
.domain([
|
.domain([
|
||||||
(d3.min(data, d => new BigNumber(d.fiat).toNumber()) ?? 1) * 0.9,
|
(d3.min(data, d => new BigNumber(d.fiat).toNumber()) ?? 1) * 0.9,
|
||||||
(d3.max(data, d => new BigNumber(d.fiat).toNumber()) ?? 1000) * 1.1
|
(d3.max(data, d => new BigNumber(d.fiat).toNumber()) ?? 1000) * 1.1,
|
||||||
])
|
])
|
||||||
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
|
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
|
||||||
|
|
||||||
|
|
@ -196,7 +196,7 @@ const Graph = ({
|
||||||
const fullBreakpoints = [
|
const fullBreakpoints = [
|
||||||
graphLimits[1],
|
graphLimits[1],
|
||||||
...R.filter(it => it > dataLimits[0] && it < dataLimits[1], breakpoints),
|
...R.filter(it => it > dataLimits[0] && it < dataLimits[1], breakpoints),
|
||||||
dataLimits[0]
|
dataLimits[0],
|
||||||
]
|
]
|
||||||
|
|
||||||
const intervals = []
|
const intervals = []
|
||||||
|
|
@ -227,7 +227,7 @@ const Graph = ({
|
||||||
g
|
g
|
||||||
.attr(
|
.attr(
|
||||||
'transform',
|
'transform',
|
||||||
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
|
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
|
||||||
)
|
)
|
||||||
.call(
|
.call(
|
||||||
d3
|
d3
|
||||||
|
|
@ -235,18 +235,18 @@ const Graph = ({
|
||||||
.ticks(dataPoints[period.code].tick)
|
.ticks(dataPoints[period.code].tick)
|
||||||
.tickFormat(d => {
|
.tickFormat(d => {
|
||||||
return d3.timeFormat(dataPoints[period.code].labelFormat)(
|
return d3.timeFormat(dataPoints[period.code].labelFormat)(
|
||||||
d.getTime() + d.getTimezoneOffset() * MINUTE
|
d.getTime() + d.getTimezoneOffset() * MINUTE,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.tickSizeOuter(0)
|
.tickSizeOuter(0),
|
||||||
)
|
)
|
||||||
.call(g =>
|
.call(g =>
|
||||||
g
|
g
|
||||||
.select('.domain')
|
.select('.domain')
|
||||||
.attr('stroke', primaryColor)
|
.attr('stroke', primaryColor)
|
||||||
.attr('stroke-width', 1)
|
.attr('stroke-width', 1),
|
||||||
),
|
),
|
||||||
[GRAPH_MARGIN, dataPoints, period.code, x]
|
[GRAPH_MARGIN, dataPoints, period.code, x],
|
||||||
)
|
)
|
||||||
|
|
||||||
const buildYAxis = useCallback(
|
const buildYAxis = useCallback(
|
||||||
|
|
@ -264,12 +264,12 @@ const Graph = ({
|
||||||
if (d >= 1000) return numberToFiatAmount(d / 1000) + 'k'
|
if (d >= 1000) return numberToFiatAmount(d / 1000) + 'k'
|
||||||
|
|
||||||
return numberToFiatAmount(d)
|
return numberToFiatAmount(d)
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
.select('.domain')
|
.select('.domain')
|
||||||
.attr('stroke', primaryColor)
|
.attr('stroke', primaryColor)
|
||||||
.attr('stroke-width', 1),
|
.attr('stroke-width', 1),
|
||||||
[GRAPH_MARGIN, y, log]
|
[GRAPH_MARGIN, y, log],
|
||||||
)
|
)
|
||||||
|
|
||||||
const buildGrid = useCallback(
|
const buildGrid = useCallback(
|
||||||
|
|
@ -286,7 +286,7 @@ const Graph = ({
|
||||||
.attr('x1', d => 0.5 + x(d))
|
.attr('x1', d => 0.5 + x(d))
|
||||||
.attr('x2', d => 0.5 + x(d))
|
.attr('x2', d => 0.5 + x(d))
|
||||||
.attr('y1', GRAPH_MARGIN.top)
|
.attr('y1', GRAPH_MARGIN.top)
|
||||||
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
|
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom),
|
||||||
)
|
)
|
||||||
// Horizontal lines
|
// Horizontal lines
|
||||||
.call(g =>
|
.call(g =>
|
||||||
|
|
@ -297,13 +297,13 @@ const Graph = ({
|
||||||
d3
|
d3
|
||||||
.axisLeft(y)
|
.axisLeft(y)
|
||||||
.scale()
|
.scale()
|
||||||
.ticks(GRAPH_HEIGHT / 100)
|
.ticks(GRAPH_HEIGHT / 100),
|
||||||
)
|
)
|
||||||
.join('line')
|
.join('line')
|
||||||
.attr('y1', d => 0.5 + y(d))
|
.attr('y1', d => 0.5 + y(d))
|
||||||
.attr('y2', d => 0.5 + y(d))
|
.attr('y2', d => 0.5 + y(d))
|
||||||
.attr('x1', GRAPH_MARGIN.left)
|
.attr('x1', GRAPH_MARGIN.left)
|
||||||
.attr('x2', GRAPH_WIDTH)
|
.attr('x2', GRAPH_WIDTH),
|
||||||
)
|
)
|
||||||
// Vertical transparent rectangles for events
|
// Vertical transparent rectangles for events
|
||||||
.call(g =>
|
.call(g =>
|
||||||
|
|
@ -319,14 +319,14 @@ const Graph = ({
|
||||||
const intervals = getAreaInterval(
|
const intervals = getAreaInterval(
|
||||||
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
|
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
|
||||||
x.range(),
|
x.range(),
|
||||||
x2.range()
|
x2.range(),
|
||||||
)
|
)
|
||||||
const interval = getAreaIntervalByX(intervals, xValue)
|
const interval = getAreaIntervalByX(intervals, xValue)
|
||||||
return Math.round((interval[0] - interval[1]) * 100) / 100
|
return Math.round((interval[0] - interval[1]) * 100) / 100
|
||||||
})
|
})
|
||||||
.attr(
|
.attr(
|
||||||
'height',
|
'height',
|
||||||
GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top
|
GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top,
|
||||||
)
|
)
|
||||||
.attr('stroke', 'transparent')
|
.attr('stroke', 'transparent')
|
||||||
.attr('fill', 'transparent')
|
.attr('fill', 'transparent')
|
||||||
|
|
@ -336,7 +336,7 @@ const Graph = ({
|
||||||
const intervals = getAreaInterval(
|
const intervals = getAreaInterval(
|
||||||
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
|
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
|
||||||
x.range(),
|
x.range(),
|
||||||
x2.range()
|
x2.range(),
|
||||||
)
|
)
|
||||||
|
|
||||||
const dateInterval = getDateIntervalByX(areas, intervals, xValue)
|
const dateInterval = getDateIntervalByX(areas, intervals, xValue)
|
||||||
|
|
@ -354,8 +354,8 @@ const Graph = ({
|
||||||
left: R.clone(d.target.getBoundingClientRect().x),
|
left: R.clone(d.target.getBoundingClientRect().x),
|
||||||
right: R.clone(
|
right: R.clone(
|
||||||
d.target.getBoundingClientRect().x +
|
d.target.getBoundingClientRect().x +
|
||||||
d.target.getBoundingClientRect().width
|
d.target.getBoundingClientRect().width,
|
||||||
)
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
const xCoord =
|
const xCoord =
|
||||||
|
|
@ -370,7 +370,7 @@ const Graph = ({
|
||||||
setSelectionData(filteredData)
|
setSelectionData(filteredData)
|
||||||
setSelectionCoords({
|
setSelectionCoords({
|
||||||
x: Math.round(xCoord),
|
x: Math.round(xCoord),
|
||||||
y: Math.round(yCoord)
|
y: Math.round(yCoord),
|
||||||
})
|
})
|
||||||
|
|
||||||
d3.select(d.target).attr('fill', subheaderColor)
|
d3.select(d.target).attr('fill', subheaderColor)
|
||||||
|
|
@ -380,7 +380,7 @@ const Graph = ({
|
||||||
setSelectionDateInterval(null)
|
setSelectionDateInterval(null)
|
||||||
setSelectionData(null)
|
setSelectionData(null)
|
||||||
setSelectionCoords(null)
|
setSelectionCoords(null)
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
// Thick vertical lines
|
// Thick vertical lines
|
||||||
.call(g =>
|
.call(g =>
|
||||||
|
|
@ -391,7 +391,7 @@ const Graph = ({
|
||||||
buildTicks(x.domain()).filter(x => {
|
buildTicks(x.domain()).filter(x => {
|
||||||
if (period.code === 'day') return x.getUTCHours() === 0
|
if (period.code === 'day') return x.getUTCHours() === 0
|
||||||
return x.getUTCDate() === 1
|
return x.getUTCDate() === 1
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
.join('line')
|
.join('line')
|
||||||
.attr('class', 'dateSeparator')
|
.attr('class', 'dateSeparator')
|
||||||
|
|
@ -400,7 +400,7 @@ const Graph = ({
|
||||||
.attr('y1', GRAPH_MARGIN.top - 50)
|
.attr('y1', GRAPH_MARGIN.top - 50)
|
||||||
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
|
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
|
||||||
.attr('stroke-width', 5)
|
.attr('stroke-width', 5)
|
||||||
.join('text')
|
.join('text'),
|
||||||
)
|
)
|
||||||
// Left side breakpoint label
|
// Left side breakpoint label
|
||||||
.call(g => {
|
.call(g => {
|
||||||
|
|
@ -458,8 +458,8 @@ const Graph = ({
|
||||||
offset,
|
offset,
|
||||||
setSelectionCoords,
|
setSelectionCoords,
|
||||||
setSelectionData,
|
setSelectionData,
|
||||||
setSelectionDateInterval
|
setSelectionDateInterval,
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
const formatTicksText = useCallback(
|
const formatTicksText = useCallback(
|
||||||
|
|
@ -470,7 +470,7 @@ const Graph = ({
|
||||||
.style('fill', fontColor)
|
.style('fill', fontColor)
|
||||||
.style('stroke-width', 0.5)
|
.style('stroke-width', 0.5)
|
||||||
.style('font-family', fontSecondary),
|
.style('font-family', fontSecondary),
|
||||||
[]
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
const formatText = useCallback(
|
const formatText = useCallback(
|
||||||
|
|
@ -481,7 +481,7 @@ const Graph = ({
|
||||||
.style('fill', offColor)
|
.style('fill', offColor)
|
||||||
.style('stroke-width', 0.5)
|
.style('stroke-width', 0.5)
|
||||||
.style('font-family', fontSecondary),
|
.style('font-family', fontSecondary),
|
||||||
[]
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
const formatTicks = useCallback(() => {
|
const formatTicks = useCallback(() => {
|
||||||
|
|
@ -505,10 +505,10 @@ const Graph = ({
|
||||||
.attr('y1', 0.5 + y(median))
|
.attr('y1', 0.5 + y(median))
|
||||||
.attr('y2', 0.5 + y(median))
|
.attr('y2', 0.5 + y(median))
|
||||||
.attr('x1', GRAPH_MARGIN.left)
|
.attr('x1', GRAPH_MARGIN.left)
|
||||||
.attr('x2', GRAPH_WIDTH)
|
.attr('x2', GRAPH_WIDTH),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
[GRAPH_MARGIN, y, data, log]
|
[GRAPH_MARGIN, y, data, log],
|
||||||
)
|
)
|
||||||
|
|
||||||
const drawData = useCallback(
|
const drawData = useCallback(
|
||||||
|
|
@ -524,7 +524,7 @@ const Graph = ({
|
||||||
.attr('fill', d => (d.txClass === 'cashIn' ? java : neon))
|
.attr('fill', d => (d.txClass === 'cashIn' ? java : neon))
|
||||||
.attr('r', 3.5)
|
.attr('r', 3.5)
|
||||||
},
|
},
|
||||||
[data, offset, x, y]
|
[data, offset, x, y],
|
||||||
)
|
)
|
||||||
|
|
||||||
const drawChart = useCallback(() => {
|
const drawChart = useCallback(() => {
|
||||||
|
|
@ -550,7 +550,7 @@ const Graph = ({
|
||||||
drawData,
|
drawData,
|
||||||
formatText,
|
formatText,
|
||||||
formatTicks,
|
formatTicks,
|
||||||
formatTicksText
|
formatTicksText,
|
||||||
])
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -566,5 +566,5 @@ export default memo(
|
||||||
(prev, next) =>
|
(prev, next) =>
|
||||||
R.equals(prev.period, next.period) &&
|
R.equals(prev.period, next.period) &&
|
||||||
R.equals(prev.selectedMachine, next.selectedMachine) &&
|
R.equals(prev.selectedMachine, next.selectedMachine) &&
|
||||||
R.equals(prev.log, next.log)
|
R.equals(prev.log, next.log),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import {
|
||||||
differenceInMilliseconds,
|
differenceInMilliseconds,
|
||||||
format,
|
format,
|
||||||
startOfWeek,
|
startOfWeek,
|
||||||
startOfYear
|
startOfYear,
|
||||||
} from 'date-fns/fp'
|
} from 'date-fns/fp'
|
||||||
import * as R from 'ramda'
|
import * as R from 'ramda'
|
||||||
import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react'
|
import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react'
|
||||||
|
|
@ -21,7 +21,7 @@ import {
|
||||||
fontColor,
|
fontColor,
|
||||||
primaryColor,
|
primaryColor,
|
||||||
fontSecondary,
|
fontSecondary,
|
||||||
subheaderColor
|
subheaderColor,
|
||||||
} from 'src/styling/variables'
|
} from 'src/styling/variables'
|
||||||
import { numberToFiatAmount } from 'src/utils/number'
|
import { numberToFiatAmount } from 'src/utils/number'
|
||||||
import { MINUTE, DAY, WEEK, MONTH } from 'src/utils/time'
|
import { MINUTE, DAY, WEEK, MONTH } from 'src/utils/time'
|
||||||
|
|
@ -33,7 +33,7 @@ const Graph = ({
|
||||||
setSelectionCoords,
|
setSelectionCoords,
|
||||||
setSelectionData,
|
setSelectionData,
|
||||||
setSelectionDateInterval,
|
setSelectionDateInterval,
|
||||||
log = false
|
log = false,
|
||||||
}) => {
|
}) => {
|
||||||
const ref = useRef(null)
|
const ref = useRef(null)
|
||||||
|
|
||||||
|
|
@ -46,9 +46,9 @@ const Graph = ({
|
||||||
top: 25,
|
top: 25,
|
||||||
right: 3.5,
|
right: 3.5,
|
||||||
bottom: 27,
|
bottom: 27,
|
||||||
left: 38
|
left: 38,
|
||||||
}),
|
}),
|
||||||
[]
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
const offset = getTimezoneOffset(timezone)
|
const offset = getTimezoneOffset(timezone)
|
||||||
|
|
@ -58,7 +58,7 @@ const Graph = ({
|
||||||
day: [NOW - DAY, NOW],
|
day: [NOW - DAY, NOW],
|
||||||
threeDays: [NOW - 3 * DAY, NOW],
|
threeDays: [NOW - 3 * DAY, NOW],
|
||||||
week: [NOW - WEEK, NOW],
|
week: [NOW - WEEK, NOW],
|
||||||
month: [NOW - MONTH, NOW]
|
month: [NOW - MONTH, NOW],
|
||||||
}
|
}
|
||||||
|
|
||||||
const dataPoints = useMemo(
|
const dataPoints = useMemo(
|
||||||
|
|
@ -67,28 +67,28 @@ const Graph = ({
|
||||||
freq: 24,
|
freq: 24,
|
||||||
step: 60 * 60 * 1000,
|
step: 60 * 60 * 1000,
|
||||||
tick: d3.utcHour.every(1),
|
tick: d3.utcHour.every(1),
|
||||||
labelFormat: '%H:%M'
|
labelFormat: '%H:%M',
|
||||||
},
|
},
|
||||||
threeDays: {
|
threeDays: {
|
||||||
freq: 12,
|
freq: 12,
|
||||||
step: 6 * 60 * 60 * 1000,
|
step: 6 * 60 * 60 * 1000,
|
||||||
tick: d3.utcDay.every(1),
|
tick: d3.utcDay.every(1),
|
||||||
labelFormat: '%a %d'
|
labelFormat: '%a %d',
|
||||||
},
|
},
|
||||||
week: {
|
week: {
|
||||||
freq: 7,
|
freq: 7,
|
||||||
step: 24 * 60 * 60 * 1000,
|
step: 24 * 60 * 60 * 1000,
|
||||||
tick: d3.utcDay.every(1),
|
tick: d3.utcDay.every(1),
|
||||||
labelFormat: '%a %d'
|
labelFormat: '%a %d',
|
||||||
},
|
},
|
||||||
month: {
|
month: {
|
||||||
freq: 30,
|
freq: 30,
|
||||||
step: 24 * 60 * 60 * 1000,
|
step: 24 * 60 * 60 * 1000,
|
||||||
tick: d3.utcDay.every(1),
|
tick: d3.utcDay.every(1),
|
||||||
labelFormat: '%d'
|
labelFormat: '%d',
|
||||||
}
|
},
|
||||||
}),
|
}),
|
||||||
[]
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
const getPastAndCurrentDayLabels = useCallback(d => {
|
const getPastAndCurrentDayLabels = useCallback(d => {
|
||||||
|
|
@ -105,11 +105,11 @@ const Graph = ({
|
||||||
const previousDateMonth = previousDate.getUTCMonth()
|
const previousDateMonth = previousDate.getUTCMonth()
|
||||||
|
|
||||||
const daysOfWeek = Array.from(Array(7)).map((_, i) =>
|
const daysOfWeek = Array.from(Array(7)).map((_, i) =>
|
||||||
format('EEE', add({ days: i }, startOfWeek(new Date())))
|
format('EEE', add({ days: i }, startOfWeek(new Date()))),
|
||||||
)
|
)
|
||||||
|
|
||||||
const months = Array.from(Array(12)).map((_, i) =>
|
const months = Array.from(Array(12)).map((_, i) =>
|
||||||
format('LLL', add({ months: i }, startOfYear(new Date())))
|
format('LLL', add({ months: i }, startOfYear(new Date()))),
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -120,7 +120,7 @@ const Graph = ({
|
||||||
current:
|
current:
|
||||||
currentDateMonth !== previousDateMonth
|
currentDateMonth !== previousDateMonth
|
||||||
? months[currentDateMonth]
|
? months[currentDateMonth]
|
||||||
: `${daysOfWeek[currentDateWeekday]} ${currentDateDay}`
|
: `${daysOfWeek[currentDateWeekday]} ${currentDateDay}`,
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
|
@ -142,7 +142,7 @@ const Graph = ({
|
||||||
|
|
||||||
return points
|
return points
|
||||||
},
|
},
|
||||||
[NOW, dataPoints, period.code]
|
[NOW, dataPoints, period.code],
|
||||||
)
|
)
|
||||||
|
|
||||||
const buildAreas = useCallback(
|
const buildAreas = useCallback(
|
||||||
|
|
@ -167,7 +167,7 @@ const Graph = ({
|
||||||
|
|
||||||
return points
|
return points
|
||||||
},
|
},
|
||||||
[NOW, dataPoints, period.code]
|
[NOW, dataPoints, period.code],
|
||||||
)
|
)
|
||||||
|
|
||||||
const x = d3
|
const x = d3
|
||||||
|
|
@ -192,14 +192,14 @@ const Graph = ({
|
||||||
else if (i === dates.length - 1)
|
else if (i === dates.length - 1)
|
||||||
return addMilliseconds(
|
return addMilliseconds(
|
||||||
-dataPoints[period.code].step,
|
-dataPoints[period.code].step,
|
||||||
dates[dates.length - 2]
|
dates[dates.length - 2],
|
||||||
)
|
)
|
||||||
else return date
|
else return date
|
||||||
})
|
})
|
||||||
.map(date => {
|
.map(date => {
|
||||||
const middleOfBin = addMilliseconds(
|
const middleOfBin = addMilliseconds(
|
||||||
dataPoints[period.code].step / 2,
|
dataPoints[period.code].step / 2,
|
||||||
date
|
date,
|
||||||
)
|
)
|
||||||
|
|
||||||
const txs = data.filter(tx => {
|
const txs = data.filter(tx => {
|
||||||
|
|
@ -236,7 +236,7 @@ const Graph = ({
|
||||||
.scaleLog()
|
.scaleLog()
|
||||||
.domain([
|
.domain([
|
||||||
min === 0 ? 0.9 : min * 0.9,
|
min === 0 ? 0.9 : min * 0.9,
|
||||||
(max === min ? min + Math.pow(10, 2 * min + 1) : max) * 2
|
(max === min ? min + Math.pow(10, 2 * min + 1) : max) * 2,
|
||||||
])
|
])
|
||||||
.clamp(true)
|
.clamp(true)
|
||||||
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
|
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
|
||||||
|
|
@ -247,7 +247,7 @@ const Graph = ({
|
||||||
const fullBreakpoints = [
|
const fullBreakpoints = [
|
||||||
graphLimits[1],
|
graphLimits[1],
|
||||||
...R.filter(it => it > dataLimits[0] && it < dataLimits[1], breakpoints),
|
...R.filter(it => it > dataLimits[0] && it < dataLimits[1], breakpoints),
|
||||||
dataLimits[0]
|
dataLimits[0],
|
||||||
]
|
]
|
||||||
|
|
||||||
const intervals = []
|
const intervals = []
|
||||||
|
|
@ -278,7 +278,7 @@ const Graph = ({
|
||||||
g
|
g
|
||||||
.attr(
|
.attr(
|
||||||
'transform',
|
'transform',
|
||||||
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
|
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
|
||||||
)
|
)
|
||||||
.call(
|
.call(
|
||||||
d3
|
d3
|
||||||
|
|
@ -286,18 +286,18 @@ const Graph = ({
|
||||||
.ticks(dataPoints[period.code].tick)
|
.ticks(dataPoints[period.code].tick)
|
||||||
.tickFormat(d => {
|
.tickFormat(d => {
|
||||||
return d3.timeFormat(dataPoints[period.code].labelFormat)(
|
return d3.timeFormat(dataPoints[period.code].labelFormat)(
|
||||||
d.getTime() + d.getTimezoneOffset() * MINUTE
|
d.getTime() + d.getTimezoneOffset() * MINUTE,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.tickSizeOuter(0)
|
.tickSizeOuter(0),
|
||||||
)
|
)
|
||||||
.call(g =>
|
.call(g =>
|
||||||
g
|
g
|
||||||
.select('.domain')
|
.select('.domain')
|
||||||
.attr('stroke', primaryColor)
|
.attr('stroke', primaryColor)
|
||||||
.attr('stroke-width', 1)
|
.attr('stroke-width', 1),
|
||||||
),
|
),
|
||||||
[GRAPH_MARGIN, dataPoints, period.code, x]
|
[GRAPH_MARGIN, dataPoints, period.code, x],
|
||||||
)
|
)
|
||||||
|
|
||||||
const buildYAxis = useCallback(
|
const buildYAxis = useCallback(
|
||||||
|
|
@ -315,12 +315,12 @@ const Graph = ({
|
||||||
if (d >= 1000) return numberToFiatAmount(d / 1000) + 'k'
|
if (d >= 1000) return numberToFiatAmount(d / 1000) + 'k'
|
||||||
|
|
||||||
return numberToFiatAmount(d)
|
return numberToFiatAmount(d)
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
.select('.domain')
|
.select('.domain')
|
||||||
.attr('stroke', primaryColor)
|
.attr('stroke', primaryColor)
|
||||||
.attr('stroke-width', 1),
|
.attr('stroke-width', 1),
|
||||||
[GRAPH_MARGIN, y, log]
|
[GRAPH_MARGIN, y, log],
|
||||||
)
|
)
|
||||||
|
|
||||||
const buildGrid = useCallback(
|
const buildGrid = useCallback(
|
||||||
|
|
@ -337,7 +337,7 @@ const Graph = ({
|
||||||
.attr('x1', d => 0.5 + x(d))
|
.attr('x1', d => 0.5 + x(d))
|
||||||
.attr('x2', d => 0.5 + x(d))
|
.attr('x2', d => 0.5 + x(d))
|
||||||
.attr('y1', GRAPH_MARGIN.top)
|
.attr('y1', GRAPH_MARGIN.top)
|
||||||
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
|
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom),
|
||||||
)
|
)
|
||||||
// Horizontal lines
|
// Horizontal lines
|
||||||
.call(g =>
|
.call(g =>
|
||||||
|
|
@ -348,13 +348,13 @@ const Graph = ({
|
||||||
d3
|
d3
|
||||||
.axisLeft(y)
|
.axisLeft(y)
|
||||||
.scale()
|
.scale()
|
||||||
.ticks(GRAPH_HEIGHT / 100)
|
.ticks(GRAPH_HEIGHT / 100),
|
||||||
)
|
)
|
||||||
.join('line')
|
.join('line')
|
||||||
.attr('y1', d => 0.5 + y(d))
|
.attr('y1', d => 0.5 + y(d))
|
||||||
.attr('y2', d => 0.5 + y(d))
|
.attr('y2', d => 0.5 + y(d))
|
||||||
.attr('x1', GRAPH_MARGIN.left)
|
.attr('x1', GRAPH_MARGIN.left)
|
||||||
.attr('x2', GRAPH_WIDTH)
|
.attr('x2', GRAPH_WIDTH),
|
||||||
)
|
)
|
||||||
// Vertical transparent rectangles for events
|
// Vertical transparent rectangles for events
|
||||||
.call(g =>
|
.call(g =>
|
||||||
|
|
@ -370,14 +370,14 @@ const Graph = ({
|
||||||
const intervals = getAreaInterval(
|
const intervals = getAreaInterval(
|
||||||
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
|
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
|
||||||
x.range(),
|
x.range(),
|
||||||
x2.range()
|
x2.range(),
|
||||||
)
|
)
|
||||||
const interval = getAreaIntervalByX(intervals, xValue)
|
const interval = getAreaIntervalByX(intervals, xValue)
|
||||||
return Math.round((interval[0] - interval[1]) * 100) / 100
|
return Math.round((interval[0] - interval[1]) * 100) / 100
|
||||||
})
|
})
|
||||||
.attr(
|
.attr(
|
||||||
'height',
|
'height',
|
||||||
GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top
|
GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top,
|
||||||
)
|
)
|
||||||
.attr('stroke', 'transparent')
|
.attr('stroke', 'transparent')
|
||||||
.attr('fill', 'transparent')
|
.attr('fill', 'transparent')
|
||||||
|
|
@ -387,7 +387,7 @@ const Graph = ({
|
||||||
const intervals = getAreaInterval(
|
const intervals = getAreaInterval(
|
||||||
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
|
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
|
||||||
x.range(),
|
x.range(),
|
||||||
x2.range()
|
x2.range(),
|
||||||
)
|
)
|
||||||
|
|
||||||
const dateInterval = getDateIntervalByX(areas, intervals, xValue)
|
const dateInterval = getDateIntervalByX(areas, intervals, xValue)
|
||||||
|
|
@ -405,8 +405,8 @@ const Graph = ({
|
||||||
left: R.clone(d.target.getBoundingClientRect().x),
|
left: R.clone(d.target.getBoundingClientRect().x),
|
||||||
right: R.clone(
|
right: R.clone(
|
||||||
d.target.getBoundingClientRect().x +
|
d.target.getBoundingClientRect().x +
|
||||||
d.target.getBoundingClientRect().width
|
d.target.getBoundingClientRect().width,
|
||||||
)
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
const xCoord =
|
const xCoord =
|
||||||
|
|
@ -421,7 +421,7 @@ const Graph = ({
|
||||||
setSelectionData(filteredData)
|
setSelectionData(filteredData)
|
||||||
setSelectionCoords({
|
setSelectionCoords({
|
||||||
x: Math.round(xCoord),
|
x: Math.round(xCoord),
|
||||||
y: Math.round(yCoord)
|
y: Math.round(yCoord),
|
||||||
})
|
})
|
||||||
|
|
||||||
d3.select(d.target).attr('fill', subheaderColor)
|
d3.select(d.target).attr('fill', subheaderColor)
|
||||||
|
|
@ -431,7 +431,7 @@ const Graph = ({
|
||||||
setSelectionDateInterval(null)
|
setSelectionDateInterval(null)
|
||||||
setSelectionData(null)
|
setSelectionData(null)
|
||||||
setSelectionCoords(null)
|
setSelectionCoords(null)
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
// Thick vertical lines
|
// Thick vertical lines
|
||||||
.call(g =>
|
.call(g =>
|
||||||
|
|
@ -442,7 +442,7 @@ const Graph = ({
|
||||||
buildTicks(x.domain()).filter(x => {
|
buildTicks(x.domain()).filter(x => {
|
||||||
if (period.code === 'day') return x.getUTCHours() === 0
|
if (period.code === 'day') return x.getUTCHours() === 0
|
||||||
return x.getUTCDate() === 1
|
return x.getUTCDate() === 1
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
.join('line')
|
.join('line')
|
||||||
.attr('class', 'dateSeparator')
|
.attr('class', 'dateSeparator')
|
||||||
|
|
@ -451,7 +451,7 @@ const Graph = ({
|
||||||
.attr('y1', GRAPH_MARGIN.top - 50)
|
.attr('y1', GRAPH_MARGIN.top - 50)
|
||||||
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
|
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
|
||||||
.attr('stroke-width', 5)
|
.attr('stroke-width', 5)
|
||||||
.join('text')
|
.join('text'),
|
||||||
)
|
)
|
||||||
// Left side breakpoint label
|
// Left side breakpoint label
|
||||||
.call(g => {
|
.call(g => {
|
||||||
|
|
@ -509,8 +509,8 @@ const Graph = ({
|
||||||
offset,
|
offset,
|
||||||
setSelectionCoords,
|
setSelectionCoords,
|
||||||
setSelectionData,
|
setSelectionData,
|
||||||
setSelectionDateInterval
|
setSelectionDateInterval,
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
const formatTicksText = useCallback(
|
const formatTicksText = useCallback(
|
||||||
|
|
@ -521,7 +521,7 @@ const Graph = ({
|
||||||
.style('fill', fontColor)
|
.style('fill', fontColor)
|
||||||
.style('stroke-width', 0.5)
|
.style('stroke-width', 0.5)
|
||||||
.style('font-family', fontSecondary),
|
.style('font-family', fontSecondary),
|
||||||
[]
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
const formatText = useCallback(
|
const formatText = useCallback(
|
||||||
|
|
@ -532,7 +532,7 @@ const Graph = ({
|
||||||
.style('fill', offColor)
|
.style('fill', offColor)
|
||||||
.style('stroke-width', 0.5)
|
.style('stroke-width', 0.5)
|
||||||
.style('font-family', fontSecondary),
|
.style('font-family', fontSecondary),
|
||||||
[]
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
const formatTicks = useCallback(() => {
|
const formatTicks = useCallback(() => {
|
||||||
|
|
@ -574,7 +574,7 @@ const Graph = ({
|
||||||
.line()
|
.line()
|
||||||
.curve(d3.curveMonotoneX)
|
.curve(d3.curveMonotoneX)
|
||||||
.x(d => x(d.date))
|
.x(d => x(d.date))
|
||||||
.y(d => y(d.cashIn))
|
.y(d => y(d.cashIn)),
|
||||||
)
|
)
|
||||||
|
|
||||||
g.append('g')
|
g.append('g')
|
||||||
|
|
@ -599,10 +599,10 @@ const Graph = ({
|
||||||
.line()
|
.line()
|
||||||
.curve(d3.curveMonotoneX)
|
.curve(d3.curveMonotoneX)
|
||||||
.x(d => x(d.date))
|
.x(d => x(d.date))
|
||||||
.y(d => y(d.cashOut))
|
.y(d => y(d.cashOut)),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
[x, y, bins, GRAPH_MARGIN]
|
[x, y, bins, GRAPH_MARGIN],
|
||||||
)
|
)
|
||||||
|
|
||||||
const drawChart = useCallback(() => {
|
const drawChart = useCallback(() => {
|
||||||
|
|
@ -626,7 +626,7 @@ const Graph = ({
|
||||||
drawData,
|
drawData,
|
||||||
formatText,
|
formatText,
|
||||||
formatTicks,
|
formatTicks,
|
||||||
formatTicksText
|
formatTicksText,
|
||||||
])
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -642,5 +642,5 @@ export default memo(
|
||||||
(prev, next) =>
|
(prev, next) =>
|
||||||
R.equals(prev.period, next.period) &&
|
R.equals(prev.period, next.period) &&
|
||||||
R.equals(prev.selectedMachine, next.selectedMachine) &&
|
R.equals(prev.selectedMachine, next.selectedMachine) &&
|
||||||
R.equals(prev.log, next.log)
|
R.equals(prev.log, next.log),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ import {
|
||||||
neon,
|
neon,
|
||||||
subheaderDarkColor,
|
subheaderDarkColor,
|
||||||
fontColor,
|
fontColor,
|
||||||
fontSecondary
|
fontSecondary,
|
||||||
} from 'src/styling/variables'
|
} from 'src/styling/variables'
|
||||||
|
|
||||||
const Graph = ({ data, machines, currency, selectedMachine }) => {
|
const Graph = ({ data, machines, currency }) => {
|
||||||
const ref = useRef(null)
|
const ref = useRef(null)
|
||||||
|
|
||||||
const AMOUNT_OF_MACHINES = 5
|
const AMOUNT_OF_MACHINES = 5
|
||||||
|
|
@ -24,9 +24,9 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
top: 25,
|
top: 25,
|
||||||
right: 0.5,
|
right: 0.5,
|
||||||
bottom: 27,
|
bottom: 27,
|
||||||
left: 36.5
|
left: 36.5,
|
||||||
}),
|
}),
|
||||||
[]
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
const machinesClone = R.clone(machines)
|
const machinesClone = R.clone(machines)
|
||||||
|
|
@ -41,7 +41,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
if (!R.isNil(machinesClone[it])) return machinesClone[it]
|
if (!R.isNil(machinesClone[it])) return machinesClone[it]
|
||||||
return { code: `ghostMachine${it}`, display: `` }
|
return { code: `ghostMachine${it}`, display: `` }
|
||||||
},
|
},
|
||||||
R.times(R.identity, AMOUNT_OF_MACHINES)
|
R.times(R.identity, AMOUNT_OF_MACHINES),
|
||||||
)
|
)
|
||||||
|
|
||||||
const txByDevice = R.reduce(
|
const txByDevice = R.reduce(
|
||||||
|
|
@ -50,14 +50,14 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
return acc
|
return acc
|
||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
filledMachines
|
filledMachines,
|
||||||
)
|
)
|
||||||
|
|
||||||
const getDeviceVolume = deviceId =>
|
const getDeviceVolume = deviceId =>
|
||||||
R.reduce(
|
R.reduce(
|
||||||
(acc, value) => acc + BigNumber(value.fiat).toNumber(),
|
(acc, value) => acc + BigNumber(value.fiat).toNumber(),
|
||||||
0,
|
0,
|
||||||
txByDevice[deviceId]
|
txByDevice[deviceId],
|
||||||
)
|
)
|
||||||
|
|
||||||
const getDeviceVolumeByTxClass = deviceId =>
|
const getDeviceVolumeByTxClass = deviceId =>
|
||||||
|
|
@ -70,18 +70,18 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
return acc
|
return acc
|
||||||
},
|
},
|
||||||
{ cashIn: 0, cashOut: 0 },
|
{ cashIn: 0, cashOut: 0 },
|
||||||
txByDevice[deviceId]
|
txByDevice[deviceId],
|
||||||
)
|
)
|
||||||
|
|
||||||
const devicesByVolume = R.sort(
|
const devicesByVolume = R.sort(
|
||||||
(a, b) => b[1] - a[1],
|
(a, b) => b[1] - a[1],
|
||||||
R.map(m => [m.code, getDeviceVolume(m.code)], filledMachines)
|
R.map(m => [m.code, getDeviceVolume(m.code)], filledMachines),
|
||||||
)
|
)
|
||||||
|
|
||||||
const topMachines = R.take(AMOUNT_OF_MACHINES, devicesByVolume)
|
const topMachines = R.take(AMOUNT_OF_MACHINES, devicesByVolume)
|
||||||
|
|
||||||
const txClassVolumeByDevice = R.fromPairs(
|
const txClassVolumeByDevice = R.fromPairs(
|
||||||
R.map(v => [v[0], getDeviceVolumeByTxClass(v[0])], topMachines)
|
R.map(v => [v[0], getDeviceVolumeByTxClass(v[0])], topMachines),
|
||||||
)
|
)
|
||||||
|
|
||||||
const x = d3
|
const x = d3
|
||||||
|
|
@ -94,7 +94,9 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
.scaleLinear()
|
.scaleLinear()
|
||||||
.domain([
|
.domain([
|
||||||
0,
|
0,
|
||||||
d3.max(topMachines, d => d[1]) !== 0 ? d3.max(topMachines, d => d[1]) : 50
|
d3.max(topMachines, d => d[1]) !== 0
|
||||||
|
? d3.max(topMachines, d => d[1])
|
||||||
|
: 50,
|
||||||
])
|
])
|
||||||
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
|
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
|
||||||
|
|
||||||
|
|
@ -104,7 +106,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
.attr('class', 'x-axis-1')
|
.attr('class', 'x-axis-1')
|
||||||
.attr(
|
.attr(
|
||||||
'transform',
|
'transform',
|
||||||
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
|
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
|
||||||
)
|
)
|
||||||
.call(
|
.call(
|
||||||
d3
|
d3
|
||||||
|
|
@ -113,12 +115,12 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
d =>
|
d =>
|
||||||
`${
|
`${
|
||||||
R.find(it => it.code === d[0], filledMachines).display ?? ''
|
R.find(it => it.code === d[0], filledMachines).display ?? ''
|
||||||
}`
|
}`,
|
||||||
)
|
)
|
||||||
.tickSize(0)
|
.tickSize(0)
|
||||||
.tickPadding(10)
|
.tickPadding(10),
|
||||||
),
|
),
|
||||||
[GRAPH_MARGIN, x, filledMachines]
|
[GRAPH_MARGIN, x, filledMachines],
|
||||||
)
|
)
|
||||||
|
|
||||||
const buildXAxis2 = useCallback(
|
const buildXAxis2 = useCallback(
|
||||||
|
|
@ -126,7 +128,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
g.attr('class', 'x-axis-2')
|
g.attr('class', 'x-axis-2')
|
||||||
.attr(
|
.attr(
|
||||||
'transform',
|
'transform',
|
||||||
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
|
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
|
||||||
)
|
)
|
||||||
.call(
|
.call(
|
||||||
d3
|
d3
|
||||||
|
|
@ -134,24 +136,24 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
.tickFormat(d =>
|
.tickFormat(d =>
|
||||||
R.includes(`ghostMachine`, d[0])
|
R.includes(`ghostMachine`, d[0])
|
||||||
? ``
|
? ``
|
||||||
: `${d[1].toFixed(2)} ${currency}`
|
: `${d[1].toFixed(2)} ${currency}`,
|
||||||
)
|
)
|
||||||
.tickSize(0)
|
.tickSize(0)
|
||||||
.tickPadding(10)
|
.tickPadding(10),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
[GRAPH_MARGIN, x, currency]
|
[GRAPH_MARGIN, x, currency],
|
||||||
)
|
)
|
||||||
|
|
||||||
const positionXAxisLabels = useCallback(() => {
|
const positionXAxisLabels = useCallback(() => {
|
||||||
d3.selectAll('.x-axis-1 .tick text').attr('transform', function (d) {
|
d3.selectAll('.x-axis-1 .tick text').attr('transform', function () {
|
||||||
const widthPerEntry = (x.range()[1] - x.range()[0]) / AMOUNT_OF_MACHINES
|
const widthPerEntry = (x.range()[1] - x.range()[0]) / AMOUNT_OF_MACHINES
|
||||||
return `translate(${-widthPerEntry / 2.25 + this.getBBox().width / 2}, 0)`
|
return `translate(${-widthPerEntry / 2.25 + this.getBBox().width / 2}, 0)`
|
||||||
})
|
})
|
||||||
}, [x])
|
}, [x])
|
||||||
|
|
||||||
const positionXAxis2Labels = useCallback(() => {
|
const positionXAxis2Labels = useCallback(() => {
|
||||||
d3.selectAll('.x-axis-2 .tick text').attr('transform', function (d) {
|
d3.selectAll('.x-axis-2 .tick text').attr('transform', function () {
|
||||||
const widthPerEntry = (x.range()[1] - x.range()[0]) / AMOUNT_OF_MACHINES
|
const widthPerEntry = (x.range()[1] - x.range()[0]) / AMOUNT_OF_MACHINES
|
||||||
return `translate(${widthPerEntry / 2.25 - this.getBBox().width / 2}, 0)`
|
return `translate(${widthPerEntry / 2.25 - this.getBBox().width / 2}, 0)`
|
||||||
})
|
})
|
||||||
|
|
@ -166,10 +168,10 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
.axisLeft(y)
|
.axisLeft(y)
|
||||||
.ticks(GRAPH_HEIGHT / 100)
|
.ticks(GRAPH_HEIGHT / 100)
|
||||||
.tickSize(0)
|
.tickSize(0)
|
||||||
.tickFormat(``)
|
.tickFormat(``),
|
||||||
)
|
)
|
||||||
.call(g => g.select('.domain').remove()),
|
.call(g => g.select('.domain').remove()),
|
||||||
[GRAPH_MARGIN, y]
|
[GRAPH_MARGIN, y],
|
||||||
)
|
)
|
||||||
|
|
||||||
const formatTicksText = useCallback(
|
const formatTicksText = useCallback(
|
||||||
|
|
@ -180,7 +182,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
.style('fill', fontColor)
|
.style('fill', fontColor)
|
||||||
.style('stroke-width', 0.5)
|
.style('stroke-width', 0.5)
|
||||||
.style('font-family', fontSecondary),
|
.style('font-family', fontSecondary),
|
||||||
[]
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
const buildGrid = useCallback(
|
const buildGrid = useCallback(
|
||||||
|
|
@ -213,10 +215,10 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
return 0.5 + x(d) - paddedXValue
|
return 0.5 + x(d) - paddedXValue
|
||||||
})
|
})
|
||||||
.attr('y1', GRAPH_MARGIN.top)
|
.attr('y1', GRAPH_MARGIN.top)
|
||||||
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
|
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
[GRAPH_MARGIN, x]
|
[GRAPH_MARGIN, x],
|
||||||
)
|
)
|
||||||
|
|
||||||
const drawCashIn = useCallback(
|
const drawCashIn = useCallback(
|
||||||
|
|
@ -231,13 +233,13 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
R.clamp(
|
R.clamp(
|
||||||
0,
|
0,
|
||||||
GRAPH_HEIGHT,
|
GRAPH_HEIGHT,
|
||||||
GRAPH_HEIGHT - y(d[1].cashIn) - GRAPH_MARGIN.bottom - BAR_MARGIN
|
GRAPH_HEIGHT - y(d[1].cashIn) - GRAPH_MARGIN.bottom - BAR_MARGIN,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
.attr('width', x.bandwidth())
|
.attr('width', x.bandwidth())
|
||||||
.attr('rx', 2.5)
|
.attr('rx', 2.5)
|
||||||
},
|
},
|
||||||
[txClassVolumeByDevice, x, y, GRAPH_MARGIN]
|
[txClassVolumeByDevice, x, y, GRAPH_MARGIN],
|
||||||
)
|
)
|
||||||
|
|
||||||
const drawCashOut = useCallback(
|
const drawCashOut = useCallback(
|
||||||
|
|
@ -252,7 +254,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
d =>
|
d =>
|
||||||
y(d[1].cashIn + d[1].cashOut) -
|
y(d[1].cashIn + d[1].cashOut) -
|
||||||
GRAPH_MARGIN.top +
|
GRAPH_MARGIN.top +
|
||||||
GRAPH_MARGIN.bottom
|
GRAPH_MARGIN.bottom,
|
||||||
)
|
)
|
||||||
.attr('height', d => {
|
.attr('height', d => {
|
||||||
return R.clamp(
|
return R.clamp(
|
||||||
|
|
@ -261,13 +263,13 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
GRAPH_HEIGHT -
|
GRAPH_HEIGHT -
|
||||||
y(d[1].cashOut) -
|
y(d[1].cashOut) -
|
||||||
GRAPH_MARGIN.bottom -
|
GRAPH_MARGIN.bottom -
|
||||||
BAR_MARGIN / 2
|
BAR_MARGIN / 2,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.attr('width', x.bandwidth())
|
.attr('width', x.bandwidth())
|
||||||
.attr('rx', 2.5)
|
.attr('rx', 2.5)
|
||||||
},
|
},
|
||||||
[txClassVolumeByDevice, x, y, GRAPH_MARGIN]
|
[txClassVolumeByDevice, x, y, GRAPH_MARGIN],
|
||||||
)
|
)
|
||||||
|
|
||||||
const drawChart = useCallback(() => {
|
const drawChart = useCallback(() => {
|
||||||
|
|
@ -295,7 +297,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
|
||||||
formatTicksText,
|
formatTicksText,
|
||||||
buildGrid,
|
buildGrid,
|
||||||
drawCashIn,
|
drawCashIn,
|
||||||
drawCashOut
|
drawCashOut,
|
||||||
])
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -310,5 +312,5 @@ export default memo(
|
||||||
Graph,
|
Graph,
|
||||||
(prev, next) =>
|
(prev, next) =>
|
||||||
R.equals(prev.period, next.period) &&
|
R.equals(prev.period, next.period) &&
|
||||||
R.equals(prev.selectedMachine, next.selectedMachine)
|
R.equals(prev.selectedMachine, next.selectedMachine),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
.welcomeBackground {
|
.welcomeBackground {
|
||||||
background: var(--ghost) url(/wizard-background.svg) no-repeat fixed center center;
|
background: var(--ghost) url(/wizard-background.svg) no-repeat fixed center
|
||||||
|
center;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
|
|
@ -22,7 +23,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 30px
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
|
|
@ -70,4 +71,3 @@
|
||||||
.confirm2FAInput {
|
.confirm2FAInput {
|
||||||
margin-top: 25px;
|
margin-top: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ const Input2FAState = ({ state, dispatch }) => {
|
||||||
onCompleted: ({ userData }) => {
|
onCompleted: ({ userData }) => {
|
||||||
setUserData(userData)
|
setUserData(userData)
|
||||||
history.push('/')
|
history.push('/')
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const [input2FA, { error: mutationError }] = useMutation(INPUT_2FA, {
|
const [input2FA, { error: mutationError }] = useMutation(INPUT_2FA, {
|
||||||
|
|
@ -55,15 +55,15 @@ const Input2FAState = ({ state, dispatch }) => {
|
||||||
return getUserData()
|
return getUserData()
|
||||||
}
|
}
|
||||||
return setInvalidToken(true)
|
return setInvalidToken(true)
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const handle2FAChange = value => {
|
const handle2FAChange = value => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: STATES.INPUT_2FA,
|
type: STATES.INPUT_2FA,
|
||||||
payload: {
|
payload: {
|
||||||
twoFAField: value
|
twoFAField: value,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
setInvalidToken(false)
|
setInvalidToken(false)
|
||||||
}
|
}
|
||||||
|
|
@ -79,8 +79,8 @@ const Input2FAState = ({ state, dispatch }) => {
|
||||||
username: state.clientField,
|
username: state.clientField,
|
||||||
password: state.passwordField,
|
password: state.passwordField,
|
||||||
code: state.twoFAField,
|
code: state.twoFAField,
|
||||||
rememberMe: state.rememberMeField
|
rememberMe: state.rememberMeField,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
input2FA(options)
|
input2FA(options)
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,12 @@ const validationSchema = Yup.object().shape({
|
||||||
localClient: Yup.string()
|
localClient: Yup.string()
|
||||||
.required('Client field is required!')
|
.required('Client field is required!')
|
||||||
.email('Username field should be in an email format!'),
|
.email('Username field should be in an email format!'),
|
||||||
localRememberMe: Yup.boolean()
|
localRememberMe: Yup.boolean(),
|
||||||
})
|
})
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
localClient: '',
|
localClient: '',
|
||||||
localRememberMe: false
|
localRememberMe: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputFIDOState = ({ state, strategy }) => {
|
const InputFIDOState = ({ state, strategy }) => {
|
||||||
|
|
@ -74,8 +74,8 @@ const InputFIDOState = ({ state, strategy }) => {
|
||||||
{
|
{
|
||||||
onCompleted: ({ validateAssertion: success }) => {
|
onCompleted: ({ validateAssertion: success }) => {
|
||||||
success ? getUserData() : setInvalidToken(true)
|
success ? getUserData() : setInvalidToken(true)
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const [assertionOptions, { error: assertionQueryError }] = useLazyQuery(
|
const [assertionOptions, { error: assertionQueryError }] = useLazyQuery(
|
||||||
|
|
@ -86,11 +86,11 @@ const InputFIDOState = ({ state, strategy }) => {
|
||||||
? {
|
? {
|
||||||
username: state.clientField,
|
username: state.clientField,
|
||||||
password: state.passwordField,
|
password: state.passwordField,
|
||||||
domain: window.location.hostname
|
domain: window.location.hostname,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
username: localClientField,
|
username: localClientField,
|
||||||
domain: window.location.hostname
|
domain: window.location.hostname,
|
||||||
},
|
},
|
||||||
onCompleted: ({ generateAssertionOptions: options }) => {
|
onCompleted: ({ generateAssertionOptions: options }) => {
|
||||||
startAssertion(options)
|
startAssertion(options)
|
||||||
|
|
@ -102,31 +102,31 @@ const InputFIDOState = ({ state, strategy }) => {
|
||||||
password: state.passwordField,
|
password: state.passwordField,
|
||||||
rememberMe: state.rememberMeField,
|
rememberMe: state.rememberMeField,
|
||||||
assertionResponse: res,
|
assertionResponse: res,
|
||||||
domain: window.location.hostname
|
domain: window.location.hostname,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
username: localClientField,
|
username: localClientField,
|
||||||
rememberMe: localRememberMeField,
|
rememberMe: localRememberMeField,
|
||||||
assertionResponse: res,
|
assertionResponse: res,
|
||||||
domain: window.location.hostname
|
domain: window.location.hostname,
|
||||||
}
|
}
|
||||||
validateAssertion({
|
validateAssertion({
|
||||||
variables
|
variables,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
setInvalidToken(true)
|
setInvalidToken(true)
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const [getUserData, { error: queryError }] = useLazyQuery(GET_USER_DATA, {
|
const [getUserData, { error: queryError }] = useLazyQuery(GET_USER_DATA, {
|
||||||
onCompleted: ({ userData }) => {
|
onCompleted: ({ userData }) => {
|
||||||
setUserData(userData)
|
setUserData(userData)
|
||||||
history.push('/')
|
history.push('/')
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const getErrorMsg = (formikErrors, formikTouched) => {
|
const getErrorMsg = (formikErrors, formikTouched) => {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import Paper from '@mui/material/Paper'
|
import Paper from '@mui/material/Paper'
|
||||||
import React, { useReducer } from 'react'
|
import React, { useReducer } from 'react'
|
||||||
import { H5 } from 'src/components/typography'
|
|
||||||
import Logo from 'src/styling/icons/menu/logo.svg?react'
|
import Logo from 'src/styling/icons/menu/logo.svg?react'
|
||||||
|
|
||||||
import Input2FAState from './Input2FAState'
|
import Input2FAState from './Input2FAState'
|
||||||
|
|
@ -18,7 +17,7 @@ const initialState = {
|
||||||
clientField: '',
|
clientField: '',
|
||||||
passwordField: '',
|
passwordField: '',
|
||||||
rememberMeField: false,
|
rememberMeField: false,
|
||||||
loginState: STATES.LOGIN
|
loginState: STATES.LOGIN,
|
||||||
}
|
}
|
||||||
|
|
||||||
const reducer = (state, action) => {
|
const reducer = (state, action) => {
|
||||||
|
|
|
||||||
|
|
@ -44,13 +44,13 @@ const GET_USER_DATA = gql`
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
email: Yup.string().label('Email').required().email(),
|
email: Yup.string().label('Email').required().email(),
|
||||||
password: Yup.string().required('Password field is required'),
|
password: Yup.string().required('Password field is required'),
|
||||||
rememberMe: Yup.boolean()
|
rememberMe: Yup.boolean(),
|
||||||
})
|
})
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
email: '',
|
email: '',
|
||||||
password: '',
|
password: '',
|
||||||
rememberMe: false
|
rememberMe: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
const getErrorMsg = (formikErrors, formikTouched, mutationError) => {
|
const getErrorMsg = (formikErrors, formikTouched, mutationError) => {
|
||||||
|
|
@ -62,7 +62,7 @@ const getErrorMsg = (formikErrors, formikTouched, mutationError) => {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const LoginState = ({ state, dispatch, strategy }) => {
|
const LoginState = ({ dispatch, strategy }) => {
|
||||||
const history = useHistory()
|
const history = useHistory()
|
||||||
const { setUserData } = useContext(AppContext)
|
const { setUserData } = useContext(AppContext)
|
||||||
|
|
||||||
|
|
@ -72,8 +72,8 @@ const LoginState = ({ state, dispatch, strategy }) => {
|
||||||
const options = {
|
const options = {
|
||||||
variables: {
|
variables: {
|
||||||
username,
|
username,
|
||||||
password
|
password,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
const { data: loginResponse } = await login(options)
|
const { data: loginResponse } = await login(options)
|
||||||
|
|
||||||
|
|
@ -84,16 +84,16 @@ const LoginState = ({ state, dispatch, strategy }) => {
|
||||||
payload: {
|
payload: {
|
||||||
clientField: username,
|
clientField: username,
|
||||||
passwordField: password,
|
passwordField: password,
|
||||||
rememberMeField: rememberMe
|
rememberMeField: rememberMe,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const [validateAssertion, { error: FIDOMutationError }] = useMutation(
|
const [validateAssertion, { error: FIDOMutationError }] = useMutation(
|
||||||
VALIDATE_ASSERTION,
|
VALIDATE_ASSERTION,
|
||||||
{
|
{
|
||||||
onCompleted: ({ validateAssertion: success }) => success && getUserData()
|
onCompleted: ({ validateAssertion: success }) => success && getUserData(),
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const [assertionOptions, { error: assertionQueryError }] = useLazyQuery(
|
const [assertionOptions, { error: assertionQueryError }] = useLazyQuery(
|
||||||
|
|
@ -105,15 +105,15 @@ const LoginState = ({ state, dispatch, strategy }) => {
|
||||||
validateAssertion({
|
validateAssertion({
|
||||||
variables: {
|
variables: {
|
||||||
assertionResponse: res,
|
assertionResponse: res,
|
||||||
domain: window.location.hostname
|
domain: window.location.hostname,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const [getUserData, { error: userDataQueryError }] = useLazyQuery(
|
const [getUserData, { error: userDataQueryError }] = useLazyQuery(
|
||||||
|
|
@ -122,8 +122,8 @@ const LoginState = ({ state, dispatch, strategy }) => {
|
||||||
onCompleted: ({ userData }) => {
|
onCompleted: ({ userData }) => {
|
||||||
setUserData(userData)
|
setUserData(userData)
|
||||||
history.push('/')
|
history.push('/')
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -149,7 +149,7 @@ const LoginState = ({ state, dispatch, strategy }) => {
|
||||||
loginMutationError ||
|
loginMutationError ||
|
||||||
FIDOMutationError ||
|
FIDOMutationError ||
|
||||||
assertionQueryError ||
|
assertionQueryError ||
|
||||||
userDataQueryError
|
userDataQueryError,
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Field
|
<Field
|
||||||
|
|
@ -164,7 +164,7 @@ const LoginState = ({ state, dispatch, strategy }) => {
|
||||||
loginMutationError ||
|
loginMutationError ||
|
||||||
FIDOMutationError ||
|
FIDOMutationError ||
|
||||||
assertionQueryError ||
|
assertionQueryError ||
|
||||||
userDataQueryError
|
userDataQueryError,
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<div className="mt-9 flex">
|
<div className="mt-9 flex">
|
||||||
|
|
@ -183,7 +183,7 @@ const LoginState = ({ state, dispatch, strategy }) => {
|
||||||
loginMutationError ||
|
loginMutationError ||
|
||||||
FIDOMutationError ||
|
FIDOMutationError ||
|
||||||
assertionQueryError ||
|
assertionQueryError ||
|
||||||
userDataQueryError
|
userDataQueryError,
|
||||||
) && (
|
) && (
|
||||||
<P className="text-tomato">
|
<P className="text-tomato">
|
||||||
{getErrorMsg(
|
{getErrorMsg(
|
||||||
|
|
@ -192,7 +192,7 @@ const LoginState = ({ state, dispatch, strategy }) => {
|
||||||
loginMutationError ||
|
loginMutationError ||
|
||||||
FIDOMutationError ||
|
FIDOMutationError ||
|
||||||
assertionQueryError ||
|
assertionQueryError ||
|
||||||
userDataQueryError
|
userDataQueryError,
|
||||||
)}
|
)}
|
||||||
</P>
|
</P>
|
||||||
)}
|
)}
|
||||||
|
|
@ -202,11 +202,11 @@ const LoginState = ({ state, dispatch, strategy }) => {
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
return strategy === 'FIDOUsernameless'
|
return strategy === 'FIDOUsernameless'
|
||||||
? assertionOptions({
|
? assertionOptions({
|
||||||
variables: { domain: window.location.hostname }
|
variables: { domain: window.location.hostname },
|
||||||
})
|
})
|
||||||
: dispatch({
|
: dispatch({
|
||||||
type: 'FIDO',
|
type: 'FIDO',
|
||||||
payload: {}
|
payload: {},
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
buttonClassName="w-full"
|
buttonClassName="w-full"
|
||||||
|
|
|
||||||
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