registry.addGlobalComponent("test-modal", Views.modalView()
.label("Terms and Conditions")
.addField("testField", Fields.string()
.label("Test Field")));
As of Broadleaf Release Train 2.3.0-GA, support for Spring Boot 3.3 & 3.5 for all common libraries has been added.
Added new attribute augmentable to Component that allows to disable form modification for views. Defaults to true.
This attribute cascades to child components overriding their settings.
Introduce Global Components to the registry
Global components are reusable components that can be shared across multiple containers. For instance, defining a modal once that can be triggered by multiple links in one or more forms.
registry.addGlobalComponent("test-modal", Views.modalView()
.label("Terms and Conditions")
.addField("testField", Fields.string()
.label("Test Field")));
Added new DSL for defining Modal Views.
Introduced ModalView interface and Views.modalView() builder method.
ModalView is a specialized form view designed for modal dialog presentations.
ModalViewCreate and ModalViewUpdate interfaces can be used for entity creation and update scenarios.
Introduced new DSL for CheckboxField component.
Introduced CheckboxField interface and Fields.checkbox() builder method.
CheckboxField is used to represent a boolean value as a checkbox in forms.
Added new DSL for BadgeColumn and BadgeTileComponent.
Introduced BadgeColumn interface and Columns.badge() builder method.
Introduced BadgeTileComponent interface and TileComponents.badge() builder method.
BadgeColumn and BadgeTileComponent are used to display badges in grid views.
Introduced new Simple classifier for components to handle simple components that don’t require or support all of the configuration options of Form Components, Groups, Views, Externals, etc.
Simple components can be added to other components using Component#addSimpleComponent, which will autogenerate the key to be in the form simple:{type}:{order}.
Generally this will be sufficient, but they can also be added like normal components and supplied a manually defined key.
Introduced a Divider component to render a horizontal rule within forms or groups.
Takes a width attribute, indicating the width of the horizontal rule—default is sm indicating 1px.
Takes a spacing attribute indicating the spacing above and below the rule in rem—default is md indicating 2rem.
Groups.basic()
.label("product.groups.basic-information")
.addField(ProductProps.NAME, Fields.string()
.label("product.fields.name")
.required()
.translatable()
.readOnly(!isCreate)
.hidden(!isCreate)
.order(1000))
.addSimpleComponent(SimpleComponents.divider()
.order(1500)
.width(Divider.Width.SMALL)
.spacing(Divider.Spacing.MEDIUM))
Added a new DSL for LargeContentColumn and its default implementation DefaultLargeContentColumn.
This renders a column for the LARGE_CONTENT type with large contents like embedded collections, which displays the content as truncated strings.
The column value is clickable, which will show a modal with the full contents formatted similar to YAML style.
This component can take a lines attribute to configure the number of lines to truncate to for the column value.
Out of box, the default value is 1 and the maximum value is 6.
There is also a clearLines() method that will clear the lines attribute from the column.
LargeContentColumnFields.residentGrid()
.label("sandbox.grid.change-summaries")
.addColumn(SandboxProps.DETAILS, Columns.largeContentColumn()
.label("sandbox.columns.details")
.lines()
.order(1000))
Added a new DSL for ModalLinkColumn and its default implementation DefaultModalLinkColumn.
This renders a column for the MODAL_LINK type whose column value is clickable, and upon clicking will show a modal form with the fields and components configured via metadata.
Aside from being able to add fields and components, the endpoint to submit the modal form to can be configured via metadata as well.
ModalLinkColumnExternals.grid()
.label("product.externals.promotional-product")
.scope(ProductScopes.PRODUCT)
.sandboxTrackable(CatalogChangeContainers.PROMOTIONAL_PRODUCT)
.catalogTrackable()
.sortable()
.addColumn(ProductProps.Marketing.TYPE, Columns.modalLink()
.label("Update Promotional Product")
.order(1000)
.sandboxTrackable(CatalogChangeContainers.PROMOTIONAL_PRODUCT)
.catalogTrackable()
.submitEndpoint(Endpoints.put()
.uri(ProductPaths.PROMOTIONAL_PRODUCT)
.scope(ProductScopes.PRODUCT))
.addField(ProductProps.Marketing.TYPE, Fields.select()
.label("Type")
.required()
.defaultValue(PromotionalProductTypeOptionEnum.FEATURED)
.options(PromotionalProductTypeOptionEnum.toOptions())
.order(1000))
.addField(ProductProps.Marketing.RELATED_PRODUCT_ID,
ProductLookupHelpers.createProductIdLookup()
.label("Select a Product")
.required()
.order(2000))
.addField(ProductProps.Marketing.PROMOTION_MESSAGE, Fields.string()
.label("Promotional Message")
.translatable()
.order(3000)));
Added displayOnly and displayOnly(boolean displayOnly) attribute methods to the Field DSL in order to display it as a plain or raw text representation of the field.
Introduce FORM_FIELD column type.
This column type allows for inline editing of the row entity by displaying an editable form field in the column.
Changes are submitted on blurring the field (moving focus away from it or just toggling for a boolean).
It supports the following field types:
BOOLEAN
DATE
DECIMAL
INTEGER
LONG
LOOKUP
MONEY
PHONE
SELECT
STRING
FORM_FIELD columnexternalGrid
// define an update endpoint to perform the save operation
.updateEndpoint(endpoint -> endpoint
.uri(EntityPaths.ENTITY)
.scope(EntityScopes.ENTITY))
// add a form field column
.addColumn(EntityProps.DATE, Columns.formField()
.label("Date")
.field(Fields.bool()
.name("date")
// required to avoid displaying decorations inside the grid cell
.decorated(false))
.order(3000))
Added new DSL for MoneyTileComponent to display monetary amount fields on tile grids
Added new DSL for CheckboxField component type.
Updated EntityFormView to be able to configure an UPDATE endpoint on the form itself that overrides the parent View’s UPDATE endpoint
UPDATE endpoint per formUpdateEntityView view = Views.entityViewUpdate()
.label("Update View")
.submitUrl("/main-entity", Scopes.SCOPE)
// ...
.addForm("separateEntityForm", Views.entityForm()
.label("Form with External Related Entity")
.updateUrl("/external-entity", Scopes.EXTERNAL_SCOPE);
Improved support for ExternalFieldGroup
|
Note
|
This work was done in support of allowing a fields within an ExternalFieldGroup to be updated using a form’s override update endpoint where the actual parent entity’s state wasn’t being modified and wouldn’t be returned from the submit endpoint, which was in a different microservice.
|
Added explicit DSL support for ExternalFieldGroup
Updated ExternalTypes & Externals to be able to expose the DefaultExternalFieldGroup DSL for metadata configuration
Added attributes map to Endpoints metadata with relevant helper methods
Added Endpoint attribute, responseIsPartialState: Indicates that this endpoint’s response will be a partial state that should be merged with the existing entity state, similar to a PATCH request. This is useful for APIs that do not support PATCH requests directly or that are backing external field groups on a different entity’s form. In those cases, the parent entity state should be merged with the new state returned by the endpoint to maintain the full view state.
Fixed Groups not getting their IDs set when using Form#addGroup(String type, Group<?> group)
Expanded javadocs on various metadata DSL interfaces
Added attribute to ExternalFieldGroup, useParentFormState. Indicates that the state for the fields in this group will be backed by the parent form’s.
If false, then a nested form state will be created to hold the field values in isolation from the parent. Note that this currently makes the group effectively read-only.
If true, then users should ensure that the field names are prefixed with the Group.getId() since this is used in the admin to ensure that the values do not collide with other fields in the parent form. TransformBody and MappingList can be used to map the form state to the appropriate structure expected by the form or entity submit endpoint (if any) and vice versa.
ExternalFieldGrouppublic void exampleUsage() {
form.updateEndpoint(Endpoints.post() // <-- overrides the View's endpoint
.responseIsPartialState()
.uri("/dto-endpoint")
.transformRequest(t -> t.mappings(transformEntityToRequestDto("externalGroupId")))
.transformResponse(t -> t.mappings(transformEntityFromRequestDto("externalGroupId")))
.scope("DTO"))
.addGroup("externalGroupId", getExternalGroup());
}
public static MappingList transformEntityToRequestDto(String groupId) {
return new MappingList(Arrays.asList(
Mappings.mapValue("%s.%s".formatted(groupId, "field1"), "field1"),
Mappings.mapValue("%s.%s".formatted(groupId, "field2"), "field2"),
Mappings.mapValue("%s.%s".formatted(groupId, "field3"), "field3")));
}
public static MappingList transformEntityFromRequestDto(String groupId) {
return new MappingList(Arrays.asList(
Mappings.mapValue("field1", "%s.%s".formatted(groupId, "field1")),
Mappings.mapValue("field2", "%s.%s".formatted(groupId, "field2")),
Mappings.mapValue("field3", "%s.%s".formatted(groupId, "field3")));
}
Added DateRangeColumn class to define a type of column that takes in a start date and end date to display a date range.
Added a DurationColumn class to define a type of column that takes in an integer value and displays it in a user-friendly format.
Includes a baseUnits attribute to specify the base units of the given duration.
Introduced DurationBaseUnits utility class to define the available base units:
DAY
WEEK
MONTH
YEAR
grid
.addColumn(DURATION, Columns.duration()
// The duration will be displayed in days
.baseUnits(DurationBaseUnits.DAY));
Added support for date fields to be computed based on another date field and a duration, e.g., allow active end date to be computed as the active start date plus 30 days.
Added computedFromDate, computedFromDuration, and computedFromDurationUnit attributes to the DateField, along with corresponding DSL methods.
form
// Add a duration field that will be used to compute the end date
.addField(DURATION, Fields.duration())
// Add a start date field
.addField(ACTIVE_START_DATE, Fields.date())
// Add an end date field that will be computed based on the start date and duration field
.addField(ACTIVE_END_DATE, Fields.date()
.computedFrom(
ACTIVE_START_DATE,
OFFER_DURATION,
// Specify the base units for the duration field
DurationBaseUnits.DAY
)
);
Added new DSL methods to CreateEntityView to configure toast notifications to display on succesful create of an entity:
Introduced successNotificationOnCreate() method to configure a success notification with a default message.
Introduced successNotificationOnCreate(String message) method to configure a success notification with a custom message.
Introduced successNotificationOnCreate(InternationalizedMessage message) method to configure a success notification with a custom internationalized message.
Added new iconName DSL method to allow setting a custom icon to be displayed by the following components:
FilterAction
CommonStartExportAction
ExportGridAction
ImportGridAction
See Import Services 2.1.1 for StartImportAction component changes.
Added ComputedField & DefaultComputedField DSL support for Form components to allow defining fields whose values are computed based on other field values using a specified function.
.Example Usage:
form
.addField("shopPrice", Fields.money()
.label("Shop Price")
.validationSchema(ValidationSchemas.money()
.method(ValidationMethods.positive(
"Must be positive")))
.order(1000))
.addField("shopMarkup", Fields.money()
.label("Shop Markup")
.validationSchema(ValidationSchemas.money()
.method(ValidationMethods.positive(
"Must be positive")))
.order(2000))
.addField("productMarkup", Fields.money()
.label("Product Markup")
.validationSchema(ValidationSchemas.money()
.method(ValidationMethods.positive(
"Must be positive")))
.order(3000))
.addField("finalPrice", Fields.computed()
.label("Final Price")
.computationType(ComputedField.ComputationTypes.SUM)
.fieldsToCompute(List.of("shopPrice", "shopMarkup", "productMarkup"))
.order(4000));
Added ToggleTileComponent as a new type of TileComponent that represents a boolean value as a toggle switch on a tile grid.
.Example Usage:
browseComponent.getDefaultGrid()
.addTileComponent("thumbnail", TileComponents.thumbnail()
.toggle(TileComponents.toggle()
.name("featured")
.label("product.browse.columns.featured")
.icon("star")
.submitEndpoint(endpoint -> endpoint
.uri(ProductPaths.TOGGLE_FEATURED_TAG)
.scope(ProductScopes.PRODUCT)
.param("toggleValue", "${toggleValue}"))
.order(1000)));
Added skipSandboxing attribute to GridExternal.
This allows grids that pull data from external sources to opt out of sandboxing if the external source is not expected to be affected by sandboxing or if the grid is intended to show unsandboxed data for some reason.
Introduced InterdependentExternalGridsGroup concept to allow grouping together multiple instances of GridExternal that are related to each other and have interdependent data such that they should have their state changes tracked together in the admin and be displayed together in the UI.
For instance, this can be used for a group of grids that all pull from the same external source and should be tracked together in the admin since they will all be affected by the same external state changes, or if a change in one grid should trigger a refresh in the other grids since they are related and likely displayed together in the UI.
The following methods & attributes were added to support this feature:
listensFor(Map<String, List<String>>) & listensForGridsAndOperations: This method adds the listensForGridsAndOperations attribute and configures the other external grids within the InterdependentExternalGridsGroup that this grid will be listening for.
This means that if a change is made to any of the configured grids, then this grid will be refreshed (i.e. the configured READ endpoint for the grid will be called).
Operations can also be defined for each dependent grid to allow for conditional updates, but are not required.
The operations are expected to be GridExternal.GridListenerOperations so that this grid is refreshed depending on the operation done on the grid being listened to.
.Example Usage:
private Group<?> getPromotionsGroup() {
return Groups.interdependentExternalGrids()
.addExternal("CURRENT_PROMOTIONS", Externals.grid()
.id("CURRENT_PROMOTIONS")
.label("Current Promotions")
...
.listensFor(Map.of("UPCOMING_PROMOTIONS", List.of())))
.addExternal("UPCOMING_PROMOTIONS", Externals.grid()
.id("UPCOMING_PROMOTIONS")
.label("Upcoming Promotions")
...
.listensFor(Map.of("CURRENT_PROMOTIONS", List.of(GridExternal.GridListenerOperations.ON_CREATE))));
}
Added the readOnSuccess attribute to ModalFormAction to specify whether a re-fetch should be executed after the modal form action is successfully executed.
The read endpoint that is configured for the grid will be used to trigger this re-fetch.
Introduced support for defining tile*based UI components within the metadata DSL.
Added the TileComponent interface and supporting types.
Created the TileGrid interface to enable grid views with tile support.
Provided default implementations:
DefaultTileComponent
DefaultLinkTileComponent
DefaultThumbnailTileComponent
Added specialized interfaces:
LinkTileComponent
ThumbnailTileComponent
Introduced utility classes:
TileComponentTypes for standard tile types.
TileComponents for convenient creation of tile components.
AbstractTileComponent as a base class for custom tiles.
Updated Classifiers to include a TILE_COMPONENT identifier.
Extended EntityGridView to support TileGrid features.
EntityGridView<?> entityGridView = productGrid
...
.tiled(Arrays.asList(
TileComponents.thumbnail()
.name(ProductProps.PRIMARY_ASSET_URL_SEARCH)
.order(1000),
TileComponents.linkById("catalog:products:${businessType}:update")
.name(ProductProps.NAME)
.label("product.columns.name")
.order(2000)))
.defaultTiled()
...
Added support for specifying additional form state fields and response fields in SlideOverFormAction, allowing more flexible data transfer between actions and forms.
Introduced new methods additionalFormState and additionalResponseFields to facilitate this functionality.
Introduced LOOKUP column type.
Added support for restricting routes by matching all security scopes not just any.
The previous default behavior when matching a Route’s security scopes was to match any.
ComponentRoute now has a scopeMatchType property that can be set to either ANY or ALL, with ANY as the default.
Related changes have been made to Admin Metadata Service 2.1.4-GA.
@Bean
public ComponentRouteLocator productMetadataRoutes(RoutesBuilder routesBuilder) {
RoutesSpec routes = routesBuilder.routes()
.route("/products", r -> r.componentId("catalog:porducts:browse")
.scope("PRODUCT")
.scope("CUSTOM_ADMIN_VIEW_SCOPE")
.allMatchScopes(); // <-- NEW, default is `.anyMatchScopes()`
return routes.build();
}
Deprecate the Pricing Consumer Metadata Module
The use of this module produced unwanted coupling between separate consumer services and versions, so it was deprecated for ease of customization across the affected services' views.
Important: All the metadata contained in this module is now defined by the consumer services themselves.
Added new attributes to EntityGridView to support restricting visibility of grids to tenant-only, application-only, or specific application contexts.
tenantOnly: Boolean flag.
applicationOnly: Boolean flag.
restrictionApplications: Array of strings that are the IDs of the applications the grid is restricted to.
Added support for UpdateEntityView to be able to define a confirmation message on the view that will be displayed in a confirmation dialog when the user attempts to submit changes from the view that will affect dependent entities.
Added the following attributes & methods to UpdateEntityView to support this feature:
confirmDialogBtnLabel - The preferred label of the confirmation dialog submit/confirm button.
confirmationDialogConfirmed - The key of the value that will be set on the submission request context when the user confirms the dialog, which can be used to conditionally perform logic in the endpoint based on whether the user confirmed or not.
confirmDialogMessage - The message to be displayed in the confirmation dialog when triggered.
confirmDialogTitle - The title to be displayed in the confirmation dialog when triggered.
dependentEntities - A map of entity types that are mapped to their respective endpoints that will be used to fetch the details of existing dependent entities that match the given types.
dependentEntitiesAction & dependentEntitiesLabel - The action configuration and label for an optional action that will be displayed in the the UpdateEntityView that allows users to view the dependent entities that will be affected by the update operation.
This is intended to help users make informed decisions when confirming the dialog by allowing them to see what entities will be affected by their action
showConfirmationDialog - A boolean flag to indicate whether to show the confirmation dialog or not.
.Example Usage
Views.entityLongFormViewUpdate()
...
.submitEndpoint(endpoint -> endpoint
.uri(Paths.URI)
.scope(Scopes.SCOPE)
.param("acceptedConfirmationDialog", "${$confirmationDialogConfirmed}"))
.confirmationDialog("entity.update.confirm-dialog.title",
"entity.update.confirm-dialog.message",
"entity.update.confirm-dialog.button-label",
"$confirmationDialogConfirmed")
.dependentEntity("PRODUCT", Endpoints.get()
.uri(ProductPaths.PRODUCTS_IGNORE_CATALOG_NARROWING)
.scope(ProductScopes.PRODUCT)
.param("cq", "businessType=eqic=(${typeKey})"))
.dependentEntitiesLabel("business-type.update.actions.dependent-entities")
Introduce rowMessage concept to Grid.
Introduce support for a 'notification' message type in Messages/MessageTypes.
Introduce SlideOverFormAction concept.
Update ResidentGridField to have CREATE_VIEW and UPDATE_VIEW action types.
Update PropertyConditional to support empty, notEmpty, and blank conditions.
Introduce maxRows concept to FieldArrayGridField.
Introduce Orderable interface to FieldArrayGridField.
Introduce new enums, properties, and form fields to support new PriceData concepts from PricingServices 2.1.0.
Added first class support for allowCustomFields attribute for rule and query builders.
Introduce new metadata dsl for EntityAssetCollections to make use of new drag-and-drop sorting in the admin.
Added custom CSS support to grids.
Added metadata changes to allow hints and help texts on select grids.
Introduce support for InlineGridSelectAction that will display a list of options to select from.
Added conditional price data view types to split subscription and non-subscription price data metadata components.
Updated pricing metadata to support various pricing strategies.
Added auditable behavior attribute flags for metadata components.
Fix behavior of orderable, selectable, and sortable grid options
A bug in this behavior caused some grids to not be disabled when set as disabled in the metadata.
Add explicit support for EnumSwitchField.
This is a special field used to display enumerated values in a boolean-like toggle switch.
Added support to MoneyColumn to display simple values.
This makes it comparable with MoneyField to allow displaying decimal fields that inherit currency from the parent entity.
Introduced AddAdjustmentModalFormAction as secondary action for the UpdateEntityView.
Added a secondary action to display a basic modal form with submit support.
Registered a new FORM secondary action for entity views that simply renders a form configured via metadata and allows submitting to an endpoint.
Enhanced the default ComponentRegistry to register components with case-insensitive keys.
Amended export related metadata to accommodate new filter parameters and fields
Added ability to define passFilterStringAsParam attribute for SelectTargetEntityGridView and ExportGridAction.
Set passFilterStringAsParam attribute to false by default for ExportGrid.
Deprecated filterTargetEntities for filterTargetEntitiesField, which adds QueryBuilderField as a field to SelectTargetEntityGridView for the passing of a filter to the export endpoint.
Added ability to fetch all fields from QueryBuilderFilterAction.
Added new URI/endpoint definitions to CommonStartExportAction for starting an export that includes the filter string from the QueryBuilderField as the filter parameter value for backwards compatibility.
Amended Grid validation logic to allow SelectTargetEntityGridView to have QueryBuilderField as a field component without having to be a column component
|
Important
|
Requires AdminWeb 1.10.7 for admin compatibility. |
Added support to use Search Facets on Entity Browse List Grids.
Allowed defining attribute to enable faceted search, useFacetedSearch
Allowed defining a fallback endpoint to use if search is disabled or in a problem state
This may be configured similarly to any read endpoint using #fallbackEndpoint builder methods.
Allowed defining search-appropriate parameters for the main read endpoint
FilterableGrid.FilterParams#FACET_RULES: Allows passing Facet Rules to Search.
Value is cq.
FilterableGrid.FilterParams#FACETABLE_TYPE: Allows passing the indexable type to Search.
Value is indexableType.
FilterableGrid.FilterParams#FACET_QUERY: Allows passing regular a text query.
Value is query.
entityGridView
// for fallback endpoint
.filterByTextQuery(FilterableGrid.FilterParams.QUERY,
UnaryOperator.identity(),
FilterableGrid.EndpointTypes.FACETED_SEARCH_FALLBACK)
.filterByQueryBuilder(FilterableGrid.FilterParams.QUERY_BUILDER,
UnaryOperator.identity(),
FilterableGrid.EndpointTypes.FACETED_SEARCH_FALLBACK)
.facetedSearch("PRODUCT",
readEndpoint -> readEndpoint
.narrowedPaging()
.uri(ProductPaths.PRODUCTS)
.scope(ProductScopes.PRODUCT))
.readEndpoint(readEndpoint -> readEndpoint
.numberedPaging()
.uri(ProductPaths.CATALOG_SEARCH)
.scope(ProductScopes.PRODUCT));
Enable search group tracking & discrimination via metadata
This works similarly to Catalog and Profile discrimination using searchGroupTrackable().
DefaultSearchSettingsFormView formView = new DefaultSearchSettingsFormView()
.searchGroupTrackable()
.sandboxTrackable(SearchSettingsChangeContainers.SEARCH_SETTINGS)
.addExternal(SearchSettingsGrids.FACET_GROUPS, Externals.grid()
.id("facetGroups")
.label("search-settings.external-grid.facet-groups")
.searchGroupTrackable()
.sandboxTrackable(
SearchSettingsChangeContainers.SETTINGS_FACET_GROUP));
Allow adding Form Views to EntityBrowseView easily Forms added to views will appear as separate "tabs".
Added support for defining "Action Groups" on ActionGrids.
These are used to create a dropdown with the included actions rather than listing them in line in the grid header.
.addGridActionGroup("Bulk Operations",
Actions.bulkAction()
.bulkOperationType("SET_ACTIVE_PRODUCT")
.entityType(entityType)
.generateFriendlyName()
.label("product.bulk-operation.update-active")
.addField(ProductProps.ONLINE, Fields.bool()
.label("product.columns.online")
.required())
.addField(ProductProps.ACTIVE_START_DATE, Fields.date()
.label("product.fields.active-start-date"))
.addField(ProductProps.ACTIVE_END_DATE, Fields.date()
.label("product.fields.active-end-date")
.validationSchema(ValidationSchemas.date()
.method(ValidationMethods.isAfter(
"product.fields.active-end-date.must-be-after")
.arg(ProductProps.ACTIVE_START_DATE))))
.addSubmitEndpoint(Endpoints.post()
.uri(BulkOperationPaths.EXECUTE_BULK_OPERATION)
.scope(BulkOperationScopes.BULK_OPERATION)),
Actions.bulkAction()
.bulkOperationType("ARCHIVE_PRODUCT")
.entityType(entityType)
.generateFriendlyName()
.label("product.bulk-operation.archive")
.addGroup("warning", Groups.inline()
.addMessage("deleteWarning", Messages.warningMessage()
.message("product.bulk-operation.archive.warning")
.order(1000)))
.addSubmitEndpoint(Endpoints.post()
.uri(BulkOperationPaths.EXECUTE_BULK_OPERATION)
.scope(BulkOperationScopes.BULK_OPERATION)))
Added support for "singleValue" flag to the ResidentMapField and removed grid column validation if the grid has the "singleValue" attribute.
As of Broadleaf Release Train 2.0.0-GA, all common libraries have been upgraded to Spring Boot 3.
This version includes all changes up to 1.7.16-GA
Added Message metadata classifier and class
Added WARNING message type
Added type field to ExplanatoryMessage metadata class
Changes to ImplicitFilter metadata:
Added attributes map field.
Added attribute and removeAttribute methods.
Add support to build implicit filters using metadata
Added targetField, operator, objectPath, and objectAttributeKey metadata attributes to ImplicitFilter
The values specified by these attributes will later be used to dynamically build a query string, for instance:
The following metadata definition of an implicit filter
----
.implicitFilters(ImplicitFilter.customFilter("cq")
.targetField("contextId")
.operator("=out=")
.objectPath("parent.$parent.isolatedCatalogs")
.objectAttributeKey("id"))
----
Will result in a cq string result like the following: contextId=out=(isolatedCatalogId1,isolatedCatalogId2,isolatedCatalogId3)
If the system fails to build a filter string using these attributes, the implicit filter will not be added
Add MODAL_SIZE attribute to ModalFormAction
Update LookupField metadata to add catalog selector attributes
Improved DerivedFields:
Allow derived values other than strings.
Use .fieldType(String).
Default is DerivedField.SupportedFieldTypes.STRING.
Boolean, Color Picker, Date, Decimal, HTML, Integer, Long, Money, String Array, and Text Area
Allow specifying more transformation types for strings
Upper, lower, start, and pascal case and capitalize
Allow specifying if a derived field’s value should actually be persisted or if the derived value should merely be displayed.
Use .persist(boolean).
Default is true.
Added DerivedColumn component:
Takes a source and columnType similar to DerivedField
Can set deriveIfNull to allow deriving the value if the column’s value is null
Does not support transformations like DerivedField
Added applicationTrackable flag to Trackable
Added decorated flag to Field
Added creatable and catalogSelector flags to LookupField