Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
34f34e9
Removed padding override in DialogUtil to allow application code add …
salmonb Dec 22, 2024
b00e0a2
Added SimpleDialogBuilder class
salmonb Dec 22, 2024
35ce04b
Added newToggleButton() factory class in I18nControls
salmonb Dec 22, 2024
5cb4ff7
Replaced File by Blob in Cloudinary
davidhello7772 Dec 28, 2024
5d8e352
Corrected equals method in DynamicEntity
davidhello7772 Dec 28, 2024
aa18fb3
Merge remote-tracking branch 'origin/staging' into staging
davidhello7772 Dec 28, 2024
be6d6d6
Initial international dictionaries creation
davidhello7772 Dec 30, 2024
a59deea
Added a test of (operationRequest == null) and return false if that's…
davidhello7772 Dec 30, 2024
f5d0553
Fixed issue for retrieving foreign entities from an updated entity cr…
salmonb Dec 30, 2024
7ca2602
Merge remote-tracking branch 'origin/staging' into staging
davidhello7772 Dec 30, 2024
30c102d
Merge branch 'staging' into dictionnary_change
davidhello7772 Dec 30, 2024
f1985b8
Commented LayoutUtil.setMaxSizeToPref() in DialogUtil.decorate()
salmonb Jan 1, 2025
f70846f
Added a parameter in CloudImageService to prevent cache to display an…
davidhello7772 Jan 1, 2025
b9f5fbf
Merge branch 'dictionnary_change' into staging
salmonb Jan 1, 2025
500a702
Ensured ClientImageService always wait for urlPattern to be loaded be…
salmonb Jan 1, 2025
9dd7c70
Added invalidate=true in Cloudinary to fix CDN image cache issue
salmonb Jan 1, 2025
12f9daa
Renamed file parameter to blob in Cloudinary API
salmonb Jan 3, 2025
50f39fa
Enabled json reply in Cloudinary
salmonb Jan 3, 2025
a0ce0fc
Added optional includeUnderlyingStore parameter (false by default) in…
salmonb Jan 3, 2025
1c3b5df
Changed the SQL requests to add the bookableScheduledItem Feature
davidhello7772 Jan 6, 2025
b58cc4e
Corrected the url pattern in ValidationSupport
davidhello7772 Jan 6, 2025
9d6f489
Added topological sort for deletes on UpdateStore submit
salmonb Jan 8, 2025
3467360
Merge remote-tracking branch 'origin/staging' into staging
davidhello7772 Jan 8, 2025
d5b725e
Fixed issues with topological sort for deletes on UpdateStore submit
salmonb Jan 9, 2025
4bf9a05
Merge remote-tracking branch 'origin/staging' into staging
davidhello7772 Jan 9, 2025
3dc1f2d
Fixed obscure issue with EntityBindings.hasChangesProperty()
davidhello7772 Jan 9, 2025
c0eccea
Fixed i18n default implementation: bracket interpretation was calling…
salmonb Jan 9, 2025
08570cc
Added a null test in applyCommittedChangesToUnderlyingStore of Update…
davidhello7772 Jan 11, 2025
5a8f0b9
Simplify the urlValidation in ValidationSupport
davidhello7772 Jan 11, 2025
ac07f18
Merge remote-tracking branch 'origin/staging' into staging
davidhello7772 Jan 11, 2025
295c4fa
Added few utility methods in EntityBindings
salmonb Jan 11, 2025
cb3a776
Fixed issues with entities implementation before going to prod
davidhello7772 Jan 13, 2025
0c0f067
Introduced setLoadedFieldValue() in Entity API
salmonb Jan 14, 2025
010b087
Added warning in UpdateStoreImpl when making changes during submit
salmonb Jan 15, 2025
8f4120a
Removed Entity.setLoadedFieldValue() (using setFieldValue() with Thre…
salmonb Jan 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

8 changes: 4 additions & 4 deletions webfx-stack-cloud-image-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,25 @@

<dependency>
<groupId>dev.webfx</groupId>
<artifactId>webfx-platform-conf</artifactId>
<artifactId>webfx-platform-blob</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>dev.webfx</groupId>
<artifactId>webfx-platform-console</artifactId>
<artifactId>webfx-platform-conf</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>dev.webfx</groupId>
<artifactId>webfx-platform-fetch</artifactId>
<artifactId>webfx-platform-console</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>dev.webfx</groupId>
<artifactId>webfx-platform-file</artifactId>
<artifactId>webfx-platform-fetch</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package dev.webfx.stack.cloud.image.impl.client;

import dev.webfx.platform.async.Future;
import dev.webfx.platform.async.Promise;
import dev.webfx.platform.blob.Blob;
import dev.webfx.platform.conf.ConfigLoader;
import dev.webfx.platform.console.Console;
import dev.webfx.platform.fetch.CorsMode;
import dev.webfx.platform.fetch.Fetch;
import dev.webfx.platform.fetch.FetchOptions;
import dev.webfx.platform.fetch.FormData;
import dev.webfx.platform.file.File;
import dev.webfx.platform.util.http.HttpMethod;
import dev.webfx.platform.util.http.HttpResponseStatus;
import dev.webfx.stack.cloud.image.CloudImageService;
Expand All @@ -23,8 +24,11 @@ public class ClientImageService implements CloudImageService {
private String uploadUrl;
private String deleteUrl;
private String urlPattern;
private final Future<Void> urlPatternFuture;

public ClientImageService() {
Promise<Void> urlPatternPromise = Promise.promise();
urlPatternFuture = urlPatternPromise.future();
ConfigLoader.onConfigLoaded(CONFIG_PATH, config -> {
existsUrl = config.getString("existsUrl");
uploadUrl = config.getString("uploadUrl");
Expand All @@ -33,45 +37,52 @@ public ClientImageService() {
Fetch.fetchText(urlPatternUrl, new FetchOptions()
.setMethod(HttpMethod.GET)
.setMode(CorsMode.NO_CORS)
)
.onFailure(Console::log)
.onSuccess(text -> urlPattern = text);
)
.onFailure(Console::log)
.onSuccess(text -> urlPattern = text)
.onComplete(ar -> urlPatternPromise.complete());
});
}

// Helper method to ensure that we return the future only when urlPattern is loaded (because the client may need to
// call CloudImageService.url() method - which requires urlPattern to be loaded - after returning the future).
private <T> Future<T> whenUrlPatternLoaded(Future<T> future) {
return urlPatternFuture.compose(v -> future);
}

public Future<Boolean> exists(String id) {
return Fetch.fetch(existsUrl, new FetchOptions()
.setMethod(HttpMethod.POST)
.setMode(CorsMode.NO_CORS)
.setBody(new FormData().append("id", id))
return whenUrlPatternLoaded(Fetch.fetch(existsUrl, new FetchOptions()
.setMethod(HttpMethod.POST)
.setMode(CorsMode.NO_CORS)
.setBody(new FormData().append("id", id))
).compose(response -> {
if (response.ok())
return Future.succeededFuture(response.status() == HttpResponseStatus.OK_200); // OK_200 = exists, NO_CONTENT_204 = doesn't exist
return Future.failedFuture("Failed to call " + existsUrl + ", status = " + response.statusText());
});
}));
}

public Future<Void> upload(File file, String id, boolean overwrite) {
return Fetch.fetch(uploadUrl, new FetchOptions()
.setMethod(HttpMethod.POST)
.setMode(CorsMode.NO_CORS)
.setBody(new FormData()
.append("id", id)
.append("overwrite", overwrite)
.append("file", file, id)
)
).map(response -> null);
public Future<Void> upload(Blob blob, String id, boolean overwrite) {
return whenUrlPatternLoaded(Fetch.fetch(uploadUrl, new FetchOptions()
.setMethod(HttpMethod.POST)
.setMode(CorsMode.NO_CORS)
.setBody(new FormData()
.append("id", id)
.append("overwrite", overwrite)
.append("file", blob, id)
)
).map(response -> null));
}

public Future<Void> delete(String id, boolean invalidate) {
return Fetch.fetch(deleteUrl, new FetchOptions()
.setMethod(HttpMethod.POST)
.setMode(CorsMode.NO_CORS)
.setBody(new FormData()
.append("id", id)
.append("invalidate", invalidate)
)
).map(response -> null);
return whenUrlPatternLoaded(Fetch.fetch(deleteUrl, new FetchOptions()
.setMethod(HttpMethod.POST)
.setMode(CorsMode.NO_CORS)
.setBody(new FormData()
.append("id", id)
.append("invalidate", invalidate)
)
).map(response -> null));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

// Direct dependencies modules
requires webfx.platform.async;
requires webfx.platform.blob;
requires webfx.platform.conf;
requires webfx.platform.console;
requires webfx.platform.fetch;
requires webfx.platform.file;
requires webfx.platform.util.http;
requires webfx.stack.cloud.image;

Expand Down
16 changes: 14 additions & 2 deletions webfx-stack-cloud-image-cloudinary/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,24 @@

<dependencies>

<dependency>
<groupId>dev.webfx</groupId>
<artifactId>webfx-platform-ast</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>dev.webfx</groupId>
<artifactId>webfx-platform-async</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>dev.webfx</groupId>
<artifactId>webfx-platform-blob</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>dev.webfx</groupId>
<artifactId>webfx-platform-conf</artifactId>
Expand All @@ -29,13 +41,13 @@

<dependency>
<groupId>dev.webfx</groupId>
<artifactId>webfx-platform-fetch</artifactId>
<artifactId>webfx-platform-console</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>dev.webfx</groupId>
<artifactId>webfx-platform-file</artifactId>
<artifactId>webfx-platform-fetch</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
package dev.webfx.stack.cloud.image.impl.cloudinary;

import dev.webfx.platform.ast.AST;
import dev.webfx.platform.ast.ReadOnlyAstObject;
import dev.webfx.platform.async.Future;
import dev.webfx.platform.blob.Blob;
import dev.webfx.platform.conf.ConfigLoader;
import dev.webfx.platform.console.Console;
import dev.webfx.platform.fetch.*;
import dev.webfx.platform.file.File;
import dev.webfx.platform.util.http.HttpHeaders;
import dev.webfx.platform.util.http.HttpMethod;
import dev.webfx.platform.util.Strings;
import dev.webfx.platform.util.collection.Collections;
import dev.webfx.platform.util.http.HttpHeaders;
import dev.webfx.platform.util.http.HttpMethod;
import dev.webfx.stack.cloud.image.impl.fetchbased.FetchBasedCloudImageService;
import dev.webfx.stack.hash.sha1.Sha1;

import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
* @author Bruno Salmon
*/
public class Cloudinary extends FetchBasedCloudImageService {

private static final boolean LOG_JSON_REPLY = true;
private static final String CONFIG_PATH = "webfx.stack.cloud.image.cloudinary";

private String cloudName;
Expand All @@ -43,17 +50,18 @@ public Future<Boolean> exists(String id) {
.map(Response::ok);
}

public Future<Void> upload(File file, String id, boolean overwrite) {
public Future<Void> upload(Blob blob, String id, boolean overwrite) {
return fetchJsonObject(
"https://api.cloudinary.com/v1_1/" + cloudName + "/image/upload",
HttpMethod.POST,
new FetchOptions().setBody(
signFormData(new FormData()
.append("public_id", id)
.append("overwrite", overwrite)
).append("file", file, id)
.append("invalidate", true) // Otherwise the new image might not be displayed immediately after upload
).append("file", blob, id)
)
).map(json -> null);
).map(json -> logJsonReply("upload", json));
}

public Future<Void> delete(String id, boolean invalidate) {
Expand All @@ -66,7 +74,14 @@ public Future<Void> delete(String id, boolean invalidate) {
.append("invalidate", invalidate)
)
)
).map(json -> null);
).map(json -> logJsonReply("delete", json));
}

private static Void logJsonReply(String operation, ReadOnlyAstObject jsonReply) {
if (LOG_JSON_REPLY) {
Console.log("[CLOUDINARY] - " + operation + " - json reply = " + AST.formatObject(jsonReply, "json"));
}
return null;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
module webfx.stack.cloud.image.cloudinary {

// Direct dependencies modules
requires webfx.platform.ast;
requires webfx.platform.async;
requires webfx.platform.blob;
requires webfx.platform.conf;
requires webfx.platform.console;
requires webfx.platform.fetch;
requires webfx.platform.file;
requires webfx.platform.util;
requires webfx.platform.util.http;
requires webfx.stack.cloud.image;
Expand Down
6 changes: 3 additions & 3 deletions webfx-stack-cloud-image/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@

<dependency>
<groupId>dev.webfx</groupId>
<artifactId>webfx-platform-fetch</artifactId>
<artifactId>webfx-platform-blob</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>dev.webfx</groupId>
<artifactId>webfx-platform-fetch-ast-json</artifactId>
<artifactId>webfx-platform-fetch</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>dev.webfx</groupId>
<artifactId>webfx-platform-file</artifactId>
<artifactId>webfx-platform-fetch-ast-json</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package dev.webfx.stack.cloud.image;

import dev.webfx.platform.ast.ReadOnlyAstObject;
import dev.webfx.platform.async.Future;
import dev.webfx.platform.file.File;
import dev.webfx.platform.blob.Blob;

/**
* @author Bruno Salmon
Expand All @@ -11,12 +10,15 @@ public interface CloudImageService {

Future<Boolean> exists(String id);

Future<Void> upload(File file, String id, boolean overwrite);
Future<Void> upload(Blob blob, String id, boolean overwrite);

Future<Void> delete(String id, boolean invalidate);

default String url(String source, int width, int height) {
String url = urlPattern().replace(":source", source);
String urlPattern = urlPattern();
if (urlPattern == null)
throw new IllegalStateException("[CloudImageService] urlPattern is null");
String url = urlPattern.replace(":source", source);
if (width > 0)
url = url.replace(":width", "" + width);
else
Expand All @@ -25,6 +27,9 @@ default String url(String source, int width, int height) {
url = url.replace(":height", "" + height);
else
url = url.replace("/h_:height", ""); // temporary

//We add a random parameter to prevent the cache to display an old image
url = url + "?t=" + System.currentTimeMillis();
return url;
}

Expand Down
2 changes: 1 addition & 1 deletion webfx-stack-cloud-image/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
// Direct dependencies modules
requires transitive webfx.platform.ast;
requires webfx.platform.async;
requires webfx.platform.blob;
requires webfx.platform.fetch;
requires webfx.platform.fetch.ast.json;
requires webfx.platform.file;
requires webfx.platform.util.http;

// Exported packages
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,8 @@ public static CheckBox newCheckBox(Object i18nKey, Object... args) {
return bindI18nProperties(new CheckBox(), i18nKey, args);
}

public static ToggleButton newToggleButton(Object i18nKey, Object... args) {
return bindI18nProperties(new ToggleButton(), i18nKey, args);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,12 @@ public <TK extends Enum<?> & TokenKey> Object interpretBracketsAndDefaultInToken
// the original language (ex: FR).
Object resolvedValue = getDictionaryTokenValueImpl(new I18nSubKey(sToken.substring(i1 + 1, i2), i18nKey), tokenKey, originalDictionary, false, originalDictionary, false, skipMessageLoading);
// If the bracket token has been resolved, we return it with the parts before and after the brackets
if (resolvedValue != null)
tokenValue = (i1 == 0 ? "" : sToken.substring(0, i1)) + resolvedValue + sToken.substring(i2 + 1);
if (resolvedValue != null) {
if (i1 == 0 && i2 == sToken.length() - 1) // except if there are no parts before and after the brackets
tokenValue = resolvedValue; // in which case we return the resolved object as is (possibly not a String)
else
tokenValue = (i1 == 0 ? "" : sToken.substring(0, i1)) + resolvedValue + sToken.substring(i2 + 1);
}
}
}
}
Expand Down Expand Up @@ -338,7 +342,7 @@ public void scheduleMessageLoading(Object i18nKey, boolean inDefaultLanguage) {
// (presumably in the same animation frame) we do the actual load of these keys.
dictionaryLoadingScheduled = UiScheduler.scheduleDeferred(() -> {
// Making a copy of the keys before clearing it for the next possible schedule
Set<Object> loadingKeys = new HashSet<>(keysToLoad);
Set<Object> loadingKeys = new HashSet<>(keysToLoad); // ConcurrentModificationException observed
keysToLoad.clear();
// Extracting the message keys to load from them (in case they are different)
Set<Object> messageKeysToLoad = loadingKeys.stream()
Expand Down
6 changes: 6 additions & 0 deletions webfx-stack-orm-entity-binding/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>dev.webfx</groupId>
<artifactId>webfx-platform-javatime-emul-j2cl</artifactId>
Expand Down
Loading