Skip to content

Commit

Permalink
#24362 Handle multiple files in dot-upload-file web component and add…
Browse files Browse the repository at this point in the history
… custom plugin for upload file for dot-asset-drop-zone component and render dot-upload-file component in dojo
  • Loading branch information
zulqarnainvd committed Mar 27, 2023
1 parent 18da93f commit d301383
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,25 @@
}

dot-file-upload {
@mixin box-style($border-style) {
border: 1px $border-style var(--color-main);
border-radius: 4px;
}
mwc-icon {
color: var(--color-grey);
font-size: 24px;
cursor: pointer;
}

mwc-button {
border: 1.5px solid var(--color-main);
border-radius: 8px;
color: var(--color-main);
}

input[type="file"] {
display: none;
}
@mixin box-style($border-style) {
border: 1px $border-style var(--color-main);
border-radius: 4px;
}
.dot-file-upload {
width: 100%;
padding: 16px;
Expand Down Expand Up @@ -50,17 +57,15 @@ dot-file-upload {
:first-child {
margin-right: 8px;
}
mwc-button {
border: 1.5px solid var(--color-main);
border-radius: 8px;
color: var(--color-main);
}
}

.dot-file-list {
@include box-style(solid);
margin-top: 10px;
padding: 16px;
mwc-icon {
color: var(--color-main);
}
.dot-file-list-item {
display: flex;
align-items: center;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export default {
browserButtonText: 'Browse',
writeCodeButtonText: 'Write Code',
cancelButtonText: 'Cancel',
currentState: 'UPLOADFILE'
currentState: 'UploadFile',
assets: []
}
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Component, Host, State, h, Prop, Element, Event, EventEmitter } from '@stencil/core';
import { Component, Host, h, Prop, Element, Event, EventEmitter, Watch } from '@stencil/core';
import '@material/mwc-button';
import '@material/mwc-icon';
import { DotCMSTempFile } from '@dotcms/dotcms-models';

enum DotFileCurrentStatus {
UPLOADFILE = 'UploadFile',
CODEEDITOR = 'CodeEditor',
FileList = 'FileList'
FILELIST = 'FileList'
}

@Component({
Expand All @@ -15,24 +16,52 @@ enum DotFileCurrentStatus {
export class DotFileUpload {
@Element() el: HTMLElement;

@State() currentState: DotFileCurrentStatus = DotFileCurrentStatus.UPLOADFILE;
@Prop() currentState: DotFileCurrentStatus = DotFileCurrentStatus.UPLOADFILE;

@Prop() dropFilesText = 'Drag and Drop or paste a file';
@Prop() browserButtonText = 'Browser';
@Prop() writeCodeButtonText = 'Write Code';
@Prop() cancelButtonText = 'Cancel';

@Event() fileUploaded: EventEmitter;
@Prop({ reflect: true, mutable: true }) assets: DotCMSTempFile[] = [];
@Watch('assets')
watchAssets(newAssets: DotCMSTempFile[], _oldAssets: DotCMSTempFile[]) {
if (newAssets.length > 0 && this.currentState !== DotFileCurrentStatus.FILELIST) {
this.currentState = DotFileCurrentStatus.FILELIST;
}
}

@Event() fileUploaded: EventEmitter<File[]>;
@Event() dataChanges: EventEmitter<File[]>;

updateCurrentStatus(status: DotFileCurrentStatus) {
private updateCurrentStatus(status: DotFileCurrentStatus) {
this.currentState = status;
if (this.currentState !== DotFileCurrentStatus.FILELIST) {
this.assets = [];
}
}

fileChangeHandler(event: Event) {
this.fileUploaded.emit(event);
private fileChangeHandler(event: Event) {
let files: File[] = [];
if (
(event.target as HTMLInputElement).files &&
(event.target as HTMLInputElement).files.length
) {
Array.from((event.target as HTMLInputElement).files).map((file: File) => {
files.push(file);
});
}
this.fileUploaded.emit(files);
}
getCurrentElement() {
if (this.currentState === DotFileCurrentStatus.UPLOADFILE) {

private removeAssetFromFileList(assetId) {
this.assets = this.assets.filter(({ id }: DotCMSTempFile) => id !== assetId);
if (this.assets.length === 0) {
this.currentState = DotFileCurrentStatus.UPLOADFILE;
}
}
private getCurrentElement(currentState: DotFileCurrentStatus) {
if (currentState === DotFileCurrentStatus.UPLOADFILE) {
return (
<div class="dot-file-upload">
<div class="dot-file-upload-drop-message">
Expand All @@ -59,18 +88,22 @@ export class DotFileUpload {
</div>
</div>
);
} else if (this.currentState === DotFileCurrentStatus.FileList) {
} else if (currentState === DotFileCurrentStatus.FILELIST) {
return (
<div class="dot-file-list">
<div class="dot-file-list-item">
<div>
<mwc-icon>insert_drive_file</mwc-icon>
</div>
<div>File12345</div>
<div>
<mwc-icon>delete</mwc-icon>
{this.assets.map((asset: DotCMSTempFile) => (
<div class="dot-file-list-item">
<div>
<mwc-icon>insert_drive_file</mwc-icon>
</div>
<div>{asset.fileName}</div>
<div>
<mwc-icon onClick={() => this.removeAssetFromFileList(asset.id)}>
delete
</mwc-icon>
</div>
</div>
</div>
))}

<div class="dot-file-list-cancel-box">
<mwc-button
Expand All @@ -84,7 +117,7 @@ export class DotFileUpload {
</div>
</div>
);
} else if (this.currentState === DotFileCurrentStatus.CODEEDITOR) {
} else if (currentState === DotFileCurrentStatus.CODEEDITOR) {
return (
<div class="dot-file-editor">
<slot />
Expand Down Expand Up @@ -120,9 +153,12 @@ export class DotFileUpload {

componentDidLoad(): void {
this.fileInput = this.el.querySelector('.dot-file-upload input');
if (this.assets.length > 0) {
this.currentState = DotFileCurrentStatus.FILELIST;
}
}

render() {
return <Host>{this.getCurrentElement()}</Host>;
return <Host>{this.getCurrentElement(this.currentState)}</Host>;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -792,18 +792,61 @@
accept="<%=accept %>" >
</div>
<div class="file-asset-container">
<dot-asset-drop-zone id="dot-asset-drop-zone-<%=field.getVelocityVarName()%>" class="file-asset__drop-zone"></dot-asset-drop-zone>
<dot-asset-drop-zone
id="dot-asset-drop-zone-<%=field.getVelocityVarName()%>"
class="file-asset__drop-zone"
></dot-asset-drop-zone>
<dot-file-upload
id="dot-file-upload-<%=field.getVelocityVarName()%>"
dropFilesText='Drag and Drop or paste a file'
browserButtonText="Browser"
writeCodeButtonText="Write Code"
cancelButtonText="Cancel"
assets="[]"
></dot-file-upload>
</div>
<script type="text/javascript">
dojo.addOnLoad(() => {
bindDotFileUploadListener("<%=field.getVelocityVarName()%>")
const uploadPlugin = ({files, onSuccess, updateProgress, onError}) => {
// Check if we get an array of files otherwise create array.
const data = Array.isArray(files) ? files : [files];
// Create Form Data
const formData = new FormData();
data.forEach((file) => formData.append('file', file));
return new Promise((res, rej) => {
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/v1/temp?maxFileLength=<%= maxFileLength%>');
xhr.onload = () => res(xhr);
xhr.onerror = rej;
// Get Upload Process
if (xhr.upload && updateProgress) {
xhr.upload.onprogress = (e) => {
const percentComplete = (e.loaded / e.total) * 100;
updateProgress(percentComplete);
};
}
xhr.send(formData);
}).then(async (request) => {
if (request.status !== 200) {
throw request;
}
onSuccess();
return JSON.parse(request.response)?.tempFiles || [];
})
.catch((request) => {
const response = typeof (request.response) === 'string' ? JSON.parse(request.response) : request.response;
const errorMesage = response.errors[0].message;
onError(headerError, errorMesage);
throw response;
});
}
bindDotFileUploadListener("<%=field.getVelocityVarName()%>", uploadPlugin)
})
function saveBinaryFileOnContent<%=field.getVelocityVarName()%>(fileName, dijitReference){
saveBinaryFileOnContent('<%=field.getInode()%>','<%=field.getVelocityVarName()%>','<%=field.getFieldContentlet()%>', dijitReference.fileNameField.value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,24 @@ function enableSiteKeyUpdate(dialogId, siteKeyInputId) {
// Dot Upload File
function bindDotFileUploadListener(id){
const dotFileUpload = document.querySelector(`#dot-file-upload-${id}`)
dotFileUpload.addEventListener('fileUploaded', function (event){
function bindDotFileUploadListener(id, uploadPlugin){
const dotFileUpload = document.querySelector(`#dot-file-upload-${id}`)
const dotAssetDropZone = document.querySelector(`#ddot-asset-drop-zone-${id}`)
const dotAssetDropZone = document.querySelector(`#dot-asset-drop-zone-${id}`);
dotFileUpload.addEventListener('fileUploaded', function (event){
event.dataTransfer = {};
event.dataTransfer.files = event.detail;
dotAssetDropZone.ondrop(event);
})
})
}
dotAssetDropZone.customUploadFiles = uploadPlugin;
dotAssetDropZone.addEventListener('uploadComplete', function(asset){
console.log("data", asset)
dotFileUpload.assets = [...asset.detail];
dotAssetDropZone.style.pointerEvents = "none";
})
}
Expand Down

0 comments on commit d301383

Please sign in to comment.