lion/packages/ui/components/input-file/src/FileHandle.js
gerjanvangeest d2de984f0b
Feat/input file (#1881)
* feat(input-file): create input-file component

* chore: improvements after review

* chore: update after review

* chore: update translations

* chore: - fixed demo with form submit, submit was not prevented
       - fixed checking allowed file extensions
       - fixed clicking on select file button in drag and drop area

* chore: since the input-file does not upload files itself but enables user to select files, I replaced "upload" and "upload" with "select" and "selected" where applicable

* chore: - removed unused properties allowedFileTypes and allowedFileExtensions from lion-input-file
       - cleaned up docs

* chore: - changed type Array.<type> to Array<type>
       - removed redundant type definition

* fix: - FocusMixin: moved registering events for from connectedCallback to firstUpdated since _focusableNode is sometimes not available yet
     - SlotMixin: changed updated to update in since slots were rendered too late (related to previous fix in FocusMixin.js)

* fix: renamed lion-uploaded-file-list.js to lion-selected-file-list.js

* fix: fixed test for lion-selected-file-list

* fix: fixed typ

* wip

* fix: - fixed issue with multiple file selection where element would not select valid files after invalid ones
     - added getMessage method to FileValidation that returns empty string to prevent message being shown that error message must be configured
     - fixed tests

* chore: replaced `uploadOnFormSubmit` with `uploadOnSelect` and flipped the default value to false. When `uploadOnSelect` is set to true, the file will be uploaded as soon as it is selected.

* fix: - replaced `uploadOnFormSubmit` with `uploadOnSelect` and flipped the default value to false. When `uploadOnSelect` is set to true, the file will be uploaded as soon as it is selected.
     - fixed issue where a valid file was not selected and added to the file list if it was preceded by an invalid file

* chore: removed redundant README.md

* fix: fixed failing test

* chore: added missing type annotation

* chore: annotated event param as optional

---------

Co-authored-by: Danny Moerkerke <danny.moerkerke@ing.com>
Co-authored-by: Thijs Louisse <Thijs.Louisse@ing.com>
2023-06-06 11:30:43 +02:00

98 lines
2.6 KiB
JavaScript

import { IsAcceptedFile } from './validators.js';
/**
* @typedef {import('../types/input-file.js').SystemFile} SystemFile
*/
// Do these global constants add value? They are only used in this file
// Typing filehandle would be enough
/**
* 500MB in bytes
*/
export const MAX_FILE_SIZE = 524288000;
/**
* @typedef {Object} property
* @property {string} type
* @property {string} size
*/
export const FILE_FAILED_PROP = {
type: 'FILE_TYPE',
size: 'FILE_SIZE',
};
export const UPLOAD_FILE_STATUS = {
fail: 'FAIL',
pass: 'SUCCESS',
};
export class FileHandle {
/**
* @param {SystemFile} systemFile
* @param {{ allowedFileTypes: Array<string>; allowedFileExtensions: Array<string>; maxFileSize: number; }} _acceptCriteria
*/
constructor(systemFile, _acceptCriteria) {
/**
* @type {Array<string>}
*/
this.failedProp = [];
this.systemFile = systemFile;
this._acceptCriteria = _acceptCriteria;
this.uploadFileStatus();
if (this.failedProp.length === 0) {
this.createDownloadUrl(systemFile);
}
}
// TDOO: same util as in validators.js
/**
* @param {string} fileName
* @return {string}
* @protected
*/
// eslint-disable-next-line class-methods-use-this
_getFileNameExtension(fileName) {
return fileName.slice(fileName.lastIndexOf('.') + 1);
}
// TODO: seems to suggest upload is going on...
// checks the file size and type to set failedProp property
uploadFileStatus() {
if (this._acceptCriteria.allowedFileExtensions.length) {
const fileExtension = this._getFileNameExtension(this.systemFile.name);
if (
!IsAcceptedFile.isExtensionAllowed(
fileExtension,
this._acceptCriteria.allowedFileExtensions,
)
) {
this.status = UPLOAD_FILE_STATUS.fail;
this.failedProp.push(FILE_FAILED_PROP.type);
}
} else if (this._acceptCriteria.allowedFileTypes.length) {
const fileType = this.systemFile.type;
if (!IsAcceptedFile.isFileTypeAllowed(fileType, this._acceptCriteria.allowedFileTypes)) {
this.status = UPLOAD_FILE_STATUS.fail;
this.failedProp.push(FILE_FAILED_PROP.type);
}
}
if (IsAcceptedFile.checkFileSize(this.systemFile.size, this._acceptCriteria.maxFileSize)) {
if (this.status !== UPLOAD_FILE_STATUS.fail) {
this.status = UPLOAD_FILE_STATUS.pass;
}
} else {
this.status = UPLOAD_FILE_STATUS.fail;
this.failedProp.push(FILE_FAILED_PROP.size);
}
}
/**
* @param {SystemFile} file
*/
createDownloadUrl(file) {
// @ts-ignore
this.downloadUrl = window.URL.createObjectURL(file);
}
}