Skip to content

Commit

Permalink
fix #942 FileUpload does not respect setMultiple(false)
Browse files Browse the repository at this point in the history
  • Loading branch information
vegegoku committed Jul 15, 2024
1 parent 5663ae4 commit f874529
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.dominokit.domino.ui.config;

import static java.util.Objects.nonNull;

import org.dominokit.domino.ui.utils.DominoUIConfig;

/** HasComponentConfig interface. */
Expand All @@ -25,6 +27,13 @@ public interface HasComponentConfig<T extends ComponentConfig> {
* @return a T object
*/
default T getConfig() {
if (nonNull(getOwnConfig())) {
return getOwnConfig();
}
return (T) DominoUIConfig.CONFIG.getUIConfig();
}

default T getOwnConfig() {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,15 @@ default FilePreviewFactory getFilePreviewFactory() {
default Supplier<FilePreviewContainer<?, ?>> getDefaultFilePreviewContainer() {
return DefaultFilePreviewContainer::new;
}

/**
* when the user uploaded a set of files that are less or equals the max uploads allowed, and they
* are already uploaded, should we allow him to upload a new set of files that are in total with
* the previous batch could overflow the max allowed upload limit.
*
* @return boolean default true
*/
default boolean isMaxUploadsOverflowAllowed() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,14 @@ default String getDefaultUploadCanceledMessage() {
* @param current The current number of uploads.
* @return The error message for exceeding the maximum allowed uploads.
*/
default String getMaxFileErrorMessage(int maxFiles, int current) {
return "The maximum allowed uploads is : " + maxFiles + ", You have " + current;
default String getMaxFileErrorMessage(int maxFiles, int current, int added, int ignored) {
return "The maximum allowed uploads is : "
+ maxFiles
+ ", You have : "
+ current
+ ", added : "
+ added
+ ", ignored : "
+ ignored;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

import static org.dominokit.domino.ui.utils.Domino.*;

import elemental2.dom.DomGlobal;
import elemental2.dom.HTMLDivElement;
import org.dominokit.domino.ui.grid.Column;
import org.dominokit.domino.ui.grid.Row;
import org.dominokit.domino.ui.utils.BaseDominoElement;
import org.dominokit.domino.ui.utils.ChildHandler;
Expand Down Expand Up @@ -50,7 +52,17 @@ public DefaultFilePreviewContainer() {
*/
@Override
public DefaultFilePreviewContainer appendChild(FileItem fileItem) {
rootRow.span2(fileItem);
rootRow.appendChild(
Column.span2()
.apply(
self -> {
self.appendChild(fileItem);
fileItem.onDetached(
mutationRecord -> {
DomGlobal.console.info("delete columns too ------------------");
self.remove();
});
}));
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import elemental2.dom.*;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import jsinterop.base.Js;
import org.dominokit.domino.ui.IsElement;
import org.dominokit.domino.ui.config.HasComponentConfig;
Expand Down Expand Up @@ -98,6 +99,7 @@ public class FileUpload extends BaseDominoElement<HTMLDivElement, FileUpload>
private UploadRequestSender requestSender = (XMLHttpRequest::send);

private DropEffect dropEffect;
private UploadConfig config;

/**
* Creates a new instance of the `FileUpload` component.
Expand Down Expand Up @@ -195,7 +197,7 @@ public FileUpload(
elementOf(filesContainer.element()).addCss(dui_file_preview_container);
init(this);
root.addClickListener(evt -> hiddenFileInput.element().click());
hiddenFileInput.addEventListener("change", evt -> uploadFiles(hiddenFileInput.element().files));
hiddenFileInput.addEventListener("change", evt -> tryUpload(hiddenFileInput.element().files));
root.addEventListener(
"drop",
evt -> {
Expand All @@ -210,14 +212,7 @@ public FileUpload(
((DragEvent) evt).dataTransfer.dropEffect = effect.getEffect();
}
});
int maxAllowed = hiddenFileInput.element().multiple ? maxAllowedUploads : 1;
if (maxAllowed > files.length) {
messagesContainer
.clearElement()
.setTextContent(getLabels().getMaxFileErrorMessage(maxAllowed, files.length));
} else {
uploadFiles(files);
}
tryUpload(files);
removeHover();
});
root.addEventListener(
Expand All @@ -242,6 +237,37 @@ public FileUpload(
});
}

private void tryUpload(FileList files) {

int maxAllowed = isMultiUpload() ? maxAllowedUploads : 1;
int addedFiles = addedFileItems.size();
List<FileItem> uploadedFiles =
addedFileItems.stream().filter(FileItem::isUploaded).collect(Collectors.toList());
int remainingAllowed = Math.max(0, maxAllowed - (addedFiles - uploadedFiles.size()));
int existing = addedFiles - uploadedFiles.size();
int ignored = files.length - remainingAllowed;
if (files.length > remainingAllowed) {
if (getConfig().isMaxUploadsOverflowAllowed()) {
uploadedFiles.forEach(FileItem::remove);
List<File> toBeUploaded = files.asList().subList(0, remainingAllowed);
uploadFiles(toBeUploaded);

messagesContainer
.clearElement()
.setTextContent(
getLabels()
.getMaxFileErrorMessage(maxAllowed, existing, remainingAllowed, ignored));
} else {
messagesContainer
.clearElement()
.setTextContent(
getLabels().getMaxFileErrorMessage(maxAllowed, existing, 0, files.length));
}
} else {
uploadFiles(files.asList());
}
}

/**
* Creates a new instance of the `FileUpload` component with a custom file preview factory, file
* preview container, and decoration element.
Expand Down Expand Up @@ -294,8 +320,9 @@ public FileUpload setDecoration(Element decoration) {
*
* @param maxAllowedUploads The maximum number of allowed uploads.
*/
public void setMaxAllowedUploads(int maxAllowedUploads) {
public FileUpload setMaxAllowedUploads(int maxAllowedUploads) {
this.maxAllowedUploads = maxAllowedUploads;
return this;
}

/**
Expand Down Expand Up @@ -333,17 +360,29 @@ private void addHover() {
*
* @param files The list of files to upload.
*/
public void uploadFiles(FileList files) {
for (int i = 0; i < files.length; i++) {
File file = files.item(i);
public FileUpload uploadFiles(List<File> files) {
for (int i = 0; i < files.size(); i++) {
File file = files.get(i);
addFilePreview(file);
}
hiddenFileInput.element().value = "";
return this;
}

/** Uploads all added files to the server. */
public void uploadAllFiles() {
public FileUpload uploadAllFiles() {
addedFileItems.forEach(fileItem -> fileItem.upload(requestSender));
return this;
}

@Override
public UploadConfig getOwnConfig() {
return config;
}

public FileUpload setConfig(UploadConfig config) {
this.config = config;
return this;
}

/**
Expand All @@ -353,7 +392,7 @@ public void uploadAllFiles() {
*/
private void addFilePreview(File file) {
if (isMultiUpload()) {
removeFileItems();
removeUploadedFiles();
}
FileItem fileItem = FileItem.create(file, new UploadOptions(), filePreviewFactory, this);

Expand Down Expand Up @@ -397,6 +436,12 @@ public HTMLDivElement element() {
*/
public FileUpload setMultiUpload(boolean multiUpload) {
hiddenFileInput.element().multiple = multiUpload;
if (multiUpload) {
hiddenFileInput.setAttribute("multiple", true);
} else {
hiddenFileInput.removeAttribute("multiple");
}

return this;
}

Expand Down Expand Up @@ -511,6 +556,13 @@ public FileUpload removeFileItems() {
return this;
}

private void removeUploadedFiles() {
List<FileItem> uploaded =
addedFileItems.stream().filter(FileItem::isUploaded).collect(Collectors.toList());
addedFileItems.removeAll(uploaded);
uploaded.forEach(FileItem::remove);
}

/**
* Gets a list of file item handlers that are executed when a file is added to the component.
*
Expand Down

0 comments on commit f874529

Please sign in to comment.