Merge branch 'dev' into fix/coinatmradar-fix-7.5
This commit is contained in:
commit
bb3c9ef2ec
9 changed files with 185 additions and 131 deletions
|
|
@ -3,6 +3,7 @@ const { parseAsync } = require('json2csv')
|
||||||
const { GraphQLDateTime } = require('graphql-iso-date')
|
const { GraphQLDateTime } = require('graphql-iso-date')
|
||||||
const { GraphQLJSON, GraphQLJSONObject } = require('graphql-type-json')
|
const { GraphQLJSON, GraphQLJSONObject } = require('graphql-type-json')
|
||||||
const got = require('got')
|
const got = require('got')
|
||||||
|
const DataLoader = require('dataloader')
|
||||||
|
|
||||||
const machineLoader = require('../../machine-loader')
|
const machineLoader = require('../../machine-loader')
|
||||||
const customers = require('../../customers')
|
const customers = require('../../customers')
|
||||||
|
|
@ -265,6 +266,8 @@ const typeDefs = gql`
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const transactionsLoader = new DataLoader(ids => transactions.getCustomerTransactionsBatch(ids))
|
||||||
|
|
||||||
const notify = () => got.post('http://localhost:3030/dbChange')
|
const notify = () => got.post('http://localhost:3030/dbChange')
|
||||||
.catch(e => console.error('Error: lamassu-server not responding'))
|
.catch(e => console.error('Error: lamassu-server not responding'))
|
||||||
|
|
||||||
|
|
@ -273,7 +276,7 @@ const resolvers = {
|
||||||
JSONObject: GraphQLJSONObject,
|
JSONObject: GraphQLJSONObject,
|
||||||
Date: GraphQLDateTime,
|
Date: GraphQLDateTime,
|
||||||
Customer: {
|
Customer: {
|
||||||
transactions: parent => transactions.getCustomerTransactions(parent.id)
|
transactions: parent => transactionsLoader.load(parent.id)
|
||||||
},
|
},
|
||||||
Query: {
|
Query: {
|
||||||
countries: () => countries,
|
countries: () => countries,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
const _ = require('lodash/fp')
|
const _ = require('lodash/fp')
|
||||||
|
const pgp = require('pg-promise')()
|
||||||
|
|
||||||
const db = require('../db')
|
const db = require('../db')
|
||||||
const machineLoader = require('../machine-loader')
|
const machineLoader = require('../machine-loader')
|
||||||
|
|
@ -65,9 +66,8 @@ function batch (from = new Date(0).toISOString(), until = new Date().toISOString
|
||||||
.then(packager)
|
.then(packager)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCustomerTransactions (customerId) {
|
function getCustomerTransactionsBatch (ids) {
|
||||||
const packager = _.flow(it => {
|
const packager = _.flow(it => {
|
||||||
console.log()
|
|
||||||
return it
|
return it
|
||||||
}, _.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames)
|
}, _.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames)
|
||||||
|
|
||||||
|
|
@ -82,7 +82,7 @@ function getCustomerTransactions (customerId) {
|
||||||
((not txs.send_confirmed) and (txs.created <= now() - interval $2)) as expired
|
((not txs.send_confirmed) and (txs.created <= now() - interval $2)) as expired
|
||||||
from cash_in_txs as txs
|
from cash_in_txs as txs
|
||||||
left outer join customers c on txs.customer_id = c.id
|
left outer join customers c on txs.customer_id = c.id
|
||||||
where c.id = $1
|
where c.id IN ($1^)
|
||||||
order by created desc limit $3`
|
order by created desc limit $3`
|
||||||
|
|
||||||
const cashOutSql = `select 'cashOut' as tx_class,
|
const cashOutSql = `select 'cashOut' as tx_class,
|
||||||
|
|
@ -100,14 +100,16 @@ function getCustomerTransactions (customerId) {
|
||||||
inner join cash_out_actions actions on txs.id = actions.tx_id
|
inner join cash_out_actions actions on txs.id = actions.tx_id
|
||||||
and actions.action = 'provisionAddress'
|
and actions.action = 'provisionAddress'
|
||||||
left outer join customers c on txs.customer_id = c.id
|
left outer join customers c on txs.customer_id = c.id
|
||||||
where c.id = $1
|
where c.id IN ($1^)
|
||||||
order by created desc limit $2`
|
order by created desc limit $2`
|
||||||
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
db.any(cashInSql, [customerId, cashInTx.PENDING_INTERVAL, NUM_RESULTS]),
|
db.any(cashInSql, [_.map(pgp.as.text, ids).join(','), cashInTx.PENDING_INTERVAL, NUM_RESULTS]),
|
||||||
db.any(cashOutSql, [customerId, NUM_RESULTS, REDEEMABLE_AGE])
|
db.any(cashOutSql, [_.map(pgp.as.text, ids).join(','), NUM_RESULTS, REDEEMABLE_AGE])
|
||||||
])
|
])
|
||||||
.then(packager)
|
.then(packager).then(transactions => {
|
||||||
|
const transactionMap = _.groupBy('customerId', transactions)
|
||||||
|
return ids.map(id => transactionMap[id])
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function single (txId) {
|
function single (txId) {
|
||||||
|
|
@ -156,4 +158,4 @@ function cancel (txId) {
|
||||||
.then(() => single(txId))
|
.then(() => single(txId))
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { batch, getCustomerTransactions, single, cancel }
|
module.exports = { batch, single, cancel, getCustomerTransactionsBatch }
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import CssBaseline from '@material-ui/core/CssBaseline'
|
import CssBaseline from '@material-ui/core/CssBaseline'
|
||||||
|
import Grid from '@material-ui/core/Grid'
|
||||||
import {
|
import {
|
||||||
StylesProvider,
|
StylesProvider,
|
||||||
jssPreset,
|
jssPreset,
|
||||||
|
|
@ -8,12 +9,18 @@ import {
|
||||||
import { create } from 'jss'
|
import { create } from 'jss'
|
||||||
import extendJss from 'jss-plugin-extend'
|
import extendJss from 'jss-plugin-extend'
|
||||||
import React, { createContext, useContext, useState } from 'react'
|
import React, { createContext, useContext, useState } from 'react'
|
||||||
import { useLocation, BrowserRouter as Router } from 'react-router-dom'
|
import {
|
||||||
|
useLocation,
|
||||||
|
useHistory,
|
||||||
|
BrowserRouter as Router
|
||||||
|
} from 'react-router-dom'
|
||||||
|
|
||||||
|
import Sidebar from 'src/components/layout/Sidebar'
|
||||||
|
import TitleSection from 'src/components/layout/TitleSection'
|
||||||
import ApolloProvider from 'src/utils/apollo'
|
import ApolloProvider from 'src/utils/apollo'
|
||||||
|
|
||||||
import Header from './components/layout/Header'
|
import Header from './components/layout/Header'
|
||||||
import { tree, Routes } from './routing/routes'
|
import { tree, hasSidebar, Routes, getParent } from './routing/routes'
|
||||||
import global from './styling/global'
|
import global from './styling/global'
|
||||||
import theme from './styling/theme'
|
import theme from './styling/theme'
|
||||||
import { backgroundColor, mainWidth } from './styling/variables'
|
import { backgroundColor, mainWidth } from './styling/variables'
|
||||||
|
|
@ -46,6 +53,18 @@ const useStyles = makeStyles({
|
||||||
flex: 1,
|
flex: 1,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection
|
flexDirection
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
flex: 1,
|
||||||
|
height: '100%'
|
||||||
|
},
|
||||||
|
contentWithSidebar: {
|
||||||
|
flex: 1,
|
||||||
|
marginLeft: 48,
|
||||||
|
paddingTop: 15
|
||||||
|
},
|
||||||
|
contentWithoutSidebar: {
|
||||||
|
width: mainWidth
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -54,15 +73,45 @@ const AppContext = createContext()
|
||||||
const Main = () => {
|
const Main = () => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
|
const history = useHistory()
|
||||||
const { wizardTested } = useContext(AppContext)
|
const { wizardTested } = useContext(AppContext)
|
||||||
|
|
||||||
|
const route = location.pathname
|
||||||
|
|
||||||
|
const sidebar = hasSidebar(route)
|
||||||
|
const parent = sidebar ? getParent(route) : {}
|
||||||
|
|
||||||
const is404 = location.pathname === '/404'
|
const is404 = location.pathname === '/404'
|
||||||
|
|
||||||
|
const isSelected = it => location.pathname === it.route
|
||||||
|
|
||||||
|
const onClick = it => history.push(it.route)
|
||||||
|
|
||||||
|
const contentClassName = sidebar
|
||||||
|
? classes.contentWithSidebar
|
||||||
|
: classes.contentWithoutSidebar
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
{!is404 && wizardTested && <Header tree={tree} />}
|
{!is404 && wizardTested && <Header tree={tree} />}
|
||||||
<main className={classes.wrapper}>
|
<main className={classes.wrapper}>
|
||||||
<Routes />
|
{sidebar && !is404 && wizardTested && (
|
||||||
|
<TitleSection title={parent.title}></TitleSection>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Grid container className={classes.grid}>
|
||||||
|
{sidebar && !is404 && wizardTested && (
|
||||||
|
<Sidebar
|
||||||
|
data={parent.children}
|
||||||
|
isSelected={isSelected}
|
||||||
|
displayName={it => it.label}
|
||||||
|
onClick={onClick}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div className={contentClassName}>
|
||||||
|
<Routes />
|
||||||
|
</div>
|
||||||
|
</Grid>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,11 @@ import classnames from 'classnames'
|
||||||
import React, { memo, useState } from 'react'
|
import React, { memo, useState } from 'react'
|
||||||
import { NavLink, useHistory } from 'react-router-dom'
|
import { NavLink, useHistory } from 'react-router-dom'
|
||||||
|
|
||||||
import { Link } from 'src/components/buttons'
|
import ActionButton from 'src/components/buttons/ActionButton'
|
||||||
import { H4 } from 'src/components/typography'
|
import { H4 } from 'src/components/typography'
|
||||||
import AddMachine from 'src/pages/AddMachine'
|
import AddMachine from 'src/pages/AddMachine'
|
||||||
|
import { ReactComponent as AddIconReverse } from 'src/styling/icons/button/add/white.svg'
|
||||||
|
import { ReactComponent as AddIcon } from 'src/styling/icons/button/add/zodiac.svg'
|
||||||
import { ReactComponent as Logo } from 'src/styling/icons/menu/logo.svg'
|
import { ReactComponent as Logo } from 'src/styling/icons/menu/logo.svg'
|
||||||
|
|
||||||
import styles from './Header.styles'
|
import styles from './Header.styles'
|
||||||
|
|
@ -76,9 +78,13 @@ const Header = memo(({ tree }) => {
|
||||||
</NavLink>
|
</NavLink>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
<Link color="action" onClick={() => setOpen(true)}>
|
<ActionButton
|
||||||
Add Machine
|
color="secondary"
|
||||||
</Link>
|
Icon={AddIcon}
|
||||||
|
InverseIcon={AddIconReverse}
|
||||||
|
onClick={() => setOpen(true)}>
|
||||||
|
Add machine
|
||||||
|
</ActionButton>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -128,19 +128,19 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => {
|
||||||
/>
|
/>
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
open={confirmDialogOpen}
|
open={confirmDialogOpen}
|
||||||
title={`${action?.command} this machine?`}
|
title={`${action?.display} this machine?`}
|
||||||
errorMessage={errorMessage}
|
errorMessage={errorMessage}
|
||||||
toBeConfirmed={machine.name}
|
toBeConfirmed={machine.name}
|
||||||
message={action?.message}
|
message={action?.message}
|
||||||
confirmationMessage={action?.confirmationMessage}
|
confirmationMessage={action?.confirmationMessage}
|
||||||
saveButtonAlwaysEnabled={action?.command === 'Rename'}
|
saveButtonAlwaysEnabled={action?.command === 'rename'}
|
||||||
onConfirmed={value => {
|
onConfirmed={value => {
|
||||||
setErrorMessage(null)
|
setErrorMessage(null)
|
||||||
machineAction({
|
machineAction({
|
||||||
variables: {
|
variables: {
|
||||||
deviceId: machine.deviceId,
|
deviceId: machine.deviceId,
|
||||||
action: `${action?.command}`.toLowerCase(),
|
action: `${action?.command}`,
|
||||||
...(action?.command === 'Rename' && { newName: value })
|
...(action?.command === 'rename' && { newName: value })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
|
|
@ -174,7 +174,8 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => {
|
||||||
InverseIcon={EditReversedIcon}
|
InverseIcon={EditReversedIcon}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setAction({
|
setAction({
|
||||||
command: 'Rename',
|
command: 'rename',
|
||||||
|
display: 'Rename',
|
||||||
confirmationMessage: 'Write the new name for this machine'
|
confirmationMessage: 'Write the new name for this machine'
|
||||||
})
|
})
|
||||||
}>
|
}>
|
||||||
|
|
@ -188,7 +189,8 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => {
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setAction({
|
setAction({
|
||||||
command: 'Unpair'
|
command: 'unpair',
|
||||||
|
display: 'Unpair'
|
||||||
})
|
})
|
||||||
}>
|
}>
|
||||||
Unpair
|
Unpair
|
||||||
|
|
@ -201,26 +203,42 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => {
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setAction({
|
setAction({
|
||||||
command: 'Reboot'
|
command: 'reboot',
|
||||||
|
display: 'Reboot'
|
||||||
})
|
})
|
||||||
}>
|
}>
|
||||||
Reboot
|
Reboot
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
className={classes.inlineChip}
|
className={classes.mr}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
color="primary"
|
color="primary"
|
||||||
Icon={ShutdownIcon}
|
Icon={ShutdownIcon}
|
||||||
InverseIcon={ShutdownReversedIcon}
|
InverseIcon={ShutdownReversedIcon}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setAction({
|
setAction({
|
||||||
command: 'Shutdown',
|
command: '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
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
|
<ActionButton
|
||||||
|
color="primary"
|
||||||
|
className={classes.inlineChip}
|
||||||
|
Icon={RebootIcon}
|
||||||
|
InverseIcon={RebootReversedIcon}
|
||||||
|
disabled={loading}
|
||||||
|
onClick={() =>
|
||||||
|
setAction({
|
||||||
|
command: 'restartServices',
|
||||||
|
display: 'Restart services for'
|
||||||
|
})
|
||||||
|
}>
|
||||||
|
Restart Services
|
||||||
|
</ActionButton>
|
||||||
</div>
|
</div>
|
||||||
</Item>
|
</Item>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
import { makeStyles } from '@material-ui/core'
|
|
||||||
import Grid from '@material-ui/core/Grid'
|
|
||||||
import React from 'react'
|
|
||||||
import {
|
|
||||||
Route,
|
|
||||||
Switch,
|
|
||||||
Redirect,
|
|
||||||
useLocation,
|
|
||||||
useHistory
|
|
||||||
} from 'react-router-dom'
|
|
||||||
|
|
||||||
import Sidebar from 'src/components/layout/Sidebar'
|
|
||||||
import TitleSection from 'src/components/layout/TitleSection'
|
|
||||||
|
|
||||||
import CoinAtmRadar from './CoinATMRadar'
|
|
||||||
import ContactInfo from './ContactInfo'
|
|
||||||
import ReceiptPrinting from './ReceiptPrinting'
|
|
||||||
import TermsConditions from './TermsConditions'
|
|
||||||
|
|
||||||
const styles = {
|
|
||||||
grid: {
|
|
||||||
flex: 1,
|
|
||||||
height: '100%'
|
|
||||||
},
|
|
||||||
content: {
|
|
||||||
flex: 1,
|
|
||||||
marginLeft: 48,
|
|
||||||
paddingTop: 15
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const useStyles = makeStyles(styles)
|
|
||||||
|
|
||||||
const innerRoutes = [
|
|
||||||
{
|
|
||||||
label: 'Contact information',
|
|
||||||
route: '/settings/operator-info/contact-info',
|
|
||||||
component: ContactInfo
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Receipt',
|
|
||||||
route: '/settings/operator-info/receipt-printing',
|
|
||||||
component: ReceiptPrinting
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Coin ATM Radar',
|
|
||||||
route: '/settings/operator-info/coin-atm-radar',
|
|
||||||
component: CoinAtmRadar
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Terms & Conditions',
|
|
||||||
route: '/settings/operator-info/terms-conditions',
|
|
||||||
component: TermsConditions
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const Routes = ({ wizard }) => (
|
|
||||||
<Switch>
|
|
||||||
<Redirect
|
|
||||||
exact
|
|
||||||
from="/settings/operator-info"
|
|
||||||
to="/settings/operator-info/contact-info"
|
|
||||||
/>
|
|
||||||
<Route exact path="/" />
|
|
||||||
{innerRoutes.map(({ route, component: Page, key }) => (
|
|
||||||
<Route path={route} key={key}>
|
|
||||||
<Page name={key} wizard={wizard} />
|
|
||||||
</Route>
|
|
||||||
))}
|
|
||||||
</Switch>
|
|
||||||
)
|
|
||||||
|
|
||||||
const OperatorInfo = ({ wizard = false }) => {
|
|
||||||
const classes = useStyles()
|
|
||||||
const history = useHistory()
|
|
||||||
const location = useLocation()
|
|
||||||
|
|
||||||
const isSelected = it => location.pathname === it.route
|
|
||||||
|
|
||||||
const onClick = it => history.push(it.route)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<TitleSection title="Operator information"></TitleSection>
|
|
||||||
<Grid container className={classes.grid}>
|
|
||||||
<Sidebar
|
|
||||||
data={innerRoutes}
|
|
||||||
isSelected={isSelected}
|
|
||||||
displayName={it => it.label}
|
|
||||||
onClick={onClick}
|
|
||||||
/>
|
|
||||||
<div className={classes.content}>
|
|
||||||
<Routes wizard={wizard} />
|
|
||||||
</div>
|
|
||||||
</Grid>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default OperatorInfo
|
|
||||||
|
|
@ -20,7 +20,10 @@ import MachineLogs from 'src/pages/MachineLogs'
|
||||||
import CashCassettes from 'src/pages/Maintenance/CashCassettes'
|
import CashCassettes from 'src/pages/Maintenance/CashCassettes'
|
||||||
import MachineStatus from 'src/pages/Maintenance/MachineStatus'
|
import MachineStatus from 'src/pages/Maintenance/MachineStatus'
|
||||||
import Notifications from 'src/pages/Notifications/Notifications'
|
import Notifications from 'src/pages/Notifications/Notifications'
|
||||||
import OperatorInfo from 'src/pages/OperatorInfo/OperatorInfo'
|
import CoinAtmRadar from 'src/pages/OperatorInfo/CoinATMRadar'
|
||||||
|
import ContactInfo from 'src/pages/OperatorInfo/ContactInfo'
|
||||||
|
import ReceiptPrinting from 'src/pages/OperatorInfo/ReceiptPrinting'
|
||||||
|
import TermsConditions from 'src/pages/OperatorInfo/TermsConditions'
|
||||||
import ServerLogs from 'src/pages/ServerLogs'
|
import ServerLogs from 'src/pages/ServerLogs'
|
||||||
import Services from 'src/pages/Services/Services'
|
import Services from 'src/pages/Services/Services'
|
||||||
import TokenManagement from 'src/pages/TokenManagement/TokenManagement'
|
import TokenManagement from 'src/pages/TokenManagement/TokenManagement'
|
||||||
|
|
@ -125,7 +128,36 @@ const tree = [
|
||||||
key: namespaces.OPERATOR_INFO,
|
key: namespaces.OPERATOR_INFO,
|
||||||
label: 'Operator Info',
|
label: 'Operator Info',
|
||||||
route: '/settings/operator-info',
|
route: '/settings/operator-info',
|
||||||
component: OperatorInfo
|
title: 'Operator Information',
|
||||||
|
get component() {
|
||||||
|
return () => <Redirect to={this.children[0].route} />
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
key: 'contact-info',
|
||||||
|
label: 'Contact information',
|
||||||
|
route: '/settings/operator-info/contact-info',
|
||||||
|
component: ContactInfo
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'receipt-printing',
|
||||||
|
label: 'Receipt',
|
||||||
|
route: '/settings/operator-info/receipt-printing',
|
||||||
|
component: ReceiptPrinting
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'coin-atm-radar',
|
||||||
|
label: 'Coin ATM Radar',
|
||||||
|
route: '/settings/operator-info/coin-atm-radar',
|
||||||
|
component: CoinAtmRadar
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'terms-conditions',
|
||||||
|
label: 'Terms & Conditions',
|
||||||
|
route: '/settings/operator-info/terms-conditions',
|
||||||
|
component: TermsConditions
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -181,10 +213,34 @@ const tree = [
|
||||||
]
|
]
|
||||||
|
|
||||||
const map = R.map(R.when(R.has('children'), R.prop('children')))
|
const map = R.map(R.when(R.has('children'), R.prop('children')))
|
||||||
const leafRoutes = R.compose(R.flatten, map)(tree)
|
const mappedRoutes = R.compose(R.flatten, map)(tree)
|
||||||
const parentRoutes = R.filter(R.has('children'))(tree)
|
const parentRoutes = R.filter(R.has('children'))(mappedRoutes).concat(
|
||||||
|
R.filter(R.has('children'))(tree)
|
||||||
|
)
|
||||||
|
const leafRoutes = R.compose(R.flatten, map)(mappedRoutes)
|
||||||
|
|
||||||
const flattened = R.concat(leafRoutes, parentRoutes)
|
const flattened = R.concat(leafRoutes, parentRoutes)
|
||||||
|
|
||||||
|
const hasSidebar = route =>
|
||||||
|
R.any(r => r.route === route)(
|
||||||
|
R.compose(
|
||||||
|
R.flatten,
|
||||||
|
R.map(R.prop('children')),
|
||||||
|
R.filter(R.has('children'))
|
||||||
|
)(mappedRoutes)
|
||||||
|
)
|
||||||
|
|
||||||
|
const getParent = route =>
|
||||||
|
R.find(
|
||||||
|
R.propEq(
|
||||||
|
'route',
|
||||||
|
R.dropLast(
|
||||||
|
1,
|
||||||
|
R.dropLastWhile(x => x !== '/', route)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)(flattened)
|
||||||
|
|
||||||
const Routes = () => {
|
const Routes = () => {
|
||||||
const history = useHistory()
|
const history = useHistory()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
|
|
@ -215,4 +271,4 @@ const Routes = () => {
|
||||||
</Switch>
|
</Switch>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
export { tree, Routes }
|
export { tree, getParent, hasSidebar, Routes }
|
||||||
|
|
|
||||||
19
package-lock.json
generated
19
package-lock.json
generated
|
|
@ -6131,6 +6131,25 @@
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
|
||||||
"integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
|
"integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
|
||||||
|
"dasherize": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg="
|
||||||
|
},
|
||||||
|
"data-uri-to-buffer": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ=="
|
||||||
|
},
|
||||||
|
"dataloader": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-YzhyDAwA4TaQIhM5go+vCLmU0UikghC/t9DTQYZR2M/UvZ1MdOhPezSDZcjj9uqQJOMqjLcpWtyW2iNINdlatQ=="
|
||||||
|
},
|
||||||
|
"date-fns": {
|
||||||
|
"version": "2.16.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.16.1.tgz",
|
||||||
|
"integrity": "sha512-sAJVKx/FqrLYHAQeN7VpJrPhagZc9R4ImZIWYRFZaaohR3KzmuK88touwsSwSVT8Qcbd4zoDsnGfX4GFB4imyQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"expand-brackets": {
|
"expand-brackets": {
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
"console-log-level": "^1.4.0",
|
"console-log-level": "^1.4.0",
|
||||||
"cookie-parser": "^1.4.3",
|
"cookie-parser": "^1.4.3",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
|
"dataloader": "^2.0.0",
|
||||||
"ethereumjs-tx": "^1.3.3",
|
"ethereumjs-tx": "^1.3.3",
|
||||||
"ethereumjs-util": "^5.2.0",
|
"ethereumjs-util": "^5.2.0",
|
||||||
"ethereumjs-wallet": "^0.6.3",
|
"ethereumjs-wallet": "^0.6.3",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue