Skip to main content

Angular Expanders 4.5.0

· 3 min read
Jan Hardy
Jan Hardy
R&D Engineer

Migration guide

@imports anchor

Some expanders have been migrated to the new import system, see changelog for the list. This means that feature anchor for imports are no longer necessary and hence they have been removed. To add imports in these files you can add uses statements to the feature expander.

Name changes

Some services have changed name to better comply to the guidelines or to better describe the functionality. This reflects in custom imports and need to be checked.

  • dataConnector.service -> DataConnector-data-access.service
  • dataConnector.datasource -> DataConnector-data-source.service
  • dataConnector.filtersource -> DataConnector-filter-source.service
  • dataConnector-infinite.datasource -> DataConnector-infinite-data-source.service
  • .data models have been changed to .document.

Moved service injection location

Instead of injection services in the constructor they are now injected as variables. This is also done using the new import system, which makes it easier to maintain. See changelog for the list of affected files. It also changed some of the injected names used:

  • dataSource -> dataConnectorDataSource
  • filterSource -> dataConnectorFilterSource
  • route -> activatedRoute
  • translate -> translateService

Mapping location change

DataConnector models are not mapped in the DataConnector-data-access.service anymore, but have there dedicated mapping services now. If any customizations were added to these mappings, then the corresponding harvest code needs to be moved to the new mapping services.

Removed shared components

The DropdownComponent and MultiSelectDropdownComponent have been removed and the use has been replaced with the select component from ngx-ns-core.

Default translation file

The default translation file has changed from en.json5 to gen.json5. This one is used by default, but can be replaced with a custom one by using option angular.defaultLanguage on AngularApp. You should change the name of the harvest file to keep custom translations.

Functional key -> id

In this version a refactoring has been done to not rely on functional key of the DataElement as a variable anymore, but use a generic id name. This impacts routes and method arguments.

Routes

In places where you retrieve the id from the route, the name of the variable should be changed.

Before
const id = this.activatedRoute.snapshot
.paramMap.get('externalId');'
After
const id = this.activatedRoute.snapshot
.paramMap.get('id');

Method arguments

The method interface has been altered in places where the id of an element is needed to use id instead of functional key. This has been done to better comply to the id and displayLabel field added to all element models. This can be used with duck typing as well now.

Before
getSingle({ uuid }: { uuid: string }): Observable<DemoElementModel>
After
getSingle({ id }: { id: string }): Observable<DemoElementModel>

QuerySearch Expanders 2.26.0

· 2 min read
Frédéric Hannes
Frédéric Hannes
R&D Engineer

Changes and improvements

QueryValueType

The QueryValueType enumeration is used to indicate the type of an object passed to a query constraint. Usually a developer will not interact with this, as every constraint factory method that takes it as a parameter, also comes with a variant that does not. In the latter case, the type will be inferred from the object that is passed to the constraint. This can only be inferred for known types, which is mostly primitives and java.util.Date.

As a default, when not recognized, the type would automatically be set to String, resulting into a conversion of the object to String in supporting constraints. With this update the type QueryValueType.OBJECT was added which handles the supplied object as a raw value that is passed directly into JPA, as this is sometimes desired.

Since converting to String is typically not intended behavior for objects that are not of that type, the default when a type cannot be determined is now QueryValueType.OBJECT. This is a breaking change, but should have very little impact, as currently, cases where unknown object types are passed to a constraint are likely to be unintended. In cases where this is intended, the migration guide will explain how to resolve this in the new implementation.

ProcessAutomation 1.0.0

· 3 min read
Jorren Hendriks
Jorren Hendriks
R&D Engineer

In the past six months we've seen adoption of the process-automation component. Feedback has been great and people seem to be happy with the changes we made. We felt the current feature set came to a point where it warrants a first stable release. This of course does not mean development will stop here, as there are many features we still plan to add.

Resources

ResourceVersion
process-automation-component 1.0.0

Feature set summary

The list below should give you a good idea of the features we currently support through process-automation:

  • Fully supports the workflow model.
    • Integrates all defined transitions, including branching transitions.
    • Respects configuration on TaskElements, such as transactionType and TaskOutcomes.
    • Supports configuring WorkflowImplementation through defining QueuedProcessors.
  • Multi-node or multi-instance configurations are supported.
    • Internal state-machine to perform leader-election in the presence of multiple nodes.
    • Ensures smooth execution of transitions, with no conflicting state.
    • Improved scalability by providing extensible queue configurations.
  • Event-based execution model, backed by a queue.
    • CRUD triggers: transition an element on create or modify.
    • Transition trigger: immediately queue the next transition after another completes.
    • DataCommand trigger: transition an element when a command is performed.
    • Schedule trigger: Cron-like configuration for time-based transitions.
    • FlowEngine trigger: behaves similar to the classic Flow implementation.
  • Modular design, ships with standard configurations and can be extended easily.
    • Provided queue implementations: ApplicationPersistence (DB) and InMemory.
    • Provided processing implementations: Asynchronous and ExecutorService.
note

There is no full feature-parity with the Workflow component yet, so consider this when planning to migrate. Reaching this point however is a goal of the following release, as the primary omission is support for TimeWindow/TimeWindowGroup.

Migration guide available in full post... (Read more)

Angular Expanders 4.4.0

· 2 min read
Jan Hardy
Jan Hardy
R&D Engineer

Migration guide

Branding

Using the option angular.hasCustomBranding we can toggle the default nsx branding off and have custom anchors instead.

caution

Some of the anchor names have been changed:

  • index.html: favicon -> branding-favicon
  • _default-theme.scss: colors -> branding-colors
  • _default-theme.scss: typography -> branding-typography
  • _default-theme.scss: density -> branding-density
  • layout.html: sidebar-branding -> branding-sidebar

Customization

Option angular.hasCustomHeaderContent can be used to turn off the default expanded behaviour of the top bar. With the option angular.hasCustomTableRowActions on a DataView you can have custom anchors instead of the default actions in a table.

caution

Some of the anchor names have been changed:

  • layout.html: header-content -> customization-header-content

Ngx-ns-core update

The size of the runtime library was getting to big for the application's initial load. For this reason the library has been split up in smaller sub-entries, which improves load times and tree-shaking. However, this changed the imports for these runtime components and services.

Before
import { AlertService } from '@nsx/ngx-ns-core'
After
import { AlertService } from '@nsx/ngx-ns-core/alert'

Expanders 6.6.0

· One min read
Koen De Cock
Koen De Cock
R&D Engineer

Resources

The expansion resources below provide Expanders 6.6.0.

ResourceVersion
Expanders6.6.0
nsx-default-stack2024.2.0

Expander development changes

Expanders 6.6.0 mainly focuses on improvements for Expander development.

Type attribute for uses

Uses statements in mapping file can now have a type attribute. The way the type is resolved in specific to the import strategy.

For java import, you can now add static imports by adding type="static".

  <uses type="static" eval="'net.democritus.sys.NullDataRef.EMPTY_DATA_REF'"/>

@import parameters

The @imports statement in Expander templates can now have one or more parameters. These parameters in case you have multiple types of imports in the same artifact (e.g. in Angular).

Read more.

ExpanderRelocation

There is now support for renaming Expanders, changing packages or changing the artifact location. By defining an ExpanderRelocation DataResource, you can redirect Features and harvest files to the new location, so that everything still works the same way after the change.

Read more.

Angular Expanders 4.3.0

· 2 min read
Jan Hardy
Jan Hardy
R&D Engineer

Changes and improvements

This update contains a lot of improvements for wiring capabilities, making it easier to reuse expanded elements in custom pages.

List page refactored

The expanded list page has been updated to use the new table with multi sort capabilities. The table is extracted from the page component and resides in its separate DataViewTable component. It now uses the upgraded filter component, that is generated based on the QuerySearch setup. Filtering state between the ngx-ns-core component and the generated dropdown form is managed by the new DataConnectorFilterSource service. Instead of managing the pagination, filtering and sorting manually in the list component, a DataConnectorDataSource service has been introduced to make this easier.

Table refactored

Breaking change: Existing components nsx-table, nsx-table-column and directive [nsxTableCell] have been replaced with counterparts from the ngx-ns-core library.

The table now has multi sort capabilities, supports sticky headers and columns, and accepts a NscDataSource as well as data arrays.

Paginator refactored

Breaking change: Existing component nsx-paginator has been replaced with counterpart from the ngx-ns-core library.

Filter refactored

Breaking change: Existing component nsx-table-search has been replaced with counterpart from the ngx-ns-core library. The filtering capabilities have been upgraded.

Expanders 6.4.0

· 2 min read
Koen De Cock
Koen De Cock
R&D Engineer

Resources

The expansion resources below provide Expanders 6.4.4.

ResourceVersion
Expanders6.4.4
nsx-default-stack2024.0.2
rest-jaxrs-stack4.11.0

Changes and improvements

Java 17

Since Expanders 6.0.0, the expanders jars are compiled for Java 17. This means that expansion can only be executed with JDK 17 or higher.

However, expanded code is still java 8 compatible.

enteredBy, enteredAt, lastModifiedBy and lastModifiedAt

There are some field names that, when used, would add additional behavior:

  • enteredAt: filled in with a timestamp when the instance is created
  • enteredBy: filled in with a dataRef to the user that created the instance
  • lastModifiedAt: updated with a timestamp each time the instance is modified
  • lastModifiedBy: updated with a dataRef to the user that modified it

There are now options that add the same behavior and can be added to any field (with the correct type).

  • enteredAt: option audit.create.timestamp
  • enteredBy: option audit.create.author
  • lastModifiedAt: option audit.modify.timestamp
  • lastModifiedBy: option audit.modify.author

The options are still implicitly added to the fields with those specific names.

Maven deprecation warnings

Maven builds will now show warnings when deprecated code is used. Can be disabled with maven.hideDeprecationWarnings.

Angular Expanders 4.2.0

· 3 min read
Jan Hardy
Jan Hardy
R&D Engineer

Changes and improvements

Upgrade to Angular 17 and Angular Material 17

In the previous release (4.1.x) we upgraded to from Angular 14 to 16, but used legacy Angular Material 14 components. Now we have upgraded completely to the latest 17 version.

Breaking change: in routing change name and isBreadcrumb data entries to breadcrumb. The former is replaced by breadcrumb and the latter has become obsolete.

Styling setup refactored

Breaking change: _theme-to-material-component-exposer.scss has been replaced with _theme-to-component-exposer.scss. Material expose mixin _theme-to-css-classes-exposer.scss has been deleted. Behaviour can be re-added custom if wanted.

Switch to Material symbols

We switched to Material symbols instead of Material icons as default icon font set.

Added use of Angular library

Created the ngx-ns-core library containing runtime components, services and directives. Some of the expanded components and services have already been migrated, e.g. sidebar, top-bar, breadcrumbs, etc.

REST Expanders 4.0.0

· 3 min read
Frédéric Hannes
Frédéric Hannes
R&D Engineer

Changes and improvements

Migrating to QuerySearch metamodel

Since version 3.x of rest-expanders, which was released just over a year ago, rest-expanders has integrated with querysearch-expanders by using the QuerySearch metamodel. This was introduced in such a way that it was 100% backwards compatible and also added to the model when expanding implicitly, so no change could really be observed from the perspective of an application developer.

Today the QuerySearch metamodel has matured to the point that what currently exists of the model is stable and will no longer have any big structural changes that are not additive. So with this version of rest-expanders, the implicitly added model will be removed. This means that it has to be defined in the model by the developer and coupled to the rest-expanders using the relevant jaxrs.querySearch option that has been implicitly used for quite some time.

The transmuters to add default REST APIs to the model have been modified to do this automatically, so in that sense, there will be no change to the way of interacting with rest-expanders in the majority of cases.

DataCommand options

In rest-expanders version 3.8.1, options were introduced to mark the DataCommands that are to be used for the CRUD operations in the REST API. Starting with this version, the validation to check if this has been migrated has been removed, as well as them being implicitly added to the model. We assume that every project has been migrated by now, but this will be the last version where the Upgrade transmutation for rest-expanders does this migration automatically.

Expanders using Data Resources

· 3 min read
Koen De Cock
Koen De Cock
R&D Engineer

DataResources have become a useful tool for expansion-resources to provide information to the Expanders. This post aims to describe how we can use the information provided by the data-resources in a set of Expanders, to gain insight in how the Expanders work. It gives a number of examples of Expanders using DataResources to make a list of libraries, option types and validation rules.

The data from DataResources is stored in a DataRegistryComposite. This object is available in mapping file as dataRegistry. The examples here will all work around the getComposites(String) method, which returns a list of all instances of an ElementType.

Expander 1. Listing libraries

Library elements define runtime libraries used by the expanded projects. The logic deciding which libraries are added to the pom.xml files depends on the LayerImplementations of each LayerTypes. This example omits that complexity and instead filters on Technologies.

<?xml version="1.0" encoding="UTF-8" ?>
<mapping xmlns="https://schemas.normalizedsystems.org/xsd/expanders/2023/1/0/mapping">
<list name="libraries" eval="dataRegistry.getComposites('net.democritus.settings.Library')"
param="lib">
<filter name="onlyApplicableLibraries" eval="technologies.has(lib.technology.name)"/>
<value name="name" eval="lib.name"/>
<value name="groupId" eval="lib.groupId"/>
<value name="artifactId" eval="lib.artifactId"/>
<value name="version" eval="lib.version"/>
<value name="technology" eval="lib.technology.name"/>
<value name="provider" eval="lib.getMetadata('origin.expansionResource').orElse('-')"/>
</list>
</mapping>
ExpansionResource metadata

Most DataResource elements contain metadata about the location where the data was found. To use, the most interesting information is the expansion-resource that declares this DataResource. This can be found by calling composite.getMetadata('origin.expansionResource'), which returns Optional<String>.

Expander 2. Listing deprecated option types

Most up-to-date expansion-resources declare the options they support as OptionTypes.

We can filter on OptionTypes with a deprecation warning or an expiration time. The example separates the options that have yet to be expired and the ones that have already expired.

<?xml version="1.0" encoding="UTF-8" ?>
<mapping xmlns="https://schemas.normalizedsystems.org/xsd/expanders/2023/0/0/mapping">
<let name="expirationHelper" eval="new org.normalizedsystems.example.OptionTypeExpirationHelper()"/>
<list name="deprecatedOptionTypes" eval="dataRegistry.getComposites('net.democritus.elements.OptionType')"
param="opt">
<filter name="deprecatedOptions" eval="not opt.deprecationWarning.empty or not opt.validUntil.empty"/>
<filter name="isNotExpired" eval="not expirationHelper.isExpired(opt)"/>
<value name="name" eval="opt.name"/>
<value name="validUntil" eval="opt.validUntil"/>
<value name="description" eval="opt.description.replace('\n', ' ')"/>
<value name="reason" eval="opt.deprecationWarning"/>
<value name="provider" eval="opt.getMetadata('origin.expansionResource').orElse('-')"/>
</list>
<list name="expiredOptionTypes" eval="dataRegistry.getComposites('net.democritus.elements.OptionType')"
param="opt">
<filter name="hasExpirationTime" eval="not opt.validUntil.empty"/>
<filter name="isExpired" eval="expirationHelper.isExpired(opt)"/>
<value name="name" eval="opt.name"/>
<value name="validUntil" eval="opt.validUntil"/>
<value name="description" eval="opt.description.replace('\n', ' ')"/>
<value name="reason" eval="opt.deprecationWarning"/>
<value name="provider" eval="opt.getMetadata('origin.expansionResource').orElse('-')"/>
</list>
</mapping>

Expander 3. Listing option types

We can also get a lot more information from the OptionType elements.

<?xml version="1.0" encoding="UTF-8" ?>
<mapping xmlns="https://schemas.normalizedsystems.org/xsd/expanders/2023/0/0/mapping">
<list name="optionTypes" eval="dataRegistry.getComposites('net.democritus.elements.OptionType')"
param="opt">
<filter name="notDeprecated" eval="opt.deprecationWarning.empty and opt.validUntil.empty"/>

<value name="name" eval="opt.name"/>
<value name="docLink" eval="opt.documentationLink"/>
<value name="hasDocLink" eval="not opt.documentationLink.empty"/>
<value name="alias" eval="opt.alias.replaceAll('\\s*,\\s*', ', ')"/>
<value name="hasAlias" eval="not opt.alias.empty"/>

<value name="description" eval="opt.description.replace('\n', ' ')"/>

<list name="properties" eval="{'alwaysEnabled', 'redundant', 'hidden', 'cascading'}" param="prop">
<filter name="isEnabled" eval="opt[prop]"/>
<value name="name" eval="prop"/>
</list>

<value name="provider" eval="opt.getMetadata('origin.expansionResource').orElse('-')"/>

<value name="defaultValue" eval="opt.defaultValue"/>
<value name="hasDefaultValue" eval="not opt.defaultValue.empty"/>
<group name="value" if="opt.valueConstraint neq null">
<value name="isRequired" eval="opt.valueConstraint.isRequired"/>
<value name="noValue" eval="opt.valueConstraint.noValue"/>
<value name="regex" eval="opt.valueConstraint.matchRegularExpression.replace('|', '&amp;#124;')"/>
<value name="hasRegex" eval="not opt.valueConstraint.matchRegularExpression.empty"/>
</group>

<list name="elementTypes" eval="opt.elementTypes" param="elementType">
<value name="name" eval="elementType.name"/>
</list>
</list>
</mapping>

Expander 4. Listing validation rules

ValidationRules (as well as Transmuters) are a bit special. We create ValidationRules by implementing classes and annotating them with @ValidationRule. However, behind the scenes an annotation-processor creates a DataResource files describing these ValidationRules.

And thus, the ValidationRules are also available as data in the DataRegistry.

To make everything run smoothly, it's best to add some dependencies on the validation metamodel:

<dependencies>
<dependency>
<groupId>net.democritus.validations.model</groupId>
<artifactId>validations-core</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>net.democritus.validations.model</groupId>
<artifactId>validations-test-support</artifactId>
<version>3.3.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<?xml version="1.0" encoding="UTF-8" ?>
<mapping xmlns="https://schemas.normalizedsystems.org/xsd/expanders/2023/0/0/mapping">
<list name="groups" eval="dataRegistry.getComposites('net.democritus.validations.ValidationGroup')"
param="group">
<value name="name" eval="group.name"/>
<value name="provider" eval="group.getMetadata('origin.expansionResource').orElse(null)"/>
<list name="rules" eval="group.rules" param="rule">
<value name="name" eval="rule.name"/>
<value name="element" eval="rule.element"/>
<value name="severity" eval="rule.severity.name"/>
<value name="description" eval="rule.description.replace('\n', ' ')"/>
</list>
</list>
</mapping>