Managing Folders and Forms¶
Forms are essential tools for users to navigate and manipulate data in the context of plans. Forms are designed interactively using the QVANTUM Web application frontend. Forms can be structured by using folders. On top of interactive form design, QVANTUM provides means for exporting and importing all folders and forms using a JSON-based representation format. This functionality is also available as part of the QVANTUM Public API.
Folders and Forms Export¶
An export of a JSON representation of all existing folder and form definitions (including invalid form definitions) is
possible with a single GET request to the allExternalForms link under a cube resource.
In order to retrieve folder and form definition data, request header Accept must be set to the custom MIME type application/
x.de.qvantum-plan.external-forms+json.
curl --silent --request GET \
--header "Authorization:Bearer ${TOKEN}" \
--header "Accept:application/x.de.qvantum-plan.external-forms+json" \
"${ALL_FORMS_LINK}"
Folders and Forms Import¶
An import of an existing JSON representation of all folder and form definitions is possible with a single PUT request to the
allForms link under a cube resource.
In order to import folder and form definition data, request header Content-Type must be set to the custom MIME type
application/x.de.qvantum-plan.external-forms+json.
Warning
An import of folder and form definitions effectively replaces all previously existing folder and form definitions in the context of the given plan.
curl --silent --show-headers --request PUT \
--header "Authorization:Bearer ${TOKEN}" \
--header "Content-Type:application/x.de.qvantum-plan.external-forms+json" \
--data @../json/forms-exported.json \
"${ALL_FORMS_LINK}"
Folder and Form Definition¶
This section provides information on the syntax elements of the JSON representation for folder and form definitions, breaking down from a list of folders or forms to the individual elements of a single folder or form definition.
List of Folders and Forms¶
On top-level, a forms definition consists of one element forms holding an array of single folder and form definitions.
{
"forms": [
<FOLDER_OR_FORM_DEFINITION_1>,
...
<FOLDER_OR_FORM_DEFINITION_N>
]
}
Single Folder¶
A folder is defined by the type "FOLDER", a display name, and an array of children representing the folders and forms contained within this folder.
{
"type": "FOLDER",
"displayName": "Folder 1",
"children": [
<FOLDER_OR_FORM_DEFINITION_1>,
...
<FOLDER_OR_FORM_DEFINITION_N>
]
}
Single Form¶
A form is defined by the type "FORM", a display name, a form header, a row axis and a column axis.
{
"type": "FORM",
"displayName": "Form 1",
"sharedWith": <SHARED_WITH_DEFINITION>,
"formats": <FORMATS_DEFINITION>,
"formHeader": <FORM_HEADER_DEFINITION>,
"rowAxis": <FORM_AXIS_DEFINITION>,
"columnAxis": <FORM_AXIS_DEFINITION>
}
Shared With¶
The "shared with" setting defines who is allowed to see the form. Controller users will always be able to see all forms, the restrictions only apply to planner users.
There are two possible configurations: sharing the form with all planners or no planners.
{
"type": "ALL"
}
{
"type": "NONE"
}
Formats¶
Most cells of a form can be formatted.
All formatting of a form is defined in a single place: the optional top-level element formats.
It consists of up to three arrays of format entries:
rows: entries formatting entire rowscolumns: entries formatting entire columnscells: entries formatting individual cells
<FORMATS_DEFINITION> = {
"rows": [ <FORMAT_ENTRY>, ... ],
"columns": [ <FORMAT_ENTRY>, ... ],
"cells": [ <FORMAT_ENTRY>, ... ]
}
Each format entry addresses one or two axis elements and defines a style and/or a column width for them:
rowElement: a reference to an element of the row axis (cf. Axis Element References). Required forrowsandcellsentries, not allowed forcolumnsentries.columnElement: a reference to an element of the column axis. Required forcolumnsandcellsentries, not allowed forrowsentries.style: an optional style applied to all addressed cells.columnWidth: an optional width in pixels. Only relevant for entries addressing a column.
<FORMATS_DEFINITION> = {
"rows": [
{
"rowElement": <AXIS_ELEMENT_REFERENCE>,
"style": {
"bold": true,
"backgroundColor": "#00FF00"
}
}
],
"columns": [
{
"columnElement": <AXIS_ELEMENT_REFERENCE>,
"style": {
"italic": true,
"textColor": "#0000FF"
},
"columnWidth": 142
}
],
"cells": [
{
"rowElement": <AXIS_ELEMENT_REFERENCE>,
"columnElement": <AXIS_ELEMENT_REFERENCE>,
"style": {
"bold": true
}
}
]
}
A style consists of the optional properties bold, italic, backgroundColor and textColor.
For the bold and italic options, only the value true is allowed.
Elements will be not bold (not italic) by default, that is if no format indicates they should be bold (italic).
It is not possible to explicitly format elements as not bold or not italic.
Colors are defined via their RGB hex codes (e.g. #FF0000 for red).
Axis Element References¶
How an axis element is referenced depends on the type of the axis it belongs to
(cf. Form Axis).
The type of the reference must match the type of the axis on the corresponding side of the form.
An element of a dimension axis is referenced with type DIMENSION_AXIS_ELEMENT and a path containing
the dimension and the structure element business key:
<AXIS_ELEMENT_REFERENCE> = {
"type": "DIMENSION_AXIS_ELEMENT",
"path": [
{
"dimension": "Costs",
"structureElementBusinessKey": "CST050"
}
]
}
An element of a nested leaves axis is referenced with type NESTED_LEAVES_AXIS_ELEMENT.
Here, the path consists of the elements displayed in the axis,
starting from the root to the element to be formatted.
For example, to format an element of the first dimension,
the path only consists of a single entry with the first dimension key and the business key
of the structure element to be formatted.
To format an element in the second dimension, it is necessary to define the element in the first dimension
under which the element in the second dimension should be formatted.
This example references the element "CCT020" under the element "CST050":
<AXIS_ELEMENT_REFERENCE> = {
"type": "NESTED_LEAVES_AXIS_ELEMENT",
"path": [
{
"dimension": "Costs",
"structureElementBusinessKey": "CST050"
},
{
"dimension": "Cost Centers",
"structureElementBusinessKey": "CCT020"
}
]
}
An element of a nested layers axis is referenced with type NESTED_LAYERS_AXIS_ELEMENT and uses the same
path structure as NESTED_LEAVES_AXIS_ELEMENT.
However, the path consists of the structure elements in the used layers (as opposed to only leaves).
The entry at each index of the path must refer to an element on the layer with the same index or it can be null
if no element exists on that layer under the current path.
The last element cannot be null.
Similar to nested leaves axes the path can have less elements than there are layers.
An element of a custom axis is referenced with type CUSTOM_AXIS_ELEMENT and the key of the custom axis element
(cf. Form Custom Axis).
With isComment set to true, the reference addresses the comment fields of a stored custom axis element
instead of its value cells.
<AXIS_ELEMENT_REFERENCE> = {
"type": "CUSTOM_AXIS_ELEMENT",
"key": "0",
"isComment": false
}
Custom attributes displayed in a form can be formatted as well.
A custom attribute is always displayed on the opposite side of the axis that uses its dimension:
for example, custom attributes of a dimension used in the row axis are displayed as columns.
A custom attribute is referenced on the side where it is displayed,
with type CUSTOM_ATTRIBUTE_ELEMENT, its dimension and its customAttributeBusinessKey:
<AXIS_ELEMENT_REFERENCE> = {
"type": "CUSTOM_ATTRIBUTE_ELEMENT",
"dimension": "Costs",
"customAttributeBusinessKey": "attribute"
}
Form Header¶
A form header defines which element is selected for each dimension in terms of cube navigation. Such an element selection is only relevant for dimensions used in form dimension axes and for dimensions not used in any axis. For dimensions used in form custom axes, element selection is given in each individual custom axis element definition and thus irrelevant for the form header definition. A special element selection is possible for the synthetic super-root node of each dimension structure. Additionally, header dimensions can be fixed to a single element or configured to force explicit element selection for planners.
Consider the following form:
- All Scenarios are put into the rows as form dimension axis.
- Cost Centers are put into the columns as only dimension in a form custom axis.
- Regarding Costs, the form selects dimension element with business key "CST000".
- For Variants dimension element selection is disabled for planners.
- For Years dimension element selection is explicitly forced for all planners.
The following form header definition represents this:
<FORM_HEADER_DEFINITION> = {
"Scenarios": {
"type": "ALL"
},
"Cost Centers": {
"type": "DEFINED_BY_AXIS"
},
"Costs": {
"type": "NODE",
"structureElementBusinessKey": "CST000",
"fixationMode": "NOT_FIXED"
},
"Variants": {
"type": "NODE",
"structureElementBusinessKey": "FINAL",
"fixationMode": "FIXED"
},
"Years": {
"type": "NONE"
}
}
- The Scenarios dimension is used in a form dimension axis.
Thus, a selection is relevant, and we select all elements by setting
typeto_ALL_. - The Cost Centers dimension is used in a form custom axis.
A header selection is not possible.
Thus, we use
type_DEFINED_BY_AXIS_. - The Costs dimension is not used in any axis and thus requires selection.
Here, we select a specific element by its business key.
Thus, we set
typeto_NODE_andstructureElementBusinessKeytoCST000. Selection is not fixed, thus usingfixationModeNOT_FIXED. - The Variants dimension is also not used in any axis.
Here we not only select the specific element "FINAL", but we also prevent planners from changing this element by
setting
fixationModeto_FIXED_. - The Years dimension is also not used in any axis.
Here, we define no prior selection by using
type_NONE_, thus explicitly forcing element selection by planners.
Form Axis¶
Forms support multiple different types of axes which can be independently selected for rows and columns. These types are
- dimension axis which simply represents the whole forest or a sub tree of the underlying structure
- nested leaves axis which interleaves (physical) leaves of multiple dimensions
- nested layers axis which interleaves elements on multiple layers in one or more dimensions
- custom axis which allows to define elements representing specific combinations of dimension elements, cell comments and elements calculating formulas based on other elements in this axis.
It is not possible to use a single dimension in both the rows and the columns at the same time.
Common Properties¶
Some properties are shared by all axis types.
- hideElements allows for defining filters about what elements are shown in an axis (cf. Form Axis Element Display Filter).
- widthInPixels specifies the width of the axis header column if the axis is used as a row axis in a form.
<FORM_AXIS_DEFINITION> = {
"hideElements": <HIDE_ELEMENTS_FILTER>,
"widthInPixels": 255,
...
}
Form Dimension Axis¶
An axis with a type of DIMENSION_AXIS is a dimension axis.
It has exactly one specific dimension, referred to by its business key
and an expansionState describing which structure elements are expanded or collapsed.
Its axis elements and custom attributes displayed in the other axis can be formatted
(cf. Formats).
{
"type": "DIMENSION_AXIS",
"hideElements": <HIDE_ELEMENTS_FILTER>,
"widthInPixels": 145,
"dimension": "Costs",
"expansionState": <DIMENSION_AXIS_EXPANSION_STATE>
}
<DIMENSION_AXIS_EXPANSION_STATE> = {
"default": "COLLAPSED",
"exceptions": [
{
"path": [
{
"dimension": "Months",
"structureElementBusinessKey": "Q1"
}
]
},
{
"path": [
{
"dimension": "Months",
"structureElementBusinessKey": "Q2"
}
]
]
}
Form Nested Leaves Axis¶
An axis of type of NESTED_LEAVES_AXIS is a nested leaves axis.
It has a list of dimensions, given by their business keys.
The list of dimensions for nesting together with their definitions of corresponding form header elements define,
which elements are finally part of the resulting synthetic nested structure.
The example below shows a nested leaves axis nesting two dimensions.
{
"type": "NESTED_LEAVES_AXIS",
"hideElements": <HIDE_ELEMENTS_FILTER>,
"widthInPixels": 145,
"dimensions": [
"Scenarios",
"Cost Centers"
],
"expansionState": <NESTED_LEAVES_AXIS_EXPANSION_STATE>
}
Similar to a dimension axis it is possible to specify which elements are expanded or collapsed and how they are formatted (cf. Formats).
The expansion state uses the path to the element to be expanded or collapsed. Such a path consists of the elements displayed in the axis, starting from the root to the element to be addressed. Note that these are always leaves in the underlying structure. Here all but the two elements "Department North" and "Department South" under "Total Year" are expanded.
<NESTED_LEAVES_AXIS_EXPANSION_STATE> = {
"default": "EXPANDED",
"exceptions": [
{
"path": [
{
"dimension": "Months",
"structureElementBusinessKey": "Total Year"
},
{
"dimension": "Cost Center",
"structureElementBusinessKey": "Department North"
}
]
},
{
"path": [
{
"dimension": "Months",
"structureElementBusinessKey": "Total Year"
},
{
"dimension": "Cost Center",
"structureElementBusinessKey": "Department South"
}
]
]
}
In addition to the above definition of a nested leaves axis, involving the two dimensions Scenarios and Cost Centers, consider the following selection of form header elements for the two dimensions. * Scenarios: All * Cost Centers: Administration
The resulting nested axis structure is the following:
* Actual
* General Administration
* IT Administration
* Forecast
* General Administration
* IT Administration
* Plan
* General Administration
* IT Administration
Also consider another selection of form header elements.
- Scenarios: Plan
- Cost Centers: All
The resulting nested axis structure is the following:
* Plan
* Sales
* General Administration
* IT Administration
Form Nested Layers Axis¶
An axis with type NESTED_LAYERS_AXIS is a nested layers axis.
Nested layer axes must always hide empty elements.
They have layers which are identified by the dimension and a layer in the structure in this dimension.
{
"type": "NESTED_LAYERS_AXIS",
...
"hideElements": [ "EMPTY" ],
"layers": [
{
"dimension": { "pluralName": <dimension.pluralName> },
"layer": { "businessKey": <layer.businessKey> }
}, ...
]
"expansionState": <NESTED_LAYERS_AXIS_EXPANSION_STATE>
}
<NESTED_LAYERS_AXIS_EXPANSION_STATE> uses the same JSON
structure as <NESTED_LEAVES_AXIS_EXPANSION_STATE>.
However, the paths consists of the structure elements in the used layers (as opposed to only leaves).
The index in the path must refer to an element on the layer with the same index or it can be null
if no element exists on that layer under the current path.
The last element cannot be null.
Similar to nested leaves axes the path can have less elements than there are layers.
Axis elements and custom attributes displayed in the other axis can be formatted (cf. Formats).
Form Custom Axis¶
An axis with type CUSTOM_AXIS is a custom axis.
Custom axes are fundamentally different from the previous types as each element is specified explicitly.
It has a customAxisHeaderDimensions definition, and a customAxisElements definition.
First and foremost, a custom axis is defined for a list of dimensions.
Each custom axis element definition in turn consists of a tuple of business keys referring to structure elements of the
respective dimensions.
Custom axes also can be formatted (cf. Formats), but expanding is not meaningful.
{
"type": "CUSTOM_AXIS",
"hideElements": <HIDE_ELEMENTS_FILTER>,
"customAxisHeaderDimensions": <CUSTOM_AXIS_HEADER_DIMENSIONS_DEFINITION>,
"customAxisElements": <CUSTOM_AXIS_ELEMENTS_DEFINITION>
"widthInPixels": 145
}
Custom axis header dimensions are defined as an array consisting of a dimension specified by its business key,
and an aspectElementLabelMode, allowing to control rendering of axis element labels either as display name
(DISPLAY_NAME) or business key (BUSINESS_KEY).
The name of this property is deprecated and will probably change in the future.
<CUSTOM_AXIS_HEADER_DIMENSIONS_DEFINITION> = [
{
"dimension": "Scenarios",
"aspectElementLabelMode": "DISPLAY_NAME"
},
{
"dimension": "Cost Centers",
"aspectElementLabelMode": "BUSINESS_KEY"
}
]
Custom axis elements support two different types, i.e. stored and formula elements.
A stored custom axis element is defined by its type STORED, a list of aspectElements for the respective custom
axis header dimensions, given as business keys, thus providing partial coordinates of a stored cube cell.
The name aspectElements is deprecated.
In order to refer to these custom axis elements in formulas, as defined for formula custom axis elements, each custom
axis element defines a key.
Furthermore, a stored custom axis element can be defined as input allowed (YES) or not (NO).
Each stored custom axis element additionally allows to optionally display comment fields for the respective cube cells
shown in this axis.
Comment fields are defined with a comment type and a list of comment suggestions.
commentTypeNONE: comment fields disabledFREE: comment fields enabled for free text commentsFREE_WITH_SUGGESTIONS: comment fields enabled for free text comments, supported with a list of suggestions as defined incommentSuggestions
The value cells and comment fields of a stored custom axis element can be formatted via its key
(cf. Axis Element References).
Continuing with the dimensions used in the previous example, an individual custom axis element representing the scenario "ACTUAL" and the Cost Center "CCT021" can look like this.
{
"type": "STORED",
"key": "0",
"inputAllowed": "NO",
"aspectElements": [
"ACTUAL",
"CCT021"
],
"commentType": "NONE",
"commentSuggestions": [
"good",
"bad"
]
}
The definition of a formula custom axis element consists of the following fields:
* type: always FORMULA
* key: a unique key for reference in other formula elements
* formula: the formula of this element. Supports the same operations as the
key figure formulas, except for the sumOfChildren and timeOffset functions.
Other axis elements are referenced via their keys (e.g. [0])
* header: the header label describing the axis element
* negativeValuesHighlighted: whether negative values are highlighted
* valueTypeReference: a reference to a value type. Used for formatting (cf. value types)
The cells of a formula custom axis element can be formatted via its key
(cf. Axis Element References).
{
"type": "FORMULA",
"key": "2",
"header": "Abweichung Actual/Plan %",
"formula": "(([1]-[0])/[0])*100",
"negativeValuesHighlighted": true,
"valueTypeReference": {
"businessKey": "Menge"
}
}
Form Axis Element Filter¶
Each axis definition includes a filter hideElements, stating whether certain axis elements are hidden or not.
Currently, QVANTUM supports only one filter EMPTY stating whether axis elements with all involved cube cells being
empty are hidden or not.
"hideElements": []
"hideElements": [
"EMPTY"
]
Converting Old Format Definitions¶
In earlier versions of QVANTUM, form formatting was defined differently:
the top-level element formats was a map of reusable cell formats keyed by identifiers,
and the formatted elements referenced these identifiers in properties spread across the form definition:
formatsarrays (withpath,formatandwidthInPixels) on dimension, nested leaves and nested layers axescustomAttributeFormatsarrays on dimension, nested layers and custom axesformat,widthInPixels,commentFormatandcommentWidthInPixelsproperties on custom axis elements
These properties are no longer supported.
Warning
Importing a form definition that still uses the old format model does not fail: the old format properties are simply ignored and the forms are imported without any formatting. Make sure to convert old form definitions to the new format model before importing them.
There are two ways to obtain form definitions using the new format model:
- Form definitions stored in QVANTUM were converted automatically when the format model changed. A fresh export therefore always uses the new format model.
- For form definition files you keep outside of QVANTUM, use the form formats converter. Paste an exported JSON document (or drop a file) and download the converted result. The converter runs entirely in your browser, so your form definitions never leave your machine; you can also save the page and open it locally. It accepts a whole export document, a single folder or form definition, or a list of them, converts all contained forms and reports what was converted.
If you maintain your own tooling that produces form definitions, adjust it according to the following rules:
| Old definition | New definition |
|---|---|
top-level formats map of cell formats |
removed; each style is written directly into the format entries that used its identifier |
axis formats entry with a path |
entry in rows or columns with a DIMENSION, NESTED_LEAVES or NESTED_LAYERS element reference |
customAttributeFormats entry |
entry in rows or columns on the side opposite to the axis, with a CUSTOM_ATTRIBUTE element reference |
format / widthInPixels on a custom axis element |
entry in rows or columns (the side of the custom axis) with a CUSTOM element reference and "isComment": false |
commentFormat / commentWidthInPixels on a stored custom axis element |
entry with a CUSTOM element reference and "isComment": true |
widthInPixels in any of the above |
columnWidth of the new format entry |
Important
A full interaction path with the QVANTUM Public API for forms definition export and import is demonstrated in the
script qvantum-forms-export-import.sh for use with our sample data set.
Additionally, we provide a complete forms definition example JSON representation in ./json/forms-pretty.json.