chore: update ramda
This commit is contained in:
parent
82132e8eb8
commit
ffb66814f6
45 changed files with 2741 additions and 1620 deletions
4196
package-lock.json
generated
4196
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -29,7 +29,7 @@
|
||||||
"material-react-table": "^3.2.1",
|
"material-react-table": "^3.2.1",
|
||||||
"pretty-ms": "^2.1.0",
|
"pretty-ms": "^2.1.0",
|
||||||
"qrcode.react": "4.2.0",
|
"qrcode.react": "4.2.0",
|
||||||
"ramda": "^0.26.1",
|
"ramda": "^0.30.1",
|
||||||
"react": "18.3.1",
|
"react": "18.3.1",
|
||||||
"react-copy-to-clipboard": "^5.0.2",
|
"react-copy-to-clipboard": "^5.0.2",
|
||||||
"react-dom": "18.3.1",
|
"react-dom": "18.3.1",
|
||||||
|
|
@ -51,12 +51,15 @@
|
||||||
"prettier": "3.4.1",
|
"prettier": "3.4.1",
|
||||||
"tailwindcss": "^4.1.4",
|
"tailwindcss": "^4.1.4",
|
||||||
"vite": "^6.0.1",
|
"vite": "^6.0.1",
|
||||||
"vite-plugin-svgr": "^4.3.0"
|
"vite-plugin-svgr": "^4.3.0",
|
||||||
|
"vitest": "^3.1.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "vite",
|
"start": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview",
|
||||||
|
"test": "vitest",
|
||||||
|
"test:run": "vitest run"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ const NotificationCenter = ({
|
||||||
const notificationsToShow =
|
const notificationsToShow =
|
||||||
!showingUnread || !hasUnread
|
!showingUnread || !hasUnread
|
||||||
? notifications
|
? notifications
|
||||||
: R.filter(R.propEq('read', false))(notifications)
|
: R.filter(R.propEq(false, 'read'))(notifications)
|
||||||
return notificationsToShow.map(n => {
|
return notificationsToShow.map(n => {
|
||||||
return (
|
return (
|
||||||
<NotificationRow
|
<NotificationRow
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ const ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const groupStriped = elements => {
|
const groupStriped = elements => {
|
||||||
const [toStripe, noStripe] = R.partition(R.propEq('stripe', true))(elements)
|
const [toStripe, noStripe] = R.partition(R.propEq(true, 'stripe'))(elements)
|
||||||
|
|
||||||
if (!toStripe.length) {
|
if (!toStripe.length) {
|
||||||
return elements
|
return elements
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ const ETable = ({
|
||||||
setSaving(true)
|
setSaving(true)
|
||||||
|
|
||||||
const it = validationSchema.cast(value, { assert: 'ignore-optionality' })
|
const it = validationSchema.cast(value, { assert: 'ignore-optionality' })
|
||||||
const index = R.findIndex(R.propEq('id', it.id))(data)
|
const index = R.findIndex(R.propEq(it.id, 'id'))(data)
|
||||||
const list = index !== -1 ? R.update(index, it, data) : R.prepend(it, data)
|
const list = index !== -1 ? R.update(index, it, data) : R.prepend(it, data)
|
||||||
|
|
||||||
if (!R.equals(data[index], it)) {
|
if (!R.equals(data[index], it)) {
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ const Autocomplete = ({
|
||||||
autoFocus,
|
autoFocus,
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
const mapFromValue = options => it => R.find(R.propEq(valueProp, it))(options)
|
const mapFromValue = options => it => R.find(R.propEq(it, valueProp))(options)
|
||||||
const mapToValue = R.prop(valueProp)
|
const mapToValue = R.prop(valueProp)
|
||||||
|
|
||||||
const getValue = () => {
|
const getValue = () => {
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ const Analytics = () => {
|
||||||
|
|
||||||
const convertFiatToLocale = item => {
|
const convertFiatToLocale = item => {
|
||||||
if (item.fiatCode === fiatLocale) return item
|
if (item.fiatCode === fiatLocale) return item
|
||||||
const itemRate = R.find(R.propEq('code', item.fiatCode))(rates)
|
const itemRate = R.find(R.propEq(item.fiatCode, 'code'))(rates)
|
||||||
const localeRate = R.find(R.propEq('code', fiatLocale))(rates)
|
const localeRate = R.find(R.propEq('code', fiatLocale))(rates)
|
||||||
const multiplier = localeRate?.rate / itemRate?.rate
|
const multiplier = localeRate?.rate / itemRate?.rate
|
||||||
return { ...item, fiat: parseFloat(item.fiat) * multiplier }
|
return { ...item, fiat: parseFloat(item.fiat) * multiplier }
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ const CashOut = ({ name: SCREEN_KEY }) => {
|
||||||
{R.isEmpty(machines) && <EmptyTable message="No machines so far" />}
|
{R.isEmpty(machines) && <EmptyTable message="No machines so far" />}
|
||||||
{wizard && (
|
{wizard && (
|
||||||
<Wizard
|
<Wizard
|
||||||
machine={R.find(R.propEq('deviceId', wizard))(machines)}
|
machine={R.find(R.propEq(wizard, 'deviceId'))(machines)}
|
||||||
onClose={() => setWizard(false)}
|
onClose={() => setWizard(false)}
|
||||||
save={save}
|
save={save}
|
||||||
error={error?.message}
|
error={error?.message}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ const Wizard = ({ machine, locale, onClose, save, error }) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const newConfig = R.merge(config, it)
|
const newConfig = R.mergeRight(config, it)
|
||||||
|
|
||||||
setState({
|
setState({
|
||||||
step: step + 1,
|
step: step + 1,
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ const CommissionsDetails = memo(
|
||||||
initialValues={commission}
|
initialValues={commission}
|
||||||
save={save}
|
save={save}
|
||||||
validationSchema={getSchema(locale)}
|
validationSchema={getSchema(locale)}
|
||||||
data={R.of(commission)}
|
data={R.of(Array, commission)}
|
||||||
elements={mainFields(currency)}
|
elements={mainFields(currency)}
|
||||||
setEditing={onEditingDefault}
|
setEditing={onEditingDefault}
|
||||||
forceDisable={isEditingOverrides}
|
forceDisable={isEditingOverrides}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ const getElement = (code, display) => ({
|
||||||
const sortCommissionsBy = prop => {
|
const sortCommissionsBy = prop => {
|
||||||
switch (prop) {
|
switch (prop) {
|
||||||
case ORDER_OPTIONS[0]:
|
case ORDER_OPTIONS[0]:
|
||||||
return R.sortBy(R.find(R.propEq('code', R.prop('machine'))))
|
return R.sortBy(R.find(R.propEq(R.prop('machine'), 'code')))
|
||||||
case ORDER_OPTIONS[1]:
|
case ORDER_OPTIONS[1]:
|
||||||
return R.sortBy(R.path(['cryptoCurrencies', 0]))
|
return R.sortBy(R.path(['cryptoCurrencies', 0]))
|
||||||
default:
|
default:
|
||||||
|
|
@ -80,7 +80,7 @@ const CommissionsList = memo(
|
||||||
|
|
||||||
const getMachineCoins = deviceId => {
|
const getMachineCoins = deviceId => {
|
||||||
const override = R.prop('overrides', localeConfig)?.find(
|
const override = R.prop('overrides', localeConfig)?.find(
|
||||||
R.propEq('machine', deviceId),
|
R.propEq(deviceId, 'machine'),
|
||||||
)
|
)
|
||||||
|
|
||||||
const machineCoins = override
|
const machineCoins = override
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ const getView = (data, code, compare) => it => {
|
||||||
if (!data) return ''
|
if (!data) return ''
|
||||||
|
|
||||||
// The following boolean should come undefined if it is rendering an unpaired machine
|
// The following boolean should come undefined if it is rendering an unpaired machine
|
||||||
const attribute = R.find(R.propEq(compare ?? 'code', it))(data)
|
const attribute = R.find(R.propEq(it, compare ?? 'code'))(data)
|
||||||
|
|
||||||
return attribute ? R.prop(code, attribute) : 'Unpaired machine'
|
return attribute ? R.prop(code, attribute) : 'Unpaired machine'
|
||||||
}
|
}
|
||||||
|
|
@ -294,8 +294,8 @@ const getAlreadyUsed = (id, machine, values) => {
|
||||||
const getCrypto = R.prop('cryptoCurrencies')
|
const getCrypto = R.prop('cryptoCurrencies')
|
||||||
const getMachineId = R.prop('machine')
|
const getMachineId = R.prop('machine')
|
||||||
|
|
||||||
const filteredOverrides = R.filter(R.propEq('machine', machine))(values)
|
const filteredOverrides = R.filter(R.propEq(machine, 'machine'))(values)
|
||||||
const originalValue = R.find(R.propEq('id', id))(values)
|
const originalValue = R.find(R.propEq(id, 'id'))(values)
|
||||||
|
|
||||||
const originalCryptos = getCrypto(originalValue)
|
const originalCryptos = getCrypto(originalValue)
|
||||||
const originalMachineId = getMachineId(originalValue)
|
const originalMachineId = getMachineId(originalValue)
|
||||||
|
|
@ -407,7 +407,7 @@ const overridesDefaults = {
|
||||||
|
|
||||||
const getOrder = ({ machine, cryptoCurrencies }) => {
|
const getOrder = ({ machine, cryptoCurrencies }) => {
|
||||||
const isAllMachines = machine === ALL_MACHINES.deviceId
|
const isAllMachines = machine === ALL_MACHINES.deviceId
|
||||||
const isAllCoins = R.contains(ALL_COINS.code, cryptoCurrencies)
|
const isAllCoins = R.includes(ALL_COINS.code, cryptoCurrencies)
|
||||||
|
|
||||||
if (isAllMachines && isAllCoins) return 0
|
if (isAllMachines && isAllCoins) return 0
|
||||||
if (isAllMachines) return 1
|
if (isAllMachines) return 1
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ const CustomerData = ({
|
||||||
deleteEditedData: () => deleteEditedData({ idCardData: null }),
|
deleteEditedData: () => deleteEditedData({ idCardData: null }),
|
||||||
save: values =>
|
save: values =>
|
||||||
editCustomer({
|
editCustomer({
|
||||||
idCardData: R.merge(idData, formatDates(values)),
|
idCardData: R.mergeRight(idData, formatDates(values)),
|
||||||
}),
|
}),
|
||||||
validationSchema: customerDataSchemas.idCardData,
|
validationSchema: customerDataSchemas.idCardData,
|
||||||
checkAgainstSanctions: () =>
|
checkAgainstSanctions: () =>
|
||||||
|
|
@ -167,7 +167,7 @@ const CustomerData = ({
|
||||||
save: values => {
|
save: values => {
|
||||||
editCustomer({
|
editCustomer({
|
||||||
subscriberInfo: {
|
subscriberInfo: {
|
||||||
result: R.merge(smsData, R.omit(['phoneNumber'])(values)),
|
result: R.mergeRight(smsData, R.omit(['phoneNumber'])(values)),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ const ManualDataEntry = ({ selectedValues, customInfoRequirementOptions }) => {
|
||||||
: requirementOptions
|
: requirementOptions
|
||||||
|
|
||||||
const requirementName = displayRequirements
|
const requirementName = displayRequirements
|
||||||
? R.find(R.propEq('code', requirementSelected))(updatedRequirementOptions)
|
? R.find(R.propEq(requirementSelected, 'code'))(updatedRequirementOptions)
|
||||||
.display
|
.display
|
||||||
: ''
|
: ''
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,9 @@ const Footer = () => {
|
||||||
const localeFiatCurrency = R.path(['locale_fiatCurrency'])(config) ?? ''
|
const localeFiatCurrency = R.path(['locale_fiatCurrency'])(config) ?? ''
|
||||||
|
|
||||||
const renderFooterItem = key => {
|
const renderFooterItem = key => {
|
||||||
const idx = R.findIndex(R.propEq('code', key))(cryptoCurrencies)
|
const idx = R.findIndex(R.propEq(key, 'code'))(cryptoCurrencies)
|
||||||
const tickerCode = wallets[`${key}_ticker`]
|
const tickerCode = wallets[`${key}_ticker`]
|
||||||
const tickerIdx = R.findIndex(R.propEq('code', tickerCode))(accountsConfig)
|
const tickerIdx = R.findIndex(R.propEq(tickerCode, 'code'))(accountsConfig)
|
||||||
|
|
||||||
const tickerName = tickerIdx > -1 ? accountsConfig[tickerIdx].display : ''
|
const tickerName = tickerIdx > -1 ? accountsConfig[tickerIdx].display : ''
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,8 +97,8 @@ const SystemPerformance = () => {
|
||||||
|
|
||||||
const convertFiatToLocale = item => {
|
const convertFiatToLocale = item => {
|
||||||
if (item.fiatCode === fiatLocale) return item
|
if (item.fiatCode === fiatLocale) return item
|
||||||
const itemRate = R.find(R.propEq('code', item.fiatCode))(data.fiatRates)
|
const itemRate = R.find(R.propEq(item.fiatCode, 'code'))(data.fiatRates)
|
||||||
const localeRate = R.find(R.propEq('code', fiatLocale))(data.fiatRates)
|
const localeRate = R.find(R.propEq(fiatLocale, 'code'))(data.fiatRates)
|
||||||
const multiplier = localeRate.rate / itemRate.rate
|
const multiplier = localeRate.rate / itemRate.rate
|
||||||
return { ...item, fiat: parseFloat(item.fiat) * multiplier }
|
return { ...item, fiat: parseFloat(item.fiat) * multiplier }
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +140,7 @@ const SystemPerformance = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDirectionPercent = () => {
|
const getDirectionPercent = () => {
|
||||||
const [cashIn, cashOut] = R.partition(R.propEq('txClass', 'cashIn'))(
|
const [cashIn, cashOut] = R.partition(R.propEq('cashIn', 'txClass'))(
|
||||||
transactionsToShow,
|
transactionsToShow,
|
||||||
)
|
)
|
||||||
const totalLength = cashIn.length + cashOut.length
|
const totalLength = cashIn.length + cashOut.length
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ const Locales = ({ name: SCREEN_KEY }) => {
|
||||||
initialValues={locale}
|
initialValues={locale}
|
||||||
save={handleSave}
|
save={handleSave}
|
||||||
validationSchema={LocaleSchema}
|
validationSchema={LocaleSchema}
|
||||||
data={R.of(locale)}
|
data={R.of(Array, locale)}
|
||||||
elements={mainFields(data, onChangeCoin)}
|
elements={mainFields(data, onChangeCoin)}
|
||||||
setEditing={onEditingDefault}
|
setEditing={onEditingDefault}
|
||||||
forceDisable={isEditingOverrides}
|
forceDisable={isEditingOverrides}
|
||||||
|
|
@ -238,7 +238,7 @@ const Locales = ({ name: SCREEN_KEY }) => {
|
||||||
{wizard && (
|
{wizard && (
|
||||||
<Wizard
|
<Wizard
|
||||||
schemas={schemas}
|
schemas={schemas}
|
||||||
coin={R.find(R.propEq('code', wizard))(cryptoCurrencies)}
|
coin={R.find(R.propEq(wizard, 'code'))(cryptoCurrencies)}
|
||||||
onClose={() => setWizard(false)}
|
onClose={() => setWizard(false)}
|
||||||
save={wizardSave}
|
save={wizardSave}
|
||||||
error={error?.message}
|
error={error?.message}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ const allFields = (getData, onChange, auxElements = []) => {
|
||||||
|
|
||||||
return R.compose(
|
return R.compose(
|
||||||
it => `${R.prop(code)(it)} ${it?.isBeta ? '(Beta)' : ''}`,
|
it => `${R.prop(code)(it)} ${it?.isBeta ? '(Beta)' : ''}`,
|
||||||
R.find(R.propEq(compare ?? 'code', it)),
|
R.find(R.propEq(it, compare ?? 'code')),
|
||||||
)(data)
|
)(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ const allFields = (getData, onChange, auxElements = []) => {
|
||||||
const timezonesData = timezoneList
|
const timezonesData = timezoneList
|
||||||
|
|
||||||
const findSuggestion = it => {
|
const findSuggestion = it => {
|
||||||
const machine = R.find(R.propEq('deviceId', it.machine))(machineData)
|
const machine = R.find(R.propEq(it.machine, 'deviceId'))(machineData)
|
||||||
return machine ? [machine] : []
|
return machine ? [machine] : []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,8 @@ const Commissions = ({ name: SCREEN_KEY, id: deviceId }) => {
|
||||||
|
|
||||||
const overrides = config.overrides
|
const overrides = config.overrides
|
||||||
? R.concat(
|
? R.concat(
|
||||||
R.filter(R.propEq('machine', 'ALL_MACHINES'), config.overrides),
|
R.filter(R.propEq('ALL_MACHINES', 'machine'), config.overrides),
|
||||||
R.filter(R.propEq('machine', deviceId), config.overrides),
|
R.filter(R.propEq(deviceId, 'machine'), config.overrides),
|
||||||
)
|
)
|
||||||
: []
|
: []
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ const CashCassettes = () => {
|
||||||
/>
|
/>
|
||||||
{wizard && (
|
{wizard && (
|
||||||
<Wizard
|
<Wizard
|
||||||
machine={R.find(R.propEq('id', machineId), machines)}
|
machine={R.find(R.propEq(machineId, 'id'), machines)}
|
||||||
cashoutSettings={getCashoutSettings(machineId)}
|
cashoutSettings={getCashoutSettings(machineId)}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setWizard(false)
|
setWizard(false)
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ const CashboxHistory = ({ machines, currency, timezone }) => {
|
||||||
textAlign: 'left',
|
textAlign: 'left',
|
||||||
view: R.pipe(
|
view: R.pipe(
|
||||||
R.prop('deviceId'),
|
R.prop('deviceId'),
|
||||||
id => R.find(R.propEq('id', id), machines),
|
id => R.find(R.propEq(id, 'id'), machines),
|
||||||
R.defaultTo({ name: <i>Unpaired device</i> }),
|
R.defaultTo({ name: <i>Unpaired device</i> }),
|
||||||
R.prop('name'),
|
R.prop('name'),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ const MachineStatus = () => {
|
||||||
]
|
]
|
||||||
|
|
||||||
const machines = R.path(['machines'])(machinesResponse) ?? []
|
const machines = R.path(['machines'])(machinesResponse) ?? []
|
||||||
const expandedIndex = R.findIndex(R.propEq('deviceId', addedMachineId))(
|
const expandedIndex = R.findIndex(R.propEq(addedMachineId, 'deviceId'))(
|
||||||
machines,
|
machines,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
|
||||||
R.pipe(R.pickAll(fields), R.map(defaultToZero))(cassetteInput)
|
R.pipe(R.pickAll(fields), R.map(defaultToZero))(cassetteInput)
|
||||||
|
|
||||||
const onContinue = it => {
|
const onContinue = it => {
|
||||||
const newConfig = R.merge(config, it)
|
const newConfig = R.mergeRight(config, it)
|
||||||
if (isLastStep) {
|
if (isLastStep) {
|
||||||
const wasCashboxEmptied = [
|
const wasCashboxEmptied = [
|
||||||
config?.wasCashboxEmptied,
|
config?.wasCashboxEmptied,
|
||||||
|
|
@ -158,7 +158,7 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
|
||||||
: {}
|
: {}
|
||||||
|
|
||||||
const makeInitialValues = () =>
|
const makeInitialValues = () =>
|
||||||
R.merge(makeCassettesInitialValues(), makeRecyclersInitialValues())
|
R.mergeRight(makeCassettesInitialValues(), makeRecyclersInitialValues())
|
||||||
|
|
||||||
const steps = R.pipe(
|
const steps = R.pipe(
|
||||||
R.concat(
|
R.concat(
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,12 @@ const CryptoBalanceOverrides = ({ section }) => {
|
||||||
|
|
||||||
const overriddenCryptos = R.map(R.prop(CRYPTOCURRENCY_KEY))(setupValues)
|
const overriddenCryptos = R.map(R.prop(CRYPTOCURRENCY_KEY))(setupValues)
|
||||||
const suggestionFilter = R.filter(
|
const suggestionFilter = R.filter(
|
||||||
it => !R.contains(it.code, overriddenCryptos),
|
it => !R.includes(it.code, overriddenCryptos),
|
||||||
)
|
)
|
||||||
const suggestions = suggestionFilter(cryptoCurrencies)
|
const suggestions = suggestionFilter(cryptoCurrencies)
|
||||||
|
|
||||||
const findSuggestion = it => {
|
const findSuggestion = it => {
|
||||||
const coin = R.compose(R.find(R.propEq('code', it?.cryptoCurrency)))(
|
const coin = R.compose(R.find(R.propEq(it?.cryptoCurrency, 'code')))(
|
||||||
cryptoCurrencies,
|
cryptoCurrencies,
|
||||||
)
|
)
|
||||||
return coin ? [coin] : []
|
return coin ? [coin] : []
|
||||||
|
|
@ -90,7 +90,7 @@ const CryptoBalanceOverrides = ({ section }) => {
|
||||||
const viewCrypto = it =>
|
const viewCrypto = it =>
|
||||||
R.compose(
|
R.compose(
|
||||||
R.path(['display']),
|
R.path(['display']),
|
||||||
R.find(R.propEq('code', it)),
|
R.find(R.propEq(it, 'code')),
|
||||||
)(cryptoCurrencies)
|
)(cryptoCurrencies)
|
||||||
|
|
||||||
const elements = [
|
const elements = [
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ const FiatBalanceOverrides = ({ config, section }) => {
|
||||||
)
|
)
|
||||||
|
|
||||||
const findSuggestion = it => {
|
const findSuggestion = it => {
|
||||||
const coin = R.find(R.propEq('deviceId', it?.machine), machines)
|
const coin = R.find(R.propEq(it?.machine, 'deviceId'), machines)
|
||||||
return coin ? [coin] : []
|
return coin ? [coin] : []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,7 +127,7 @@ const FiatBalanceOverrides = ({ config, section }) => {
|
||||||
)
|
)
|
||||||
|
|
||||||
const viewMachine = it =>
|
const viewMachine = it =>
|
||||||
R.compose(R.path(['name']), R.find(R.propEq('deviceId', it)))(machines)
|
R.compose(R.path(['name']), R.find(R.propEq(it, 'deviceId')))(machines)
|
||||||
|
|
||||||
const elements = R.concat(
|
const elements = R.concat(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const ThirdPartyProvider = () => {
|
||||||
const getDisplayName = type => it =>
|
const getDisplayName = type => it =>
|
||||||
R.compose(
|
R.compose(
|
||||||
R.prop('display'),
|
R.prop('display'),
|
||||||
R.find(R.propEq('code', it)),
|
R.find(R.propEq(it, 'code')),
|
||||||
)(filterOptions(type))
|
)(filterOptions(type))
|
||||||
|
|
||||||
const innerSave = async value => {
|
const innerSave = async value => {
|
||||||
|
|
@ -73,7 +73,7 @@ const ThirdPartyProvider = () => {
|
||||||
<EditableTable
|
<EditableTable
|
||||||
name="thirdParty"
|
name="thirdParty"
|
||||||
initialValues={values}
|
initialValues={values}
|
||||||
data={R.of(values)}
|
data={R.of(Array, values)}
|
||||||
error={error?.message}
|
error={error?.message}
|
||||||
enableEdit
|
enableEdit
|
||||||
editWidth={174}
|
editWidth={174}
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ const ContactInfo = ({ wizard }) => {
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const findField = name => R.find(R.propEq('name', name))(fields)
|
const findField = name => R.find(R.propEq(name, 'name'))(fields)
|
||||||
const findValue = name => findField(name).value
|
const findValue = name => findField(name).value
|
||||||
|
|
||||||
const displayTextValue = value => value
|
const displayTextValue = value => value
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ const TermsConditions = () => {
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const findField = name => R.find(R.propEq('name', name))(fields)
|
const findField = name => R.find(R.propEq(name, 'name'))(fields)
|
||||||
const findValue = name => findField(name).value
|
const findValue = name => findField(name).value
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ const FormRenderer = ({
|
||||||
R.map(({ code }) => ({ [code]: (value && value[code]) ?? '' })),
|
R.map(({ code }) => ({ [code]: (value && value[code]) ?? '' })),
|
||||||
)(elements)
|
)(elements)
|
||||||
|
|
||||||
const values = R.merge(initialValues, value)
|
const values = R.mergeRight(initialValues, value)
|
||||||
|
|
||||||
const [saveError, setSaveError] = useState([])
|
const [saveError, setSaveError] = useState([])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ const Services = () => {
|
||||||
|
|
||||||
const getAccounts = ({ elements, code }) => {
|
const getAccounts = ({ elements, code }) => {
|
||||||
const account = accounts[code]
|
const account = accounts[code]
|
||||||
const filterBySecretComponent = R.filter(R.propEq('component', SecretInput))
|
const filterBySecretComponent = R.filter(R.propEq(SecretInput, 'component'))
|
||||||
const mapToCode = R.map(R.prop(['code']))
|
const mapToCode = R.map(R.prop(['code']))
|
||||||
const passwordFields = R.compose(
|
const passwordFields = R.compose(
|
||||||
mapToCode,
|
mapToCode,
|
||||||
|
|
|
||||||
|
|
@ -70,13 +70,13 @@ const Triggers = () => {
|
||||||
const enabledCustomInfoRequests = R.pipe(
|
const enabledCustomInfoRequests = R.pipe(
|
||||||
R.path(['customInfoRequests']),
|
R.path(['customInfoRequests']),
|
||||||
R.defaultTo([]),
|
R.defaultTo([]),
|
||||||
R.filter(R.propEq('enabled', true)),
|
R.filter(R.propEq(true, 'enabled')),
|
||||||
)(customInfoReqData)
|
)(customInfoReqData)
|
||||||
|
|
||||||
const emailAuth =
|
const emailAuth =
|
||||||
data?.config?.triggersConfig_customerAuthentication === 'EMAIL'
|
data?.config?.triggersConfig_customerAuthentication === 'EMAIL'
|
||||||
|
|
||||||
const complianceServices = R.filter(R.propEq('class', 'compliance'))(
|
const complianceServices = R.filter(R.propEq('compliance', 'class'))(
|
||||||
data?.accountsConfig || [],
|
data?.accountsConfig || [],
|
||||||
)
|
)
|
||||||
const triggers = fromServer(data?.config?.triggers ?? [])
|
const triggers = fromServer(data?.config?.triggers ?? [])
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ const Wizard = ({
|
||||||
)
|
)
|
||||||
|
|
||||||
const onContinue = async it => {
|
const onContinue = async it => {
|
||||||
const newConfig = R.merge(config, stepOptions.schema.cast(it))
|
const newConfig = R.mergeRight(config, stepOptions.schema.cast(it))
|
||||||
|
|
||||||
if (isLastStep) {
|
if (isLastStep) {
|
||||||
return save(newConfig)
|
return save(newConfig)
|
||||||
|
|
@ -221,7 +221,7 @@ const Wizard = ({
|
||||||
|
|
||||||
const createErrorMessage = (errors, touched, values) => {
|
const createErrorMessage = (errors, touched, values) => {
|
||||||
const triggerType = values?.triggerType
|
const triggerType = values?.triggerType
|
||||||
const containsType = R.contains(triggerType)
|
const containsType = R.includes(triggerType)
|
||||||
const isSuspend = values?.requirement?.requirement === 'suspend'
|
const isSuspend = values?.requirement?.requirement === 'suspend'
|
||||||
const isCustom = values?.requirement?.requirement === 'custom'
|
const isCustom = values?.requirement?.requirement === 'custom'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ const AdvancedTriggersSettings = memo(() => {
|
||||||
|
|
||||||
const customInfoRequests =
|
const customInfoRequests =
|
||||||
R.path(['customInfoRequests'])(customInfoReqData) ?? []
|
R.path(['customInfoRequests'])(customInfoReqData) ?? []
|
||||||
const enabledCustomInfoRequests = R.filter(R.propEq('enabled', true))(
|
const enabledCustomInfoRequests = R.filter(R.propEq(true, 'enabled'))(
|
||||||
customInfoRequests,
|
customInfoRequests,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -98,7 +98,7 @@ const AdvancedTriggersSettings = memo(() => {
|
||||||
initialValues={requirementsDefaults}
|
initialValues={requirementsDefaults}
|
||||||
save={saveDefaults}
|
save={saveDefaults}
|
||||||
validationSchema={defaultSchema}
|
validationSchema={defaultSchema}
|
||||||
data={R.of(requirementsDefaults)}
|
data={R.of(Array, requirementsDefaults)}
|
||||||
elements={getDefaultSettings()}
|
elements={getDefaultSettings()}
|
||||||
setEditing={onEditingDefault}
|
setEditing={onEditingDefault}
|
||||||
forceDisable={isEditingOverrides}
|
forceDisable={isEditingOverrides}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ const buildAdvancedRequirementOptions = customInfoRequests => {
|
||||||
const displayRequirement = (code, customInfoRequests) => {
|
const displayRequirement = (code, customInfoRequests) => {
|
||||||
return R.prop(
|
return R.prop(
|
||||||
'display',
|
'display',
|
||||||
R.find(R.propEq('code', code))(
|
R.find(R.propEq(code, 'code'))(
|
||||||
buildAdvancedRequirementOptions(customInfoRequests),
|
buildAdvancedRequirementOptions(customInfoRequests),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -47,7 +47,7 @@ const getOverridesSchema = (values, customInfoRequests) => {
|
||||||
const { id, requirement } = this.parent
|
const { id, requirement } = this.parent
|
||||||
// If we're editing, filter out the override being edited so that validation schemas don't enter in circular conflicts
|
// If we're editing, filter out the override being edited so that validation schemas don't enter in circular conflicts
|
||||||
const _values = R.filter(it => it.id !== id, values)
|
const _values = R.filter(it => it.id !== id, values)
|
||||||
if (R.find(R.propEq('requirement', requirement))(_values)) {
|
if (R.find(R.propEq(requirement, 'requirement'))(_values)) {
|
||||||
return this.createError({
|
return this.createError({
|
||||||
message: `Requirement '${displayRequirement(
|
message: `Requirement '${displayRequirement(
|
||||||
requirement,
|
requirement,
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ const Type = ({ ...props }) => {
|
||||||
'text-tomato': errors.triggerType && touched.triggerType,
|
'text-tomato': errors.triggerType && touched.triggerType,
|
||||||
}
|
}
|
||||||
|
|
||||||
const containsType = R.contains(values?.triggerType)
|
const containsType = R.includes(values?.triggerType)
|
||||||
const isThresholdCurrencyEnabled = containsType(['txAmount', 'txVolume'])
|
const isThresholdCurrencyEnabled = containsType(['txAmount', 'txVolume'])
|
||||||
const isTransactionAmountEnabled = containsType(['txVelocity'])
|
const isTransactionAmountEnabled = containsType(['txVelocity'])
|
||||||
const isThresholdDaysEnabled = containsType(['txVolume', 'txVelocity'])
|
const isThresholdDaysEnabled = containsType(['txVolume', 'txVelocity'])
|
||||||
|
|
@ -542,7 +542,7 @@ const requirements = (
|
||||||
const getView = (data, code, compare) => it => {
|
const getView = (data, code, compare) => it => {
|
||||||
if (!data) return ''
|
if (!data) return ''
|
||||||
|
|
||||||
return R.compose(R.prop(code), R.find(R.propEq(compare ?? 'code', it)))(data)
|
return R.compose(R.prop(code), R.find(R.propEq(it, compare ?? 'code')))(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
const customReqIdMatches = customReqId => it => {
|
const customReqIdMatches = customReqId => it => {
|
||||||
|
|
|
||||||
|
|
@ -69,12 +69,12 @@ const AdvancedWallet = () => {
|
||||||
AdvancedWalletSettingsOverrides,
|
AdvancedWalletSettingsOverrides,
|
||||||
)
|
)
|
||||||
const suggestionFilter = R.filter(
|
const suggestionFilter = R.filter(
|
||||||
it => !R.contains(it.code, overriddenCryptos),
|
it => !R.includes(it.code, overriddenCryptos),
|
||||||
)
|
)
|
||||||
const coinSuggestions = suggestionFilter(cryptoCurrencies)
|
const coinSuggestions = suggestionFilter(cryptoCurrencies)
|
||||||
|
|
||||||
const findSuggestion = it => {
|
const findSuggestion = it => {
|
||||||
const coin = R.compose(R.find(R.propEq('code', it?.cryptoCurrency)))(
|
const coin = R.compose(R.find(R.propEq(it?.cryptoCurrency, 'code')))(
|
||||||
cryptoCurrencies,
|
cryptoCurrencies,
|
||||||
)
|
)
|
||||||
return coin ? [coin] : []
|
return coin ? [coin] : []
|
||||||
|
|
@ -85,13 +85,13 @@ const AdvancedWallet = () => {
|
||||||
<Section>
|
<Section>
|
||||||
<EditableTable
|
<EditableTable
|
||||||
name="wallets"
|
name="wallets"
|
||||||
data={R.of(AdvancedWalletSettings)}
|
data={R.of(Array, AdvancedWalletSettings)}
|
||||||
error={error?.message}
|
error={error?.message}
|
||||||
enableEdit
|
enableEdit
|
||||||
editWidth={174}
|
editWidth={174}
|
||||||
save={save}
|
save={save}
|
||||||
stripeWhen={it => !AdvancedWalletSchema.isValidSync(it)}
|
stripeWhen={it => !AdvancedWalletSchema.isValidSync(it)}
|
||||||
inialValues={R.of(AdvancedWalletSettings)}
|
inialValues={R.of(Array, AdvancedWalletSettings)}
|
||||||
validationSchema={AdvancedWalletSchema}
|
validationSchema={AdvancedWalletSchema}
|
||||||
elements={getAdvancedWalletElements()}
|
elements={getAdvancedWalletElements()}
|
||||||
setEditing={onEditingDefault}
|
setEditing={onEditingDefault}
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,7 @@ const Wallet = ({ name: SCREEN_KEY }) => {
|
||||||
/>
|
/>
|
||||||
{wizard && (
|
{wizard && (
|
||||||
<Wizard
|
<Wizard
|
||||||
coin={R.find(R.propEq('code', wizard))(cryptoCurrencies)}
|
coin={R.find(R.propEq(wizard, 'code'))(cryptoCurrencies)}
|
||||||
onClose={() => setWizard(false)}
|
onClose={() => setWizard(false)}
|
||||||
save={save}
|
save={save}
|
||||||
schemas={schemas}
|
schemas={schemas}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ import { has0Conf } from './helper'
|
||||||
const MAX_STEPS = 5
|
const MAX_STEPS = 5
|
||||||
const MODAL_WIDTH = 554
|
const MODAL_WIDTH = 554
|
||||||
|
|
||||||
const contains = crypto => R.compose(R.contains(crypto), R.prop('cryptos'))
|
const contains = crypto => R.compose(R.includes(crypto), R.prop('cryptos'))
|
||||||
const sameClass = type => R.propEq('class', type)
|
const sameClass = type => R.propEq(type, 'class')
|
||||||
const filterConfig = (crypto, type) =>
|
const filterConfig = (crypto, type) =>
|
||||||
R.filter(it => sameClass(type)(it) && contains(crypto)(it))
|
R.filter(it => sameClass(type)(it) && contains(crypto)(it))
|
||||||
const removeDeprecated = R.filter(({ deprecated }) => !deprecated)
|
const removeDeprecated = R.filter(({ deprecated }) => !deprecated)
|
||||||
|
|
@ -59,7 +59,7 @@ const Wizard = ({
|
||||||
const exchanges = getItems(accountsConfig, accounts, 'exchange', coin.code)
|
const exchanges = getItems(accountsConfig, accounts, 'exchange', coin.code)
|
||||||
const zeroConfs = getItems(accountsConfig, accounts, 'zeroConf', coin.code)
|
const zeroConfs = getItems(accountsConfig, accounts, 'zeroConf', coin.code)
|
||||||
|
|
||||||
const getValue = code => R.find(R.propEq('code', code))(accounts)
|
const getValue = code => R.find(R.propEq(code, 'code'))(accounts)
|
||||||
|
|
||||||
const commonWizardSteps = [
|
const commonWizardSteps = [
|
||||||
{ type: 'ticker', ...tickers },
|
{ type: 'ticker', ...tickers },
|
||||||
|
|
@ -99,9 +99,9 @@ const Wizard = ({
|
||||||
const stepData = step > 0 ? wizardSteps[step - 1] : null
|
const stepData = step > 0 ? wizardSteps[step - 1] : null
|
||||||
|
|
||||||
const onContinue = async (stepConfig, stepAccount) => {
|
const onContinue = async (stepConfig, stepAccount) => {
|
||||||
const newConfig = R.merge(config, stepConfig)
|
const newConfig = R.mergeRight(config, stepConfig)
|
||||||
const newAccounts = stepAccount
|
const newAccounts = stepAccount
|
||||||
? R.merge(accountsToSave, stepAccount)
|
? R.mergeRight(accountsToSave, stepAccount)
|
||||||
: accountsToSave
|
: accountsToSave
|
||||||
|
|
||||||
if (isLastStep) {
|
if (isLastStep) {
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ const reducer = (state, action) => {
|
||||||
iError: false,
|
iError: false,
|
||||||
}
|
}
|
||||||
case 'error':
|
case 'error':
|
||||||
return R.merge(state, { innerError: true })
|
return R.mergeRight(state, { innerError: true })
|
||||||
case 'reset':
|
case 'reset':
|
||||||
return initialState
|
return initialState
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import { CURRENCY_MAX } from '../../utils/constants'
|
||||||
import { defaultToZero } from '../../utils/number'
|
import { defaultToZero } from '../../utils/number'
|
||||||
|
|
||||||
const filterClass = type => R.filter(it => it.class === type)
|
const filterClass = type => R.filter(it => it.class === type)
|
||||||
const filterCoins = ({ id }) => R.filter(it => R.contains(id)(it.cryptos))
|
const filterCoins = ({ id }) => R.filter(it => R.includes(id)(it.cryptos))
|
||||||
|
|
||||||
const WalletSchema = Yup.object().shape({
|
const WalletSchema = Yup.object().shape({
|
||||||
ticker: Yup.string('The ticker must be a string').required(
|
ticker: Yup.string('The ticker must be a string').required(
|
||||||
|
|
@ -57,7 +57,7 @@ const OverridesDefaults = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const viewFeeMultiplier = it =>
|
const viewFeeMultiplier = it =>
|
||||||
R.compose(R.prop(['display']), R.find(R.propEq('code', it)))(feeOptions)
|
R.compose(R.prop(['display']), R.find(R.propEq(it, 'code')))(feeOptions)
|
||||||
|
|
||||||
const feeOptions = [
|
const feeOptions = [
|
||||||
{ display: '+60%', code: '1.6' },
|
{ display: '+60%', code: '1.6' },
|
||||||
|
|
@ -204,7 +204,7 @@ const getElements = (cryptoCurrencies, accounts, onChange, wizard = false) => {
|
||||||
const viewCryptoCurrency = it => {
|
const viewCryptoCurrency = it => {
|
||||||
const currencyDisplay = R.compose(
|
const currencyDisplay = R.compose(
|
||||||
it => `${R.prop(['display'])(it)} ${it?.isBeta ? '(Beta)' : ''}`,
|
it => `${R.prop(['display'])(it)} ${it?.isBeta ? '(Beta)' : ''}`,
|
||||||
R.find(R.propEq('code', it)),
|
R.find(R.propEq(it, 'code')),
|
||||||
)(cryptoCurrencies)
|
)(cryptoCurrencies)
|
||||||
return currencyDisplay
|
return currencyDisplay
|
||||||
}
|
}
|
||||||
|
|
@ -213,7 +213,7 @@ const getElements = (cryptoCurrencies, accounts, onChange, wizard = false) => {
|
||||||
const getDisplayName = type => it =>
|
const getDisplayName = type => it =>
|
||||||
R.compose(
|
R.compose(
|
||||||
R.prop('display'),
|
R.prop('display'),
|
||||||
R.find(R.propEq('code', it)),
|
R.find(R.propEq(it, 'code')),
|
||||||
)(filterOptions(type))
|
)(filterOptions(type))
|
||||||
|
|
||||||
const getOptions = R.curry((option, it) =>
|
const getOptions = R.curry((option, it) =>
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ const SAVE_ACCOUNTS = gql`
|
||||||
`
|
`
|
||||||
|
|
||||||
const isConfigurable = it =>
|
const isConfigurable = it =>
|
||||||
!R.isNil(it) && !R.contains(it)(['mock-exchange', 'no-exchange'])
|
!R.isNil(it) && !R.includes(it)(['mock-exchange', 'no-exchange'])
|
||||||
|
|
||||||
const ChooseExchange = ({ data: currentData, addData }) => {
|
const ChooseExchange = ({ data: currentData, addData }) => {
|
||||||
const { data } = useQuery(GET_CONFIG)
|
const { data } = useQuery(GET_CONFIG)
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,10 @@ const SAVE_ACCOUNTS = gql`
|
||||||
`
|
`
|
||||||
|
|
||||||
const isConfigurable = it =>
|
const isConfigurable = it =>
|
||||||
R.contains(it)(['infura', 'bitgo', 'trongrid', 'galoy'])
|
R.includes(it)(['infura', 'bitgo', 'trongrid', 'galoy'])
|
||||||
|
|
||||||
const isLocalHosted = it =>
|
const isLocalHosted = it =>
|
||||||
R.contains(it)([
|
R.includes(it)([
|
||||||
'bitcoind',
|
'bitcoind',
|
||||||
'geth',
|
'geth',
|
||||||
'litecoind',
|
'litecoind',
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ const Wallet = ({ doContinue }) => {
|
||||||
const Component = mySteps[step].component
|
const Component = mySteps[step].component
|
||||||
|
|
||||||
const addData = it => {
|
const addData = it => {
|
||||||
setData(R.merge(data, it))
|
setData(R.mergeRight(data, it))
|
||||||
setStep(step + 1)
|
setStep(step + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ import * as R from 'ramda'
|
||||||
|
|
||||||
import _schema from '../../../Services/schemas'
|
import _schema from '../../../Services/schemas'
|
||||||
|
|
||||||
const contains = crypto => R.compose(R.contains(crypto), R.prop('cryptos'))
|
const contains = crypto => R.compose(R.includes(crypto), R.prop('cryptos'))
|
||||||
const sameClass = type => R.propEq('class', type)
|
const sameClass = type => R.propEq(type, 'class')
|
||||||
const filterConfig = (crypto, type) =>
|
const filterConfig = (crypto, type) =>
|
||||||
R.filter(it => sameClass(type)(it) && contains(crypto)(it))
|
R.filter(it => sameClass(type)(it) && contains(crypto)(it))
|
||||||
export const getItems = (accountsConfig, accounts, type, crypto) => {
|
export const getItems = (accountsConfig, accounts, type, crypto) => {
|
||||||
|
|
|
||||||
|
|
@ -41,11 +41,11 @@ const hasSidebar = route =>
|
||||||
const getParent = route =>
|
const getParent = route =>
|
||||||
R.find(
|
R.find(
|
||||||
R.propEq(
|
R.propEq(
|
||||||
'route',
|
|
||||||
R.dropLast(
|
R.dropLast(
|
||||||
1,
|
1,
|
||||||
R.dropLastWhile(x => x !== '/', route),
|
R.dropLastWhile(x => x !== '/', route),
|
||||||
),
|
),
|
||||||
|
'route',
|
||||||
),
|
),
|
||||||
)(flattened)
|
)(flattened)
|
||||||
|
|
||||||
|
|
@ -69,8 +69,8 @@ const Routes = () => {
|
||||||
Transition === Slide
|
Transition === Slide
|
||||||
? {
|
? {
|
||||||
direction:
|
direction:
|
||||||
R.findIndex(R.propEq('route', history.state.prev))(leafRoutes) >
|
R.findIndex(R.propEq(history.state.prev, 'route'))(leafRoutes) >
|
||||||
R.findIndex(R.propEq('route', location))(leafRoutes)
|
R.findIndex(R.propEq(location, 'route'))(leafRoutes)
|
||||||
? 'right'
|
? 'right'
|
||||||
: 'left',
|
: 'left',
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue