import { makeStyles } from '@mui/styles' import Switch from '@mui/material/Switch' import IconButton from '@mui/material/IconButton' import SvgIcon from '@mui/material/SvgIcon' import classnames from 'classnames' import { Field, useFormikContext } from 'formik' import * as R from 'ramda' import React, { useContext, useState } from 'react' import { DeleteDialog } from 'src/components/DeleteDialog' import { Td, Tr } from 'src/components/fake-table/Table' import { Label2 } from 'src/components/typography' import DisabledDeleteIcon from 'src/styling/icons/action/delete/disabled.svg?react' import DeleteIcon from 'src/styling/icons/action/delete/enabled.svg?react' import DisabledEditIcon from 'src/styling/icons/action/edit/disabled.svg?react' import EditIcon from 'src/styling/icons/action/edit/enabled.svg?react' import StripesSvg from 'src/styling/icons/stripes.svg?react' import { Link } from 'src/components/buttons' import TableCtx from './Context' import styles from './Row.styles' const useStyles = makeStyles(styles) const ActionCol = ({ disabled, editing }) => { const classes = useStyles() const { values, submitForm, resetForm } = useFormikContext() const { editWidth, onEdit, enableEdit, enableDelete, disableRowEdit, onDelete, deleteWidth, enableToggle, onToggle, toggleWidth, forceAdd, clearError, actionColSize, error } = useContext(TableCtx) const disableEdit = disabled || (disableRowEdit && disableRowEdit(values)) const cancel = () => { clearError() resetForm() } const [deleteDialog, setDeleteDialog] = useState(false) const onConfirmed = () => { onDelete(values.id).then(res => { if (!R.isNil(res)) setDeleteDialog(false) }) } return ( <> {editing && ( Save {!forceAdd && ( Cancel )} )} {!editing && enableEdit && ( onEdit && onEdit(values.id)}> {disableEdit ? : } )} {!editing && enableDelete && ( { setDeleteDialog(true) }}> {disabled ? : } { setDeleteDialog(false) clearError() }} errorMessage={error} /> )} {!editing && enableToggle && ( onToggle(values.id)} /> )} ) } const ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => { const { name, names, bypassField, input, editable = true, size, bold, width, textAlign, editingAlign = textAlign, prefix, PrefixComponent = Label2, suffix, SuffixComponent = Label2, textStyle = it => {}, isHidden = it => false, view = it => it?.toString(), inputProps = {} } = config const fields = names ?? [name] const { values } = useFormikContext() const isEditable = editable => { if (typeof editable === 'function') return editable(values) return editable } const isEditing = editing && isEditable(editable) const isField = !bypassField const classes = useStyles({ textAlign: isEditing ? editingAlign : textAlign, size }) const innerProps = { fullWidth: true, autoFocus: focus, size, bold, textAlign: isEditing ? editingAlign : textAlign, ...inputProps } return (
{fields.map((f, idx) => ( {prefix && !isHidden(values) && ( {typeof prefix === 'function' ? prefix(f) : prefix} )} {isEditing && isField && !isHidden(values) && ( )} {isEditing && !isField && !isHidden(values) && ( )} {!isEditing && values && !isHidden(values) && (
{view(values[f], values)}
)} {suffix && !isHidden(values) && ( {suffix} )} {isHidden(values) && } ))}
) } const groupStriped = elements => { const [toStripe, noStripe] = R.partition(R.propEq('stripe', true))(elements) if (!toStripe.length) { return elements } const index = R.indexOf(toStripe[0], elements) const width = R.compose(R.sum, R.map(R.path(['width'])))(toStripe) return R.insert( index, { width, editable: false, view: () => }, noStripe ) } const ERow = ({ editing, disabled, lastOfGroup, newRow }) => { const { touched, errors, values } = useFormikContext() const { elements, enableEdit, enableDelete, error, enableToggle, rowSize, stripeWhen } = useContext(TableCtx) const classes = useStyles() const shouldStripe = !editing && stripeWhen && stripeWhen(values) const innerElements = shouldStripe ? groupStriped(elements) : elements const [toSHeader] = R.partition(R.has('doubleHeader'))(elements) const extraPaddingIndex = toSHeader?.length ? R.indexOf(toSHeader[0], elements) : -1 const extraPaddingRightIndex = toSHeader?.length ? R.indexOf(toSHeader[toSHeader.length - 1], elements) : -1 const elementToFocusIndex = innerElements.findIndex( it => it.editable === undefined || it.editable ) const classNames = { [classes.lastOfGroup]: lastOfGroup } const touchedErrors = R.pick(R.keys(touched), errors) const hasTouchedErrors = touchedErrors && R.keys(touchedErrors).length > 0 const hasErrors = hasTouchedErrors || !!error const errorMessage = error || (touchedErrors && R.values(touchedErrors).join(', ')) return ( {innerElements.map((it, idx) => { return ( ) })} {(enableEdit || enableDelete || enableToggle) && ( )} ) } export default ERow