Before this the WizardEditor only supported a single level of inputs of basic types,
meaning no arrays, no objects, and no recursion. The DOI metadata import use case
quickly showed that the previous state was not sufficient at all.
This commit introduces support for arrays, objects, indefinite recursion, and buttons.
Arrays are configured by input key-value 'multi_valued: true'. Objects are configured
by input type 'object' and can receive its child-level input specification via its own
'inputs' key. Buttons are configured by input type 'button' and can specify which
function to run via the 'on_click.call' option. If in addition the 'on_click.plugin'
is provided, the function to call will be retrieved from the context of the provided
(and presumably autoregistered) plugin.
Additional support is also provided for rendering a custom component inside the
WizardEditor component, as opposed to the current approach of rendering each input
based on config specification. The component feature was also introduced when it became
clear that the complexity of the DOI metadata import use case could not be achieved using
the standard input specification use case. Custom components are specified via the root
'component' key for a given wizard spec, and its value should be provided in the format
'plugin_name:component_name'.
Here is an example wizard configuration using all new options:
DOIImportWizard:
name: DOI Import Wizard
component: doi:DOIFetcher
inputs:
- prop: doi
type: text
required: true
- prop: import
type: button
on_click:
plugin: doi
call: importMetadata
- prop: title
type: text
required: true
- prop: abstract
type: text-paragraph
- prop: authors
type: object
multi_valued: true
inputs:
- prop: pid
type: text
- prop: given_name
type: text
- prop: family_name
type: text
- prop: role
type: text
multi_valued: true
template: content:DOIImportWizardTemplate
To support the new input specifications, the WizardEditor was refactored into a set of
self-contained components that support recursion.
Finally, the WizardEditor also supports the rendering of a custom component instead of
configured inputs. When a component is specified, it will be rendered instead of all
specified inputs. It is important to note that these inputs that will be used for the
template-filling procedure of the wizard should all still be specified, as they are used
by the WizardEditor to manage state between parent/child components and between the wizard
and the templating mechanism.
Before this, the fillStringTemplate method was a simple, and the only, template filling
procedure that replaced variables in a string template, surrounded by curly braces, with
their values. No logic, no loops, no further support. This was not sufficient for cases
where the wizardeditor needed to support inputs of type arrays or objects. With previous
experience with jinja, nunjucks looked like a sensible library to add such support.
Templates included via the existing 'content' configuration option can now also be supplied
as nunjucks templates. These have to have the string '.nunjucks' precede the extension of
the filename, in order to be recognized as a nunjucks template. E.g. 'MyTemplate.nunjucks.ttl'.
New utility and configuration composable code allows getting the template type, and the
wizardeditor will use this type to either call the existing fillStringTemplate function,
or the new nunjucks code supplied by the new useNunjucks composable.
This provides shacl-vue with the ability to support the use of plugin modules and plugin
components. The existing index.js now also lets the app use runtime-plugins, which is
a catch-all for all plugin code that is included in 'runtime-plugins/plugin_name/' before
the the application is built with Vite. The plugin module should be located at
'runtime-plugins/plugin_name/index.js' and any components should be located at
'runtime-plugins/plugin_name/*.vue' in order for them to be autoregistered. These plugins
are then made available to any component in the whole via inject('runtimePlugins'). Plugin
module exports are then available at runtimePlugins['plugin_name'].api and plugin components
are available at runtimePlugins['plugin_name'].components.
This functionality allows complex and domain-specific logic and UI to be inclued in a
shacl-vue build, while shacl-vue keeps its domain-agnosticity. It was developed in part
because of the need to inject complex functionality and rendering logic into the wizard
editor mechanism.