lamassu-server/new-lamassu-admin/src/pages/Services/Services.jsx
2025-04-22 13:11:45 +01:00

156 lines
4.4 KiB
JavaScript

import { useQuery, useMutation, gql } from "@apollo/client";
import Grid from '@mui/material/Grid'
import { makeStyles } from '@mui/styles'
import * as R from 'ramda'
import React, { useState } from 'react'
import Modal from 'src/components/Modal'
import CheckboxInput from 'src/components/inputs/formik/Checkbox'
import TitleSection from 'src/components/layout/TitleSection'
import SingleRowTable from 'src/components/single-row-table/SingleRowTable'
import { SecretInput } from 'src/components/inputs/formik'
import { formatLong } from 'src/utils/string'
import FormRenderer from './FormRenderer'
import _schemas from './schemas'
const GET_INFO = gql`
query getData {
accounts
config
}
`
const GET_MARKETS = gql`
query getMarkets {
getMarkets
}
`
const SAVE_ACCOUNT = gql`
mutation Save($accounts: JSONObject) {
saveAccounts(accounts: $accounts)
}
`
const styles = {
wrapper: {
// widths + spacing is a little over 1200 on the design
// this adjusts the margin after a small reduction on card size
marginLeft: 1
}
}
const useStyles = makeStyles(styles)
const Services = () => {
const [editingSchema, setEditingSchema] = useState(null)
const { data, loading: configLoading } = useQuery(GET_INFO)
const { data: marketsData, loading: marketsLoading } = useQuery(GET_MARKETS)
const [saveAccount] = useMutation(SAVE_ACCOUNT, {
onCompleted: () => setEditingSchema(null),
refetchQueries: ['getData']
})
const markets = marketsData?.getMarkets
const schemas = _schemas(markets)
const classes = useStyles()
const accounts = data?.accounts ?? {}
const getItems = (code, elements) => {
const faceElements = R.filter(R.prop('face'))(elements)
const values = accounts[code] || {}
return R.map(({ display, code, long }) => ({
label: display,
value: long ? formatLong(values[code]) : values[code]
}))(faceElements)
}
const updateSettings = element => {
const settings = element.settings
const field = R.lensPath(['config', settings.field])
const isEnabled = R.isNil(settings.requirement)
? true
: R.equals(R.view(field, data), settings.requirement)
settings.enabled = isEnabled
return element
}
const getElements = ({ code, elements }) => {
return R.map(elem => {
if (elem.component === CheckboxInput) return updateSettings(elem)
if (elem.component !== SecretInput) return elem
return {
...elem,
inputProps: {
isPasswordFilled:
!R.isNil(accounts[code]) &&
!R.isNil(R.path([elem.code], accounts[code]))
}
}
}, elements)
}
const getAccounts = ({ elements, code }) => {
const account = accounts[code]
const filterBySecretComponent = R.filter(R.propEq('component', SecretInput))
const mapToCode = R.map(R.prop(['code']))
const passwordFields = R.compose(
mapToCode,
filterBySecretComponent
)(elements)
return R.mapObjIndexed(
(value, key) => (R.includes(key, passwordFields) ? '' : value),
account
)
}
const getValidationSchema = ({ code, getValidationSchema }) =>
getValidationSchema(accounts[code])
const loading = marketsLoading || configLoading
return (
!loading && (
<div className={classes.wrapper}>
<TitleSection title="Third-Party services" />
<Grid container spacing={4}>
{R.values(schemas).map(schema => (
<Grid item key={schema.code}>
<SingleRowTable
editMessage={'Configure ' + schema.title}
title={schema.title}
onEdit={() => setEditingSchema(schema)}
items={getItems(schema.code, schema.elements)}
/>
</Grid>
))}
</Grid>
{editingSchema && (
<Modal
title={`Edit ${editingSchema.name}`}
width={525}
handleClose={() => setEditingSchema(null)}
open={true}>
<FormRenderer
save={it =>
saveAccount({
variables: { accounts: { [editingSchema.code]: it } }
})
}
elements={getElements(editingSchema)}
validationSchema={getValidationSchema(editingSchema)}
value={getAccounts(editingSchema)}
/>
</Modal>
)}
</div>
)
)
}
export default Services