wizard
The Live Configuration provides an infrastructure for configuring bundles directly inside an app.
Usage
After clicking the "Live Configuration" button a new window is displayed after a short loading time. The menu navigation is inspired by mobile devices. After configuration changes, an "update preview" button appears that allows to apply live changes to the app. To make the changes persistent, click "save app".
Use Cases
How to provide a custom configuration bundle
Custom configuration bundles can be integrated in the wizard's in-app configuration menu.
A configuration bundle is created as a sub-bundle of the bundle to configure and is named config
.
To allow configuration changes for a bundle, the bundle has to provide the config bundle location in its manifest.json
file.
"Config-Bundle-Location" : "/config",
How to provide a custom configuration widget
A configuration widget provides a UI for configuring one or more components using the configuration API (see "OSGi - Configuration" section in Development Guide). The wizard bundle expects following methods within a configuration widget.
define(["dijit/_Widget",function(_Widget){
// the methods expected in a configuration widget
return declare([_Widget],{
/**
Called by the wizard if this widget becomes visible.
The widget should read the current configuration at this point.
(optional)
*/
show : function(){},
/**
Called by the wizard if this widget becomes invisible (the user switches to another widget).
The widget should clear its internal state at this point.
(optional)
*/
hide : function(){},
/**
Called by the wizard if the user decides not to apply the configuration changes.
The widget should reset configuration changes at this point.
Only if this method exists allows the wizard the user to switch to another widget without applying configuration changes.
(optional)
*/
reset : function(){},
/**
The wizard listens on this method for configuration changes.
The "Apply" button is only visible if this event is fired.
As long as this event is not fired, the wizard assumes that there are no configuration changes.
The event object should have a property "config".
This property is transported untouched to the updateConfig method if the user applies the changes.
*/
onConfigChange: function(event){},
/**
Called by the wizard if the user applies the configuration changes.
The widget should use the configuration API to save the changes in the configuration subsystem.
*/
updateConfig: function(config){}
});
});
A custom configuration widget must be registered as dijit.wizard.Widget
with an id
property in the system.
The id
property is used to link the widget to a menu entry.
For more details, see the following sections.
wizard/_BuilderWidget
To make it easier to implement custom configuration widgets it is recommended to inherit from wizard/_BuilderWidget
.
define(["wizard/_BuilderWidget"], function(_BuilderWidget){
// sample of a custom _BuilderWidget
return declare([_BuilderWidget],{
// the bundle identifier
bid : "mybundle",
// the persistent identifier of the configuration entry
pid : "mybundle-ComponentNameToConfigure",
description : "a description at the top",
hint : "a info message at the top",
errorMessage : "a error message, displayed if isValid returns false",
// sample of a show method implementation
show : function(){
// retrieve configuration data from app.json file
// no default properties are read from the manifest.json file, they have to be defined manually
var currentConfigProperties = this.getComponentProperties();
// display the ui...
},
_onUserChangedConfiguration : function(){
// this method is provided by _BuilderWidget to trigger the onConfigChange event
this.fireConfigChangeEvent({
some_config_data : true
});
},
/**
Here validation code can be implemented.
This method is called by _BuilderWidget during the updateConfig method.
(optional)
*/
isValid : function(config){
var isValid = false;
// check if config is valid
return isValid;
}
});
});
A typical component registration of a custom configuration widget looks like the following in the manifest.json
file:
{
"name": "CustomBuilderWidget",
"provides" : ["dijit.wizard.Widget"],
"propertiesConstructor" : true,
"properties" : {
// the ID of the widget to link to the menu, this must be a unique id!
"id": "customComponentBuilderWidget"
},
"references": [{
"name": "configAdminService",
"providing": "ct.framework.api.ConfigurationAdmin"
}]
}
How to build configuration widgets based on the dataform bundle
The simplest way to provide a configuration widget is to utilize the class wizard/DataFormBuilderWidgetFactory
inside the manifest.json
file of the configuration widget.
With this the layout of the configuration UI can be defined in a JSON file without the need for programming.
// manifest.json
{
"name": "BuilderWidget",
"impl": "wizard/DataFormBuilderWidgetFactory",
"provides": ["dijit.wizard.Widget"],
"immediate": true,
"instanceFactory": true,
"properties" : {
// points to json file with the dataform definition
"dataformFile": "resource('./DataFormFile.json')",
// symbolic name of the configuring bundle
"bid": "custombundle",
// ID of the component (must be a combination of symbolic name and component name)
"pid": "custombundle-CustomComponent",
// unique ID to reference the menu entry
"id": "customComponentBuilderWidget",
// default properties of the widget
"defaultProperties": {
"property1" : "operational1",
"property2" : "operational2"
},
// a description of the widget
"description" : "Some bundle description",
// optional: a hint that is shown in the widget
"hint" : "Some additional hint",
// optional: css class for custom styles
"styleClass" : "ctCustomBundleBuilderWidget"
},
"references": [{
"name": "_configAdminService",
"providing": "ct.framework.api.ConfigurationAdmin"
},{
"name": "_dataformService",
"providing": "ct.bundles.dataform.DataFormService"
}]
}
How to link custom widgets with the menu structure
Each configuration bundle has to provide a BuilderEntry component that stores the properties for the menu integration.
If no widget
-property is defined for a node a category node is created.
In this case the children
-property has to be specified.
It defines an array with further category or widget nodes.
A description
-property can be used with information about this category.
Entries are sorted alphabetically by their titles unless no priority
-property is defined for a node.
The default priority is 0.
If any node defines a higher priority it is placed higher regardless of the alphabetical order.
The following code sample shows how the widget can be integrated in an existing parent node:
// manifest.json
{
"name" : "BuilderEntry",
"impl" : "ct.Stateful",
"provides" : ["ct.bundles.wizard.MenuEntry"],
"propertiesConstructor" : true,
"properties" : {
// optional: parent node id
"parentNodeId" : "appBuilderMapWidgetsNode",
"menuNode" : {
"title": "Custom Widget",
"iconUrl": "resource('styles/images/bundleIcon.png')",
"widget" : "customComponentBuilderWidget"
}
}
}
The configuration menu entry is only visible if the corresponding bundle is available in the app.
Default Menu Structure
The Live Configuration provides only the basic menu structure.
The following default nodes can be used as value for parentNodeId
:
appBuilderContentNode
appBuilderSearchNode
appBuilderToolsNode