UNPKG

@toolpad/core

Version:

Dashboard framework powered by Material UI.

311 lines (310 loc) 11.8 kB
"use strict"; 'use client'; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.CrudForm = CrudForm; var React = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _invariant = _interopRequireDefault(require("invariant")); var _Box = _interopRequireDefault(require("@mui/material/Box")); var _Button = _interopRequireDefault(require("@mui/material/Button")); var _Checkbox = _interopRequireDefault(require("@mui/material/Checkbox")); var _FormControl = _interopRequireDefault(require("@mui/material/FormControl")); var _FormControlLabel = _interopRequireDefault(require("@mui/material/FormControlLabel")); var _FormGroup = _interopRequireDefault(require("@mui/material/FormGroup")); var _FormHelperText = _interopRequireDefault(require("@mui/material/FormHelperText")); var _Grid = _interopRequireDefault(require("@mui/material/Grid")); var _InputLabel = _interopRequireDefault(require("@mui/material/InputLabel")); var _MenuItem = _interopRequireDefault(require("@mui/material/MenuItem")); var _Select = _interopRequireDefault(require("@mui/material/Select")); var _TextField = _interopRequireDefault(require("@mui/material/TextField")); var _AdapterDayjs = require("@mui/x-date-pickers/AdapterDayjs"); var _DatePicker = require("@mui/x-date-pickers/DatePicker"); var _DateTimePicker = require("@mui/x-date-pickers/DateTimePicker"); var _LocalizationProvider = require("@mui/x-date-pickers/LocalizationProvider"); var _dayjs = _interopRequireDefault(require("dayjs")); var _context = require("../shared/context"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } /** * * Demos: * * - [CRUD](https://mui.com/toolpad/core/react-crud/) * * API: * * - [CrudForm API](https://mui.com/toolpad/core/api/crud-form) */ function CrudForm(props) { const { formState, onFieldChange, onSubmit, onReset, submitButtonLabel, slots, slotProps } = props; const formValues = formState.values; const formErrors = formState.errors; const crudContext = React.useContext(_context.CrudContext); const dataSource = props.dataSource ?? crudContext.dataSource; (0, _invariant.default)(dataSource, 'No data source found.'); const { fields } = dataSource; const [, submitAction, isSubmitting] = React.useActionState(async () => { try { await onSubmit(formValues); } catch (error) { return error; } return null; }, null); const handleTextFieldChange = React.useCallback(event => { onFieldChange(event.target.name, event.target.value); }, [onFieldChange]); const handleNumberFieldChange = React.useCallback(event => { onFieldChange(event.target.name, Number(event.target.value)); }, [onFieldChange]); const handleCheckboxFieldChange = React.useCallback((event, checked) => { onFieldChange(event.target.name, checked); }, [onFieldChange]); const handleDateFieldChange = React.useCallback(name => value => { if (value?.isValid()) { onFieldChange(name, value.toISOString() ?? null); } else if (formValues[name]) { onFieldChange(name, null); } }, [formValues, onFieldChange]); const handleSelectFieldChange = React.useCallback(event => { onFieldChange(event.target.name, event.target.value); }, [onFieldChange]); const renderField = React.useCallback(formField => { const { field, type, headerName } = formField; const fieldValue = formValues[field]; const fieldError = formErrors[field]; let fieldElement = null; if (!type || type === 'string') { const TextFieldComponent = slots?.textField ?? _TextField.default; fieldElement = /*#__PURE__*/(0, _jsxRuntime.jsx)(TextFieldComponent, { value: fieldValue ?? '', onChange: handleTextFieldChange, name: field, label: headerName, error: !!fieldError, helperText: fieldError ?? ' ', fullWidth: true, ...slotProps?.textField }); } if (type === 'number') { fieldElement = /*#__PURE__*/(0, _jsxRuntime.jsx)(_TextField.default, { value: fieldValue ?? '', onChange: handleNumberFieldChange, name: field, type: "number", label: headerName, error: !!fieldError, helperText: fieldError ?? ' ', fullWidth: true }); } if (type === 'boolean') { fieldElement = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_FormControl.default, { children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_FormControlLabel.default, { name: field, control: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Checkbox.default, { size: "large", checked: fieldValue, onChange: handleCheckboxFieldChange }), label: headerName }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_FormHelperText.default, { error: !!fieldError, children: fieldError ?? ' ' })] }); } if (type === 'date') { fieldElement = /*#__PURE__*/(0, _jsxRuntime.jsx)(_LocalizationProvider.LocalizationProvider, { dateAdapter: _AdapterDayjs.AdapterDayjs, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_DatePicker.DatePicker, { value: fieldValue ? (0, _dayjs.default)(fieldValue) : null, onChange: handleDateFieldChange(field), name: field, label: headerName, slotProps: { textField: { error: !!fieldError, helperText: fieldError ?? ' ', fullWidth: true } } }) }); } if (type === 'dateTime') { fieldElement = /*#__PURE__*/(0, _jsxRuntime.jsx)(_LocalizationProvider.LocalizationProvider, { dateAdapter: _AdapterDayjs.AdapterDayjs, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_DateTimePicker.DateTimePicker, { value: fieldValue ? (0, _dayjs.default)(fieldValue) : null, onChange: handleDateFieldChange(field), name: field, label: headerName, slotProps: { textField: { error: !!fieldError, helperText: fieldError ?? ' ', fullWidth: true } } }) }); } if (type === 'singleSelect') { const { getOptionValue, getOptionLabel, valueOptions } = formField; if (valueOptions && Array.isArray(valueOptions)) { const labelId = `${field}-label`; fieldElement = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_FormControl.default, { error: !!fieldError, fullWidth: true, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_InputLabel.default, { id: labelId, children: headerName }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Select.default, { value: fieldValue ?? '', onChange: handleSelectFieldChange, labelId: labelId, name: field, label: headerName, defaultValue: "", fullWidth: true, children: valueOptions.map(option => { let optionValue = option; let optionLabel = option; if (typeof option !== 'string' && typeof option !== 'number') { optionValue = getOptionValue ? getOptionValue(option) : option.value; optionLabel = getOptionLabel ? getOptionLabel(option) : option.label; } return /*#__PURE__*/(0, _jsxRuntime.jsx)(_MenuItem.default, { value: optionValue, children: optionLabel }, optionValue); }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_FormHelperText.default, { children: fieldError ?? ' ' })] }); } } return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Grid.default, { size: { xs: 12, sm: 6 }, sx: { display: 'flex' }, children: fieldElement }, field); }, [formErrors, formValues, handleCheckboxFieldChange, handleDateFieldChange, handleNumberFieldChange, handleSelectFieldChange, handleTextFieldChange, slotProps?.textField, slots]); const handleReset = React.useCallback(async () => { if (onReset) { await onReset(formValues); } }, [formValues, onReset]); return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Box.default, { component: "form", action: submitAction, noValidate: true, autoComplete: "off", onReset: handleReset, sx: { width: '100%' }, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_FormGroup.default, { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Grid.default, { container: true, spacing: 2, sx: { mb: 2, width: '100%' }, children: fields.filter(({ field }) => field !== 'id').map(renderField) }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, { sx: { display: 'flex', justifyContent: 'flex-end' }, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, { type: "submit", variant: "contained", size: "large", loading: isSubmitting, children: submitButtonLabel }) })] }); } process.env.NODE_ENV !== "production" ? CrudForm.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │ // └─────────────────────────────────────────────────────────────────────┘ /** * Server-side [data source](https://mui.com/toolpad/core/react-crud/#data-sources). */ dataSource: _propTypes.default.object, /** * Form state object, including field values and errors. */ formState: _propTypes.default.shape({ errors: _propTypes.default.object.isRequired, values: _propTypes.default.object.isRequired }).isRequired, /** * Callback fired when a form field is changed. */ onFieldChange: _propTypes.default.func.isRequired, /** * Callback fired when the form is reset. */ onReset: _propTypes.default.func, /** * Callback fired when the form is submitted. */ onSubmit: _propTypes.default.func.isRequired, /** * The props used for each slot inside. * @default {} */ slotProps: _propTypes.default.shape({ textField: _propTypes.default.object }), /** * The components used for each slot inside. * @default {} */ slots: _propTypes.default.shape({ textField: _propTypes.default.elementType }), /** * Text for form submit button. */ submitButtonLabel: _propTypes.default.string.isRequired } : void 0;