diff --git a/extensions/dashboard/sources/pom.xml b/extensions/dashboard/sources/pom.xml index 7fb115db..08b84a01 100644 --- a/extensions/dashboard/sources/pom.xml +++ b/extensions/dashboard/sources/pom.xml @@ -23,7 +23,7 @@ tools.dynamia.modules tools.dynamia.modules.parent - 26.2.0 + 26.2.1 ../../pom.xml @@ -38,12 +38,12 @@ tools.dynamia tools.dynamia.zk - 26.2.0 + 26.2.1 tools.dynamia.modules tools.dynamia.modules.saas.api - 26.2.0 + 26.2.1 diff --git a/extensions/email-sms/sources/core/pom.xml b/extensions/email-sms/sources/core/pom.xml index fbb9ce67..2935fb9b 100644 --- a/extensions/email-sms/sources/core/pom.xml +++ b/extensions/email-sms/sources/core/pom.xml @@ -23,7 +23,7 @@ tools.dynamia.modules.email.parent tools.dynamia.modules - 26.2.0 + 26.2.1 tools.dynamia.modules.email @@ -50,12 +50,12 @@ tools.dynamia tools.dynamia.domain.jpa - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.templates - 26.2.0 + 26.2.1 org.springframework diff --git a/extensions/email-sms/sources/pom.xml b/extensions/email-sms/sources/pom.xml index 9a155a64..a05efbbb 100644 --- a/extensions/email-sms/sources/pom.xml +++ b/extensions/email-sms/sources/pom.xml @@ -23,7 +23,7 @@ tools.dynamia.modules tools.dynamia.modules.parent - 26.2.0 + 26.2.1 ../../pom.xml @@ -85,7 +85,7 @@ tools.dynamia.modules tools.dynamia.modules.saas.jpa - 26.2.0 + 26.2.1 diff --git a/extensions/email-sms/sources/ui/pom.xml b/extensions/email-sms/sources/ui/pom.xml index 4980daa9..e6a0bc43 100644 --- a/extensions/email-sms/sources/ui/pom.xml +++ b/extensions/email-sms/sources/ui/pom.xml @@ -22,7 +22,7 @@ tools.dynamia.modules.email.parent tools.dynamia.modules - 26.2.0 + 26.2.1 DynamiaModules - Email UI @@ -34,12 +34,12 @@ tools.dynamia tools.dynamia.zk - 26.2.0 + 26.2.1 tools.dynamia.modules tools.dynamia.modules.email - 26.2.0 + 26.2.1 tools.dynamia.zk.addons diff --git a/extensions/entity-files/sources/core/pom.xml b/extensions/entity-files/sources/core/pom.xml index 91b5e6ed..9e0f70a4 100644 --- a/extensions/entity-files/sources/core/pom.xml +++ b/extensions/entity-files/sources/core/pom.xml @@ -22,7 +22,7 @@ tools.dynamia.modules.entityfiles.parent tools.dynamia.modules - 26.2.0 + 26.2.1 DynamiaModules - EntityFiles - Core tools.dynamia.modules.entityfiles @@ -54,20 +54,20 @@ tools.dynamia tools.dynamia.domain.jpa - 26.2.0 + 26.2.1 jar tools.dynamia tools.dynamia.io - 26.2.0 + 26.2.1 jar tools.dynamia tools.dynamia.web - 26.2.0 + 26.2.1 jar diff --git a/extensions/entity-files/sources/pom.xml b/extensions/entity-files/sources/pom.xml index fb9b64c8..bc277c33 100644 --- a/extensions/entity-files/sources/pom.xml +++ b/extensions/entity-files/sources/pom.xml @@ -23,7 +23,7 @@ tools.dynamia.modules tools.dynamia.modules.parent - 26.2.0 + 26.2.1 ../../pom.xml diff --git a/extensions/entity-files/sources/s3/pom.xml b/extensions/entity-files/sources/s3/pom.xml index 6669900b..df2309eb 100644 --- a/extensions/entity-files/sources/s3/pom.xml +++ b/extensions/entity-files/sources/s3/pom.xml @@ -23,7 +23,7 @@ tools.dynamia.modules tools.dynamia.modules.entityfiles.parent - 26.2.0 + 26.2.1 DynamiaModules - EntityFiles - S3 @@ -49,7 +49,7 @@ tools.dynamia.modules tools.dynamia.modules.entityfiles - 26.2.0 + 26.2.1 software.amazon.awssdk diff --git a/extensions/entity-files/sources/ui/pom.xml b/extensions/entity-files/sources/ui/pom.xml index 164f64b0..fd3eaa38 100644 --- a/extensions/entity-files/sources/ui/pom.xml +++ b/extensions/entity-files/sources/ui/pom.xml @@ -22,7 +22,7 @@ tools.dynamia.modules.entityfiles.parent tools.dynamia.modules - 26.2.0 + 26.2.1 DynamiaModules - EntityFiles UI tools.dynamia.modules.entityfiles.ui @@ -48,12 +48,12 @@ tools.dynamia.modules tools.dynamia.modules.entityfiles - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.zk - 26.2.0 + 26.2.1 jar diff --git a/extensions/file-importer/sources/core/pom.xml b/extensions/file-importer/sources/core/pom.xml index b21783fb..1dbb6fe0 100644 --- a/extensions/file-importer/sources/core/pom.xml +++ b/extensions/file-importer/sources/core/pom.xml @@ -23,7 +23,7 @@ tools.dynamia.modules.importer.parent tools.dynamia.modules - 26.2.0 + 26.2.1 Dynamia Modules - Importer Core tools.dynamia.modules.importer @@ -56,7 +56,7 @@ tools.dynamia tools.dynamia.reports - 26.2.0 + 26.2.1 diff --git a/extensions/file-importer/sources/pom.xml b/extensions/file-importer/sources/pom.xml index 8bc9ed4c..248a8970 100644 --- a/extensions/file-importer/sources/pom.xml +++ b/extensions/file-importer/sources/pom.xml @@ -26,7 +26,7 @@ tools.dynamia.modules tools.dynamia.modules.parent - 26.2.0 + 26.2.1 ../../pom.xml diff --git a/extensions/file-importer/sources/ui/pom.xml b/extensions/file-importer/sources/ui/pom.xml index 354e8625..4ece0470 100644 --- a/extensions/file-importer/sources/ui/pom.xml +++ b/extensions/file-importer/sources/ui/pom.xml @@ -23,7 +23,7 @@ tools.dynamia.modules.importer.parent tools.dynamia.modules - 26.2.0 + 26.2.1 Dynamia Modules - Importer UI tools.dynamia.modules.importer.ui @@ -55,13 +55,13 @@ tools.dynamia tools.dynamia.zk - 26.2.0 + 26.2.1 tools.dynamia.modules tools.dynamia.modules.importer - 26.2.0 + 26.2.1 diff --git a/extensions/finances/sources/api/pom.xml b/extensions/finances/sources/api/pom.xml index 51c317e1..8c94ee9b 100644 --- a/extensions/finances/sources/api/pom.xml +++ b/extensions/finances/sources/api/pom.xml @@ -26,7 +26,7 @@ tools.dynamia.modules tools.dynamia.modules.finances.parent - 26.2.0 + 26.2.1 Dynamia Modules - Finances API diff --git a/extensions/finances/sources/pom.xml b/extensions/finances/sources/pom.xml index f0a82eb9..3d97e12d 100644 --- a/extensions/finances/sources/pom.xml +++ b/extensions/finances/sources/pom.xml @@ -26,7 +26,7 @@ tools.dynamia.modules tools.dynamia.modules.parent - 26.2.0 + 26.2.1 ../../pom.xml diff --git a/extensions/pom.xml b/extensions/pom.xml index 613075c8..ec366e9a 100644 --- a/extensions/pom.xml +++ b/extensions/pom.xml @@ -6,7 +6,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../pom.xml diff --git a/extensions/reports/sources/api/pom.xml b/extensions/reports/sources/api/pom.xml index 0dea6198..f027acff 100644 --- a/extensions/reports/sources/api/pom.xml +++ b/extensions/reports/sources/api/pom.xml @@ -23,7 +23,7 @@ tools.dynamia.modules tools.dynamia.modules.reports.parent - 26.2.0 + 26.2.1 DynamiaModules - Reports API diff --git a/extensions/reports/sources/core/pom.xml b/extensions/reports/sources/core/pom.xml index 3e9e43ab..5b9b70bd 100644 --- a/extensions/reports/sources/core/pom.xml +++ b/extensions/reports/sources/core/pom.xml @@ -23,7 +23,7 @@ tools.dynamia.modules tools.dynamia.modules.reports.parent - 26.2.0 + 26.2.1 DynamiaModules - Reports Core @@ -50,17 +50,17 @@ tools.dynamia.modules tools.dynamia.modules.reports.api - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.domain.jpa - 26.2.0 + 26.2.1 tools.dynamia.modules tools.dynamia.modules.saas.jpa - 26.2.0 + 26.2.1 org.springframework @@ -69,12 +69,12 @@ tools.dynamia tools.dynamia.reports - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.templates - 26.2.0 + 26.2.1 compile diff --git a/extensions/reports/sources/pom.xml b/extensions/reports/sources/pom.xml index 65bad709..124b0d59 100644 --- a/extensions/reports/sources/pom.xml +++ b/extensions/reports/sources/pom.xml @@ -23,7 +23,7 @@ tools.dynamia.modules tools.dynamia.modules.parent - 26.2.0 + 26.2.1 ../../pom.xml diff --git a/extensions/reports/sources/ui/pom.xml b/extensions/reports/sources/ui/pom.xml index 34366b55..1990924f 100644 --- a/extensions/reports/sources/ui/pom.xml +++ b/extensions/reports/sources/ui/pom.xml @@ -23,7 +23,7 @@ tools.dynamia.modules tools.dynamia.modules.reports.parent - 26.2.0 + 26.2.1 DynamiaModules - Reports UI @@ -49,12 +49,12 @@ tools.dynamia.modules tools.dynamia.modules.reports.core - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.zk - 26.2.0 + 26.2.1 io.swagger.core.v3 diff --git a/extensions/saas/sources/api/pom.xml b/extensions/saas/sources/api/pom.xml index c4cf3d6a..59a492ab 100644 --- a/extensions/saas/sources/api/pom.xml +++ b/extensions/saas/sources/api/pom.xml @@ -26,7 +26,7 @@ tools.dynamia.modules tools.dynamia.modules.saas.parent - 26.2.0 + 26.2.1 @@ -55,7 +55,7 @@ tools.dynamia tools.dynamia.actions - 26.2.0 + 26.2.1 org.springframework.boot diff --git a/extensions/saas/sources/core/pom.xml b/extensions/saas/sources/core/pom.xml index ea1687f1..c554b18e 100644 --- a/extensions/saas/sources/core/pom.xml +++ b/extensions/saas/sources/core/pom.xml @@ -22,7 +22,7 @@ tools.dynamia.modules tools.dynamia.modules.saas.parent - 26.2.0 + 26.2.1 DynamiaModules - SaaS Core @@ -49,18 +49,18 @@ tools.dynamia.modules tools.dynamia.modules.saas.api - 26.2.0 + 26.2.1 tools.dynamia.modules tools.dynamia.modules.saas.jpa - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.integration - 26.2.0 + 26.2.1 @@ -86,7 +86,7 @@ tools.dynamia.modules tools.dynamia.modules.entityfiles - 26.2.0 + 26.2.1 org.hibernate.orm diff --git a/extensions/saas/sources/jpa/pom.xml b/extensions/saas/sources/jpa/pom.xml index c146e923..29e94c43 100644 --- a/extensions/saas/sources/jpa/pom.xml +++ b/extensions/saas/sources/jpa/pom.xml @@ -24,7 +24,7 @@ tools.dynamia.modules.saas.parent tools.dynamia.modules - 26.2.0 + 26.2.1 DynamiaModules - SaaS JPA @@ -35,12 +35,12 @@ tools.dynamia.modules tools.dynamia.modules.saas.api - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.domain.jpa - 26.2.0 + 26.2.1 diff --git a/extensions/saas/sources/pom.xml b/extensions/saas/sources/pom.xml index 8b473036..ad180d50 100644 --- a/extensions/saas/sources/pom.xml +++ b/extensions/saas/sources/pom.xml @@ -23,7 +23,7 @@ tools.dynamia.modules tools.dynamia.modules.parent - 26.2.0 + 26.2.1 ../../pom.xml diff --git a/extensions/saas/sources/remote/pom.xml b/extensions/saas/sources/remote/pom.xml index 3f036348..a18adc53 100644 --- a/extensions/saas/sources/remote/pom.xml +++ b/extensions/saas/sources/remote/pom.xml @@ -25,7 +25,7 @@ tools.dynamia.modules.saas.parent tools.dynamia.modules - 26.2.0 + 26.2.1 @@ -38,7 +38,7 @@ tools.dynamia.modules tools.dynamia.modules.saas.jpa - 26.2.0 + 26.2.1 diff --git a/extensions/saas/sources/ui/pom.xml b/extensions/saas/sources/ui/pom.xml index 273b57c6..4013e7f8 100644 --- a/extensions/saas/sources/ui/pom.xml +++ b/extensions/saas/sources/ui/pom.xml @@ -22,7 +22,7 @@ tools.dynamia.modules tools.dynamia.modules.saas.parent - 26.2.0 + 26.2.1 DynamiaModules - SaaS UI tools.dynamia.modules.saas.ui @@ -54,12 +54,12 @@ tools.dynamia tools.dynamia.zk - 26.2.0 + 26.2.1 tools.dynamia.modules tools.dynamia.modules.saas - 26.2.0 + 26.2.1 @@ -70,7 +70,7 @@ tools.dynamia.modules tools.dynamia.modules.entityfiles.ui - 26.2.0 + 26.2.1 diff --git a/extensions/security/sources/core/pom.xml b/extensions/security/sources/core/pom.xml index ec578f13..38b8adb8 100644 --- a/extensions/security/sources/core/pom.xml +++ b/extensions/security/sources/core/pom.xml @@ -17,7 +17,7 @@ tools.dynamia.modules tools.dynamia.modules.security.parent - 26.2.0 + 26.2.1 4.0.0 @@ -32,34 +32,34 @@ tools.dynamia.modules tools.dynamia.modules.saas.api - 26.2.0 + 26.2.1 tools.dynamia.modules tools.dynamia.modules.entityfiles - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.domain.jpa - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.domain - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.integration - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.web - 26.2.0 + 26.2.1 diff --git a/extensions/security/sources/pom.xml b/extensions/security/sources/pom.xml index da962e15..40cdb7a9 100644 --- a/extensions/security/sources/pom.xml +++ b/extensions/security/sources/pom.xml @@ -19,7 +19,7 @@ tools.dynamia.modules tools.dynamia.modules.parent - 26.2.0 + 26.2.1 ../../pom.xml diff --git a/extensions/security/sources/ui/pom.xml b/extensions/security/sources/ui/pom.xml index 94c237f9..13da8823 100644 --- a/extensions/security/sources/ui/pom.xml +++ b/extensions/security/sources/ui/pom.xml @@ -17,7 +17,7 @@ tools.dynamia.modules tools.dynamia.modules.security.parent - 26.2.0 + 26.2.1 DynamiaModules - Security UI @@ -44,18 +44,18 @@ tools.dynamia.modules tools.dynamia.modules.security - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.zk - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.app - 26.2.0 + 26.2.1 diff --git a/platform/app/pom.xml b/platform/app/pom.xml index 9177e288..ba929956 100644 --- a/platform/app/pom.xml +++ b/platform/app/pom.xml @@ -23,7 +23,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../../pom.xml @@ -74,58 +74,58 @@ tools.dynamia tools.dynamia.actions - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.commons - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.crud - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.domain - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.integration - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.io - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.navigation - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.reports - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.templates - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.viewers - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.web - 26.2.0 + 26.2.1 @@ -205,7 +205,7 @@ tools.dynamia tools.dynamia.domain.jpa - 26.2.0 + 26.2.1 test diff --git a/platform/core/actions/pom.xml b/platform/core/actions/pom.xml index 18c6a2b1..2da9bc25 100644 --- a/platform/core/actions/pom.xml +++ b/platform/core/actions/pom.xml @@ -23,7 +23,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../../../pom.xml @@ -65,12 +65,12 @@ tools.dynamia tools.dynamia.integration - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.commons - 26.2.0 + 26.2.1 diff --git a/platform/core/commons/pom.xml b/platform/core/commons/pom.xml index 60ed9d56..9ea8ef26 100644 --- a/platform/core/commons/pom.xml +++ b/platform/core/commons/pom.xml @@ -25,7 +25,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../../../pom.xml DynamiaTools - Commons diff --git a/platform/core/crud/pom.xml b/platform/core/crud/pom.xml index 4e3717a1..aab7ce74 100644 --- a/platform/core/crud/pom.xml +++ b/platform/core/crud/pom.xml @@ -23,7 +23,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../../../pom.xml @@ -62,23 +62,23 @@ tools.dynamia tools.dynamia.actions - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.viewers - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.navigation - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.domain.jpa - 26.2.0 + 26.2.1 test diff --git a/platform/core/domain-jpa/pom.xml b/platform/core/domain-jpa/pom.xml index c262e843..adb17148 100644 --- a/platform/core/domain-jpa/pom.xml +++ b/platform/core/domain-jpa/pom.xml @@ -23,7 +23,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../../../pom.xml @@ -65,7 +65,7 @@ tools.dynamia tools.dynamia.domain - 26.2.0 + 26.2.1 diff --git a/platform/core/domain/pom.xml b/platform/core/domain/pom.xml index 2b43ee05..0886a430 100644 --- a/platform/core/domain/pom.xml +++ b/platform/core/domain/pom.xml @@ -26,7 +26,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../../../pom.xml DynamiaTools - Domain diff --git a/platform/core/integration/pom.xml b/platform/core/integration/pom.xml index 89179ce7..3af75b1d 100644 --- a/platform/core/integration/pom.xml +++ b/platform/core/integration/pom.xml @@ -27,7 +27,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../../../pom.xml @@ -67,7 +67,7 @@ tools.dynamia tools.dynamia.commons - 26.2.0 + 26.2.1 provided diff --git a/platform/core/io/pom.xml b/platform/core/io/pom.xml index ad279ff8..bef5c458 100644 --- a/platform/core/io/pom.xml +++ b/platform/core/io/pom.xml @@ -28,7 +28,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../../../pom.xml diff --git a/platform/core/navigation/pom.xml b/platform/core/navigation/pom.xml index 99ce2190..1d09b6e4 100644 --- a/platform/core/navigation/pom.xml +++ b/platform/core/navigation/pom.xml @@ -23,7 +23,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../../../pom.xml @@ -63,17 +63,17 @@ tools.dynamia tools.dynamia.commons - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.integration - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.actions - 26.2.0 + 26.2.1 diff --git a/platform/core/reports/pom.xml b/platform/core/reports/pom.xml index 4b926bf7..accc7d0a 100644 --- a/platform/core/reports/pom.xml +++ b/platform/core/reports/pom.xml @@ -26,7 +26,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../../../pom.xml diff --git a/platform/core/reports/src/main/java/tools/dynamia/reports/ExporterFieldLoader.java b/platform/core/reports/src/main/java/tools/dynamia/reports/ExporterFieldLoader.java index 7cba8fee..ddab1481 100644 --- a/platform/core/reports/src/main/java/tools/dynamia/reports/ExporterFieldLoader.java +++ b/platform/core/reports/src/main/java/tools/dynamia/reports/ExporterFieldLoader.java @@ -39,7 +39,7 @@ * case "status": * return user.isActive() ? "Active" : "Inactive"; * default: - * return BeanUtils.getFieldValue(field, user); + * return {@link tools.dynamia.commons.ObjectOperations}.getFieldValue(field, user); * } * } * } diff --git a/platform/core/templates/pom.xml b/platform/core/templates/pom.xml index cbda6cff..77e09127 100644 --- a/platform/core/templates/pom.xml +++ b/platform/core/templates/pom.xml @@ -23,7 +23,7 @@ tools.dynamia.parent tools.dynamia - 26.2.0 + 26.2.1 ../../../pom.xml @@ -64,12 +64,12 @@ tools.dynamia tools.dynamia.integration - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.commons - 26.2.0 + 26.2.1 diff --git a/platform/core/viewers/pom.xml b/platform/core/viewers/pom.xml index 7e24ce76..4e1a90fb 100644 --- a/platform/core/viewers/pom.xml +++ b/platform/core/viewers/pom.xml @@ -25,7 +25,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../../../pom.xml @@ -67,27 +67,27 @@ tools.dynamia tools.dynamia.commons - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.integration - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.io - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.domain - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.actions - 26.2.0 + 26.2.1 org.yaml diff --git a/platform/core/viewers/src/main/java/tools/dynamia/viewers/ViewDescriptorBuilder.java b/platform/core/viewers/src/main/java/tools/dynamia/viewers/ViewDescriptorBuilder.java index abe5600c..de0cf7f5 100644 --- a/platform/core/viewers/src/main/java/tools/dynamia/viewers/ViewDescriptorBuilder.java +++ b/platform/core/viewers/src/main/java/tools/dynamia/viewers/ViewDescriptorBuilder.java @@ -27,28 +27,63 @@ import java.util.function.Supplier; /** - * The Class ViewDescriptorBuilder. + * Builder class for creating and configuring ViewDescriptor instances using a fluent API. + * This builder provides a convenient way to programmatically construct view descriptors + * for forms, tables, and other view types without using YAML configuration files. + * + *

The builder follows the Builder pattern, allowing method chaining for a more + * readable and maintainable code structure. It supports field configuration, layout + * customization, field grouping, and parameter specification.

+ * + * Example usage: + *
{@code
+ * ViewDescriptor descriptor = ViewDescriptorBuilder
+ *     .viewDescriptor("form", Customer.class)
+ *     .fields(
+ *         field("name").label("Customer Name"),
+ *         field("email").component("email"),
+ *         field("phone")
+ *     )
+ *     .layout("columns", 2)
+ *     .build();
+ * }
* * @author Mario A. Serrano Leones + * @see ViewDescriptor + * @see FieldBuilder + * @see FieldGroupBuilder */ @SuppressWarnings("unchecked") public class ViewDescriptorBuilder { /** - * The vd. + * The internal view descriptor being built. */ protected DefaultViewDescriptor descriptor; + /** + * Protected constructor to enforce the use of static factory methods. + */ protected ViewDescriptorBuilder() { } /** - * View descriptor. + * Creates a new ViewDescriptorBuilder for building view descriptors programmatically. * - * @param type the type - * @param beanClass the bean class - * @param autofields the autofields - * @return the view descriptor builder + *

This factory method initializes a builder with the specified view type and bean class, + * allowing you to control whether fields should be automatically detected from the bean class.

+ * + * @param type the view type (e.g., "form", "table", "tree") + * @param beanClass the Java class representing the entity or bean for this view + * @param autofields if true, fields will be automatically detected from the bean class; + * if false, only explicitly added fields will be included + * @return a new ViewDescriptorBuilder instance configured with the specified parameters + * + * Example: + *
{@code
+     * ViewDescriptorBuilder builder = ViewDescriptorBuilder
+     *     .viewDescriptor("table", Product.class, true);
+     * }
*/ public static ViewDescriptorBuilder viewDescriptor(String type, Class beanClass, boolean autofields) { ViewDescriptorBuilder builder = new ViewDescriptorBuilder(); @@ -57,11 +92,22 @@ public static ViewDescriptorBuilder viewDescriptor(String type, Class beanClass, } /** - * View descriptor. + * Creates a new ViewDescriptorBuilder with automatic field detection enabled by default. + * + *

This is a convenience method that calls {@link #viewDescriptor(String, Class, boolean)} + * with autofields set to true.

* - * @param type the type - * @param beanClass the bean class - * @return the view descriptor builder + * @param type the view type (e.g., "form", "table", "tree") + * @param beanClass the Java class representing the entity or bean for this view + * @return a new ViewDescriptorBuilder instance with autofields enabled + * + * Example: + *
{@code
+     * ViewDescriptor descriptor = ViewDescriptorBuilder
+     *     .viewDescriptor("form", Customer.class)
+     *     .layout("columns", 3)
+     *     .build();
+     * }
*/ public static ViewDescriptorBuilder viewDescriptor(String type, Class beanClass) { ViewDescriptorBuilder builder = new ViewDescriptorBuilder(); @@ -69,22 +115,40 @@ public static ViewDescriptorBuilder viewDescriptor(String type, Class beanClass) return builder; } + /** + * Creates a new ViewDescriptorBuilder without a bean class, useful for generic views. + * + *

This method is suitable when creating view descriptors that don't map to a specific + * Java bean or entity, such as custom views or composite views.

+ * + * @param type the view type (e.g., "form", "table", "custom") + * @return a new ViewDescriptorBuilder instance without a bean class + */ public static ViewDescriptorBuilder viewDescriptor(String type) { ViewDescriptorBuilder builder = new ViewDescriptorBuilder(); builder.descriptor = new DefaultViewDescriptor(null, type); return builder; } + /** + * Sets the unique identifier for this view descriptor. + * + * @param id the unique identifier for the view descriptor + * @return this builder instance for method chaining + */ public ViewDescriptorBuilder id(String id) { descriptor.setId(id); return this; } /** - * Customizer. + * Sets a custom ViewCustomizer class for this view descriptor. + * + *

ViewCustomizers allow for dynamic modification of view descriptors at runtime, + * enabling custom logic to adjust field visibility, layout, or other view properties.

* - * @param customizer the customizers - * @return the view descriptor builder + * @param customizer the ViewCustomizer class to apply custom modifications + * @return this builder instance for method chaining */ public ViewDescriptorBuilder customizer(Class customizer) { descriptor.setViewCustomizerClass(customizer); @@ -92,10 +156,13 @@ public ViewDescriptorBuilder customizer(Class customiz } /** - * Sort fields. + * Defines the order in which fields should be displayed in the view. * - * @param fields the fields - * @return the view descriptor builder + *

This method allows you to specify a custom ordering for the fields, + * overriding their default or alphabetical order.

+ * + * @param fields the field names in the desired display order + * @return this builder instance for method chaining */ public ViewDescriptorBuilder sortFields(String... fields) { descriptor.sortFields(Arrays.asList(fields)); @@ -103,10 +170,13 @@ public ViewDescriptorBuilder sortFields(String... fields) { } /** - * Hidden. + * Marks the specified fields as hidden in the view. + * + *

Hidden fields will not be displayed to the user but may still be present + * in the underlying data structure for processing purposes.

* - * @param fields the fields - * @return the view descriptor builder + * @param fields the names of the fields to hide + * @return this builder instance for method chaining */ public ViewDescriptorBuilder hidden(String... fields) { descriptor.hideFields(fields); @@ -114,10 +184,22 @@ public ViewDescriptorBuilder hidden(String... fields) { } /** - * Fields. + * Adds multiple fields to the view descriptor using FieldBuilder instances. + * + *

This method allows you to configure fields with specific properties such as labels, + * components, and parameters before adding them to the view.

* - * @param fields the fields - * @return the view descriptor builder + * @param fields an array of FieldBuilder instances defining the fields to add + * @return this builder instance for method chaining + * + * Example: + *
{@code
+     * builder.fields(
+     *     field("name").label("Full Name"),
+     *     field("email").component("email"),
+     *     field("phone")
+     * );
+     * }
*/ public ViewDescriptorBuilder fields(FieldBuilder... fields) { for (FieldBuilder field : fields) { @@ -127,10 +209,18 @@ public ViewDescriptorBuilder fields(FieldBuilder... fields) { } /** - * Add fields usind a {@link Supplier} + * Adds fields to the view descriptor using a Supplier that provides a list of Field instances. + * + *

This method is useful when fields are generated dynamically or retrieved from an + * external source at runtime.

+ * + * @param fieldsSupplier a Supplier that returns a list of Field instances to add + * @return this builder instance for method chaining * - * @param fieldsSupplier should return a list of field - * @return builder + * Example: + *
{@code
+     * builder.fields(() -> getFieldsFromConfiguration());
+     * }
*/ public ViewDescriptorBuilder fields(Supplier> fieldsSupplier) { fieldsSupplier.get().forEach(descriptor::addField); @@ -138,10 +228,21 @@ public ViewDescriptorBuilder fields(Supplier> fieldsSupplier) { } /** - * Groups. + * Adds field groups to the view descriptor for organizing fields into logical sections. * - * @param groups the groups - * @return the view descriptor builder + *

Field groups help structure complex forms by grouping related fields together, + * improving the user interface organization and usability.

+ * + * @param groups an array of FieldGroupBuilder instances defining the field groups + * @return this builder instance for method chaining + * + * Example: + *
{@code
+     * builder.groups(
+     *     group("personal", "Personal Information").fields("name", "email"),
+     *     group("address", "Address Details").fields("street", "city", "zipCode")
+     * );
+     * }
*/ public ViewDescriptorBuilder groups(FieldGroupBuilder... groups) { for (FieldGroupBuilder fieldGroupBuilder : groups) { @@ -154,10 +255,18 @@ public ViewDescriptorBuilder groups(FieldGroupBuilder... groups) { } /** - * Params. + * Adds multiple parameters to the view descriptor as key-value pairs. + * + *

Parameters are used to configure view-level settings and behaviors. This method + * accepts varargs in key-value format (key1, value1, key2, value2, ...).

* - * @param keyValue the key value - * @return the view descriptor builder + * @param keyValue the parameters in key-value pairs (must be an even number of arguments) + * @return this builder instance for method chaining + * + * Example: + *
{@code
+     * builder.params("readOnly", true, "showHeader", false);
+     * }
*/ public ViewDescriptorBuilder params(Object... keyValue) { Map params = MapBuilder.put(keyValue); @@ -167,10 +276,19 @@ public ViewDescriptorBuilder params(Object... keyValue) { } /** - * Add global parameter to descriptor + * Adds a single global parameter to the view descriptor. + * + *

This method allows you to add individual parameters one at a time, + * which is useful for conditional parameter addition.

* - * @param key param - * @param value value + * @param key the parameter key or name + * @param value the parameter value + * @return this builder instance for method chaining + * + * Example: + *
{@code
+     * builder.addParam("customStyle", "border: 1px solid red");
+     * }
*/ public ViewDescriptorBuilder addParam(String key, Object value) { descriptor.getParams().put(key, value); @@ -178,10 +296,18 @@ public ViewDescriptorBuilder addParam(String key, Object value) { } /** - * Layout. + * Configures layout parameters for the view descriptor. + * + *

Layout parameters control how fields are arranged and displayed in the view. + * Common parameters include columns, spacing, alignment, and responsive behavior.

* - * @param keyValue the key value - * @return the view descriptor builder + * @param keyValue the layout parameters in key-value pairs (key1, value1, key2, value2, ...) + * @return this builder instance for method chaining + * + * Example: + *
{@code
+     * builder.layout("columns", 3, "spacing", 10);
+     * }
*/ @SuppressWarnings("unchecked") public ViewDescriptorBuilder layout(Object... keyValue) { @@ -192,11 +318,19 @@ public ViewDescriptorBuilder layout(Object... keyValue) { } /** - * Add param to layout + * Adds a single parameter to the layout configuration. + * + *

This method allows you to add individual layout parameters one at a time, + * which is useful for conditional layout configuration.

+ * + * @param key the layout parameter key or name + * @param value the layout parameter value + * @return this builder instance for method chaining * - * @param key - * @param value - * @return + * Example: + *
{@code
+     * builder.addLayoutParam("responsive", true);
+     * }
*/ public ViewDescriptorBuilder addLayoutParam(String key, Object value) { descriptor.getLayout().getParams().put(key, value); @@ -204,33 +338,57 @@ public ViewDescriptorBuilder addLayoutParam(String key, Object value) { } /** - * Field. + * Creates a new FieldBuilder instance for defining a field in the view. * - * @param name the name - * @return the field builder + *

This factory method creates a basic field with the specified name. + * Additional properties like label and component can be configured using the builder's fluent API.

+ * + * @param name the field name (typically matches a property name in the bean class) + * @return a new FieldBuilder instance for configuring the field + * + * Example: + *
{@code
+     * FieldBuilder nameField = field("name");
+     * }
*/ public static FieldBuilder field(String name) { return field(name, null); } /** - * Field. + * Creates a new FieldBuilder instance with a custom label. + * + *

This factory method allows you to specify a user-friendly label for the field, + * which will be displayed in the UI instead of the raw field name.

* - * @param name the name - * @param label the label - * @return the field builder + * @param name the field name (typically matches a property name in the bean class) + * @param label the display label for the field (human-readable text) + * @return a new FieldBuilder instance configured with the specified name and label + * + * Example: + *
{@code
+     * FieldBuilder emailField = field("email", "Email Address");
+     * }
*/ public static FieldBuilder field(String name, String label) { return field(name, label, null); } /** - * Field. + * Creates a new FieldBuilder instance with label and custom component type. + * + *

This factory method allows full customization of the field by specifying + * the display label and the UI component type to be used for rendering.

+ * + * @param name the field name (typically matches a property name in the bean class) + * @param label the display label for the field (human-readable text) + * @param component the component type to use for rendering (e.g., "textbox", "email", "datepicker") + * @return a new FieldBuilder instance configured with the specified properties * - * @param name the name - * @param label the label - * @param component the component - * @return the field builder + * Example: + *
{@code
+     * FieldBuilder passwordField = field("password", "Password", "password");
+     * }
*/ public static FieldBuilder field(String name, String label, String component) { FieldBuilder fb = new FieldBuilder(name); @@ -239,69 +397,120 @@ public static FieldBuilder field(String name, String label, String component) { } /** - * Group. + * Creates a new FieldGroupBuilder for organizing fields into a named group. * - * @param name the name - * @return the field group builder + *

This factory method creates a field group using the provided name as both + * the internal identifier and the display label.

+ * + * @param name the group name (used as both identifier and display label) + * @return a new FieldGroupBuilder instance for configuring the field group */ public static FieldGroupBuilder group(String name) { return group(name, name); } /** - * Group. + * Creates a new FieldGroupBuilder with a custom display label. + * + *

This factory method creates a field group with separate name (identifier) + * and label (display text) values.

* - * @param name the name - * @param label the label - * @return the field group builder + * @param name the group identifier (used internally) + * @param label the display label for the group (shown to users) + * @return a new FieldGroupBuilder instance configured with name and label */ public static FieldGroupBuilder group(String name, String label) { return group(name, label, null); } /** - * Group. + * Creates a new FieldGroupBuilder with label and icon. + * + *

This factory method creates a fully customized field group with name, + * display label, and an optional icon for visual representation.

* - * @param name the name - * @param label the label - * @param icon the icon - * @return the field group builder + * @param name the group identifier (used internally) + * @param label the display label for the group (shown to users) + * @param icon the icon identifier or path to display with the group (optional) + * @return a new FieldGroupBuilder instance configured with name, label, and icon */ public static FieldGroupBuilder group(String name, String label, String icon) { return new FieldGroupBuilder(name); } /** - * Builds the. + * Builds and returns the configured ViewDescriptor instance. * - * @return the view descriptor + *

This method completes the building process and returns the final + * ViewDescriptor object with all configured properties, fields, groups, + * layout, and parameters.

+ * + * @return the fully configured ViewDescriptor instance */ public ViewDescriptor build() { return descriptor; } + /** + * Configures whether fields should be automatically detected from the bean class. + * + *

When autofields is true, the framework will introspect the bean class + * and automatically create field descriptors for its properties. When false, + * only explicitly defined fields will be included in the view.

+ * + * @param autofields true to enable automatic field detection, false otherwise + * @return this builder instance for method chaining + */ public ViewDescriptorBuilder autofields(boolean autofields) { descriptor.setAutofields(autofields); return this; } /** - * Creates a new ViewDescriptorBuilder from an existing ViewDescriptor + * Creates a new ViewDescriptorBuilder by copying an existing ViewDescriptor. + * + *

This factory method creates a builder initialized with all properties, fields, + * field groups, layout parameters, and actions from the source descriptor. This is useful + * for creating variations of existing descriptors or extending them with additional configuration.

* - * @param other the other - * @return the view descriptor builder + * @param other the source ViewDescriptor to copy from + * @return a new ViewDescriptorBuilder instance initialized with the source descriptor's configuration + * + * Example: + *
{@code
+     * ViewDescriptor existing = getExistingDescriptor();
+     * ViewDescriptor modified = ViewDescriptorBuilder
+     *     .from(existing)
+     *     .addParam("readOnly", true)
+     *     .build();
+     * }
*/ public static ViewDescriptorBuilder from(ViewDescriptor other) { return from(other.getViewTypeName(), other.getBeanClass(), other); } /** - * Creates a new ViewDescriptorBuilder from an existing ViewDescriptor + * Creates a new ViewDescriptorBuilder by copying an existing ViewDescriptor with a different view type and bean class. + * + *

This factory method creates a builder initialized with all properties from the source descriptor, + * but allows you to override the view type and bean class. This is particularly useful when you need + * to create a descriptor for a different view type (e.g., converting a "form" descriptor to a "table" descriptor) + * or adapt a descriptor to work with a different entity class while preserving the field configuration.

+ * + * @param viewType the new view type to use (e.g., "form", "table", "tree") + * @param beanClass the new bean class to associate with the descriptor + * @param other the source ViewDescriptor to copy configuration from + * @return a new ViewDescriptorBuilder instance with the specified view type and bean class, + * initialized with the source descriptor's configuration * - * @param viewType the view type - * @param beanClass the bean class - * @param other the other - * @return the view descriptor builder + * Example: + *
{@code
+     * ViewDescriptor formDescriptor = getFormDescriptor();
+     * ViewDescriptor tableDescriptor = ViewDescriptorBuilder
+     *     .from("table", Customer.class, formDescriptor)
+     *     .hidden("description")
+     *     .build();
+     * }
*/ public static ViewDescriptorBuilder from(String viewType, Class beanClass, ViewDescriptor other) { ViewDescriptorBuilder builder = new ViewDescriptorBuilder(); diff --git a/platform/core/web/pom.xml b/platform/core/web/pom.xml index cc9924f5..6becc541 100644 --- a/platform/core/web/pom.xml +++ b/platform/core/web/pom.xml @@ -29,7 +29,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../../../pom.xml @@ -88,27 +88,27 @@ tools.dynamia tools.dynamia.commons - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.integration - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.navigation - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.viewers - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.crud - 26.2.0 + 26.2.1 org.springframework diff --git a/platform/core/web/src/main/java/tools/dynamia/web/controllers/PeriodicTaskExecutorRestController.java b/platform/core/web/src/main/java/tools/dynamia/web/controllers/PeriodicTaskExecutorRestController.java index 438c8157..7c050f72 100644 --- a/platform/core/web/src/main/java/tools/dynamia/web/controllers/PeriodicTaskExecutorRestController.java +++ b/platform/core/web/src/main/java/tools/dynamia/web/controllers/PeriodicTaskExecutorRestController.java @@ -7,6 +7,11 @@ import org.springframework.web.bind.annotation.RestController; import tools.dynamia.integration.scheduling.PeriodicTaskExecutor; +/** + * REST controller that exposes endpoints for executing periodic tasks defined in the {@link PeriodicTaskExecutor} class. This controller allows you to trigger the execution of morning, midday, afternoon, and evening tasks via HTTP GET requests. Each endpoint corresponds to a specific time of day and will execute the associated tasks when accessed. This can be useful for testing or manually triggering scheduled tasks without waiting for their scheduled execution time. + * + * @author Mario A. Serrano Leones + */ @RestController @RequestMapping("/schedule/execute-tasks") @Tag(name = "DynamiaPeriodicTasks") diff --git a/platform/core/web/src/main/java/tools/dynamia/web/navigation/DefaultCrudRestNavigationCustomizer.java b/platform/core/web/src/main/java/tools/dynamia/web/navigation/DefaultCrudRestNavigationCustomizer.java index 4057419e..275e8ebd 100644 --- a/platform/core/web/src/main/java/tools/dynamia/web/navigation/DefaultCrudRestNavigationCustomizer.java +++ b/platform/core/web/src/main/java/tools/dynamia/web/navigation/DefaultCrudRestNavigationCustomizer.java @@ -5,6 +5,11 @@ import tools.dynamia.navigation.Page; import tools.dynamia.web.navigation.CrudRestNavigationCustomizer; +/** + * Default implementation of the {@link CrudRestNavigationCustomizer} interface that provides a basic customization for CRUD REST API endpoints. This implementation simply returns the actual endpoint without any modifications, allowing for a straightforward mapping of CRUD operations to their respective endpoints based on the page's virtual path. Developers can extend this class and override the `customEndpoint` method to implement specific customizations for their application's REST API routes as needed. + * + * @author Mario A. Serrano Leones + */ @Provider public class DefaultCrudRestNavigationCustomizer implements CrudRestNavigationCustomizer { diff --git a/platform/core/web/src/main/java/tools/dynamia/web/navigation/PageNavigationConfiguration.java b/platform/core/web/src/main/java/tools/dynamia/web/navigation/PageNavigationConfiguration.java index 56aa818c..833d9609 100644 --- a/platform/core/web/src/main/java/tools/dynamia/web/navigation/PageNavigationConfiguration.java +++ b/platform/core/web/src/main/java/tools/dynamia/web/navigation/PageNavigationConfiguration.java @@ -15,7 +15,21 @@ import java.lang.reflect.Method; import java.util.List; - +/** + * Configuration class that dynamically registers page navigation routes based on the pages defined in the application's modules. + * + *

This class listens for the application context to be fully initialized and then iterates through all modules and their associated pages to create dynamic routes for page navigation. Each page's virtual path is used to construct a unique URI, which is then mapped to the {@link PageNavigationController#route} method.

+ * + *

Example usage:

+ *
{@code
+ * @Configuration
+ * public class MyAppPageNavigationConfig extends PageNavigationConfiguration {
+ *     // Additional configuration or overrides can be added here if needed
+ * }
+ * }
+ * + * @author Mario A. Serrano Leones + */ public class PageNavigationConfiguration { public static final String PAGE_URI = "/page/"; diff --git a/platform/core/web/src/main/java/tools/dynamia/web/navigation/PageNavigationController.java b/platform/core/web/src/main/java/tools/dynamia/web/navigation/PageNavigationController.java index 67430520..994d6048 100644 --- a/platform/core/web/src/main/java/tools/dynamia/web/navigation/PageNavigationController.java +++ b/platform/core/web/src/main/java/tools/dynamia/web/navigation/PageNavigationController.java @@ -34,6 +34,11 @@ import static tools.dynamia.navigation.NavigationElement.PATH_SEPARATOR; +/** + * Controller responsible for handling page navigation requests in the web application. It maps incoming HTTP requests to specific page paths and manages the navigation flow based on the requested URL structure. The controller supports various URL patterns to accommodate different levels of page hierarchy, allowing for flexible navigation within the application. It also handles access restrictions and integrates with page navigation interceptors to provide additional functionality during the navigation process. + * + * @author Mario A. Serrano Leones + */ @Controller("pageNavigationController") @RequestMapping("/page") public class PageNavigationController { diff --git a/platform/core/web/src/main/java/tools/dynamia/web/navigation/RestApiNavigationConfiguration.java b/platform/core/web/src/main/java/tools/dynamia/web/navigation/RestApiNavigationConfiguration.java index 5cfc70bf..4b42e5f8 100644 --- a/platform/core/web/src/main/java/tools/dynamia/web/navigation/RestApiNavigationConfiguration.java +++ b/platform/core/web/src/main/java/tools/dynamia/web/navigation/RestApiNavigationConfiguration.java @@ -17,7 +17,21 @@ import java.lang.reflect.Method; import java.util.List; - +/** + * Configuration class that dynamically registers REST API routes for CRUD operations based on the pages defined in the application's modules. + * + *

This class listens for the application context to be fully initialized and then iterates through all modules and their associated pages to create dynamic REST API routes for CRUD operations. Each page's virtual path is used to construct unique URIs for the standard CRUD operations (Create, Read, Update, Delete), which are then mapped to the corresponding methods in the {@link RestNavigationController}.

+ * + *

Example usage:

+ *
{@code
+ * @Configuration
+ * public class MyAppRestApiNavigationConfig extends RestApiNavigationConfiguration {
+ *     // Additional configuration or overrides can be added here if needed
+ * }
+ * }
+ * + * @author Mario A. Serrano Leones + */ public class RestApiNavigationConfiguration { diff --git a/platform/core/web/src/main/java/tools/dynamia/web/navigation/RestNavigationController.java b/platform/core/web/src/main/java/tools/dynamia/web/navigation/RestNavigationController.java index cb33d977..33209067 100644 --- a/platform/core/web/src/main/java/tools/dynamia/web/navigation/RestNavigationController.java +++ b/platform/core/web/src/main/java/tools/dynamia/web/navigation/RestNavigationController.java @@ -52,6 +52,11 @@ import java.util.List; import java.util.Map; +/** + * Controller responsible for handling RESTful API requests related to CRUD operations on entities defined in the application. It provides endpoints for reading, creating, updating, and deleting entities based on the paths defined in the application's navigation structure. The controller utilizes the CrudService to perform database operations and returns JSON responses with the appropriate data and metadata for each request. It also handles pagination and query parameters for listing entities, as well as access restrictions based on the navigation configuration. + * + * @author Mario A. Serrano Leones + */ @RestController("restNavigationController") @Order(1000) public class RestNavigationController extends AbstractLoggable { diff --git a/platform/starters/zk-starter/pom.xml b/platform/starters/zk-starter/pom.xml index 56012381..4bfad27e 100644 --- a/platform/starters/zk-starter/pom.xml +++ b/platform/starters/zk-starter/pom.xml @@ -4,7 +4,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../../../pom.xml @@ -28,22 +28,22 @@ tools.dynamia tools.dynamia.app - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.commons - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.zk - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.domain.jpa - 26.2.0 + 26.2.1 org.hibernate.validator diff --git a/platform/ui/ui-shared/pom.xml b/platform/ui/ui-shared/pom.xml index 9f0497f3..f25c0486 100644 --- a/platform/ui/ui-shared/pom.xml +++ b/platform/ui/ui-shared/pom.xml @@ -23,7 +23,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../../../pom.xml @@ -64,17 +64,17 @@ tools.dynamia tools.dynamia.integration - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.commons - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.io - 26.2.0 + 26.2.1 diff --git a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/Form.java b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/Form.java index fb244134..83a216c9 100644 --- a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/Form.java +++ b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/Form.java @@ -19,40 +19,71 @@ import tools.dynamia.commons.Callback; import tools.dynamia.commons.PropertyChangeSupport; - +/** + * Base class for forms in the UI layer. This class provides common functionality for handling form actions such as submit, cancel, and close. + * It also supports property change notifications to allow UI components to react to changes in form state. + * + *

Subclasses can override the submit(), cancel(), and close() methods to implement specific behavior for these actions.

+ * + * @author Mario A. Serrano Leones + */ public class Form extends PropertyChangeSupport { private Callback onSubmitCallback; private Callback onCancelCallback; private Callback onCloseCallback; - + /** + * Trigger the submit action. This method checks if an onSubmitCallback is registered and executes it if present. + * Subclasses can override this method to provide additional behavior on form submission. + */ protected void submit() { if (onSubmitCallback != null) { onSubmitCallback.doSomething(); } } + /** + * Trigger the cancel action. This method checks if an onCancelCallback is registered and executes it if present. + * Subclasses can override this method to provide additional behavior on form cancellation. + */ protected void cancel() { if (onCancelCallback != null) { onCancelCallback.doSomething(); } } + /** + * Trigger the close action. This method checks if an onCloseCallback is registered and executes it if present. + * Subclasses can override this method to provide additional behavior on form closure. + */ public void close() { if (onCloseCallback != null) { onCloseCallback.doSomething(); } } + /** + * Setters for action callbacks. These methods allow external code to register callbacks that will be executed when the corresponding form actions are triggered. + */ public void onCancel(Callback onCancelCallback) { this.onCancelCallback = onCancelCallback; } + /** + * Set the callback to be executed when the form is submitted. This allows external code to define custom behavior for form submission. + * + * @param onSubmitCallback The callback to execute on form submission. + */ public void onSubmit(Callback onSubmitCallback) { this.onSubmitCallback = onSubmitCallback; } + /** + * Set the callback to be executed when the form is closed. This allows external code to define custom behavior for form closure. + * + * @param callback The callback to execute on form closure. + */ public void onClose(Callback callback) { this.onCloseCallback = callback; } diff --git a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/MessageType.java b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/MessageType.java index 2005380e..0d96e5de 100644 --- a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/MessageType.java +++ b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/MessageType.java @@ -17,6 +17,10 @@ package tools.dynamia.ui; /** + * Enumeration representing different types of messages that can be displayed in the UI. + * This enum can be used to categorize messages based on their severity or purpose, such as normal informational messages, + * warnings, errors, critical issues, or special notifications. + * * @author Mario A. Serrano Leones */ public enum MessageType { diff --git a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/UITools.java b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/UITools.java index 09ac315a..c713fda0 100644 --- a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/UITools.java +++ b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/UITools.java @@ -4,11 +4,33 @@ import java.util.List; +/** + * Central utility class for UI-related operations in the Dynamia Tools framework. + * This class provides static methods for creating and displaying common UI components + * such as dialogs, listboxes, comboboxes, and buttons. It serves as a facade over + * the underlying {@link UIToolsProvider} implementation, allowing for decoupled + * UI component creation and management. + * + *

Example usage:

+ *
{@code
+ * DialogComponent dialog = UITools.showDialog("My Dialog", "This is the content");
+ * ListboxComponent listbox = UITools.listbox(List.of("Option 1", "Option 2"));
+ * ButtonComponent button = UITools.button("Click Me", () -> System.out.println("Button clicked"));
+ * }
+ * + * @author Mario A. Serrano Leones + */ public class UITools { private static UIToolsProvider currentProvider; + /** + * Get the current UIToolsProvider instance. + * + * @return the current provider + * @throws IllegalStateException if no provider is found + */ private static UIToolsProvider getProvider() { if (currentProvider == null) { currentProvider = Containers.get().findObject(UIToolsProvider.class); @@ -19,6 +41,12 @@ private static UIToolsProvider getProvider() { return currentProvider; } + /** + * Set the current UIToolsProvider instance. This method can be used to override the default provider + * found in the container, allowing for custom implementations or testing purposes. + * + * @param currentProvider the new provider to set + */ public static void setCurrentProvider(UIToolsProvider currentProvider) { UITools.currentProvider = currentProvider; } diff --git a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/AbstractFontIconsProvider.java b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/AbstractFontIconsProvider.java index a3750f48..dbde5317 100644 --- a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/AbstractFontIconsProvider.java +++ b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/AbstractFontIconsProvider.java @@ -27,19 +27,80 @@ import java.util.Properties; /** - * IconsProvider for Fonts Icons + * Abstract base class for IconsProvider implementations that serve font-based icons. + * This class provides common functionality for loading and managing icon sets from font libraries + * such as FontAwesome, Material Icons, or other web font icon systems. * - * @author Mario + *

Font icons are lightweight, scalable, and customizable through CSS. This provider manages + * the mapping between logical icon names and their internal font class names or Unicode values.

+ * + *

Subclasses must implement {@link #getNamesMapping()} to provide a Properties object + * that maps logical icon names to their internal font-specific identifiers.

+ * + *

The initialization process:

+ *
    + *
  • Loads icon name mappings from the Properties returned by getNamesMapping()
  • + *
  • Creates Icon objects with IconType.FONT for each mapping
  • + *
  • Stores icons in an internal cache for quick retrieval
  • + *
  • Logs the installation progress for debugging
  • + *
+ * + *

Example implementation:

+ *
{@code
+ * @Component
+ * public class FontAwesomeProvider extends AbstractFontIconsProvider {
+ *
+ *     @Override
+ *     public Properties getNamesMapping() {
+ *         Properties props = new Properties();
+ *         props.setProperty("save", "fa-save");
+ *         props.setProperty("edit", "fa-edit");
+ *         props.setProperty("delete", "fa-trash");
+ *         return props;
+ *     }
+ * }
+ * }
+ * + * @author Mario A. Serrano Leones + * @see IconsProvider + * @see Icon + * @see IconType */ public abstract class AbstractFontIconsProvider implements IconsProvider { + /** + * Internal cache storing all loaded icons by their logical name. + */ private final Map icons = new HashMap<>(); + + /** + * Logging service for reporting icon loading progress and issues. + */ private final LoggingService logger = new SLF4JLoggingService(getClass()); + /** + * Constructs a new AbstractFontIconsProvider and automatically initializes + * the icon mappings by calling {@link #init()}. + */ public AbstractFontIconsProvider() { init(); } + /** + * Initializes the icon provider by loading all icon mappings. + * This method retrieves the Properties from {@link #getNamesMapping()}, + * iterates through all entries, and creates Icon objects for each mapping. + * + *

The initialization process:

+ *
    + *
  • Obtains the Properties object from the subclass
  • + *
  • Logs the number of icons being installed
  • + *
  • Iterates through each property entry
  • + *
  • Creates a new Icon with IconType.FONT for each mapping
  • + *
  • Stores the icon in the internal cache
  • + *
  • Logs successful completion
  • + *
+ */ private void init() { Properties names = getNamesMapping(); if (names != null) { @@ -56,10 +117,26 @@ private void init() { } } + /** + * Factory method for creating Icon instances. + * Subclasses can override this method to customize how Icon objects are created, + * for example to add additional metadata or use custom Icon subclasses. + * + * @param name the logical name of the icon (e.g., "save", "edit") + * @param internalName the internal font-specific identifier (e.g., "fa-save", "md-edit") + * @return a new Icon instance configured for font-based rendering + */ protected Icon newIcon(String name, String internalName) { return new Icon(name, internalName, IconType.FONT); } + /** + * Retrieves a font icon by its logical name. + * If the icons cache is empty, triggers initialization automatically. + * + * @param name the logical name of the icon to retrieve + * @return the Icon object if found, or null if not available in this provider + */ @Override public Icon getIcon(String name) { if (icons.isEmpty()) { @@ -69,13 +146,50 @@ public Icon getIcon(String name) { return icons.get(name); } + /** + * Provides the mapping between logical icon names and font-specific identifiers. + * Subclasses must implement this method to supply their icon set configuration. + * + *

The Properties object should contain entries where:

+ *
    + *
  • Key: logical icon name used throughout the application (e.g., "save", "edit")
  • + *
  • Value: font-specific CSS class or identifier (e.g., "fa-save", "md-edit")
  • + *
+ * + *

Example:

+ *
{@code
+     * Properties props = new Properties();
+     * props.setProperty("save", "fa-floppy-disk");
+     * props.setProperty("edit", "fa-pen-to-square");
+     * props.setProperty("delete", "fa-trash-can");
+     * return props;
+     * }
+ * + * @return a Properties object containing icon name mappings, or null if no icons are available + */ public abstract Properties getNamesMapping(); + /** + * Returns all icons provided by this font icon provider. + * The returned list is a copy of the internal cache values. + * + * @return a list containing all font icons managed by this provider + */ @Override public List getAll() { return new ArrayList<>(icons.values()); } + /** + * Manually adds an icon to this provider's cache. + * This method allows runtime addition of icons without requiring them to be + * defined in the Properties returned by {@link #getNamesMapping()}. + * + *

Useful for dynamically registering icons or overriding existing ones.

+ * + * @param name the logical name for the icon + * @param icon the Icon object to register + */ public void addIcon(String name, Icon icon) { icons.put(name, icon); } diff --git a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/AbstractIconsProvider.java b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/AbstractIconsProvider.java index e8320367..5a6faf13 100644 --- a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/AbstractIconsProvider.java +++ b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/AbstractIconsProvider.java @@ -29,19 +29,107 @@ import java.util.Map; /** + * Abstract base class for IconsProvider implementations that serve image-based icons. + * This class provides common functionality for loading and managing icon sets from file resources + * such as PNG, SVG, GIF, or other image formats stored in the classpath. + * + *

Image-based icons are loaded from a conventional directory structure under the classpath: + * {@code classpath:web/{prefix}/16/*.{extension}}. The provider scans this directory at initialization + * and automatically registers all icons found.

+ * + *

Subclasses must implement two methods to configure the icon location:

+ *
    + *
  • {@link #getPrefix()}: Defines the subdirectory name under web/ where icons are located
  • + *
  • {@link #getExtension()}: Specifies the file extension of the icon images
  • + *
+ * + *

The initialization process:

+ *
    + *
  • Constructs the classpath pattern using prefix and extension
  • + *
  • Scans the directory for matching resources
  • + *
  • Creates Icon objects for each found resource
  • + *
  • Caches icons in an internal map for quick retrieval
  • + *
  • Logs the installation progress and any errors
  • + *
+ * + *

Example implementation:

+ *
{@code
+ * @Component
+ * public class SilkIconsProvider extends AbstractIconsProvider {
+ *
+ *     @Override
+ *     public String getPrefix() {
+ *         return "silk"; // Icons in classpath:web/silk/16/*.png
+ *     }
+ *
+ *     @Override
+ *     public String getExtension() {
+ *         return "png";
+ *     }
+ * }
+ * }
+ * + *

Expected directory structure:

+ *
+ * src/main/resources/
+ *   web/
+ *     silk/           (prefix)
+ *       16/           (fixed size directory)
+ *         save.png    (icon files with extension)
+ *         edit.png
+ *         delete.png
+ * 
* * @author Mario A. Serrano Leones + * @see IconsProvider + * @see Icon + * @see IconType */ public abstract class AbstractIconsProvider implements IconsProvider { + /** + * Logging service for reporting icon loading progress and errors. + */ private final LoggingService logger = new SLF4JLoggingService(getClass()); + + /** + * Internal cache storing all loaded icons by their name (without extension). + */ private final Map icons = new HashMap<>(); + + /** + * List containing all loaded icons for quick retrieval. + */ private final List all = new ArrayList<>(); + /** + * Constructs a new AbstractIconsProvider and automatically initializes + * the icon set by scanning the classpath directory. + */ public AbstractIconsProvider() { init(); } + /** + * Initializes the icon provider by scanning and loading icon resources from the classpath. + * This method builds the resource path using the prefix and extension provided by subclasses, + * scans for matching resources, and creates Icon objects for each found file. + * + *

The scanning process:

+ *
    + *
  • Constructs the classpath pattern: {@code classpath:web/{prefix}/16/*.{extension}}
  • + *
  • Logs the installation path for debugging
  • + *
  • Uses IOUtils to scan for matching resources
  • + *
  • Warns if no icons are found in the directory
  • + *
  • Iterates through found resources and extracts icon names from filenames
  • + *
  • Creates Icon objects with IconType.IMAGE for each resource
  • + *
  • Stores icons in both the cache map and the complete list
  • + *
  • Logs successful completion or errors
  • + *
+ * + *

The icon name is derived from the filename without its extension. + * For example, {@code save.png} becomes an icon with name {@code "save"}.

+ */ private void init() { String prefix = getPrefix(); String extension = getExtension(); @@ -69,10 +157,51 @@ private void init() { } } + /** + * Returns the prefix (subdirectory name) where icons are located under the web/ directory. + * This prefix is used to construct the classpath resource pattern for icon scanning. + * + *

The prefix defines the icon set name and should match the directory structure: + * {@code src/main/resources/web/{prefix}/16/}

+ * + *

Examples:

+ *
    + *
  • "silk" for Silk icon set → {@code web/silk/16/*.png}
  • + *
  • "fugue" for Fugue icon set → {@code web/fugue/16/*.png}
  • + *
  • "custom" for custom icons → {@code web/custom/16/*.svg}
  • + *
+ * + * @return the prefix (subdirectory name) for the icon set + */ public abstract String getPrefix(); + /** + * Returns the file extension for icon image files (without the leading dot). + * This extension is used to filter icon resources during directory scanning. + * + *

Common extensions include:

+ *
    + *
  • "png" for PNG images (most common)
  • + *
  • "svg" for SVG vector graphics
  • + *
  • "gif" for GIF images
  • + *
  • "jpg" or "jpeg" for JPEG images
  • + *
+ * + * @return the file extension without the leading dot (e.g., "png", "svg", "gif") + */ public abstract String getExtension(); + /** + * Retrieves an image icon by its logical name. + * If the icons cache is empty, triggers initialization automatically. + * + *

The name should match the filename (without extension) of an icon in the + * configured directory. For example, if {@code save.png} exists in the icon directory, + * use "save" as the name parameter.

+ * + * @param name the logical name of the icon (filename without extension) + * @return the Icon object if found, or null if not available in this provider + */ @Override public Icon getIcon(String name) { if (icons.isEmpty()) { @@ -81,6 +210,12 @@ public Icon getIcon(String name) { return icons.get(name); } + /** + * Returns all image icons provided by this icon provider. + * The returned list contains all icons discovered during initialization. + * + * @return a list containing all image icons managed by this provider + */ @Override public List getAll() { return all; diff --git a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/Icon.java b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/Icon.java index 3e8d1142..45fb1eb8 100644 --- a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/Icon.java +++ b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/Icon.java @@ -19,6 +19,8 @@ import java.io.Serializable; /** + * Class representing an icon in the UI. This class encapsulates the properties of an icon, such as its name, internal name, directory, extension, and type. + * It provides methods to retrieve the real path of the icon based on its properties and the specified size. The class also includes a static instance representing the absence of an icon (NONE). * * @author Mario A. Serrano Leones */ diff --git a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconName.java b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconName.java new file mode 100644 index 00000000..eeb43879 --- /dev/null +++ b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconName.java @@ -0,0 +1,24 @@ +package tools.dynamia.ui.icons; + +import java.util.List; + +/** + * Immutable record representing an icon name and its associated CSS classes. + * + *

This class is used to encapsulate the logical name of an icon along with any additional + * CSS classes that should be applied when rendering the icon. The name typically corresponds + * to a key in an IconsProvider, while the classes can be used for styling purposes.

+ * + *

Example usage:

+ *
{@code
+ * IconName iconName = new IconName("edit", List.of("red", "bold"));
+ * String name = iconName.name(); // "edit"
+ * List classes = iconName.classes(); // ["red", "bold"]
+ * }
+ * + * @author Mario A. Serrano Leones + */ +public record IconName(String name, List classes) { + + +} diff --git a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconSize.java b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconSize.java index 9cba207b..8d2681ca 100644 --- a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconSize.java +++ b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconSize.java @@ -17,6 +17,7 @@ package tools.dynamia.ui.icons; /** + * Enumeration representing different sizes for icons in the UI. This enum defines three standard sizes: SMALL, NORMAL, and LARGE, each associated with a specific directory name that can be used to locate the corresponding icon resources. The getDir() method allows retrieval of the directory name for each size, facilitating the organization and access of icon assets based on their intended display size. * * @author Mario A. Serrano Leones */ diff --git a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/Icons.java b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/Icons.java index c69eef19..09bf8384 100644 --- a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/Icons.java +++ b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/Icons.java @@ -18,30 +18,97 @@ import org.springframework.stereotype.Component; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** + * A Spring-managed bean that provides access to icon resources through a Map-like interface. + * This class extends HashMap but overrides key methods to integrate with the IconsTheme system + * for dynamic icon resolution and size specification. + * + *

The class allows icon retrieval using simple string keys, with optional size specification + * using a colon-separated format (e.g., "icon-name:large"). Icons are resolved through the + * IconsTheme system and return the real path to the icon resource.

+ * + *

Example usage in expression language (EL):

+ *
{@code
+ * ${icons['save']}           // Returns small save icon path
+ * ${icons['save:large']}     // Returns large save icon path
+ * ${icons.get('save', 'disk')} // Returns save icon or disk icon as fallback
+ * }
+ * + *

This component is registered with Spring using the bean name "icons" for easy access + * in templates and views.

+ * * @author Mario A. Serrano Leones + * @see IconsTheme + * @see Icon + * @see IconSize */ @Component("icons") public class Icons extends HashMap { + /** + * Overridden to prevent modification of the internal map structure. + * This method intentionally does nothing and always returns null, as icons + * are managed by the IconsTheme system and should not be added directly. + * + * @param key the icon name key (ignored) + * @param value the icon value (ignored) + * @return always returns null + */ @Override public String put(String key, String value) { return null; } + /** + * Overridden to prevent modification of the internal map structure. + * This method intentionally does nothing, as icons are managed by the + * IconsTheme system and should not be added directly. + * + * @param m the map of entries to add (ignored) + */ @Override public void putAll(Map m) { } + /** + * Retrieves the real path to an icon resource by its name. + * The key can include an optional size specification using colon notation (e.g., "icon-name:large"). + * If no size is specified, IconSize.SMALL is used by default. + * + * @param key the icon name, optionally followed by ":size" (e.g., "save", "save:large") + * @return the real path to the icon resource, or null if the icon is not found + * + *

Example:

+ *
{@code
+     * Icons icons = new Icons();
+     * String path = icons.get("save");        // Returns small save icon path
+     * String path2 = icons.get("save:large"); // Returns large save icon path
+     * }
+ */ @Override public String get(Object key) { var icon = getIcon((String) key); return icon.getRealPath(getSize((String) key)); } + /** + * Retrieves the real path to an icon resource by its name, with a fallback to a default icon. + * If the requested icon is not found or equals Icon.NONE, the default icon is used instead. + * The key can include an optional size specification using colon notation. + * + * @param key the icon name, optionally followed by ":size" (e.g., "save", "save:large") + * @param defaultIcon the fallback icon name to use if the primary icon is not found + * @return the real path to the icon resource (primary or default), or null if neither is found + * + *

Example:

+ *
{@code
+     * Icons icons = new Icons();
+     * String path = icons.get("custom-icon", "save"); // Returns custom-icon if exists, otherwise save
+     * String path2 = icons.get("missing:large", "fallback:large"); // Returns fallback icon in large size
+     * }
+ */ public String get(Object key, String defaultIcon) { var icon = getIcon((String) key); if (icon == null || icon.equals(Icon.NONE)) { @@ -51,6 +118,13 @@ public String get(Object key, String defaultIcon) { return icon.getRealPath(getSize((String) key)); } + /** + * Retrieves an Icon object from the IconsTheme system. + * Extracts the icon name (without size specification) and looks it up in the theme. + * + * @param key the icon name, possibly including size specification (e.g., "save:large") + * @return the Icon object, or null if the key is null or icon not found + */ private Icon getIcon(String key) { if (key == null) { return null; @@ -59,6 +133,22 @@ private Icon getIcon(String key) { } + /** + * Extracts the icon size from a name string using colon notation. + * If the name contains a colon, the text after it is parsed as an IconSize enum value. + * If no colon is present or parsing fails, returns IconSize.SMALL as default. + * + * @param name the icon name with optional size (e.g., "save", "save:large", "delete:medium") + * @return the parsed IconSize, or IconSize.SMALL if not specified or invalid + * + *

Example:

+ *
{@code
+     * getSize("save");        // Returns IconSize.SMALL
+     * getSize("save:large");  // Returns IconSize.LARGE
+     * getSize("save:MEDIUM"); // Returns IconSize.MEDIUM
+     * getSize("save:invalid");// Returns IconSize.SMALL (fallback)
+     * }
+ */ private IconSize getSize(String name) { IconSize iconSize = IconSize.SMALL; try { @@ -72,5 +162,95 @@ private IconSize getSize(String name) { return iconSize; } + /** + * Parses a comma-separated string of icon class names into a list of trimmed, non-blank strings. + * + * @param names the comma-separated string of icon class names (e.g., "class1, class2, class3") + * @return a List of individual icon class names, or an empty list if the input is null or blank + * + *

Example:

+ *
{@code
+     * parseIconNames("class1, class2, class3"); // Returns ["class1", "class2", "class3"]
+     * parseIconNames("  class1 , , class2  , "); // Returns ["class1", "class2"]
+     * parseIconNames(null); // Returns []
+     * parseIconNames(""); // Returns []
+     * }
+ */ + public static List parseIconNames(String names) { + if (names == null || names.isBlank()) { + return Collections.emptyList(); + } + return Arrays.stream(names.split(",")) + .map(String::trim) + .filter(s -> !s.isBlank()) + .toList(); + } + + /** + * Parses a string into an IconName object containing the icon name and optional CSS classes. + * The expected format is: {@code iconName|class1,class2,class3} where the icon name comes first, + * followed by an optional pipe separator and comma-separated CSS class names. + * + *

This method is useful for specifying icons with additional styling or animation classes + * in a compact, string-friendly format. The pipe character (|) separates the base icon name + * from the CSS classes, and commas separate individual class names.

+ * + *

Format rules:

+ *
    + *
  • Icon name is always the first part before the pipe (|) separator
  • + *
  • CSS classes are optional and come after the pipe separator
  • + *
  • Multiple CSS classes are separated by commas
  • + *
  • Whitespace around names and classes is automatically trimmed
  • + *
  • Empty or blank strings return null
  • + *
+ * + * @param name the string to parse in format "iconName|class1,class2" or just "iconName" + * @return an IconName object containing the icon name and CSS classes, or null if the input is null or blank + * + *

Examples:

+ *
{@code
+     * // Simple icon without classes
+     * IconName icon1 = Icons.parseIconName("edit");
+     * // Returns: IconName{name="edit", classes=[]}
+     *
+     * // Icon with single CSS class
+     * IconName icon2 = Icons.parseIconName("check|text-success");
+     * // Returns: IconName{name="check", classes=["text-success"]}
+     *
+     * // Icon with multiple CSS classes
+     * IconName icon3 = Icons.parseIconName("edit|text-danger,pulse,fa-spin");
+     * // Returns: IconName{name="edit", classes=["text-danger", "pulse", "fa-spin"]}
+     *
+     * // Icon with whitespace (automatically trimmed)
+     * IconName icon4 = Icons.parseIconName("  save | text-primary , bounce  ");
+     * // Returns: IconName{name="save", classes=["text-primary", "bounce"]}
+     *
+     * // Invalid inputs
+     * Icons.parseIconName(null);   // Returns: null
+     * Icons.parseIconName("");     // Returns: null
+     * Icons.parseIconName("   ");  // Returns: null
+     * }
+ * @see IconName + * @see #parseIconNames(String) + */ + public static IconName parseIconName(String name) { + + if (name == null || name.isBlank()) { + return new IconName(null, Collections.emptyList()); + } + + if (!name.contains("|")) { + return new IconName(name.trim(), Collections.emptyList()); + } + + String[] parts = name.split("\\|"); + String iconName = parts[0].trim(); + List classes = Collections.emptyList(); + if (parts.length > 1) { + classes = parseIconNames(parts[1]); + } + return new IconName(iconName, classes); + } + } diff --git a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconsProvider.java b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconsProvider.java index 173305fe..1ead3143 100644 --- a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconsProvider.java +++ b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconsProvider.java @@ -19,12 +19,74 @@ import java.util.List; /** + * Service provider interface for supplying icon resources to the Dynamia Tools framework. + * Implementations of this interface are responsible for providing Icon objects from various sources + * such as file systems, resources, databases, or external icon libraries. + * + *

IconsProvider implementations are automatically discovered and registered by the Spring container + * through component scanning. The {@link IconsTheme} class queries all registered providers to resolve + * icon requests, searching through them sequentially until a match is found.

+ * + *

Typical use cases include:

+ *
    + *
  • Providing icons from theme resources
  • + *
  • Loading icons from external icon libraries (FontAwesome, Material Icons, etc.)
  • + *
  • Serving custom application-specific icons
  • + *
  • Implementing icon sets with different visual styles
  • + *
+ * + *

Example implementation:

+ *
{@code
+ * @Component
+ * public class MyIconsProvider implements IconsProvider {
+ *
+ *     @Override
+ *     public Icon getIcon(String name) {
+ *         // Load icon from resources
+ *         if ("custom-icon".equals(name)) {
+ *             return new Icon(name, "/icons/custom.png");
+ *         }
+ *         return null;
+ *     }
+ *
+ *     @Override
+ *     public List getAll() {
+ *         // Return all available icons
+ *         return Arrays.asList(
+ *             new Icon("custom-icon", "/icons/custom.png"),
+ *             new Icon("another-icon", "/icons/another.png")
+ *         );
+ *     }
+ * }
+ * }
* * @author Mario A. Serrano Leones + * @see Icon + * @see IconsTheme */ public interface IconsProvider { + /** + * Retrieves an icon by its logical name. + * Implementations should search their icon repository for an icon matching + * the provided name and return it if found. + * + *

If the icon is not available in this provider, this method should return null + * to allow the IconsTheme to continue searching in other providers.

+ * + * @param name the logical name of the icon to retrieve (e.g., "save", "edit", "delete") + * @return the Icon object if found, or null if this provider doesn't have the requested icon + */ Icon getIcon(String name); + /** + * Retrieves all icons available from this provider. + * This method is typically used for building icon selectors, catalogs, or documentation. + * + *

Implementations should return a complete list of all icons they can provide. + * The returned list should not be null but may be empty if no icons are available.

+ * + * @return a list containing all available icons from this provider, never null + */ List getAll(); } diff --git a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconsTheme.java b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconsTheme.java index b0eaa44f..e667792a 100644 --- a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconsTheme.java +++ b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/IconsTheme.java @@ -25,16 +25,57 @@ import java.util.Map; /** + * Central manager for icon resources in the Dynamia Tools framework. + * This singleton class provides a unified interface for retrieving icons from multiple + * {@link IconsProvider} implementations, with built-in caching for improved performance. + * + *

The IconsTheme acts as a facade over all registered IconsProvider beans, + * searching through them sequentially until an icon with the requested name is found. + * Once found, icons are cached to avoid repeated lookups.

+ * + *

Icons can be retrieved by their logical name, with optional support for + * prefixed names (e.g., "icons:save") and fallback icons when the primary icon is not found.

+ * + *

Example usage:

+ *
{@code
+ * Icon saveIcon = IconsTheme.get().getIcon("save");
+ * Icon customIcon = IconsTheme.get().getIcon("custom-icon", "default-icon");
+ * List allIcons = IconsTheme.get().getAll();
+ * }
* * @author Mario A. Serrano Leones + * @see Icon + * @see IconsProvider */ public class IconsTheme { + /** + * Singleton instance of IconsTheme. + */ private static IconsTheme instance; + + /** + * Cache map storing already resolved icons by their name for quick lookup. + */ private final Map iconsCache = new HashMap<>(); + + /** + * Logging service for reporting icon resolution issues. + */ private final LoggingService logger = Containers.get().findObject(LoggingService.class); + + /** + * List containing all available icons from all registered providers. + * Populated lazily on first call to {@link #getAll()}. + */ private final List all = new ArrayList<>(); + /** + * Returns the singleton instance of IconsTheme. + * Creates the instance on first call (lazy initialization). + * + * @return the singleton IconsTheme instance + */ public static IconsTheme get() { if (instance == null) { instance = new IconsTheme(); @@ -43,8 +84,26 @@ public static IconsTheme get() { } /** - * Get the icon info using its logical name. + * Retrieves an icon by its logical name. + * This method searches through all registered IconsProvider implementations + * to find the requested icon. Results are cached for subsequent requests. + * + *

The method handles special cases:

+ *
    + *
  • Returns Icon.NONE if the name is null or blank
  • + *
  • Strips "icons:" prefix if present (e.g., "icons:save" becomes "save")
  • + *
  • Uses cached icon if available
  • + *
  • Logs a warning and returns Icon.NONE if icon is not found
  • + *
+ * + * @param name the logical name of the icon (e.g., "save", "edit", "delete") + * @return the Icon object, or Icon.NONE if not found * + *

Example:

+ *
{@code
+     * Icon icon = IconsTheme.get().getIcon("save");
+     * Icon prefixedIcon = IconsTheme.get().getIcon("icons:edit");
+     * }
*/ public Icon getIcon(String name) { if (name == null || name.isBlank()) { @@ -71,9 +130,22 @@ public Icon getIcon(String name) { } /** - * Get the icon info using its logical name, if not found its find by - * defaultName; + * Retrieves an icon by its logical name, with a fallback to a default icon. + * If the primary icon is not found or has no real path, the method attempts + * to retrieve the icon specified by the default name. * + *

This method is useful when you want to ensure an icon is always returned, + * falling back to a known icon if the requested one doesn't exist.

+ * + * @param name the logical name of the primary icon to retrieve + * @param defaultName the logical name of the fallback icon if primary is not found + * @return the Icon object (primary or fallback), or Icon.NONE if neither is found + * + *

Example:

+ *
{@code
+     * // Returns custom-icon if exists, otherwise returns the save icon
+     * Icon icon = IconsTheme.get().getIcon("custom-icon", "save");
+     * }
*/ public Icon getIcon(String name, String defaultName) { Icon icon = getIcon(name); @@ -83,6 +155,14 @@ public Icon getIcon(String name, String defaultName) { return icon; } + /** + * Searches for an icon by name across all registered IconsProvider implementations. + * This method iterates through providers in the order they are discovered by the + * container and returns the first matching icon found. + * + * @param name the logical name of the icon to find + * @return the Icon object if found in any provider, or null if not found + */ private Icon findIcon(String name) { Icon icon = null; @@ -96,6 +176,23 @@ private Icon findIcon(String name) { return icon; } + /** + * Retrieves all available icons from all registered IconsProvider implementations. + * The list is populated lazily on the first call and cached for subsequent requests. + * + *

This method aggregates icons from all providers found in the container, + * which is useful for displaying icon selectors or generating icon catalogs.

+ * + * @return an unmodifiable list containing all available icons + * + *

Example:

+ *
{@code
+     * List allIcons = IconsTheme.get().getAll();
+     * for (Icon icon : allIcons) {
+     *     System.out.println(icon.getName());
+     * }
+     * }
+ */ public List getAll() { if (all.isEmpty()) { for (IconsProvider p : Containers.get().findObjects(IconsProvider.class)) { diff --git a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/InstallIcons.java b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/InstallIcons.java index 71c7014a..bf721d0b 100644 --- a/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/InstallIcons.java +++ b/platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/InstallIcons.java @@ -25,6 +25,8 @@ import java.lang.annotation.Target; /** + * Annotation to mark a class as an IconsProvider installer. + * Classes annotated with @InstallIcons will be automatically detected and registered as IconsProvider beans in the Spring application context. * * @author Mario A. Serrano Leones */ diff --git a/platform/ui/ui-shared/src/test/java/tools/dynamia/ui/AppTest.java b/platform/ui/ui-shared/src/test/java/tools/dynamia/ui/AppTest.java deleted file mode 100644 index 42c87359..00000000 --- a/platform/ui/ui-shared/src/test/java/tools/dynamia/ui/AppTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2023 Dynamia Soluciones IT S.A.S - NIT 900302344-1 - * Colombia / South America - * - * 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. - */ -package tools.dynamia.ui; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -/** - * Unit test for simple App. - */ -public class AppTest - extends TestCase { - - /** - * Create the test case - * - * @param testName name of the test case - */ - public AppTest(String testName) { - super(testName); - } - - /** - * @return the suite of tests being tested - */ - public static Test suite() { - return new TestSuite(AppTest.class); - } - - /** - * Rigourous Test :-) - */ - public void testApp() { - assertTrue(true); - } -} diff --git a/platform/ui/ui-shared/src/test/java/tools/dynamia/ui/IconTest.java b/platform/ui/ui-shared/src/test/java/tools/dynamia/ui/IconTest.java new file mode 100644 index 00000000..001e6345 --- /dev/null +++ b/platform/ui/ui-shared/src/test/java/tools/dynamia/ui/IconTest.java @@ -0,0 +1,19 @@ +package tools.dynamia.ui; + +import org.junit.Test; +import tools.dynamia.ui.icons.IconName; +import tools.dynamia.ui.icons.Icons; + +public class IconTest { + + @Test + public void shouldParseIconName() { + IconName iconName = Icons.parseIconName("edit|red,blue,green"); + assert iconName.name().equals("edit"); + assert iconName.classes().size() == 3; + assert iconName.classes().get(0).equals("red"); + assert iconName.classes().get(1).equals("blue"); + assert iconName.classes().get(2).equals("green"); + + } +} diff --git a/platform/ui/zk/pom.xml b/platform/ui/zk/pom.xml index 6816e10d..d9694205 100644 --- a/platform/ui/zk/pom.xml +++ b/platform/ui/zk/pom.xml @@ -21,7 +21,7 @@ tools.dynamia.parent tools.dynamia - 26.2.0 + 26.2.1 ../../../pom.xml 4.0.0 @@ -99,31 +99,31 @@ tools.dynamia tools.dynamia.web - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.navigation - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.ui - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.domain - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.viewers - 26.2.0 + 26.2.1 org.yaml @@ -134,19 +134,19 @@ tools.dynamia tools.dynamia.crud - 26.2.0 + 26.2.1 tools.dynamia tools.dynamia.reports - 26.2.0 + 26.2.1 compile tools.dynamia tools.dynamia.templates - 26.2.0 + 26.2.1 compile diff --git a/platform/ui/zk/src/main/java/tools/dynamia/zk/ui/EnumIconImage.java b/platform/ui/zk/src/main/java/tools/dynamia/zk/ui/EnumIconImage.java index 6b057b6b..ec8d9e38 100644 --- a/platform/ui/zk/src/main/java/tools/dynamia/zk/ui/EnumIconImage.java +++ b/platform/ui/zk/src/main/java/tools/dynamia/zk/ui/EnumIconImage.java @@ -21,15 +21,12 @@ import org.zkoss.zul.Image; import org.zkoss.zul.Label; import org.zkoss.zul.Span; -import tools.dynamia.ui.icons.Icon; -import tools.dynamia.ui.icons.IconSize; -import tools.dynamia.ui.icons.IconType; -import tools.dynamia.ui.icons.IconsTheme; +import tools.dynamia.ui.icons.*; import tools.dynamia.zk.BindingComponentIndex; import tools.dynamia.zk.ComponentAliasIndex; import tools.dynamia.zk.util.ZKUtil; -public class EnumIconImage extends Span implements LoadableOnly{ +public class EnumIconImage extends Span implements LoadableOnly { /** * @@ -54,22 +51,25 @@ public void setValue(Object value) { private void render() { getChildren().clear(); - setTooltiptext(null); - String iconName = getIconName(); - if (iconName != null) { - Icon icon = IconsTheme.get().getIcon(iconName); - setTooltiptext(value.name()); - if (icon.getType() == IconType.IMAGE) { - Image image = new Image(); - image.setParent(this); - ZKUtil.configureComponentIcon(icon, image, size); + if (value != null) { + setTooltiptext(null); + String iconName = getIconName(); + if (iconName != null) { + IconName iconNameObj = Icons.parseIconName(iconName); + Icon icon = IconsTheme.get().getIcon(iconNameObj.name()); + setTooltiptext(value.name()); + if (icon.getType() == IconType.IMAGE) { + Image image = new Image(); + image.setParent(this); + ZKUtil.configureComponentIcon(icon, image, size, iconNameObj.classes()); + } else { + I i = new I(); + i.setParent(this); + ZKUtil.configureComponentIcon(icon, i, size, iconNameObj.classes()); + } } else { - I i = new I(); - i.setParent(this); - ZKUtil.configureComponentIcon(icon, i, size); + appendChild(new Label(value.name())); } - } else { - appendChild(new Label(value.name())); } } @@ -105,14 +105,25 @@ public String[] getIconsNames() { return iconsNames; } - public void setIconsNames(String[] iconsNames) { + public void setIconsNamesValues(String[] iconsNames) { this.iconsNames = iconsNames; render(); } + /** + * Sets the icon names from a comma-separated string and triggers a re-render. + * Spaces are automatically removed from the input string. + * + * @param iconsNames comma-separated string of icon names (e.g., "check,clock,times") + *

+ * Example: + *

{@code
+     *                                                       iconImage.setIconsNames("check-circle, clock, times-circle");
+     *                                                       }
+ */ public void setIconsNames(String iconsNames) { if (iconsNames != null) { - setIconsNames(iconsNames.replace(" ", "").split(",")); + setIconsNamesValues(iconsNames.replace(" ", "").split(",")); } } } diff --git a/platform/ui/zk/src/main/java/tools/dynamia/zk/ui/FontAwesomeIconsProvider.java b/platform/ui/zk/src/main/java/tools/dynamia/zk/ui/FontAwesomeIconsProvider.java index 9a78b65c..3f28bad2 100644 --- a/platform/ui/zk/src/main/java/tools/dynamia/zk/ui/FontAwesomeIconsProvider.java +++ b/platform/ui/zk/src/main/java/tools/dynamia/zk/ui/FontAwesomeIconsProvider.java @@ -27,11 +27,48 @@ import java.io.IOException; import java.util.Properties; +/** + * IconsProvider implementation for Font Awesome icon library. + * This provider loads and manages Font Awesome icons, supporting both predefined mappings + * from a properties file and dynamic icon name resolution. + * + *

The provider supports multiple icon resolution strategies:

+ *
    + *
  • Loading predefined icon mappings from {@code /META-INF/dynamia/fa-icons.properties}
  • + *
  • Dynamically resolving icons with "fa-" prefix (e.g., "fa-save" → "fa fa-save")
  • + *
  • Direct Font Awesome class names (e.g., "fa fa-user", "fab fa-github")
  • + *
+ * + *

Example usage:

+ *
{@code
+ * Icon saveIcon = provider.getIcon("save");           // From properties file
+ * Icon customIcon = provider.getIcon("fa-user");      // Dynamic resolution
+ * Icon brandIcon = provider.getIcon("fab fa-github"); // Direct class name
+ * }
+ * + * @see AbstractFontIconsProvider + * @see FAIcon + */ public class FontAwesomeIconsProvider extends AbstractFontIconsProvider { + /** + * Logger for reporting icon loading errors and warnings. + */ private static final LoggingService logger = new SLF4JLoggingService(FontAwesomeIconsProvider.class); - + /** + * Provides the mapping between logical icon names and Font Awesome class names. + * Loads the icon mappings from a properties file located at {@code /META-INF/dynamia/fa-icons.properties}. + * + *

The properties file format:

+ *
+     * save=floppy-disk
+     * edit=pen-to-square
+     * delete=trash-can
+     * 
+ * + * @return Properties object containing icon name mappings, or empty Properties if loading fails + */ @Override public Properties getNamesMapping() { Properties properties = new Properties(); @@ -44,10 +81,36 @@ public Properties getNamesMapping() { return properties; } + /** + * Returns the classpath location of the Font Awesome icons properties file. + * Subclasses can override this method to provide a different properties file location. + * + * @return the classpath path to the icons properties file + */ protected String getIconsPath() { return "/META-INF/dynamia/fa-icons.properties"; } + /** + * Retrieves a Font Awesome icon by its name with support for multiple resolution strategies. + * + *

Resolution order:

+ *
    + *
  1. Checks the predefined mappings from properties file
  2. + *
  3. If not found and name starts with "fa-", creates icon dynamically
  4. + *
  5. If name starts with "fa " or "fab ", uses it as direct Font Awesome class
  6. + *
+ * + *

Examples:

+ *
{@code
+     * getIcon("save");           // From properties: fa fa-floppy-disk
+     * getIcon("fa-user");        // Dynamic: fa fa-user
+     * getIcon("fab fa-github");  // Direct: fab fa-github
+     * }
+ * + * @param name the icon name or Font Awesome class + * @return the Icon object, or null if not resolvable + */ @Override public Icon getIcon(String name) { Icon icon = super.getIcon(name); @@ -66,10 +129,24 @@ public Icon getIcon(String name) { return icon; } + /** + * Returns the prefix used for Font Awesome icon names. + * This prefix is used in dynamic icon resolution and icon class generation. + * + * @return the icon prefix, default is "fa-" + */ protected String getIconsPrefix() { return "fa-"; } + /** + * Creates a new FAIcon instance with proper Font Awesome class formatting. + * Constructs the full Font Awesome CSS class by combining "fa " prefix with the icon name. + * + * @param name the logical name of the icon + * @param internalName the Font Awesome specific icon name (without "fa-" prefix) + * @return a new FAIcon instance configured with Font Awesome classes + */ @Override protected Icon newIcon(String name, String internalName) { return new FAIcon(name, "fa " + getIconsPrefix() + internalName); diff --git a/platform/ui/zk/src/main/java/tools/dynamia/zk/util/ZKUtil.java b/platform/ui/zk/src/main/java/tools/dynamia/zk/util/ZKUtil.java index 6c5abe5b..50ae1296 100644 --- a/platform/ui/zk/src/main/java/tools/dynamia/zk/util/ZKUtil.java +++ b/platform/ui/zk/src/main/java/tools/dynamia/zk/util/ZKUtil.java @@ -38,10 +38,7 @@ import tools.dynamia.io.Resource; import tools.dynamia.ui.MessageDisplayer; import tools.dynamia.ui.MessageType; -import tools.dynamia.ui.icons.Icon; -import tools.dynamia.ui.icons.IconSize; -import tools.dynamia.ui.icons.IconType; -import tools.dynamia.ui.icons.IconsTheme; +import tools.dynamia.ui.icons.*; import tools.dynamia.web.util.HttpUtils; import tools.dynamia.zk.EventQueueSubscriber; import tools.dynamia.zk.crud.ui.EntityTreeNode; @@ -795,6 +792,19 @@ public static Popup createTooltip(String text) { * @param size the desired icon size */ public static void configureComponentIcon(Icon icon, Component component, IconSize size) { + configureComponentIcon(icon, component, size, Collections.emptyList()); + } + + /** + * Configures an icon for a ZK component, supporting both IMAGE and FONT icon types. + * Automatically handles different component types (LabelImageElement, AbstractTag, Image). + * + * @param icon the icon to configure + * @param component the component to apply the icon to + * @param size the desired icon size + * @param extraClasses additional CSS classes to apply to the component (can be null or empty) + */ + public static void configureComponentIcon(Icon icon, Component component, IconSize size, List extraClasses) { if (icon == null) { return; @@ -819,18 +829,31 @@ public static void configureComponentIcon(Icon icon, Component component, IconSi } else if (component instanceof Image image && icon.getType() == IconType.IMAGE) { image.setSrc(realPath); } + + if (extraClasses != null && !extraClasses.isEmpty()) { + if (component instanceof HtmlBasedComponent hcomp) { + extraClasses.forEach(hcomp::addSclass); + } else if (component instanceof AbstractTag tag) { + if (tag.getSclass() != null) { + tag.setSclass(tag.getSclass() + " " + String.join(" ", extraClasses)); + } else { + tag.setSclass(String.join(" ", extraClasses)); + } + } + } } /** * Configures an icon for a component using an icon name from the current theme. * Resolves the icon from {@link IconsTheme} and applies it to the component. * - * @param image the icon name or identifier + * @param icon the icon name or identifier * @param component the component to apply the icon to * @param size the desired icon size */ - public static void configureComponentIcon(String image, Component component, IconSize size) { - configureComponentIcon(IconsTheme.get().getIcon(image), component, size); + public static void configureComponentIcon(String icon, Component component, IconSize size) { + IconName iconName = Icons.parseIconName(icon); + configureComponentIcon(IconsTheme.get().getIcon(iconName.name()), component, size, iconName.classes()); } /** diff --git a/platform/ui/zk/src/main/resources/META-INF/dynamia/fa-icons.properties b/platform/ui/zk/src/main/resources/META-INF/dynamia/fa-icons.properties index 32cdf93b..90e42c97 100644 --- a/platform/ui/zk/src/main/resources/META-INF/dynamia/fa-icons.properties +++ b/platform/ui/zk/src/main/resources/META-INF/dynamia/fa-icons.properties @@ -175,3 +175,495 @@ error=exclamation-triangle warning=exclamation-circle success=check-circle information=info-circle +# Additional UI icons +power-off=power-off +bell=bell +volume-up=volume-up +volume-down=volume-down +volume-mute=volume-mute +archive=archive +inbox=inbox +outbox=share-square +reply=reply +reply-all=reply-all +forward=share +send=paper-plane +clock=clock +history=history +calendar-alt=calendar-alt +calendar-check=calendar-check +calendar-times=calendar-times +calendar-plus=calendar-plus +calendar-minus=calendar-minus +stopwatch=stopwatch +hourglass=hourglass +hourglass-start=hourglass-start +hourglass-half=hourglass-half +hourglass-end=hourglass-end +alarm=bell +timer=stopwatch +badge=certificate +bookmark=bookmark +bookmark-off=bookmark-o +flag=flag +flag-checkered=flag-checkered +thumbtack=thumbtack +paperclip=paperclip +file-text=file-alt +file-code=file-code +file-image=file-image +file-video=file-video +file-audio=file-audio +file-archive=file-archive +file-word=file-word +file-powerpoint=file-powerpoint +folder-open=folder-open +folder-plus=folder-plus +folder-minus=folder-minus +cloud=cloud +cloud-upload=cloud-upload-alt +cloud-download=cloud-download-alt +save-cloud=cloud-upload-alt +cloud-sync=sync-alt +share=share-alt +share-square=share-square +external-link=external-link-alt +anchor=anchor +link-broken=unlink +chain=link +chain-broken=unlink +qrcode=qrcode +sync=sync +sync-alt=sync-alt +spinner=spinner +circle-notch=circle-notch +redo=redo +redo-alt=redo-alt +forward-step=step-forward +backward-step=step-backward +fast-forward=fast-forward +fast-backward=fast-backward +skip-forward=forward +skip-backward=backward +record=dot-circle +volume=volume-up +mute=volume-mute +unmute=volume-up +eye=eye +eye-slash=eye-slash +show=eye +hide=eye-slash +visible=eye +invisible=eye-slash +toggle-on=toggle-on +toggle-off=toggle-off +power=power-off +plug=plug +battery-full=battery-full +battery-half=battery-half +battery-empty=battery-empty +battery-quarter=battery-quarter +battery-three-quarters=battery-three-quarters +signal=signal +wifi-slash=wifi +bluetooth=bluetooth +location=location-arrow +location-arrow=location-arrow +crosshairs=crosshairs +compass=compass +map-marker=map-marker-alt +map-pin=map-pin +directions=directions +route=route +lightbulb=lightbulb +idea=lightbulb +sun=sun +moon=moon +star-outline=star-o +adjust=adjust +sliders=sliders-h +equalizer=sliders-h +wrench=wrench +screwdriver=screwdriver +hammer=hammer +gavel=gavel +magic=magic +wand=magic +key=key +unlock-alt=unlock-alt +shield=shield-alt +shield-check=shield-check +bug=bug +fire=fire +fire-extinguisher=fire-extinguisher +first-aid=first-aid +medkit=medkit +heartbeat=heartbeat +hospital=hospital +ambulance=ambulance +plus-circle=plus-circle +plus-square=plus-square +minus-circle=minus-circle +minus-square=minus-square +times-circle=times-circle +times-square=times-square +check-square=check-square +check-double=check-double +question=question +question-circle=question-circle +exclamation=exclamation +exclamation-circle=exclamation-circle +exclamation-triangle=exclamation-triangle +info-square=info-square +angle-up=angle-up +angle-down=angle-down +angle-left=angle-left +angle-right=angle-right +angle-double-up=angle-double-up +angle-double-down=angle-double-down +angle-double-left=angle-double-left +angle-double-right=angle-double-right +caret-up=caret-up +caret-down=caret-down +caret-left=caret-left +caret-right=caret-right +caret-square-up=caret-square-up +caret-square-down=caret-square-down +caret-square-left=caret-square-left +caret-square-right=caret-square-right +chevron-up=chevron-up +chevron-down=chevron-down +chevron-left=chevron-left +chevron-right=chevron-right +chevron-circle-up=chevron-circle-up +chevron-circle-down=chevron-circle-down +chevron-circle-left=chevron-circle-left +chevron-circle-right=chevron-circle-right +arrow-up-long=long-arrow-alt-up +arrow-down-long=long-arrow-alt-down +arrow-left-long=long-arrow-alt-left +arrow-right-long=long-arrow-alt-right +arrows-alt=arrows-alt +arrows-alt-h=arrows-alt-h +arrows-alt-v=arrows-alt-v +sort=sort +sort-up=sort-up +sort-down=sort-down +sort-alpha-down=sort-alpha-down +sort-alpha-up=sort-alpha-up +sort-amount-down=sort-amount-down +sort-amount-up=sort-amount-up +sort-numeric-down=sort-numeric-down +sort-numeric-up=sort-numeric-up +grip-horizontal=grip-horizontal +grip-vertical=grip-vertical +grip-lines=grip-lines +ellipsis-h=ellipsis-h +ellipsis-v=ellipsis-v +ellipsis=ellipsis-h +more=ellipsis-h +more-vertical=ellipsis-v +more-horizontal=ellipsis-h +menu=bars +sidebar=bars +box=box +boxes=boxes +archive-box=archive +shopping-bag=shopping-bag +shopping-basket=shopping-basket +shopping=shopping-cart +cart=shopping-cart +basket=shopping-basket +percentage=percentage +percent=percent +infinity=infinity +recycle=recycle +trash=trash +trash-restore=trash-restore +trash-undo=trash-restore-alt +square=square +square-full=square +circle-outline=circle-o +dot=circle +bullseye=bullseye +crosshair=crosshairs +asterisk=asterisk +hashtag=hashtag +at=at +registered=registered +trademark=trademark +copyright=copyright +paragraph=paragraph +section=section +heading=heading +h1=heading +h2=heading +h3=heading +text-height=text-height +text-width=text-width +align-left=align-left +align-center=align-center +align-right=align-right +align-justify=align-justify +bold=bold +italic=italic +underline=underline +strikethrough=strikethrough +subscript=subscript +superscript=superscript +font=font +text=font +quote-left=quote-left +quote-right=quote-right +quote=quote-left +indent=indent +outdent=outdent +unlink=unlink +image=image +picture=image +photo=image +video=video +film=film +music=music +audio=volume-up +microphone-slash=microphone-slash +video-slash=video-slash +rss=rss +podcast=podcast +broadcast=broadcast-tower +signal-stream=signal +stream=video +wifi-strong=wifi +wifi-weak=wifi +signal-weak=signal +signal-strong=signal +graduation-cap=graduation-cap +university=university +school=school +certificate=certificate +award=award +trophy=trophy +medal=medal +ribbon=ribbon +crown=crown +gem=gem +coins=coins +money-bill=money-bill +money-bill-wave=money-bill-wave +hand-holding-usd=hand-holding-usd +donate=donate +handshake=handshake +balance-scale=balance-scale +chart-column=chart-bar +analytics=chart-line +stats=chart-area +trending-up=arrow-trend-up +trending-down=arrow-trend-down +briefcase=briefcase +suitcase=suitcase +luggage=suitcase +backpack=shopping-bag +laptop=laptop +laptop-code=laptop-code +laptop-medical=laptop-medical +keyboard=keyboard +mouse=mouse-pointer +print-printer=print +fax=fax +phone=phone +phone-alt=phone-alt +phone-slash=phone-slash +envelope-open=envelope-open +envelope-square=envelope-square +comment-dots=comment-dots +comment-alt=comment-alt +commenting=comments +conversation=comments +chat=comment +sms-message=sms +message=envelope +messages=comments +video-camera=video +webcam=video +smile=smile +laugh=laugh +grin=grin +sad=frown +angry=angry +surprise=surprise +thumbs-up-outline=thumbs-o-up +thumbs-down-outline=thumbs-o-down +handshake-alt=handshake +hands-helping=hands-helping +hand-paper=hand-paper +hand-rock=hand-rock +hand-scissors=hand-scissors +hand-spock=hand-spock +hand-point-up=hand-point-up +hand-point-down=hand-point-down +hand-point-left=hand-point-left +hand-point-right=hand-point-right +fingerprint=fingerprint +id-card=id-card +id-card-alt=id-card-alt +address-card=address-card +address-book=address-book +contacts=address-book +male=male +female=female +child=child +baby=baby +user-tie=user-tie +user-check=user-check +user-plus=user-plus +user-minus=user-minus +user-times=user-times +user-edit=user-edit +user-cog=user-settings +user-settings=user-cog +user-lock=user-lock +user-shield=user-shield +user-circle=user-circle +user-tag=user-tag +users-cog=users-cog +user-friends=user-friends +user-group=users +team=users +accessibility=universal-access +wheelchair=wheelchair +blind=braille +deaf=assistive-listening-systems +sign-language=sign-language +language=language +translate=language +globe-americas=globe-americas +globe-europe=globe-europe +globe-asia=globe-asia +globe-africa=globe-africa +plane=plane +plane-departure=plane-departure +plane-arrival=plane-arrival +car=car +taxi=taxi +bus=bus +train=train +subway=subway +bicycle=bicycle +motorcycle=motorcycle +ship=ship +rocket=rocket +helicopter=helicopter +parking=parking +gas-pump=gas-pump +traffic-light=traffic-light +road=road +home-alt=home +house=home +hotel=hotel +warehouse=warehouse +industry=industry +factory=industry +city=city +tree-alt=tree +mountain=mountain +umbrella=umbrella +umbrella-beach=umbrella-beach +coffee=coffee +mug=mug-hot +glass=glass-martini +beer=beer +wine-glass=wine-glass +utensils=utensils +cutlery=utensils +pizza-slice=pizza-slice +hamburger=hamburger +hotdog=hotdog +ice-cream=ice-cream +apple-alt=apple-alt +carrot=carrot +leaf=leaf +seedling=seedling +spa=spa +dumbbell=dumbbell +running=running +walking=walking +biking=biking +swimmer=swimmer +football=football-ball +basketball=basketball-ball +baseball=baseball-ball +volleyball=volleyball-ball +bowling=bowling-ball +golf=golf-ball +hockey=hockey-puck +table-tennis=table-tennis +gamepad=gamepad +dice=dice +puzzle-piece=puzzle-piece +chess=chess +crown-king=chess-king +crown-queen=chess-queen +paint-brush=paint-brush +palette-colors=palette +pencil-ruler=pencil-ruler +drafting-compass=drafting-compass +ruler=ruler +ruler-horizontal=ruler-horizontal +ruler-vertical=ruler-vertical +ruler-combined=ruler-combined +pen=pen +pen-fancy=pen-fancy +marker=marker +highlighter=highlighter +eraser=eraser +pushpin=thumbtack +paperclip-attach=paperclip +stapler=paperclip +scissors=cut +tape=tape +folder-tree=folder-tree +sitemap=sitemap +flow-chart=project-diagram +org-chart=sitemap +# Restaurant icons +chef=user-chef +chef-hat=hat-chef +kitchen=fire-burner +cooking=fire +menu-card=book-open +dish=plate-wheat +serving=concierge-bell +waiter=user-tie +dining=utensils +reservation=calendar-check +table-service=chair +food-order=clipboard-list +takeout=shopping-bag +delivery=truck +ingredients=carrot +recipe=list-alt +plate=circle +wine-bottle=wine-bottle +cocktail=glass-martini-alt +bar=glass-cheers +# POS (Point of Sale) icons +pos=cash-register +barcode-scan=barcode +receipt-print=receipt +card-reader=credit-card +card-swipe=credit-card-front +card-chip=microchip +payment-terminal=calculator +cashier=user-tie +cash-drawer=box-open +transaction=exchange-alt +refund=undo-alt +discount=percent +coupon=ticket-alt +loyalty=star +price-tag=tags +inventory=boxes +stock=warehouse +sale=hand-holding-usd +checkout=shopping-cart +bill=file-invoice-dollar diff --git a/pom.xml b/pom.xml index 779c9b08..c61ae36f 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ 4.0.0 tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 pom Dynamia Soluciones IT SAS diff --git a/themes/pom.xml b/themes/pom.xml index 35e6409f..8d7b2083 100644 --- a/themes/pom.xml +++ b/themes/pom.xml @@ -6,7 +6,7 @@ tools.dynamia tools.dynamia.parent - 26.2.0 + 26.2.1 ../pom.xml diff --git a/themes/theme-dynamical/sources/pom.xml b/themes/theme-dynamical/sources/pom.xml index 90812182..5c45a33e 100644 --- a/themes/theme-dynamical/sources/pom.xml +++ b/themes/theme-dynamical/sources/pom.xml @@ -24,7 +24,7 @@ tools.dynamia.themes tools.dynamia.themes.parent - 26.2.0 + 26.2.1 ../../pom.xml @@ -102,7 +102,7 @@ tools.dynamia tools.dynamia.zk - 26.2.0 + 26.2.1 provided