@toolpad/core
Version:
Dashboard framework powered by Material UI.
268 lines (267 loc) • 10.1 kB
JavaScript
"use strict";
'use client';
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Edit = Edit;
var React = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _Alert = _interopRequireDefault(require("@mui/material/Alert"));
var _Box = _interopRequireDefault(require("@mui/material/Box"));
var _CircularProgress2 = _interopRequireDefault(require("@mui/material/CircularProgress"));
var _invariant = _interopRequireDefault(require("invariant"));
var _useNotifications = require("../useNotifications");
var _context = require("../shared/context");
var _LocalizationProvider = require("../AppProvider/LocalizationProvider");
var _CrudForm = require("./CrudForm");
var _cache = require("./cache");
var _useCachedDataSource = require("./useCachedDataSource");
var _localeText = require("./localeText");
var _jsxRuntime = require("react/jsx-runtime");
var _CircularProgress;
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); }
function EditForm(props) {
const {
dataSource,
initialValues,
onSubmit,
onSubmitSuccess,
localeText
} = props;
const {
fields,
validate
} = dataSource;
const notifications = (0, _useNotifications.useNotifications)();
const [formState, setFormState] = React.useState({
values: {
...Object.fromEntries(fields.filter(({
field
}) => field !== 'id').map(({
field,
type
}) => [field, type === 'boolean' ? initialValues[field] ?? false : initialValues[field]])),
...initialValues
},
errors: {}
});
const formValues = formState.values;
const formErrors = formState.errors;
const setFormValues = React.useCallback(newFormValues => {
setFormState(previousState => ({
...previousState,
values: newFormValues
}));
}, []);
const setFormErrors = React.useCallback(newFormErrors => {
setFormState(previousState => ({
...previousState,
errors: newFormErrors
}));
}, []);
const handleFormFieldChange = React.useCallback((name, value) => {
const validateField = async values => {
if (validate) {
const {
issues
} = await validate(values);
setFormErrors({
...formErrors,
[name]: issues?.find(issue => issue.path?.[0] === name)?.message
});
}
};
const newFormValues = {
...formValues,
[name]: value
};
setFormValues(newFormValues);
validateField(newFormValues);
}, [formErrors, formValues, setFormErrors, setFormValues, validate]);
const handleFormReset = React.useCallback(() => {
setFormValues(initialValues);
}, [initialValues, setFormValues]);
const handleFormSubmit = React.useCallback(async () => {
if (validate) {
const {
issues
} = await validate(formValues);
if (issues && issues.length > 0) {
setFormErrors(Object.fromEntries(issues.map(issue => [issue.path?.[0], issue.message])));
throw new Error('Form validation failed');
}
}
setFormErrors({});
try {
await onSubmit(formValues);
notifications.show(localeText.editSuccessMessage, {
severity: 'success',
autoHideDuration: 3000
});
if (onSubmitSuccess) {
await onSubmitSuccess(formValues);
}
} catch (editError) {
notifications.show(`${localeText.editErrorMessage} ${editError.message}`, {
severity: 'error',
autoHideDuration: 3000
});
throw editError;
}
}, [formValues, localeText.editErrorMessage, localeText.editSuccessMessage, notifications, onSubmit, onSubmitSuccess, setFormErrors, validate]);
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_CrudForm.CrudForm, {
dataSource: dataSource,
formState: formState,
onFieldChange: handleFormFieldChange,
onSubmit: handleFormSubmit,
onReset: handleFormReset,
submitButtonLabel: localeText.editLabel
});
}
process.env.NODE_ENV !== "production" ? EditForm.propTypes /* remove-proptypes */ = {
// ┌────────────────────────────── Warning ──────────────────────────────┐
// │ These PropTypes are generated from the TypeScript type definitions. │
// │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
// └─────────────────────────────────────────────────────────────────────┘
dataSource: _propTypes.default.object.isRequired,
initialValues: _propTypes.default.object.isRequired,
localeText: _propTypes.default.object.isRequired,
onSubmit: _propTypes.default.func.isRequired,
onSubmitSuccess: _propTypes.default.func
} : void 0;
/**
*
* Demos:
*
* - [CRUD](https://mui.com/toolpad/core/react-crud/)
*
* API:
*
* - [Edit API](https://mui.com/toolpad/core/api/edit)
*/
function Edit(props) {
const {
id,
onSubmitSuccess,
dataSourceCache,
localeText: propsLocaleText
} = props;
const globalLocaleText = (0, _LocalizationProvider.useLocaleText)();
const crudContext = React.useContext(_context.CrudContext);
const dataSource = props.dataSource ?? crudContext.dataSource;
(0, _invariant.default)(dataSource, 'No data source found.');
const cache = React.useMemo(() => {
const manualCache = dataSourceCache ?? crudContext.dataSourceCache;
return typeof manualCache !== 'undefined' ? manualCache : new _cache.DataSourceCache();
}, [crudContext.dataSourceCache, dataSourceCache]);
const cachedDataSource = (0, _useCachedDataSource.useCachedDataSource)(dataSource, cache);
const {
fields,
validate,
...methods
} = cachedDataSource;
const {
getOne,
updateOne
} = methods;
const [data, setData] = React.useState(null);
const [isLoading, setIsLoading] = React.useState(false);
const [error, setError] = React.useState(null);
const loadData = React.useCallback(async () => {
setError(null);
setIsLoading(true);
try {
const showData = await getOne(id);
setData(showData);
} catch (showDataError) {
setError(showDataError);
}
setIsLoading(false);
}, [getOne, id]);
React.useEffect(() => {
loadData();
}, [loadData]);
const handleSubmit = React.useCallback(async formValues => {
const updatedData = await updateOne(id, formValues);
setData(updatedData);
}, [id, updateOne]);
const renderEdit = React.useMemo(() => {
if (isLoading) {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
sx: {
flex: 1,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
m: 1
},
children: _CircularProgress || (_CircularProgress = /*#__PURE__*/(0, _jsxRuntime.jsx)(_CircularProgress2.default, {}))
});
}
if (error) {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
sx: {
flexGrow: 1
},
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Alert.default, {
severity: "error",
children: error.message
})
});
}
const localeText = {
..._localeText.CRUD_DEFAULT_LOCALE_TEXT,
...globalLocaleText,
...propsLocaleText
};
return data ? /*#__PURE__*/(0, _jsxRuntime.jsx)(EditForm, {
dataSource: dataSource,
initialValues: data,
onSubmit: handleSubmit,
onSubmitSuccess: onSubmitSuccess,
localeText: localeText
}) : null;
}, [data, dataSource, error, globalLocaleText, handleSubmit, isLoading, onSubmitSuccess, propsLocaleText]);
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
sx: {
display: 'flex',
flex: 1
},
children: renderEdit
});
}
process.env.NODE_ENV !== "production" ? Edit.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,
/**
* [Cache](https://mui.com/toolpad/core/react-crud/#data-caching) for the data source.
*/
dataSourceCache: _propTypes.default.shape({
cache: _propTypes.default.object.isRequired,
clear: _propTypes.default.func.isRequired,
get: _propTypes.default.func.isRequired,
set: _propTypes.default.func.isRequired,
ttl: _propTypes.default.number.isRequired
}),
/**
* @ignore
*/
id: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]).isRequired,
/**
* Locale text for the component.
*/
localeText: _propTypes.default.object,
/**
* Callback fired when the form is successfully submitted.
*/
onSubmitSuccess: _propTypes.default.func
} : void 0;