132 lines
4.7 KiB
JavaScript
132 lines
4.7 KiB
JavaScript
import { makeStyles } from '@mui/material/styles'
|
|
import classnames from 'classnames'
|
|
import { useFormikContext, Form, Formik, Field as FormikField } from 'formik'
|
|
import * as R from 'ramda'
|
|
import React, { useState, memo } from 'react'
|
|
import PromptWhenDirty from 'src/components/PromptWhenDirty'
|
|
import { H4 } from 'src/components/typography'
|
|
import EditIconDisabled from 'src/styling/icons/action/edit/disabled.svg?react'
|
|
import EditIcon from 'src/styling/icons/action/edit/enabled.svg?react'
|
|
import FalseIcon from 'src/styling/icons/table/false.svg?react'
|
|
import TrueIcon from 'src/styling/icons/table/true.svg?react'
|
|
import * as Yup from 'yup'
|
|
|
|
import { Link, IconButton } from 'src/components/buttons'
|
|
import { RadioGroup } from 'src/components/inputs/formik'
|
|
import { Table, TableBody, TableRow, TableCell } from 'src/components/table'
|
|
|
|
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, forcedEditing = false }) => {
|
|
const initialValues = R.fromPairs(
|
|
elements.map(it => [it.name, data[it.name]?.toString() ?? 'false'])
|
|
)
|
|
|
|
const validationSchema = Yup.object().shape(
|
|
R.fromPairs(
|
|
elements.map(it => [
|
|
it.name,
|
|
Yup.mixed().oneOf(['true', 'false', true, false]).required()
|
|
])
|
|
)
|
|
)
|
|
|
|
const [editing, setEditing] = useState(forcedEditing)
|
|
|
|
const classes = useStyles()
|
|
|
|
const innerSave = async values => {
|
|
const toBoolean = (num, _) => R.equals(num, 'true')
|
|
save(R.mapObjIndexed(toBoolean, R.filter(R.complement(R.isNil))(values)))
|
|
setEditing(false)
|
|
}
|
|
|
|
const radioButtonOptions = [
|
|
{ display: 'Yes', code: 'true' },
|
|
{ display: 'No', code: 'false' }
|
|
]
|
|
return (
|
|
<div className={classes.booleanPropertiesTableWrapper}>
|
|
<Formik
|
|
validateOnBlur={false}
|
|
validateOnChange={false}
|
|
enableReinitialize
|
|
onSubmit={innerSave}
|
|
initialValues={initialValues}
|
|
validationSchema={validationSchema}>
|
|
{({ resetForm }) => {
|
|
return (
|
|
<Form>
|
|
<div className={classes.rowWrapper}>
|
|
<H4>{title}</H4>
|
|
{editing ? (
|
|
<div className={classes.rightAligned}>
|
|
<Link type="submit" color="primary">
|
|
Save
|
|
</Link>
|
|
<Link
|
|
type="reset"
|
|
className={classes.rightLink}
|
|
onClick={() => {
|
|
resetForm()
|
|
setEditing(false)
|
|
}}
|
|
color="secondary">
|
|
Cancel
|
|
</Link>
|
|
</div>
|
|
) : (
|
|
<IconButton
|
|
className={classes.transparentButton}
|
|
onClick={() => setEditing(true)}>
|
|
{disabled ? <EditIconDisabled /> : <EditIcon />}
|
|
</IconButton>
|
|
)}
|
|
</div>
|
|
<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>
|
|
)
|
|
}
|
|
)
|
|
|
|
export default BooleanPropertiesTable
|