gov-gui
Version:
Gov UI Component Library Typscript Build
384 lines (383 loc) • 14.6 kB
JavaScript
import { h } from "@stencil/core";
import { getGlobalPropsClasses } from "../../global/global-styles-helper";
import { getAnimationClasses } from "../../global/animation-helpers";
export class FileUpload {
constructor() {
this.fileNames = [];
this.status = null;
this.failedStatus = '';
this.allowedFileTypes = ['pdf', 'xls', 'png', 'jpeg'];
this.fileNameValue = ''; // Value to return when filename is identified
this.required = false; // New required prop
this.animationDelay = '2s';
this.allClasses = '';
this.uploadUrl = ''; // Private property for the upload URL
}
get allowedTypesString() {
// Handle both string and array formats
if (Array.isArray(this.allowedFileTypes)) {
return this.allowedFileTypes.join(', ');
}
return this.allowedFileTypes;
}
//watching for any change in animations to trigger them
watchAnimations() {
this.provideClass();
}
watchAnimationsDelay() {
this.provideClass();
}
watchAnimationsSpeed() {
this.provideClass();
}
componentWillLoad() {
if (typeof this.allowedFileTypes === 'string') {
try {
this.allowedFileTypes = JSON.parse(this.allowedFileTypes);
}
catch (e) {
console.error('Invalid allowedFileTypes format');
this.allowedFileTypes = ['pdf', 'xls', 'png', 'jpeg'];
}
}
const animationClasses = getAnimationClasses({
animation: this.animation,
animationDelay: this.animationDelay,
animationSpeed: this.animationSpeed
});
this.allClasses = getGlobalPropsClasses({
classes: ' ' + animationClasses,
});
}
handleFileUpload(event) {
const input = event.target; // Access the file input element
const files = Array.from(input.files || []); // Get the selected files
this.processFiles(files);
}
handleFileDrop(event) {
var _a;
event.preventDefault();
const files = Array.from(((_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.files) || []);
this.processFiles(files);
}
processFiles(files) {
// If no files are provided and the upload is required, set an error.
if (files.length === 0) {
if (this.required) {
this.status = 'failed';
this.failedStatus = 'File upload is required.';
}
return;
}
// Filter valid files first
const validFiles = files.filter(file => {
var _a;
const fileExtension = (_a = file.name.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
return this.allowedFileTypes.includes(fileExtension || '');
});
if (validFiles.length > 0) {
this.fileNames = validFiles.map(file => file.name);
this.fileNameValue = String(this.fileNames);
this.fileUpload(validFiles);
}
else {
this.fileNames = [];
this.status = 'failed';
this.failedStatus = 'Uploaded files have unsupported formats.';
}
}
async fileUpload(files) {
this.status = 'loading';
const formData = new FormData();
files.forEach(file => {
formData.append('files', file);
});
try {
const response = await fetch(this.uploadUrl || '/', {
method: 'POST',
body: formData,
});
if (!response.ok) {
throw new Error('Upload failed');
}
const contentType = response.headers.get('Content-Type');
if (contentType && contentType.includes('application/json')) {
const result = await response.json();
if (result && typeof result === 'object' && result['success']) {
this.status = 'done';
}
else {
this.status = 'failed';
this.failedStatus = `Failed: False success response.`;
}
}
else if (contentType && contentType.includes('text/html')) {
const result = await response.text();
if (result && result.includes('success')) {
this.status = 'done';
}
else {
this.status = 'failed';
this.failedStatus = `Failed: False success response.`;
}
}
else if (!contentType) {
this.status = 'done';
}
else {
this.failedStatus = `Failed: Unexpected response format.`;
throw new Error('Unexpected response format');
}
}
catch (error) {
console.error('Upload error:', error);
this.status = 'failed';
this.failedStatus = `Failed: Failed to upload.`;
}
}
triggerFileUpload() {
this.fileInput.click();
}
preventDefaults(event) {
event.preventDefault();
event.stopPropagation();
}
getStatusClass() {
return this.status ? this.status : '';
}
/**
* Public getter returns a comma‑separated list of file names.
* If no files have been uploaded, it returns "No files uploaded".
*/
get value() {
return this.fileNames.length > 0 ? this.fileNames.join(', ') : 'No files uploaded';
}
/**
* Public method to set the upload URL through script.
*/
async setUploadUrl(url) {
this.uploadUrl = url;
}
/**
* Public method to validate that a file has been uploaded when required.
* Returns true if valid; otherwise, sets an error status and returns false.
*/
async validate() {
if (this.required && this.fileNames.length === 0) {
this.status = 'failed';
this.failedStatus = 'File upload is required.';
return false;
}
return true;
}
//Called on change of any animation related property to trigger change
provideClass() {
const animationClasses = getAnimationClasses({
animation: this.animation,
animationDelay: this.animationDelay,
animationSpeed: this.animationSpeed
});
this.allClasses = getGlobalPropsClasses({
classes: ' ' + animationClasses,
});
}
render() {
return (h("div", { key: '350c9421b4001c4d30f92d747db7ccc21d242aa2', class: `upload-container ${this.getStatusClass()} ${this.allClasses}`, onDragOver: this.preventDefaults, onDragEnter: this.preventDefaults, onDrop: event => this.handleFileDrop(event) }, h("div", { key: '408e9f484aa0b67bff2d53902de04b72e0bfd6ba', class: `upload-field ${this.getStatusClass()}` }, h("input", { key: '78b6b3e17341fe11025f6a1fe2ee20c3113ecbcc', type: "file", id: "file-input", class: "file-input", multiple: true, required: this.required, ref: el => (this.fileInput = el), onChange: event => this.handleFileUpload(event) }), h("label", { key: 'd332ee6838b8a91c1cbed50774cd450dece0b3b6', htmlFor: "file-input", class: "file-label" }, this.fileNames.length > 0 ? this.fileNames.join(', ') : `Drop files here (${this.allowedTypesString})`), h("button", { key: '2aa61dd6ee70f443fecd3c87ed22a67526f57dff', class: `upload-button ${this.getStatusClass()}`, type: "button", onClick: () => this.triggerFileUpload() }, "Upload Files")), this.status && (h("div", { key: 'c800cc5034cef35ff18054d8f5149f939c11bc1c', class: `upload-status ${this.getStatusClass()}` }, this.status === 'loading' && 'Loading...', this.status === 'done' && 'Files uploaded successfully!', this.status === 'warning' && 'Warning: Uploaded file is too large.', this.status === 'failed' && (this.failedStatus !== '' ? this.failedStatus : 'Failed: Uploaded files have unsupported formats.')))));
}
static get is() { return "gov-upload"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() {
return {
"$": ["gov-upload.css"]
};
}
static get styleUrls() {
return {
"$": ["gov-upload.css"]
};
}
static get properties() {
return {
"allowedFileTypes": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string | string[]",
"resolved": "string | string[]",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"getter": false,
"setter": false,
"attribute": "allowed-file-types",
"reflect": false,
"defaultValue": "['pdf', 'xls', 'png', 'jpeg']"
},
"fileNameValue": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"getter": false,
"setter": false,
"attribute": "file-name-value",
"reflect": false,
"defaultValue": "''"
},
"required": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"getter": false,
"setter": false,
"attribute": "required",
"reflect": false,
"defaultValue": "false"
},
"animation": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": ""
},
"getter": false,
"setter": false,
"attribute": "animation",
"reflect": false
},
"animationDelay": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'2s' | '3s' | '4s' | '5s'",
"resolved": "\"2s\" | \"3s\" | \"4s\" | \"5s\"",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": ""
},
"getter": false,
"setter": false,
"attribute": "animation-delay",
"reflect": false,
"defaultValue": "'2s'"
},
"animationSpeed": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'slow' | 'slower' | 'fast' | 'faster'",
"resolved": "\"fast\" | \"faster\" | \"slow\" | \"slower\"",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": ""
},
"getter": false,
"setter": false,
"attribute": "animation-speed",
"reflect": false
}
};
}
static get states() {
return {
"fileNames": {},
"status": {},
"failedStatus": {}
};
}
static get methods() {
return {
"setUploadUrl": {
"complexType": {
"signature": "(url: string) => Promise<void>",
"parameters": [{
"name": "url",
"type": "string",
"docs": ""
}],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "Public method to set the upload URL through script.",
"tags": []
}
},
"validate": {
"complexType": {
"signature": "() => Promise<boolean>",
"parameters": [],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
}
},
"return": "Promise<boolean>"
},
"docs": {
"text": "Public method to validate that a file has been uploaded when required.\r\nReturns true if valid; otherwise, sets an error status and returns false.",
"tags": []
}
}
};
}
static get watchers() {
return [{
"propName": "animation",
"methodName": "watchAnimations"
}, {
"propName": "animationDelay",
"methodName": "watchAnimationsDelay"
}, {
"propName": "animationSpeed",
"methodName": "watchAnimationsSpeed"
}];
}
}
//# sourceMappingURL=gov-upload.js.map