From db74c793d4c7b211d24b098e52ee7246462d3108 Mon Sep 17 00:00:00 2001
From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com>
Date: Thu, 24 Oct 2024 17:38:58 -0300
Subject: [PATCH] feat: initial implementation
---
README.md | 26 +--
pom.xml | 32 ++-
.../vaadin/addons/uploadhelper/FileInfo.java | 212 ++++++++++++++++++
.../META-INF/VAADIN/package.properties | 19 ++
.../addons/AppShellConfiguratorImpl.java} | 25 +--
.../flowingcode/vaadin/addons/DemoLayout.java | 8 +-
.../vaadin/addons/template/TemplateDemo.java | 17 --
.../vaadin/addons/template/it/ViewIT.java | 64 ------
.../template/test/SerializationTest.java | 52 -----
.../{template => uploadhelper}/DemoView.java | 12 +-
.../addons/uploadhelper/FileInfoDemo.java | 101 +++++++++
.../addons/uploadhelper/NullUpload.java | 53 +++++
.../addons/uploadhelper/PlaygroundDemo.java | 104 +++++++++
.../UploadHelperDemoView.java} | 17 +-
.../it/AbstractViewTest.java | 10 +-
.../uploadhelper/it/IntegrationCallables.java | 34 +++
.../uploadhelper/it/IntegrationView.java | 73 ++++++
.../vaadin/addons/uploadhelper/it/ViewIT.java | 81 +++++++
.../frontend/styles/shared-styles.css | 21 +-
19 files changed, 767 insertions(+), 194 deletions(-)
create mode 100644 src/main/java/com/flowingcode/vaadin/addons/uploadhelper/FileInfo.java
rename src/{main/java/com/flowingcode/vaadin/addons/template/TemplateAddon.java => test/java/com/flowingcode/vaadin/addons/AppShellConfiguratorImpl.java} (56%)
delete mode 100644 src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemo.java
delete mode 100644 src/test/java/com/flowingcode/vaadin/addons/template/it/ViewIT.java
delete mode 100644 src/test/java/com/flowingcode/vaadin/addons/template/test/SerializationTest.java
rename src/test/java/com/flowingcode/vaadin/addons/{template => uploadhelper}/DemoView.java (84%)
create mode 100644 src/test/java/com/flowingcode/vaadin/addons/uploadhelper/FileInfoDemo.java
create mode 100644 src/test/java/com/flowingcode/vaadin/addons/uploadhelper/NullUpload.java
create mode 100644 src/test/java/com/flowingcode/vaadin/addons/uploadhelper/PlaygroundDemo.java
rename src/test/java/com/flowingcode/vaadin/addons/{template/TemplateDemoView.java => uploadhelper/UploadHelperDemoView.java} (71%)
rename src/test/java/com/flowingcode/vaadin/addons/{template => uploadhelper}/it/AbstractViewTest.java (96%)
create mode 100644 src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/IntegrationCallables.java
create mode 100644 src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/IntegrationView.java
create mode 100644 src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/ViewIT.java
diff --git a/README.md b/README.md
index e600a7e..db54cc3 100644
--- a/README.md
+++ b/README.md
@@ -1,24 +1,24 @@
-[![Published on Vaadin Directory](https://img.shields.io/badge/Vaadin%20Directory-published-00b4f0.svg)](https://vaadin.com/directory/component/template-addon)
-[![Stars on vaadin.com/directory](https://img.shields.io/vaadin-directory/star/template-addon.svg)](https://vaadin.com/directory/component/template-addon)
-[![Build Status](https://jenkins.flowingcode.com/job/template-addon/badge/icon)](https://jenkins.flowingcode.com/job/template-addon)
-[![Maven Central](https://img.shields.io/maven-central/v/com.flowingcode.vaadin.addons/template-addon)](https://mvnrepository.com/artifact/com.flowingcode.vaadin.addons/template-addon)
-[![Javadoc](https://img.shields.io/badge/javadoc-00b4f0)](https://javadoc.flowingcode.com/artifact/com.flowingcode.vaadin.addons/template-addon)
+[![Published on Vaadin Directory](https://img.shields.io/badge/Vaadin%20Directory-published-00b4f0.svg)](https://vaadin.com/directory/component/upload-helper-add-on)
+[![Stars on vaadin.com/directory](https://img.shields.io/vaadin-directory/star/upload-helper-addon.svg)](https://vaadin.com/directory/component/upload-helper-add-on)
+[![Build Status](https://jenkins.flowingcode.com/job/upload-helper-addon/badge/icon)](https://jenkins.flowingcode.com/job/upload-helper-addon)
+[![Maven Central](https://img.shields.io/maven-central/v/com.flowingcode.vaadin.addons/upload-helper-addon)](https://mvnrepository.com/artifact/com.flowingcode.vaadin.addons/upload-helper-addon)
+[![Javadoc](https://img.shields.io/badge/javadoc-00b4f0)](https://javadoc.flowingcode.com/artifact/com.flowingcode.vaadin.addons/upload-helper-addon)
-# Template Add-on
+# Upload helper Add-on
-This is a template project for building new Vaadin 24 add-ons
+Flow API for `vaadin-upload-file`
## Features
-* List the features of your add-on in here
+* Provide an API for manipulating the [vaadin-upload-file](https://cdn.vaadin.com/vaadin-web-components/24.5.0/#/elements/vaadin-upload-file) element.
## Online demo
-[Online demo here](http://addonsv24.flowingcode.com/template)
+[Online demo here](http://addonsv24.flowingcode.com/upload-helper)
## Download release
-[Available in Vaadin Directory](https://vaadin.com/directory/component/template-addon)
+[Available in Vaadin Directory](https://vaadin.com/directory/component/upload-helper-add-on)
### Maven install
@@ -27,7 +27,7 @@ Add the following dependencies in your pom.xml file:
```xml
com.flowingcode.vaadin.addons
- template-addon
+ upload-helper-addon
X.Y.Z
```
@@ -44,7 +44,7 @@ To see the demo, navigate to http://localhost:8080/
## Release notes
-See [here](https://github.com/FlowingCode/TemplateAddon/releases)
+See [here](https://github.com/FlowingCode/UploadHelper/releases)
## Issue tracking
@@ -69,7 +69,7 @@ Then, follow these steps for creating a contribution:
This add-on is distributed under Apache License 2.0. For license terms, see LICENSE.txt.
-TEMPLATE_ADDON is written by Flowing Code S.A.
+Upload Helper Add-On is written by Flowing Code S.A.
# Developer Guide
diff --git a/pom.xml b/pom.xml
index 7ceac95..432318a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,14 +5,14 @@
4.0.0
com.flowingcode.vaadin.addons
- template-addon
+ upload-helper-addon
1.0.0-SNAPSHOT
- Template Add-on
- Template Add-on for Vaadin Flow
+ Upload Helper Add-on
+ Upload Helper Add-on for Vaadin Flow
https://www.flowingcode.com/en/open-source/
- 24.4.6
+ 24.5.0
4.10.0
17
17
@@ -29,7 +29,7 @@
https://www.flowingcode.com
- 2024
+ 2022
Apache 2
@@ -39,9 +39,9 @@
- https://github.com/FlowingCode/AddonStarter24
- scm:git:git://github.com/FlowingCode/AddonStarter24.git
- scm:git:ssh://git@github.com:/FlowingCode/AddonStarter24.git
+ https://github.com/FlowingCode/UploadHelper
+ scm:git:git://github.com/FlowingCode/UploadHelper.git
+ scm:git:ssh://git@github.com:/FlowingCode/UploadHelper.git
master
@@ -122,6 +122,17 @@
vaadin-core
true
+
+ org.projectlombok
+ lombok
+ 1.18.34
+ provided
+
+
+ com.flowingcode.vaadin.test
+ testbench-rpc
+ 1.3.0
+
com.flowingcode.vaadin.addons.demo
commons-demo
@@ -313,9 +324,9 @@
true
none
- true
+ true
- https://javadoc.io/doc/com.vaadin/vaadin-platform-javadoc/${vaadin.version}
+ https://javadoc.io/doc/com.vaadin/vaadin-platform-javadoc/${vaadin.version}
@@ -496,6 +507,7 @@
**/it/*
**/DemoView.class
**/DemoLayout.class
+ **/AppShellConfiguratorImpl.class
diff --git a/src/main/java/com/flowingcode/vaadin/addons/uploadhelper/FileInfo.java b/src/main/java/com/flowingcode/vaadin/addons/uploadhelper/FileInfo.java
new file mode 100644
index 0000000..4557e91
--- /dev/null
+++ b/src/main/java/com/flowingcode/vaadin/addons/uploadhelper/FileInfo.java
@@ -0,0 +1,212 @@
+/*-
+ * #%L
+ * Upload Helper Add-on
+ * %%
+ * Copyright (C) 2022 - 2024 Flowing Code
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.flowingcode.vaadin.addons.uploadhelper;
+
+import com.vaadin.flow.component.upload.FinishedEvent;
+import com.vaadin.flow.component.upload.Upload;
+import elemental.json.Json;
+import elemental.json.JsonObject;
+import java.io.Serializable;
+import lombok.AccessLevel;
+import lombok.Getter;
+
+/** Represents a file in the file list of an {@link Upload} component. */
+@SuppressWarnings("serial")
+public final class FileInfo implements Serializable {
+
+ private final String name;
+
+ @Getter(AccessLevel.PACKAGE)
+ private Upload upload;
+
+ private Boolean complete;
+ private Boolean indeterminate;
+ private String errorMessage;
+ private Integer progress;
+ private String status;
+
+ /**
+ * Constructs a {@code FileInfo} object with the specified upload and file name.
+ *
+ * @param upload the {@code Upload} instance representing the file upload source
+ * @param name the name of the file being uploaded
+ */
+ public FileInfo(Upload upload, String name) {
+ this.upload = upload;
+ this.name = name;
+ }
+
+ /**
+ * Constructs a {@code FileInfo} object from the specified finished upload event.
+ *
+ * @param ev the {@code FinishedEvent} representing the succeeded or failed event
+ */
+ public FileInfo(FinishedEvent ev) {
+ upload = ev.getSource();
+ name = ev.getFileName();
+ }
+
+ /** Updates this file in the upload component. */
+ public void update() {
+ update(false);
+ }
+
+ /** Adds a new file to the upload component. */
+ public void create() {
+ update(true);
+ }
+
+ private void update(boolean createIfNotExists) {
+ upload.getElement().executeJs(
+ """
+ var d = this;
+ var i = d.files.findIndex(f=>f.name==$0.name);
+ if (i<0) {
+ if ($1) d.files = [... d.files, $0]; else return;
+ } else {
+ if (d.files.some((e,j)=>e.name==$0.name && j>i)) d.files=d.files.filter((e,j)=>e.name!=$0.name || j<=i);
+ d.files[i] = Object.assign(d.files[i], $0);
+ }
+ d.files = Array.from(d.files);
+ """,
+ toJson(), createIfNotExists);
+ }
+
+ private JsonObject toJson() {
+ JsonObject json = Json.createObject();
+ json.put("name", name);
+ if (complete != null) {
+ json.put("complete", complete);
+ }
+ if (indeterminate != null) {
+ json.put("indeterminate", indeterminate);
+ }
+ if (errorMessage != null) {
+ json.put("error", errorMessage);
+ }
+ if (progress != null) {
+ json.put("progress", progress);
+ }
+ if (status != null) {
+ json.put("status", status);
+ }
+ return json;
+ }
+
+ /**
+ * True if uploading is completed, false otherwise.
+ *
+ * @return This instance for method chaining
+ */
+ public FileInfo complete(Boolean complete) {
+ this.complete = complete;
+ return this;
+ }
+
+ /**
+ * Configure the upload in complete state (i.e. uploading is completed)
+ *
+ * @return This instance for method chaining
+ */
+ public FileInfo complete() {
+ complete = true;
+ return this;
+ }
+
+ /**
+ * Configure the upload in indeterminate state (i.e. the remaining time is unknown)
+ *
+ * @return This instance for method chaining
+ */
+ public FileInfo indeterminate() {
+ return indeterminate(true);
+ }
+
+ /**
+ * True if the remaining time is unknown, false otherwise.
+ *
+ * @return This instance for method chaining
+ */
+ public FileInfo indeterminate(Boolean indeterminate) {
+ this.indeterminate = indeterminate;
+ return this;
+ }
+
+ /**
+ * Error message returned by the server, if any.
+ *
+ * @return This instance for method chaining
+ */
+ public FileInfo errorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ return this;
+ }
+
+ /**
+ * Number representing the uploading progress.
+ *
+ * @return This instance for method chaining
+ */
+ public FileInfo progress(Integer progress) {
+ this.progress = progress;
+ return this;
+ }
+
+ /**
+ * Uploading status message.
+ *
+ * @return This instance for method chaining
+ */
+ public FileInfo status(String status) {
+ this.status = status;
+ return this;
+ }
+
+ /** Returns the name of the uploaded file. */
+ public String getName() {
+ return name;
+ }
+
+ /** Returns {@code true} if uploading is completed, false otherwise. */
+ public Boolean getComplete() {
+ return complete;
+ }
+
+ /** Returns {@code true} if the remaining progress is unknown, false otherwise. */
+ public Boolean getIndeterminate() {
+ return indeterminate;
+ }
+
+ /** Returns the error message returned by the server. */
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ /** Returns a number between 0 and 100, representing the uploading progress. */
+ public Integer getProgress() {
+ return progress;
+ }
+
+ /** Returns the uploading status. */
+ public String getStatus() {
+ return status;
+ }
+
+}
diff --git a/src/main/resources/META-INF/VAADIN/package.properties b/src/main/resources/META-INF/VAADIN/package.properties
index c66616f..b96d56a 100644
--- a/src/main/resources/META-INF/VAADIN/package.properties
+++ b/src/main/resources/META-INF/VAADIN/package.properties
@@ -1 +1,20 @@
+###
+# #%L
+# Upload Helper Add-on
+# %%
+# Copyright (C) 2022 - 2024 Flowing Code
+# %%
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# #L%
+###
vaadin.allowed-packages=com.flowingcode
diff --git a/src/main/java/com/flowingcode/vaadin/addons/template/TemplateAddon.java b/src/test/java/com/flowingcode/vaadin/addons/AppShellConfiguratorImpl.java
similarity index 56%
rename from src/main/java/com/flowingcode/vaadin/addons/template/TemplateAddon.java
rename to src/test/java/com/flowingcode/vaadin/addons/AppShellConfiguratorImpl.java
index c9ec694..e7a6481 100644
--- a/src/main/java/com/flowingcode/vaadin/addons/template/TemplateAddon.java
+++ b/src/test/java/com/flowingcode/vaadin/addons/AppShellConfiguratorImpl.java
@@ -1,15 +1,15 @@
/*-
* #%L
- * Template Add-on
+ * Upload Helper Add-on
* %%
- * Copyright (C) 2024 Flowing Code
+ * Copyright (C) 2022 - 2024 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,16 +17,13 @@
* limitations under the License.
* #L%
*/
+package com.flowingcode.vaadin.addons;
-package com.flowingcode.vaadin.addons.template;
-
-import com.vaadin.flow.component.Tag;
-import com.vaadin.flow.component.dependency.JsModule;
-import com.vaadin.flow.component.dependency.NpmPackage;
-import com.vaadin.flow.component.html.Div;
+import com.vaadin.flow.component.page.AppShellConfigurator;
+import com.vaadin.flow.component.page.Push;
@SuppressWarnings("serial")
-@NpmPackage(value = "@polymer/paper-input", version = "3.2.1")
-@JsModule("@polymer/paper-input/paper-input.js")
-@Tag("paper-input")
-public class TemplateAddon extends Div {}
+@Push
+public class AppShellConfiguratorImpl implements AppShellConfigurator {
+
+}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/DemoLayout.java b/src/test/java/com/flowingcode/vaadin/addons/DemoLayout.java
index b84172e..988e949 100644
--- a/src/test/java/com/flowingcode/vaadin/addons/DemoLayout.java
+++ b/src/test/java/com/flowingcode/vaadin/addons/DemoLayout.java
@@ -1,15 +1,15 @@
/*-
* #%L
- * Template Add-on
+ * Upload Helper Add-on
* %%
- * Copyright (C) 2024 Flowing Code
+ * Copyright (C) 2022 - 2024 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemo.java b/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemo.java
deleted file mode 100644
index 5f6e6ee..0000000
--- a/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemo.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.flowingcode.vaadin.addons.template;
-
-import com.flowingcode.vaadin.addons.demo.DemoSource;
-import com.vaadin.flow.component.html.Div;
-import com.vaadin.flow.router.PageTitle;
-import com.vaadin.flow.router.Route;
-
-@DemoSource
-@PageTitle("Template Add-on Demo")
-@SuppressWarnings("serial")
-@Route(value = "demo", layout = TemplateDemoView.class)
-public class TemplateDemo extends Div {
-
- public TemplateDemo() {
- add(new TemplateAddon());
- }
-}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/it/ViewIT.java b/src/test/java/com/flowingcode/vaadin/addons/template/it/ViewIT.java
deleted file mode 100644
index 0e5f164..0000000
--- a/src/test/java/com/flowingcode/vaadin/addons/template/it/ViewIT.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * #%L
- * Template Add-on
- * %%
- * Copyright (C) 2024 Flowing Code
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
-
-package com.flowingcode.vaadin.addons.template.it;
-
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertThat;
-
-import com.vaadin.testbench.TestBenchElement;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.TypeSafeDiagnosingMatcher;
-import org.junit.Test;
-
-public class ViewIT extends AbstractViewTest {
-
- private Matcher hasBeenUpgradedToCustomElement =
- new TypeSafeDiagnosingMatcher() {
-
- @Override
- public void describeTo(Description description) {
- description.appendText("a custom element");
- }
-
- @Override
- protected boolean matchesSafely(TestBenchElement item, Description mismatchDescription) {
- String script = "let s=arguments[0].shadowRoot; return !!(s&&s.childElementCount)";
- if (!item.getTagName().contains("-")) {
- return true;
- }
- if ((Boolean) item.getCommandExecutor().executeScript(script, item)) {
- return true;
- } else {
- mismatchDescription.appendText(item.getTagName() + " ");
- mismatchDescription.appendDescriptionOf(is(not(this)));
- return false;
- }
- }
- };
-
- @Test
- public void componentWorks() {
- TestBenchElement element = $("paper-input").first();
- assertThat(element, hasBeenUpgradedToCustomElement);
- }
-}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/test/SerializationTest.java b/src/test/java/com/flowingcode/vaadin/addons/template/test/SerializationTest.java
deleted file mode 100644
index 1ee78c3..0000000
--- a/src/test/java/com/flowingcode/vaadin/addons/template/test/SerializationTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * #%L
- * Template Add-on
- * %%
- * Copyright (C) 2024 Flowing Code
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
-package com.flowingcode.vaadin.addons.template.test;
-
-import com.flowingcode.vaadin.addons.template.TemplateAddon;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SerializationTest {
-
- private void testSerializationOf(Object obj) throws IOException, ClassNotFoundException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
- oos.writeObject(obj);
- }
- try (ObjectInputStream in =
- new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
- obj.getClass().cast(in.readObject());
- }
- }
-
- @Test
- public void testSerialization() throws ClassNotFoundException, IOException {
- try {
- testSerializationOf(new TemplateAddon());
- } catch (Exception e) {
- Assert.fail("Problem while testing serialization: " + e.getMessage());
- }
- }
-}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/DemoView.java b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/DemoView.java
similarity index 84%
rename from src/test/java/com/flowingcode/vaadin/addons/template/DemoView.java
rename to src/test/java/com/flowingcode/vaadin/addons/uploadhelper/DemoView.java
index a600c9d..1d9e1b5 100644
--- a/src/test/java/com/flowingcode/vaadin/addons/template/DemoView.java
+++ b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/DemoView.java
@@ -1,15 +1,15 @@
/*-
* #%L
- * Template Add-on
+ * Upload Helper Add-on
* %%
- * Copyright (C) 2024 Flowing Code
+ * Copyright (C) 2022 - 2024 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,7 +18,7 @@
* #L%
*/
-package com.flowingcode.vaadin.addons.template;
+package com.flowingcode.vaadin.addons.uploadhelper;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.BeforeEnterEvent;
@@ -31,6 +31,6 @@ public class DemoView extends VerticalLayout implements BeforeEnterObserver {
@Override
public void beforeEnter(BeforeEnterEvent event) {
- event.forwardTo(TemplateDemoView.class);
+ event.forwardTo(UploadHelperDemoView.class);
}
}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/FileInfoDemo.java b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/FileInfoDemo.java
new file mode 100644
index 0000000..efdf0c6
--- /dev/null
+++ b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/FileInfoDemo.java
@@ -0,0 +1,101 @@
+/*-
+ * #%L
+ * Upload Helper Add-on
+ * %%
+ * Copyright (C) 2022 - 2024 Flowing Code
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.flowingcode.vaadin.addons.uploadhelper;
+
+import com.flowingcode.vaadin.addons.demo.DemoSource;
+import com.vaadin.flow.component.UI;
+import com.vaadin.flow.component.html.Div;
+import com.vaadin.flow.component.upload.Upload;
+import com.vaadin.flow.component.upload.receivers.MultiFileMemoryBuffer;
+import com.vaadin.flow.router.PageTitle;
+import com.vaadin.flow.router.Route;
+import java.io.OutputStream; // hide-source
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.commons.io.output.NullOutputStream; // hide-source
+
+@DemoSource
+@PageTitle("FileInfo Demo")
+@SuppressWarnings("serial")
+@Route(value = "upload-helper/demo2", layout = UploadHelperDemoView.class)
+public class FileInfoDemo extends Div {
+
+ public FileInfoDemo() {
+ // show-source Upload upload = new Upload(new MultiFileMemoryBuffer());
+
+ // #if vaadin eq 0
+ add(new Div(
+ """
+ Simulates progress updates, incrementing from 0% to 100% and updating the UI in real-time.
+ After reaching 100%, the file is set to "Please wait..." with an indeterminate progress state to represent some final processing.
+ After a 2-second delay, the system randomly determines if the processing succeeded or failed, updating the UI accordingly."""));
+
+ Upload upload = new Upload(new MultiFileMemoryBuffer() {
+ @Override
+ public OutputStream receiveUpload(String fileName, String MIMEType) {
+ super.receiveUpload(fileName, MIMEType);
+ return NullOutputStream.INSTANCE;
+ }
+ });
+ add(upload);
+ // #endif
+
+ Map processing = new ConcurrentHashMap<>();
+
+ upload.addSucceededListener(ev -> {
+ if (processing.put(ev.getFileName(), true) == null) {
+ UI ui = ev.getSource().getUI().get();
+ new Thread(() -> {
+ AtomicInteger progress = new AtomicInteger();
+ while (progress.get() <= 100) {
+ int p = progress.getAndIncrement();
+ ui.access(() -> new FileInfo(ev).status(String.format("Processing (%s%%)", p))
+ .progress(p).update());
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ ui.access(() -> new FileInfo(ev).indeterminate().status("Please wait...").update());
+
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ if (Math.random() < 0.5) {
+ ui.access(() -> new FileInfo(ev).complete().update());
+ } else {
+ ui.access(() -> new FileInfo(ev).errorMessage("Random failure").update());
+ }
+
+ processing.remove(ev.getFileName());
+ }).start();
+ }
+ });
+
+ }
+
+
+}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/NullUpload.java b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/NullUpload.java
new file mode 100644
index 0000000..dba136a
--- /dev/null
+++ b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/NullUpload.java
@@ -0,0 +1,53 @@
+/*-
+ * #%L
+ * Upload Helper Add-on
+ * %%
+ * Copyright (C) 2022 - 2024 Flowing Code
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.flowingcode.vaadin.addons.uploadhelper;
+
+import com.vaadin.flow.component.upload.MultiFileReceiver;
+import com.vaadin.flow.component.upload.Upload;
+import com.vaadin.flow.component.upload.receivers.MemoryBuffer;
+import com.vaadin.flow.component.upload.receivers.MultiFileMemoryBuffer;
+import java.io.OutputStream;
+import org.apache.commons.io.output.NullOutputStream;
+
+// this is just a helper class that discards the uploaded file
+@SuppressWarnings("serial")
+class NullUpload extends Upload {
+
+ public NullUpload(MultiFileReceiver receiver) {
+ super(new MultiFileMemoryBuffer() {
+ @Override
+ public OutputStream receiveUpload(String fileName, String MIMEType) {
+ super.receiveUpload(fileName, MIMEType);
+ return NullOutputStream.INSTANCE;
+ }
+ });
+ }
+
+ public NullUpload() {
+ super(new MemoryBuffer() {
+ @Override
+ public OutputStream receiveUpload(String fileName, String MIMEType) {
+ super.receiveUpload(fileName, MIMEType);
+ return NullOutputStream.INSTANCE;
+ }
+ });
+ }
+
+}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/PlaygroundDemo.java b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/PlaygroundDemo.java
new file mode 100644
index 0000000..a7f3af3
--- /dev/null
+++ b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/PlaygroundDemo.java
@@ -0,0 +1,104 @@
+/*-
+ * #%L
+ * Upload Helper Add-on
+ * %%
+ * Copyright (C) 2022 - 2024 Flowing Code
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.flowingcode.vaadin.addons.uploadhelper;
+
+import com.vaadin.flow.component.checkbox.Checkbox;
+import com.vaadin.flow.component.formlayout.FormLayout;
+import com.vaadin.flow.component.html.Div;
+import com.vaadin.flow.component.textfield.IntegerField;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.component.upload.Upload;
+import com.vaadin.flow.data.binder.Binder;
+import com.vaadin.flow.router.PageTitle;
+import com.vaadin.flow.router.Route;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@PageTitle("Playground")
+@SuppressWarnings("serial")
+@Route(value = "upload-helper/demo", layout = UploadHelperDemoView.class)
+public class PlaygroundDemo extends Div {
+
+ private String fileName;
+ private Upload upload;
+
+ @Data
+ @Accessors(fluent = true)
+ private static class Bean {
+ boolean complete;
+ boolean indeterminate;
+ int progress;
+ String status;
+ String errorMessage;
+ }
+
+ public PlaygroundDemo() {
+ add(upload = new NullUpload());
+ new FileInfo(upload, fileName = "test").create();
+
+ upload.addSucceededListener(ev -> {
+ fileName = ev.getFileName();
+ new FileInfo(ev).indeterminate().status("Processing...").update();
+ });
+
+ Binder binder = new Binder<>();
+
+ FormLayout formLayout = new FormLayout();
+ formLayout.setResponsiveSteps(new FormLayout.ResponsiveStep("0", 1));
+ add(formLayout);
+
+ Checkbox indeterminate = new Checkbox();
+ Checkbox complete = new Checkbox();
+ TextField status = new TextField();
+ TextField errorMessage = new TextField();
+
+ IntegerField progress = new IntegerField();
+ progress.setStepButtonsVisible(true);
+
+ formLayout.addFormItem(indeterminate, "Indeterminate");
+ formLayout.addFormItem(complete, "Complete");
+ formLayout.addFormItem(status, "Status");
+ formLayout.addFormItem(errorMessage, "Error Message");
+ formLayout.addFormItem(progress, "Progress");
+
+ binder.forField(indeterminate).bind(Bean::indeterminate, Bean::indeterminate);
+ binder.forField(complete).bind(Bean::complete, Bean::complete);
+ binder.forField(status).bind(Bean::status, Bean::status);
+ binder.forField(errorMessage).bind(Bean::errorMessage, Bean::errorMessage);
+ binder.forField(progress).bind(Bean::progress, Bean::progress);
+
+ binder.setBean(new Bean());
+
+ binder.addValueChangeListener(ev -> {
+ Bean bean = binder.getBean();
+ var file = new FileInfo(upload, fileName);
+ file.indeterminate(bean.indeterminate);
+ file.complete(bean.complete);
+ file.status(bean.status);
+ file.errorMessage(bean.errorMessage);
+ file.progress(bean.progress);
+ file.update();
+ });
+
+ indeterminate.setValue(true);
+ }
+
+
+}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemoView.java b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/UploadHelperDemoView.java
similarity index 71%
rename from src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemoView.java
rename to src/test/java/com/flowingcode/vaadin/addons/uploadhelper/UploadHelperDemoView.java
index 1954535..2f839b3 100644
--- a/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemoView.java
+++ b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/UploadHelperDemoView.java
@@ -1,8 +1,8 @@
/*-
* #%L
- * Template Add-on
+ * Upload Helper Add-on
* %%
- * Copyright (C) 2024 Flowing Code
+ * Copyright (C) 2022 - 2024 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@
* limitations under the License.
* #L%
*/
-package com.flowingcode.vaadin.addons.template;
+package com.flowingcode.vaadin.addons.uploadhelper;
import com.flowingcode.vaadin.addons.DemoLayout;
import com.flowingcode.vaadin.addons.GithubLink;
@@ -27,12 +27,13 @@
@SuppressWarnings("serial")
@ParentLayout(DemoLayout.class)
-@Route("template")
-@GithubLink("https://github.com/FlowingCode/AddonStarter24")
-public class TemplateDemoView extends TabbedDemo {
+@Route("upload-helper")
+@GithubLink("https://github.com/FlowingCode/UploadHelper")
+public class UploadHelperDemoView extends TabbedDemo {
- public TemplateDemoView() {
- addDemo(TemplateDemo.class);
+ public UploadHelperDemoView() {
+ addDemo(PlaygroundDemo.class);
+ addDemo(FileInfoDemo.class);
setSizeFull();
}
}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/it/AbstractViewTest.java b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/AbstractViewTest.java
similarity index 96%
rename from src/test/java/com/flowingcode/vaadin/addons/template/it/AbstractViewTest.java
rename to src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/AbstractViewTest.java
index 1f7749b..eda431a 100644
--- a/src/test/java/com/flowingcode/vaadin/addons/template/it/AbstractViewTest.java
+++ b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/AbstractViewTest.java
@@ -1,15 +1,15 @@
/*-
* #%L
- * Template Add-on
+ * Upload Helper Add-on
* %%
- * Copyright (C) 2024 Flowing Code
+ * Copyright (C) 2022 - 2024 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,7 +18,7 @@
* #L%
*/
-package com.flowingcode.vaadin.addons.template.it;
+package com.flowingcode.vaadin.addons.uploadhelper.it;
import com.vaadin.testbench.ScreenshotOnFailureRule;
import com.vaadin.testbench.TestBench;
diff --git a/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/IntegrationCallables.java b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/IntegrationCallables.java
new file mode 100644
index 0000000..0095e8e
--- /dev/null
+++ b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/IntegrationCallables.java
@@ -0,0 +1,34 @@
+/*-
+ * #%L
+ * Upload Helper Add-on
+ * %%
+ * Copyright (C) 2022 - 2024 Flowing Code
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.flowingcode.vaadin.addons.uploadhelper.it;
+
+public interface IntegrationCallables {
+
+ void complete();
+
+ void indeterminate();
+
+ void progress(int progress);
+
+ void status(String status);
+
+ void errorMessage(String errorMessage);
+
+}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/IntegrationView.java b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/IntegrationView.java
new file mode 100644
index 0000000..414c4f6
--- /dev/null
+++ b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/IntegrationView.java
@@ -0,0 +1,73 @@
+/*-
+ * #%L
+ * Upload Helper Add-on
+ * %%
+ * Copyright (C) 2022 - 2024 Flowing Code
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.flowingcode.vaadin.addons.uploadhelper.it;
+
+import com.flowingcode.vaadin.addons.uploadhelper.FileInfo;
+import com.vaadin.flow.component.ClientCallable;
+import com.vaadin.flow.component.html.Div;
+import com.vaadin.flow.component.upload.Upload;
+import com.vaadin.flow.component.upload.receivers.MemoryBuffer;
+import com.vaadin.flow.router.Route;
+
+@Route("it")
+public class IntegrationView extends Div implements IntegrationCallables {
+
+ private Upload upload;
+
+ public IntegrationView() {
+ add(upload = new Upload(new MemoryBuffer()));
+ file().create();
+ }
+
+ private FileInfo file() {
+ return new FileInfo(upload, "test");
+ }
+
+ @Override
+ @ClientCallable
+ public void indeterminate() {
+ file().indeterminate().update();
+ }
+
+ @Override
+ @ClientCallable
+ public void complete() {
+ file().complete().update();
+ }
+
+ @Override
+ @ClientCallable
+ public void progress(int progress) {
+ file().progress(progress).update();
+ }
+
+ @Override
+ @ClientCallable
+ public void status(String status) {
+ file().status(status).update();
+ }
+
+ @Override
+ @ClientCallable
+ public void errorMessage(String errorMessage) {
+ file().errorMessage(errorMessage).update();
+ }
+
+}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/ViewIT.java b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/ViewIT.java
new file mode 100644
index 0000000..660b7d0
--- /dev/null
+++ b/src/test/java/com/flowingcode/vaadin/addons/uploadhelper/it/ViewIT.java
@@ -0,0 +1,81 @@
+/*-
+ * #%L
+ * Upload Helper Add-on
+ * %%
+ * Copyright (C) 2022 - 2024 Flowing Code
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+package com.flowingcode.vaadin.addons.uploadhelper.it;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import com.flowingcode.vaadin.testbench.rpc.HasRpcSupport;
+import com.vaadin.flow.component.progressbar.testbench.ProgressBarElement;
+import com.vaadin.testbench.TestBenchElement;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ViewIT extends AbstractViewTest implements HasRpcSupport {
+
+ IntegrationCallables $server = createCallableProxy(IntegrationCallables.class);
+
+ public ViewIT() {
+ super("it");
+ }
+
+ private TestBenchElement file() {
+ return $("vaadin-upload-file").waitForFirst();
+ }
+
+ @Before
+ public void before() {
+ file();
+ }
+
+ @Test
+ public void indeterminate() {
+ $server.indeterminate();
+ assertTrue("has attribute indeterminate", file().hasAttribute("indeterminate"));
+ }
+
+ @Test
+ public void complete() {
+ $server.complete();
+ assertTrue("has attribute complete", file().hasAttribute("complete"));
+ }
+
+ @Test
+ public void errorMessage() {
+ $server.errorMessage("msg1");
+ assertTrue("has attribute error", file().hasAttribute("error"));
+ assertEquals("msg1",
+ file().$("div").withAttribute("part", "error").first().getText());
+ }
+
+ @Test
+ public void status() {
+ $server.status("msg2");
+ assertEquals("msg2",
+ file().$("div").withAttribute("part", "status").first().getText());
+ }
+
+ @Test
+ public void progress() {
+ $server.progress(42);
+ assertEquals(0.42, file().$(ProgressBarElement.class).first().getValue(), 0.001);
+ }
+
+}
diff --git a/src/test/resources/META-INF/frontend/styles/shared-styles.css b/src/test/resources/META-INF/frontend/styles/shared-styles.css
index 6680e2d..591fc71 100644
--- a/src/test/resources/META-INF/frontend/styles/shared-styles.css
+++ b/src/test/resources/META-INF/frontend/styles/shared-styles.css
@@ -1 +1,20 @@
-/*Demo styles*/
\ No newline at end of file
+/*-
+ * #%L
+ * Upload Helper Add-on
+ * %%
+ * Copyright (C) 2022 - 2024 Flowing Code
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+/*Demo styles*/