@pinuts/bsr-uikit-relaunch
Version:
BSR UI-KIT Relaunch
280 lines (275 loc) • 12.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _propTypes = _interopRequireDefault(require("prop-types"));
var _react = _interopRequireWildcard(require("react"));
var _reactDropzone = require("react-dropzone");
var _formBuilder = require("@pinuts/form-builder");
var _reactI18next = require("react-i18next");
var _FormFieldChildPropTypes = _interopRequireDefault(require("../FormFieldWrapper/FormFieldChildPropTypes.jsx"));
var _FormFieldWrapper = _interopRequireDefault(require("../FormFieldWrapper/FormFieldWrapper.jsx"));
var _withFieldGroup = _interopRequireDefault(require("../../hooks/withFieldGroup.jsx"));
var _Icon = _interopRequireDefault(require("../Icon/Icon.jsx"));
var _PictureUploadRowFieldModule = _interopRequireDefault(require("./PictureUploadRowField.module.scss"));
var _acceptedUploadTypeMapping = require("./acceptedUploadTypeMapping.js");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } // form-builder
const {
useField,
useFormikContext
} = _formBuilder.formik;
const {
getClassNames
} = _formBuilder.utils;
//accept-prop needs an object mit mimeType as keys and an array of file extensions as values
const getFormattedAcceptesFileTypes = acceptedFileTypes => acceptedFileTypes?.reduce((newObj, type) => _acceptedUploadTypeMapping.ACCEPTED_UPLOAD_TYPE_MAPPING?.[type] ? {
...newObj,
[type]: _acceptedUploadTypeMapping.ACCEPTED_UPLOAD_TYPE_MAPPING[type] || []
} : newObj, {});
const PictureUploadRowField = _ref => {
let {
viewMode,
field,
ariaAttributes,
isInvalid,
readOnly,
disabled,
fieldIds,
uploadConfig
} = _ref;
// eslint-disable-next-line no-unused-vars
const [formikField, _meta, helpers] = useField(field.name);
const [t] = (0, _reactI18next.useTranslation)();
const usedViewMode = (0, _react.useMemo)(() => readOnly || disabled || viewMode, [readOnly, disabled, viewMode]);
const {
status,
setStatus
} = useFormikContext();
const [previewFiles, setPreviewFiles] = (0, _react.useState)([]); // State to hold the files and previews
(0, _react.useEffect)(() => {
if (formikField.value && formikField.value.length > 0 && previewFiles.length === 0) {
const initFiles = formikField.value.map(file => Object.assign(file, {
preview: URL.createObjectURL(file)
}));
setPreviewFiles(initFiles);
}
}, [formikField.value, previewFiles.length]);
const uploadFilesToUM = (0, _react.useCallback)(async uploadFiles => {
const successfulUploads = [];
for (const file of uploadFiles) {
const formData = new FormData();
formData.append(file.name, file);
if (uploadConfig) {
formData.append('uploadConfig', JSON.stringify(uploadConfig));
}
try {
// eslint-disable-next-line no-await-in-loop
const response = await fetch(uploadConfig.uploadPath, {
method: 'POST',
body: formData,
headers: {
'X-CSRF-Safe': 'Yes'
}
});
if (response.ok) {
// eslint-disable-next-line no-await-in-loop
const data = await response.json();
if (data && data.success && data.files && data.files.length > 0) {
successfulUploads.push(...data.files);
}
}
} catch (error) {
console.error('Upload error for file:', file.name, error);
}
}
return successfulUploads;
}, [uploadConfig]);
const onChange = (0, _react.useCallback)(async acceptedFiles => {
const uploadableFiles = [...previewFiles, ...acceptedFiles.map(file => Object.assign(file, {
preview: URL.createObjectURL(file)
}))];
const uploadedFiles = await uploadFilesToUM(uploadableFiles);
if (uploadedFiles) {
const filteredUploadableFiles = uploadableFiles.map(uploadableFile => {
const found = uploadedFiles.find(uploadedFile => uploadedFile.name === uploadableFile.name);
if (found) {
const mergedObject = uploadableFile;
mergedObject.uuid = found.uuid;
return mergedObject;
}
return uploadableFile;
}).filter(uploadableFile => {
return uploadedFiles.some(uploadedFile => uploadedFile.name === uploadableFile.name);
});
setPreviewFiles(filteredUploadableFiles);
helpers.setTouched(true);
helpers.setValue(filteredUploadableFiles);
setStatus({
...status,
[formikField.name]: uploadedFiles
});
}
}, [previewFiles, formikField.name, helpers, setStatus, status, uploadFilesToUM]);
const onDrop = (0, _react.useCallback)(acceptedFiles => {
onChange(acceptedFiles);
}, [onChange]);
const {
fileRejections,
getRootProps,
getInputProps
} = (0, _reactDropzone.useDropzone)({
onDrop: !usedViewMode ? onDrop : () => {},
noClick: usedViewMode || previewFiles.length >= uploadConfig.maxFiles,
// Disable click if view mode is used or maxFiles limit is reached
noKeyboard: usedViewMode,
accept: getFormattedAcceptesFileTypes(uploadConfig.acceptedFileTypes || []) || {},
maxFiles: uploadConfig.maxFiles,
maxSize: uploadConfig.maxSize
});
const removeFile = async (e, index, uuid) => {
e.preventDefault();
e.stopPropagation();
try {
const response = await fetch(`${uploadConfig.deletePath}/${uuid}`, {
method: 'DELETE',
headers: {
'X-CSRF-Safe': 'Yes'
}
});
if (response.ok) {
const data = await response.json();
if (data && data.success) {
setPreviewFiles(previewFiles.filter((file, i) => i !== index));
helpers.setTouched(true);
if (status[formikField.name]) {
setStatus({
...status,
[formikField.name]: null
});
} else {
helpers.setValue('');
}
}
}
} catch (error) {
console.error('Error removing file by uuid:', uuid, error);
}
};
const fileRejectionItems = fileRejections.map(_ref2 => {
let {
file,
errors
} = _ref2;
return /*#__PURE__*/_react.default.createElement("li", {
key: file.path,
className: 'filename'
}, file.name, ' ', "-", Math.floor(file.size / 1024), ' ', "kb", /*#__PURE__*/_react.default.createElement("ul", null, errors.map(e => /*#__PURE__*/_react.default.createElement("li", {
key: e.code,
className: 'errorMsg'
}, t(`bsrItems.DropzoneUploadField.${e.code}`, {
maxFiles: uploadConfig.maxFiles,
maxFileSize: uploadConfig.maxSize / 1000000
})))));
});
const createThumbs = () => {
if (viewMode && field.value.length > 0) {
const uuids = field.value.map(file => file.uuid);
return uuids.map(uuid => {
return /*#__PURE__*/_react.default.createElement("div", {
className: _PictureUploadRowFieldModule.default.thumb,
key: uuid
}, /*#__PURE__*/_react.default.createElement("div", {
className: _PictureUploadRowFieldModule.default.thumbInner
}, /*#__PURE__*/_react.default.createElement("img", {
src: uploadConfig.previewPath.replace(':uuid', uuid),
alt: '',
className: _PictureUploadRowFieldModule.default.img
})));
});
}
return previewFiles.map((file, index) => {
return /*#__PURE__*/_react.default.createElement("div", {
className: _PictureUploadRowFieldModule.default.thumb,
key: file.name
}, /*#__PURE__*/_react.default.createElement("div", {
className: _PictureUploadRowFieldModule.default.thumbInner
}, /*#__PURE__*/_react.default.createElement("img", {
src: file.preview,
alt: '',
className: _PictureUploadRowFieldModule.default.img,
onLoad: () => {
URL.revokeObjectURL(file.preview);
}
}), /*#__PURE__*/_react.default.createElement("button", {
type: "button",
"aria-label": 'Ausgewählte Datei entfernen',
className: `${_PictureUploadRowFieldModule.default.deleteBtn}`,
onClick: e => removeFile(e, index, file.uuid)
}, /*#__PURE__*/_react.default.createElement(_Icon.default, {
icon: "trash",
height: "12",
width: "12",
stroke: '#fff'
}))));
});
};
// Cleanup previews on unmount
(0, _react.useEffect)(() => {
return () => previewFiles.forEach(file => URL.revokeObjectURL(file.preview));
}, [previewFiles]);
return /*#__PURE__*/_react.default.createElement("section", {
className: getClassNames(['container-fluid', _PictureUploadRowFieldModule.default.dropZoneWrapper, isInvalid && _PictureUploadRowFieldModule.default.isInvalid
// usedViewMode && styles.disabled,
]),
"aria-labelledby": fieldIds.label
}, /*#__PURE__*/_react.default.createElement("div", {
className: "d-flex justify-content-between"
}, /*#__PURE__*/_react.default.createElement("div", getRootProps({
onDrop,
className: getClassNames(['dropzone', 'flex-fill', _PictureUploadRowFieldModule.default.fakeButton]),
role: 'button',
'aria-disabled': usedViewMode || previewFiles.length >= uploadConfig.maxFiles,
// Reflect disabled state in ARIA attributes
tabIndex: usedViewMode ? '-1' : '0',
...ariaAttributes,
'aria-controls': fieldIds.fieldId,
'aria-labelledby': ''
}), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("input", _extends({}, getInputProps({
id: fieldIds.fieldId
}), {
accept: uploadConfig.acceptedFileTypes?.join(',')
})), /*#__PURE__*/_react.default.createElement("aside", {
className: `${_PictureUploadRowFieldModule.default.thumbsContainer} d-flex`
}, createThumbs(), previewFiles.length < uploadConfig.maxFiles && /*#__PURE__*/_react.default.createElement("div", {
className: _PictureUploadRowFieldModule.default.addBtnContainer
}, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_Icon.default, {
icon: usedViewMode ? 'lock' : 'circlePlus',
height: "24",
width: "24",
className: ""
}))))))), /*#__PURE__*/_react.default.createElement("ul", null, fileRejectionItems));
};
PictureUploadRowField.propTypes = {
..._FormFieldChildPropTypes.default,
acceptedFileTypes: _propTypes.default.arrayOf(_propTypes.default.string),
localeRejected: _propTypes.default.string,
onChange: _propTypes.default.func,
key: _propTypes.default.string,
maxFiles: _propTypes.default.number
};
PictureUploadRowField.formFieldConfig = {
labelIsLegend: true,
isFieldset: true
};
const HigherOrderDropzoneUploadField = (0, _withFieldGroup.default)(PictureUploadRowField);
// wrap the field label, error message help text and more
const WrappedPictureUploadRowField = props => {
return /*#__PURE__*/_react.default.createElement(_FormFieldWrapper.default, props, /*#__PURE__*/_react.default.createElement(HigherOrderDropzoneUploadField, props));
};
(0, _formBuilder.registerComponent)('PictureUploadRowField', WrappedPictureUploadRowField);
(0, _formBuilder.registerComponent)('PictureUploadRowFieldBasic', HigherOrderDropzoneUploadField);
var _default = exports.default = HigherOrderDropzoneUploadField;