chore: use monorepo organization

This commit is contained in:
Rafael Taranto 2025-05-12 10:52:54 +01:00
parent deaf7d6ecc
commit a687827f7e
1099 changed files with 8184 additions and 11535 deletions

View file

@ -0,0 +1,255 @@
import { useQuery, useMutation, gql } from '@apollo/client'
import * as R from 'ramda'
import React, { useState } from 'react'
import Modal from 'src/components/Modal'
import { HelpTooltip } from 'src/components/Tooltip'
import Section from 'src/components/layout/Section'
import TitleSection from 'src/components/layout/TitleSection'
import { P } from 'src/components/typography'
import _schemas from 'src/pages/Services/schemas'
import Wizard from 'src/pages/Wallet/Wizard'
import { WalletSchema } from 'src/pages/Wallet/helper'
import { Link, SupportLinkButton } from 'src/components/buttons'
import { Table as EditableTable } from 'src/components/editableTable'
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
import {
mainFields,
overrides,
LocaleSchema,
OverridesSchema,
localeDefaults,
overridesDefaults
} from './helper'
const GET_DATA = gql`
query getData {
config
accounts
accountsConfig {
code
display
class
cryptos
}
currencies {
code
display
}
countries {
code
display
}
cryptoCurrencies {
code
display
isBeta
}
languages {
code
display
}
machines {
name
deviceId
}
}
`
const SAVE_CONFIG = gql`
mutation Save($config: JSONObject, $accounts: JSONObject) {
saveConfig(config: $config)
saveAccounts(accounts: $accounts)
}
`
const GET_MARKETS = gql`
query getMarkets {
getMarkets
}
`
const FiatCurrencyChangeAlert = ({ open, close, save }) => {
return (
<Modal
title={'Change fiat currency?'}
handleClose={close}
width={450}
height={310}
open={open}>
<P>
Please note that all values you set that were based on your prior fiat
currency are still the same. If you need to adjust these to reflect the
new fiat currency (such as minimum transaction amounts, fixed fees, and
compliance triggers, for example), please do so now.
</P>
<P>
Also, if you have cash-out enabled, you must define new dispenser bill
counts for the new currency for cash-out on the new currency to work.
</P>
<div className="ml-auto">
<Link onClick={close} color="secondary">
Cancel
</Link>
<Link className="ml-5" onClick={save} color="primary">
Save
</Link>
</div>
</Modal>
)
}
const Locales = ({ name: SCREEN_KEY }) => {
const [wizard, setWizard] = useState(false)
const [onChangeFunction, setOnChangeFunction] = useState(null)
const [error, setError] = useState(null)
const [isEditingDefault, setEditingDefault] = useState(false)
const [isEditingOverrides, setEditingOverrides] = useState(false)
const { data } = useQuery(GET_DATA)
const { data: marketsData } = useQuery(GET_MARKETS)
const schemas = _schemas(marketsData?.getMarkets)
const [saveConfig] = useMutation(SAVE_CONFIG, {
onCompleted: () => setWizard(false),
refetchQueries: () => ['getData'],
onError: error => setError(error)
})
const [dataToSave, setDataToSave] = useState(null)
const config = data?.config && fromNamespace(SCREEN_KEY)(data.config)
const wallets = data?.config && fromNamespace(namespaces.WALLETS)(data.config)
const accountsConfig = data?.accountsConfig
const accounts = data?.accounts ?? []
const cryptoCurrencies = data?.cryptoCurrencies ?? []
const locale = config && !R.isEmpty(config) ? config : localeDefaults
const localeOverrides = locale.overrides ?? []
const handleSave = it => {
const newConfig = toNamespace(SCREEN_KEY)(it.locale[0])
if (
config.fiatCurrency &&
newConfig.locale_fiatCurrency !== config.fiatCurrency
)
return setDataToSave(newConfig)
return save(newConfig)
}
const save = (config, accounts) => {
setDataToSave(null)
return saveConfig({ variables: { config, accounts } })
}
const saveOverrides = it => {
const config = toNamespace(SCREEN_KEY)(it)
setError(null)
return saveConfig({ variables: { config } })
}
const onChangeCoin = (prev, curr, setValue) => {
const coin = R.difference(curr, prev)[0]
if (!coin) return setValue(curr)
const namespaced = fromNamespace(coin)(wallets)
if (!WalletSchema.isValidSync(namespaced)) {
setOnChangeFunction(() => () => setValue(curr))
setWizard(coin)
return
}
setValue(curr)
}
const onEditingDefault = (it, editing) => setEditingDefault(editing)
const onEditingOverrides = (it, editing) => setEditingOverrides(editing)
const wizardSave = (config, accounts) =>
save(toNamespace(namespaces.WALLETS)(config), accounts).then(it => {
onChangeFunction()
setOnChangeFunction(null)
return it
})
return (
<>
<FiatCurrencyChangeAlert
open={dataToSave}
close={() => setDataToSave(null)}
save={() => dataToSave && save(dataToSave)}
/>
<TitleSection
title="Locales"
appendix={
<HelpTooltip width={320}>
<P>
For details on configuring languages, please read the relevant
knowledgebase article:
</P>
<SupportLinkButton
link="https://support.lamassu.is/hc/en-us/articles/360016257471-Setting-multiple-machine-languages"
label="Setting multiple machine languages"
bottomSpace="1"
/>
</HelpTooltip>
}
/>
<Section>
<EditableTable
title="Default settings"
error={error?.message}
titleLg
name="locale"
enableEdit
initialValues={locale}
save={handleSave}
validationSchema={LocaleSchema}
data={R.of(locale)}
elements={mainFields(data, onChangeCoin)}
setEditing={onEditingDefault}
forceDisable={isEditingOverrides}
/>
</Section>
<Section>
<EditableTable
error={error?.message}
title="Overrides"
titleLg
name="overrides"
enableDelete
enableEdit
enableCreate
initialValues={overridesDefaults}
save={saveOverrides}
validationSchema={OverridesSchema}
data={localeOverrides ?? []}
elements={overrides(data, localeOverrides, onChangeCoin)}
disableAdd={R.compose(R.isEmpty, R.difference)(
data?.machines.map(m => m.deviceId) ?? [],
localeOverrides?.map(o => o.machine) ?? []
)}
setEditing={onEditingOverrides}
forceDisable={isEditingDefault}
/>
</Section>
{wizard && (
<Wizard
schemas={schemas}
coin={R.find(R.propEq('code', wizard))(cryptoCurrencies)}
onClose={() => setWizard(false)}
save={wizardSave}
error={error?.message}
cryptoCurrencies={cryptoCurrencies}
userAccounts={data?.config?.accounts}
accounts={accounts}
accountsConfig={accountsConfig}
/>
)}
</>
)
}
export default Locales

View file

@ -0,0 +1,192 @@
import * as R from 'ramda'
import Autocomplete from 'src/components/inputs/formik/Autocomplete'
import * as Yup from 'yup'
import { labels as timezoneList } from 'src/utils/timezone-list'
const getFields = (getData, names, onChange, auxElements = []) => {
return R.filter(
it => R.includes(it.name, names),
allFields(getData, onChange, auxElements)
)
}
const allFields = (getData, onChange, auxElements = []) => {
const getView = (data, code, compare) => it => {
if (!data) return ''
return R.compose(
it => `${R.prop(code)(it)} ${it?.isBeta ? '(Beta)' : ''}`,
R.find(R.propEq(compare ?? 'code', it))
)(data)
}
const displayCodeArray = data => it => {
if (!it) return it
return R.compose(R.join(', '), R.map(getView(data, 'code')))(it)
}
const overriddenMachines = R.map(override => override.machine, auxElements)
const suggestionFilter = it =>
R.differenceWith((x, y) => x.deviceId === y, it, overriddenMachines)
const machineData = getData(['machines'])
const countryData = getData(['countries'])
const currencyData = getData(['currencies'])
const languageData = getData(['languages'])
const rawCryptoData = getData(['cryptoCurrencies'])
const cryptoData = rawCryptoData?.map(it => {
it.codeLabel = `${it.code}${it.isBeta ? ' (Beta)' : ''}`
return it
})
const timezonesData = timezoneList
const findSuggestion = it => {
const machine = R.find(R.propEq('deviceId', it.machine))(machineData)
return machine ? [machine] : []
}
return [
{
name: 'machine',
width: 200,
size: 'sm',
view: getView(machineData, 'name', 'deviceId'),
input: Autocomplete,
inputProps: {
options: it =>
R.concat(findSuggestion(it))(suggestionFilter(machineData)),
valueProp: 'deviceId',
labelProp: 'name'
}
},
{
name: 'country',
width: 200,
size: 'sm',
view: getView(countryData, 'display'),
input: Autocomplete,
inputProps: {
options: countryData,
valueProp: 'code',
labelProp: 'display'
}
},
{
name: 'fiatCurrency',
width: 150,
size: 'sm',
view: getView(currencyData, 'code'),
input: Autocomplete,
inputProps: {
options: currencyData,
valueProp: 'code',
labelProp: 'code'
}
},
{
name: 'languages',
width: 200,
size: 'sm',
view: displayCodeArray(languageData),
input: Autocomplete,
inputProps: {
options: languageData,
valueProp: 'code',
labelProp: 'display',
multiple: true
}
},
{
name: 'cryptoCurrencies',
width: 170,
size: 'sm',
view: displayCodeArray(cryptoData),
input: Autocomplete,
inputProps: {
options: cryptoData,
valueProp: 'code',
labelProp: 'codeLabel',
multiple: true,
optionsLimit: null,
onChange
}
},
{
name: 'timezone',
width: 320,
size: 'sm',
view: getView(timezonesData, 'label'),
input: Autocomplete,
inputProps: {
options: timezonesData,
valueProp: 'code',
labelProp: 'label'
}
}
]
}
const mainFields = (auxData, configureCoin) => {
const getData = R.path(R.__, auxData)
return getFields(
getData,
['country', 'fiatCurrency', 'languages', 'cryptoCurrencies', 'timezone'],
configureCoin,
undefined
)
}
const overrides = (auxData, auxElements, configureCoin) => {
const getData = R.path(R.__, auxData)
return getFields(
getData,
['machine', 'country', 'languages', 'cryptoCurrencies'],
configureCoin,
auxElements
)
}
const LocaleSchema = Yup.object().shape({
country: Yup.string().label('Country').required(),
fiatCurrency: Yup.string().label('Fiat currency').required(),
languages: Yup.array().label('Languages').required().min(1).max(4),
cryptoCurrencies: Yup.array().label('Crypto currencies').required().min(1),
timezone: Yup.string().label('Timezone').required()
})
const OverridesSchema = Yup.object().shape({
machine: Yup.string().label('Machine').required(),
country: Yup.string().label('Country').required(),
languages: Yup.array().label('Languages').required().min(1).max(4),
cryptoCurrencies: Yup.array().label('Crypto currencies').required().min(1)
})
const localeDefaults = {
country: '',
fiatCurrency: '',
languages: [],
cryptoCurrencies: [],
timezone: ''
}
const overridesDefaults = {
machine: '',
country: '',
languages: [],
cryptoCurrencies: []
}
export {
mainFields,
overrides,
LocaleSchema,
OverridesSchema,
localeDefaults,
overridesDefaults
}

View file

@ -0,0 +1,3 @@
import Locales from './Locales'
export default Locales