feat: Prevent leaving the page without saving (#431)
* fix: make all fields required on the Terms & Conditions page if Show on screen is enabled fix: enable/disable the Terms & Conditions form based on the Show on screen toggle fix: replaced deactivated field with plain text when not editing fix: make de non editable text content field scrollable style: make it follow the same style as the other screens, with the edit button and links to save and cancel feat: created Prompt component to avoid leaving pages without saving feat: applied component to the editable table feat: applied component to the Cashout, Commissions, Locales, Cashboxes, Notifications, CryptoBalanceOverrides and Wallet pages feat: applied component to the ContactInfo and ReceiptPrinting pages refactor: export the default prompt message to be used in other contexts fix: applied prompt component to the Operator Info pages fix: create routes for the operator info components feat: applied the Prompt component to the Contact Info and Receipt pages feat: applied the Prompt component to the Terms & Conditions page * refactor: move prompt to components * feat: use formik on the boolean properties table * chore: removed console.logs chore: removed comments refactor: moved BooleanCell to the BooleanPropertiesTable file and make it not a formik field
This commit is contained in:
parent
dbfb37a756
commit
3c0f4ec194
10 changed files with 173 additions and 129 deletions
|
|
@ -1,117 +1,110 @@
|
|||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import classnames from 'classnames'
|
||||
import { useFormikContext, Form, Formik, Field as FormikField } from 'formik'
|
||||
import _ from 'lodash'
|
||||
import React, { useState, memo } from 'react'
|
||||
import * as Yup from 'yup'
|
||||
|
||||
import PromptWhenDirty from 'src/components/PromptWhenDirty'
|
||||
import { Link } from 'src/components/buttons'
|
||||
import { RadioGroup } from 'src/components/inputs'
|
||||
import { RadioGroup } from 'src/components/inputs/formik'
|
||||
import { Table, TableBody, TableRow, TableCell } from 'src/components/table'
|
||||
import BooleanCell from 'src/components/tables/BooleanCell'
|
||||
import { H4 } from 'src/components/typography'
|
||||
import { ReactComponent as EditIconDisabled } from 'src/styling/icons/action/edit/disabled.svg'
|
||||
import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg'
|
||||
import { ReactComponent as FalseIcon } from 'src/styling/icons/table/false.svg'
|
||||
import { ReactComponent as TrueIcon } from 'src/styling/icons/table/true.svg'
|
||||
|
||||
import { booleanPropertiesTableStyles } from './BooleanPropertiesTable.styles'
|
||||
|
||||
const useStyles = makeStyles(booleanPropertiesTableStyles)
|
||||
|
||||
const BooleanCell = ({ name }) => {
|
||||
const { values } = useFormikContext()
|
||||
return values[name] === 'true' ? <TrueIcon /> : <FalseIcon />
|
||||
}
|
||||
|
||||
const BooleanPropertiesTable = memo(
|
||||
({ title, disabled, data, elements, save }) => {
|
||||
const initialValues = _.fromPairs(elements.map(it => [it.name, '']))
|
||||
const schemaValidation = _.fromPairs(
|
||||
elements.map(it => [it.name, Yup.boolean().required()])
|
||||
)
|
||||
|
||||
const [editing, setEditing] = useState(false)
|
||||
const [radioGroupValues, setRadioGroupValues] = useState(elements)
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const innerSave = () => {
|
||||
radioGroupValues.forEach(element => {
|
||||
data[element.name] = element.value
|
||||
})
|
||||
|
||||
save(data)
|
||||
const innerSave = async value => {
|
||||
save(value)
|
||||
setEditing(false)
|
||||
}
|
||||
|
||||
const innerCancel = () => {
|
||||
setRadioGroupValues(elements)
|
||||
setEditing(false)
|
||||
}
|
||||
|
||||
const handleRadioButtons = (elementName, newValue) => {
|
||||
setRadioGroupValues(
|
||||
radioGroupValues.map(element =>
|
||||
element.name === elementName
|
||||
? { ...element, value: newValue }
|
||||
: element
|
||||
)
|
||||
)
|
||||
}
|
||||
const innerCancel = () => setEditing(false)
|
||||
|
||||
const radioButtonOptions = [
|
||||
{ display: 'Yes', code: true },
|
||||
{ display: 'No', code: false }
|
||||
{ display: 'Yes', code: 'true' },
|
||||
{ display: 'No', code: 'false' }
|
||||
]
|
||||
|
||||
if (!elements || radioGroupValues?.length === 0) return null
|
||||
|
||||
return (
|
||||
<div className={classes.booleanPropertiesTableWrapper}>
|
||||
<div className={classes.rowWrapper}>
|
||||
<H4>{title}</H4>
|
||||
{editing ? (
|
||||
<div className={classes.rightAligned}>
|
||||
<Link onClick={innerCancel} color="secondary">
|
||||
Cancel
|
||||
</Link>
|
||||
<Link
|
||||
className={classes.rightLink}
|
||||
onClick={innerSave}
|
||||
color="primary">
|
||||
Save
|
||||
</Link>
|
||||
<Formik
|
||||
enableReinitialize
|
||||
onSubmit={innerSave}
|
||||
initialValues={data || initialValues}
|
||||
schemaValidation={schemaValidation}>
|
||||
<Form>
|
||||
<div className={classes.rowWrapper}>
|
||||
<H4>{title}</H4>
|
||||
{editing ? (
|
||||
<div className={classes.rightAligned}>
|
||||
<Link onClick={innerCancel} color="secondary">
|
||||
Cancel
|
||||
</Link>
|
||||
<Link
|
||||
className={classes.rightLink}
|
||||
type="submit"
|
||||
color="primary">
|
||||
Save
|
||||
</Link>
|
||||
</div>
|
||||
) : (
|
||||
<div className={classes.transparentButton}>
|
||||
<button disabled={disabled} onClick={() => setEditing(true)}>
|
||||
{disabled ? <EditIconDisabled /> : <EditIcon />}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className={classes.transparentButton}>
|
||||
<button disabled={disabled} onClick={() => setEditing(true)}>
|
||||
{disabled ? <EditIconDisabled /> : <EditIcon />}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Table className={classes.fillColumn}>
|
||||
<TableBody className={classes.fillColumn}>
|
||||
{radioGroupValues &&
|
||||
radioGroupValues.map((element, idx) => (
|
||||
<TableRow key={idx} size="sm" className={classes.tableRow}>
|
||||
<TableCell className={classes.leftTableCell}>
|
||||
{element.display}
|
||||
</TableCell>
|
||||
<TableCell className={classes.rightTableCell}>
|
||||
{editing && (
|
||||
<RadioGroup
|
||||
options={radioButtonOptions}
|
||||
value={element.value}
|
||||
onChange={event =>
|
||||
handleRadioButtons(
|
||||
element.name,
|
||||
event.target.value === 'true'
|
||||
)
|
||||
}
|
||||
className={classnames(
|
||||
classes.radioButtons,
|
||||
classes.rightTableCell
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{!editing && (
|
||||
<BooleanCell
|
||||
className={classes.rightTableCell}
|
||||
value={element.value}
|
||||
/>
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<PromptWhenDirty />
|
||||
<Table className={classes.fillColumn}>
|
||||
<TableBody className={classes.fillColumn}>
|
||||
{elements.map((it, idx) => (
|
||||
<TableRow key={idx} size="sm" className={classes.tableRow}>
|
||||
<TableCell className={classes.leftTableCell}>
|
||||
{it.display}
|
||||
</TableCell>
|
||||
<TableCell className={classes.rightTableCell}>
|
||||
{editing && (
|
||||
<FormikField
|
||||
component={RadioGroup}
|
||||
name={it.name}
|
||||
options={radioButtonOptions}
|
||||
className={classnames(
|
||||
classes.radioButtons,
|
||||
classes.rightTableCell
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{!editing && <BooleanCell name={it.name} />}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue