Some thoughts on the implementation of this viewer...
Housekeeping
- implement in the incubator - Andi Huber has done the legwork here already
- use current coding standards - as per https://apache-isis-committers.github.io/isis-nightly/setupguide/intellij/about.html#configuring
Vision
- provide a continuum from completely generic UI through to a completely custom UI
- problem solver ↔ process follower
- should be able to "escape from the box", but not be a jarring experience for the end-user
- everything should be a WebComponent, leverage this as a basic standard
- meaning not just Vaadin WC's, but also third-party
- to also support custom value types
- this will require enhancements/extensions to the core metamodel
- fully UI tested, so no regressions.
- responsive design, so can run on mobile/tablet just as easily as desktop
- a more sophisticated type-safe UI model
- in addition to xxx.layout.xml support
Architecture
- server-side (rather than over the REST API), similar to the Wicket viewer
- NB: we don't yet have a formal public API to query/consume the metamodel ... it would be nice to factor one out as a side-effect of this work.
- suggest a UI similar to the Wicket viewer, and honouring the layout.xml grid
- of course, it won't use bootstrap3, instead can use Vaadin layouts to get to the same effect
- the sidebar works well
- similar to Wicket viewer, suggest using the chain-of-responsibility pattern
- idea is that this can render any part of the page, and allow the developer to intercept at either a coarse-grained level (eg an entire domain object), successively moving down to more fine-grained components.
- at a more fine-grained level, we have custom renderings of tables (can be either standalone or parented)
- eg map, fullcalendar, excel (download link)
- at more fine-grained since, we have custom rendering of properties
- eg Asciidoc, Markdown, Summernote, PDF
- should try to find a way to make this easily extensible for third party web components
- the Wicket viewer has quite a complex hinting mechanism, which probably is valuable enough to be re-implemented
Testing
- extend demo app, incorporate the stuff also in kitchensink
- use https://www.cypress.io/ for testing
- should run in headless mode, possibly leverage Docker and perhaps https://www.testcontainers.org/ to start up the demo app and orchestrate cypress tests
Possible Features
... that the Wicket viewer doesn't do so well...
- field that's half-way between text and autocomplete/choices (Wicket only does one or the other)
- paging/filtering/sorting of tables
- shelf of recent items, drag/drop ?
- most recent items
- invoke action on a panel, should replace entire panel
Possible Future requirements
(as these might impact the architecture):
- custom value types
- support both in action parameters and in properties
- over time, these will take over from the concept of a property group/panel
- detachable areas of the page, eg move PDFs onto a separate tab/window
- dynamic properties or collections
- this would be an extension to the programming model, returning a Mono<> or a Flux<> etc
- would be updated dynamically.
- distributed tracing support
- so can profile the time to render the different parts of the page
- dynamic configuration/JMX/logging
Out of scope
- no need to worry about the complexity of bulk actions, as these will disappear in v2.0
- instead we use view models
Typesafe UI Model - Ideas regarding its Implementation
Background:
Alf's NO framework uses String constants in the domain classes for each domain class member (property, collection, action). His UI model builder (which is a fluent programmatic builder to create an in-memory structure analogous to the BS3Grid uses these string constants. They choose String constants because it's very light weight with no external deps and referenceable in Annotations. It is often used to quickly jump from the ui definition to the property.
Pojo example:
@Anno(prop_ref=Bar.PROP_foo)
class Bar {
public static final String PROP_foo = "foo";
Foo getFoo()
}
The Apache Isis model doesn't have any mandated mechanism to reference domain class members in a type-safe way. (If we were using C# then there would be a way to do this, but, well, we aren't).
However, it is very common for each domain member to have a corresponding domain event class, which is then used to emit events and allow for fine-grained subscribers, eg:
public class UpdateNameEvent extends ActionDomainEvent<Customer> {}
@Action(domainEvent=UpdateNameEvent.class)
public Customer updateName(String newName) { ... }
What the Vaadin programmatic UI model could therefore do is to use this domain event as a proxy to represent the domain class member. There could be a metamodel validator that ensures that each such domain class is used only once on an annotation. Any members that don't have a domain event would not be referenceable, and would either not appear or would be grouped into an "other" category.
Note that this mechanism would also work for mixins, though there would be nothing to prevent the developer from accidentally referencing a mixin's domain event for a "foreign" mixin that doesn't contribute to the domain class under consideration. Again, a metamodel validator would be able to take care of this.
The question is for what to we need the compile type safety. For example UI definitions are mostly simple tree structures, they form often a tree, which can only have one generic node type.