UNPKG

drf-react-by-schema

Version:

Components and Tools for building a React App having Django Rest Framework (DRF) as server

266 lines (265 loc) 15.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = __importStar(require("react")); const react_hook_form_1 = require("react-hook-form"); const TextField_1 = __importDefault(require("@mui/material/TextField")); const Autocomplete_1 = __importStar(require("@mui/material/Autocomplete")); const Edit_1 = __importDefault(require("@mui/icons-material/Edit")); const IconButton_1 = __importDefault(require("@mui/material/IconButton")); const Chip_1 = __importDefault(require("@mui/material/Chip")); const utils_1 = require("../../../utils"); const DialogActions_1 = __importDefault(require("../../DialogActions")); const APIWrapperContext_1 = require("../../../context/APIWrapperContext"); const filter = (0, Autocomplete_1.createFilterOptions)(); const EditableAutocompleteFieldBySchema = react_1.default.forwardRef((_a, _) => { var { control, schema, errors, setValue, getValues, fieldKey, labelKey = 'nome', index, name = 'name', optionsAC, optionsModel, getOptionLabel, renderOption, onEditModel, sx = { mr: 2 }, onValueChange, multiple = false, disabled, fieldsLayout, autoFocus } = _a, other = __rest(_a, ["control", "schema", "errors", "setValue", "getValues", "fieldKey", "labelKey", "index", "name", "optionsAC", "optionsModel", "getOptionLabel", "renderOption", "onEditModel", "sx", "onValueChange", "multiple", "disabled", "fieldsLayout", "autoFocus"]); const { setDialog } = (0, APIWrapperContext_1.useAPIWrapper)(); const [options, setOptions] = (0, react_1.useState)(null); const model = name; const label = schema[model].label; if (!optionsModel) { optionsModel = model; } if (fieldKey && index && index >= 0) { name = `${fieldKey}.${index}.${name}`; } (0, react_1.useEffect)(() => { if (optionsAC && optionsModel && optionsAC[optionsModel]) { setOptions(optionsAC[optionsModel]); } }, [optionsAC, optionsModel]); (0, react_1.useEffect)(() => { if (!getValues || !setValue || !options) { return; } const valuesInitial = getValues(model); if (!valuesInitial) { return; } if (multiple) { const harmonizedValues = []; for (const valueInitial of valuesInitial) { const harmonizedValue = options.find((option) => option.id === valueInitial.id); if (harmonizedValue) { harmonizedValues.push(harmonizedValue); } } setValue(model, harmonizedValues); return; } const harmonizedValues = options.find((option) => option.id === valuesInitial.id); setValue(model, harmonizedValues); }, [options, setValue, getValues, model, multiple]); const { error, helperText } = fieldKey && index && index >= 0 ? (0, utils_1.errorProps)({ fieldKey, index, fieldKeyProp: name, errors, }) : { error: errors && Boolean(errors[name]), helperText: errors && errors[name] ? errors[name].message : schema[name].help_text || '', }; if (options === null) { return react_1.default.createElement(react_1.default.Fragment, null); } if (!disabled && !schema[model].disabled && onEditModel && optionsModel) { return (react_1.default.createElement(react_hook_form_1.Controller, { control: control, name: name, render: ({ field }) => (react_1.default.createElement(Autocomplete_1.default, Object.assign({ key: name }, field, { id: name, options: options, disabled: schema[model].disabled === true, autoHighlight: true, isOptionEqualToValue: (option, value) => option.id === value.id, fullWidth: true, multiple: multiple, sx: sx, onChange: (e, value) => { let valueAr = value; if (!multiple) { valueAr = [value]; } const newValueAr = []; if (valueAr) { for (let newValue of valueAr) { if (typeof newValue === 'string') { const tmpId = (0, utils_1.getTmpId)(); newValue = { id: tmpId, label: newValue, [labelKey]: newValue, }; } if (newValue && newValue.inputValue) { const tmpId = (0, utils_1.getTmpId)(); if (onEditModel) { // Open modal to save new item: onEditModel({ fieldKey, index, model: optionsModel, id: tmpId, labelKey, setValue, getValues, fieldsLayout, initialValuesPartial: { [labelKey]: newValue.inputValue, }, }); } // Define new Item as an "optimistic response" newValue = { id: tmpId, label: newValue.inputValue, [labelKey]: newValue.inputValue, }; } newValueAr.push(newValue); } } field.onChange(multiple ? newValueAr : newValueAr[0]); if (onValueChange) { onValueChange(e); } }, renderInput: (params) => (react_1.default.createElement(TextField_1.default, Object.assign({}, params, { label: label, required: schema[model].required, margin: "normal", error: error, autoFocus: autoFocus, helperText: helperText, InputProps: Object.assign(Object.assign({}, params.InputProps), { endAdornment: (react_1.default.createElement(react_1.default.Fragment, null, !multiple && field.value && (react_1.default.createElement(IconButton_1.default, { size: "small", onClick: () => { if ((0, utils_1.isTmpId)(field.value.id)) { setDialog({ open: true, loading: false, title: 'Item sendo criado', Body: 'Este item está sendo criado agora por você. Para editar suas propriedades, salve antes, e depois você poderá editar!', Actions: (react_1.default.createElement(DialogActions_1.default, { setDialog: setDialog, btnCancel: "Entendi" })), }); return; } if (optionsModel) { onEditModel({ fieldKey, index, model: optionsModel, id: field.value.id, labelKey, setValue, getValues, fieldsLayout, }); } } }, react_1.default.createElement(Edit_1.default, null))), params.InputProps.endAdornment)) }) }, other))), freeSolo: true, filterOptions: (filteredOptions, params) => { if (filteredOptions.length === 0) { return []; } let filtered = filter(filteredOptions, params); const { inputValue } = params; const inputValueSlug = (0, utils_1.slugify)(inputValue); const inputValueLength = inputValueSlug.length; // Suggest the creation of a new value const isExisting = filteredOptions.find((option) => inputValueSlug === (0, utils_1.slugify)(option.label)); if (inputValue !== '' && !isExisting) { filtered.push({ inputValue, label: `Criar "${inputValue}"`, }); } // Show first the exact match: if (isExisting) { filtered = [ isExisting, ...filtered.filter((option) => isExisting.id !== option.id), ]; } // Show first the options that start with inputValue: const startsWith = filtered.filter((option) => inputValueSlug === (0, utils_1.slugify)(option.label).substring(0, inputValueLength)); if (startsWith.length > 0) { const startsWithIds = startsWith.map((option) => option.id); filtered = [ ...startsWith, ...filtered.filter((option) => !startsWithIds.includes(option.id)), ]; } return filtered; }, handleHomeEndKeys: true, getOptionLabel: getOptionLabel ? getOptionLabel : (option) => { // Value selected with enter, right from the input if (typeof option === 'string') { return option; } // Criar "xxx" option created dynamically if (option.inputValue) { return option.inputValue; } // Regular option return option.label; }, renderOption: renderOption ? renderOption : (props, option) => react_1.default.createElement("li", Object.assign({}, props), option.label), renderTags: multiple ? (tagValue, getTagProps) => { return tagValue.map((option, index) => ( // eslint-disable-next-line react/jsx-key react_1.default.createElement(Chip_1.default, Object.assign({}, getTagProps({ index }), { label: option.label, icon: (0, utils_1.isTmpId)(option.id) ? (react_1.default.createElement(react_1.default.Fragment, null)) : (react_1.default.createElement(IconButton_1.default, { size: "small", onClick: () => { if (optionsModel) { onEditModel({ fieldKey, index, model: optionsModel, id: option.id, labelKey, setValue, getValues, fieldsLayout, }); } } }, react_1.default.createElement(Edit_1.default, null))) })))); } : undefined }))) })); } return (react_1.default.createElement(react_hook_form_1.Controller, { control: control, name: name, render: ({ field }) => (react_1.default.createElement(Autocomplete_1.default, Object.assign({ key: name }, field, { id: name, options: options, disabled: schema[model].disabled === true || disabled === true, autoHighlight: true, isOptionEqualToValue: (option, value) => option.id === value.id, fullWidth: true, multiple: multiple, sx: sx, onChange: (e, value) => { field.onChange(value); if (onValueChange) { onValueChange(e); } }, renderInput: (params) => (react_1.default.createElement(TextField_1.default, Object.assign({}, params, { label: label, required: schema[model].required, margin: "normal", error: error, autoFocus: autoFocus, helperText: helperText }, other))), getOptionLabel: getOptionLabel, renderOption: renderOption }))) })); }); EditableAutocompleteFieldBySchema.displayName = 'EditableAutocompleteFieldBySchema'; exports.default = EditableAutocompleteFieldBySchema;